GTIRB  v2.1.0
GrammaTech Intermediate Representation for Binaries: C++ API
Section.hpp
Go to the documentation of this file.
1 //===- Section.hpp ----------------------------------------------*- C++ -*-===//
2 //
3 // Copyright (C) 2020 GrammaTech, Inc.
4 //
5 // This code is licensed under the MIT license. See the LICENSE file in the
6 // project root for license terms.
7 //
8 // This project is sponsored by the Office of Naval Research, One Liberty
9 // Center, 875 N. Randolph Street, Arlington, VA 22203 under contract #
10 // N68335-17-C-0700. The content of the information does not necessarily
11 // reflect the position or policy of the Government and no official
12 // endorsement should be inferred.
13 //
14 //===----------------------------------------------------------------------===//
15 #ifndef GTIRB_SECTION_H
16 #define GTIRB_SECTION_H
17 
18 #include <gtirb/Addr.hpp>
19 #include <gtirb/ByteInterval.hpp>
20 #include <gtirb/CodeBlock.hpp>
21 #include <gtirb/DataBlock.hpp>
22 #include <gtirb/Node.hpp>
23 #include <gtirb/Observer.hpp>
24 #include <gtirb/Utility.hpp>
25 #include <gtirb/proto/Section.pb.h>
26 #include <algorithm>
27 #include <boost/icl/interval_map.hpp>
28 #include <boost/iterator/indirect_iterator.hpp>
29 #include <boost/iterator/iterator_traits.hpp>
30 #include <boost/multi_index/hashed_index.hpp>
31 #include <boost/multi_index/key_extractors.hpp>
32 #include <boost/multi_index/mem_fun.hpp>
33 #include <boost/multi_index/ordered_index.hpp>
34 #include <boost/range/iterator_range.hpp>
35 #include <cstdint>
36 #include <functional>
37 #include <set>
38 
41 
42 namespace gtirb {
43 class Module; // Forward declared for the backpointer.
44 class SectionObserver;
45 template <typename T> class ErrorOr;
46 
50 enum class SectionFlag : uint8_t {
51  Undefined = proto::SectionFlag::Section_Undefined,
52  Readable = proto::SectionFlag::Readable,
53  Writable = proto::SectionFlag::Writable,
54  Executable = proto::SectionFlag::Executable,
55  Loaded = proto::SectionFlag::Loaded,
56  Initialized = proto::SectionFlag::Initialized,
57  ThreadLocal = proto::SectionFlag::ThreadLocal,
58 };
59 
66 class GTIRB_EXPORT_API Section : public Node {
67  Section(Context& C);
68  Section(Context& C, const std::string& N);
69  Section(Context& C, const std::string& N, const UUID& U);
70 
71  static Section* Create(Context& C, const std::string& Name, const UUID& U) {
72  return C.Create<Section>(C, Name, U);
73  }
74 
75  struct by_address {};
76  struct by_pointer {};
77 
78  using ByteIntervalSet = boost::multi_index::multi_index_container<
79  ByteInterval*,
80  boost::multi_index::indexed_by<
81  boost::multi_index::ordered_non_unique<
82  boost::multi_index::tag<by_address>,
83  boost::multi_index::identity<ByteInterval*>, AddressLess>,
84  boost::multi_index::hashed_unique<
85  boost::multi_index::tag<by_pointer>,
86  boost::multi_index::identity<ByteInterval*>>>>;
87  using ByteIntervalIntMap =
88  boost::icl::interval_map<Addr, std::set<ByteInterval*, AddressLess>>;
89 
90  class ByteIntervalObserverImpl;
91 
92 public:
96  static Section* Create(Context& C) { return C.Create<Section>(C); }
97 
104  static Section* Create(Context& C, const std::string& Name) {
105  return C.Create<Section>(C, Name);
106  }
107 
109  bool operator==(const Section& Other) const;
110 
112  bool operator!=(const Section& Other) const;
113 
115  Module* getModule() { return Parent; }
117  const Module* getModule() const { return Parent; }
118 
122  const std::string& getName() const { return Name; }
123 
127  void addFlag(SectionFlag F) { Flags.insert(F); }
128 
132  template <typename... Fs> void addFlags(Fs... F) { (addFlag(F), ...); }
133 
137  void removeFlag(SectionFlag F) { Flags.erase(F); }
138 
143  bool isFlagSet(SectionFlag F) const {
144  return std::find(Flags.begin(), Flags.end(), F) != Flags.end();
145  }
146 
148  using const_section_flag_iterator = std::set<SectionFlag>::const_iterator;
151  boost::iterator_range<const_section_flag_iterator>;
152 
154  const_section_flag_iterator flags_begin() const { return Flags.begin(); }
157  const_section_flag_iterator flags_end() const { return Flags.end(); }
160  return boost::make_iterator_range(flags_begin(), flags_end());
161  }
162 
164  using byte_interval_iterator =
165  boost::indirect_iterator<ByteIntervalSet::iterator>;
167  using byte_interval_range = boost::iterator_range<byte_interval_iterator>;
169  using byte_interval_subrange = boost::iterator_range<
170  boost::indirect_iterator<ByteIntervalIntMap::codomain_type::iterator>>;
173  boost::indirect_iterator<ByteIntervalSet::const_iterator,
174  const ByteInterval>;
177  boost::iterator_range<const_byte_interval_iterator>;
180  boost::iterator_range<boost::indirect_iterator<
181  ByteIntervalIntMap::codomain_type::const_iterator>>;
182 
185  return ByteIntervals.begin();
186  }
189  return ByteIntervals.begin();
190  }
193  byte_interval_iterator byte_intervals_end() { return ByteIntervals.end(); }
197  return ByteIntervals.end();
198  }
201  return boost::make_iterator_range(byte_intervals_begin(),
202  byte_intervals_end());
203  }
207  return boost::make_iterator_range(byte_intervals_begin(),
208  byte_intervals_end());
209  }
210 
219  if (auto It = ByteIntervalAddrs.find(A); It != ByteIntervalAddrs.end()) {
220  return boost::make_iterator_range(
221  boost::make_indirect_iterator(It->second.begin()),
222  boost::make_indirect_iterator(It->second.end()));
223  }
224  return {};
225  }
226 
235  if (auto It = ByteIntervalAddrs.find(A); It != ByteIntervalAddrs.end()) {
236  return boost::make_iterator_range(
237  boost::make_indirect_iterator(It->second.begin()),
238  boost::make_indirect_iterator(It->second.end()));
239  }
240  return {};
241  }
242 
249  auto Pair = ByteIntervals.get<by_address>().equal_range(A);
250  return boost::make_iterator_range(byte_interval_iterator(Pair.first),
251  byte_interval_iterator(Pair.second));
252  }
253 
262  auto& Index = ByteIntervals.get<by_address>();
263  if (High < Low) {
264  return boost::make_iterator_range(Index.end(), Index.end());
265  }
266  return boost::make_iterator_range(
267  byte_interval_iterator(Index.lower_bound(Low)),
268  byte_interval_iterator(Index.lower_bound(High)));
269  }
270 
277  auto Pair = ByteIntervals.get<by_address>().equal_range(A);
278  return boost::make_iterator_range(
279  const_byte_interval_iterator(Pair.first),
280  const_byte_interval_iterator(Pair.second));
281  }
282 
291  auto& Index = ByteIntervals.get<by_address>();
292  if (High < Low) {
293  return boost::make_iterator_range(Index.end(), Index.end());
294  }
295  return boost::make_iterator_range(
296  const_byte_interval_iterator(Index.lower_bound(Low)),
297  const_byte_interval_iterator(Index.lower_bound(High)));
298  }
299 
309  std::optional<Addr> getAddress() const {
310  if (Extent) {
311  return Extent->lower();
312  }
313  return std::nullopt;
314  }
315 
325  std::optional<uint64_t> getSize() const {
326  if (Extent) {
327  return Extent->size();
328  }
329  return std::nullopt;
330  }
331 
338  ChangeStatus removeByteInterval(ByteInterval* N);
339 
345  ChangeStatus addByteInterval(ByteInterval* BI);
346 
352  template <typename... Args>
354  ByteInterval* BI = ByteInterval::Create(C, std::forward<Args>(A)...);
355  [[maybe_unused]] ChangeStatus status = addByteInterval(BI);
356  // addByteInterval(ByteInterval*) does not currently reject any insertions
357  // and the result cannot be NoChange because we just inserted a newly
358  // created ByteInterval.
359  assert(status == ChangeStatus::Accepted &&
360  "unexpected result when inserting ByteInterval");
361  return BI;
362  }
363 
365  void setName(const std::string& N);
366 
371  using block_iterator =
372  MergeSortedIterator<ByteInterval::block_iterator, BlockAddressLess>;
377  using block_range = boost::iterator_range<block_iterator>;
382  using block_subrange = boost::iterator_range<MergeSortedIterator<
383  ByteInterval::block_subrange::iterator, BlockAddressLess>>;
388  using const_block_iterator =
389  MergeSortedIterator<ByteInterval::const_block_iterator, BlockAddressLess>;
394  using const_block_range = boost::iterator_range<const_block_iterator>;
400  using const_block_subrange = boost::iterator_range<MergeSortedIterator<
401  ByteInterval::const_block_subrange::iterator, BlockAddressLess>>;
402 
405  return block_iterator(
406  boost::make_transform_iterator(this->byte_intervals_begin(),
407  NodeToBlockRange<ByteInterval>()),
408  boost::make_transform_iterator(this->byte_intervals_end(),
409  NodeToBlockRange<ByteInterval>()));
410  }
411 
414 
417  return boost::make_iterator_range(blocks_begin(), blocks_end());
418  }
419 
422  return const_block_iterator(
423  boost::make_transform_iterator(this->byte_intervals_begin(),
424  NodeToBlockRange<const ByteInterval>()),
425  boost::make_transform_iterator(this->byte_intervals_end(),
426  NodeToBlockRange<const ByteInterval>()));
427  }
428 
431 
434  return boost::make_iterator_range(blocks_begin(), blocks_end());
435  }
436 
445  byte_interval_subrange Intervals = findByteIntervalsOn(A);
446  return block_subrange(
447  block_subrange::iterator(
448  boost::make_transform_iterator(Intervals.begin(),
449  FindBlocksIn<ByteInterval>(A)),
450  boost::make_transform_iterator(Intervals.end(),
451  FindBlocksIn<ByteInterval>(A))),
452  block_subrange::iterator());
453  }
454 
463  const_byte_interval_subrange Intervals = findByteIntervalsOn(A);
464  return const_block_subrange(
465  const_block_subrange::iterator(
466  boost::make_transform_iterator(Intervals.begin(),
467  FindBlocksIn<const ByteInterval>(A)),
468  boost::make_transform_iterator(
469  Intervals.end(), FindBlocksIn<const ByteInterval>(A))),
470  const_block_subrange::iterator());
471  }
472 
480  byte_interval_subrange Intervals = findByteIntervalsOn(A);
481  return block_range(
482  block_range::iterator(
483  boost::make_transform_iterator(Intervals.begin(),
484  FindBlocksAt<ByteInterval>(A)),
485  boost::make_transform_iterator(Intervals.end(),
486  FindBlocksAt<ByteInterval>(A))),
487  block_range::iterator());
488  }
489 
498  std::vector<ByteInterval::block_range> Ranges;
499  for (ByteInterval& BI : findByteIntervalsOn(Low))
500  Ranges.push_back(BI.findBlocksAt(Low, High));
501  for (ByteInterval& BI : findByteIntervalsAt(Low + 1, High))
502  Ranges.push_back(BI.findBlocksAt(Low, High));
503  return block_range(block_iterator(Ranges), block_iterator());
504  }
505 
513  const_byte_interval_subrange Intervals = findByteIntervalsOn(A);
514  return const_block_range(
515  const_block_range::iterator(
516  boost::make_transform_iterator(Intervals.begin(),
517  FindBlocksAt<const ByteInterval>(A)),
518  boost::make_transform_iterator(
519  Intervals.end(), FindBlocksAt<const ByteInterval>(A))),
520  const_block_range::iterator());
521  }
522 
531  std::vector<ByteInterval::const_block_range> Ranges;
532  for (const ByteInterval& BI : findByteIntervalsOn(Low))
533  Ranges.push_back(BI.findBlocksAt(Low, High));
534  for (const ByteInterval& BI : findByteIntervalsAt(Low + 1, High))
535  Ranges.push_back(BI.findBlocksAt(Low, High));
538  }
539 
544  using code_block_iterator =
545  MergeSortedIterator<ByteInterval::code_block_iterator, AddressLess>;
550  using code_block_range = boost::iterator_range<code_block_iterator>;
556  using code_block_subrange = boost::iterator_range<MergeSortedIterator<
557  ByteInterval::code_block_subrange::iterator, AddressLess>>;
563  MergeSortedIterator<ByteInterval::const_code_block_iterator, AddressLess>;
568  using const_code_block_range =
569  boost::iterator_range<const_code_block_iterator>;
575  using const_code_block_subrange = boost::iterator_range<MergeSortedIterator<
576  ByteInterval::const_code_block_subrange::iterator, AddressLess>>;
577 
578 private:
579  code_block_range makeCodeBlockRange(ByteIntervalSet::iterator Begin,
580  ByteIntervalSet::iterator End) {
581  NodeToCodeBlockRange<ByteInterval> Transformer;
582  return boost::make_iterator_range(
583  code_block_iterator(boost::make_transform_iterator(
584  byte_interval_iterator(Begin), Transformer),
585  boost::make_transform_iterator(
586  byte_interval_iterator(End), Transformer)),
588  }
589 
590 public:
593  return code_block_iterator(
594  boost::make_transform_iterator(this->byte_intervals_begin(),
595  NodeToCodeBlockRange<ByteInterval>()),
596  boost::make_transform_iterator(this->byte_intervals_end(),
597  NodeToCodeBlockRange<ByteInterval>()));
598  }
599 
603 
606  return boost::make_iterator_range(code_blocks_begin(), code_blocks_end());
607  }
608 
612  boost::make_transform_iterator(
613  this->byte_intervals_begin(),
614  NodeToCodeBlockRange<const ByteInterval>()),
615  boost::make_transform_iterator(
616  this->byte_intervals_end(),
617  NodeToCodeBlockRange<const ByteInterval>()));
618  }
619 
623  return const_code_block_iterator();
624  }
625 
628  return boost::make_iterator_range(code_blocks_begin(), code_blocks_end());
629  }
630 
638  byte_interval_subrange Intervals = findByteIntervalsOn(A);
639  return code_block_subrange(
640  code_block_subrange::iterator(
641  boost::make_transform_iterator(Intervals.begin(),
642  FindCodeBlocksIn<ByteInterval>(A)),
643  boost::make_transform_iterator(Intervals.end(),
644  FindCodeBlocksIn<ByteInterval>(A))),
645  code_block_subrange::iterator());
646  }
647 
655  const_byte_interval_subrange Intervals = findByteIntervalsOn(A);
657  const_code_block_subrange::iterator(
658  boost::make_transform_iterator(
659  Intervals.begin(), FindCodeBlocksIn<const ByteInterval>(A)),
660  boost::make_transform_iterator(
661  Intervals.end(), FindCodeBlocksIn<const ByteInterval>(A))),
662  const_code_block_subrange::iterator());
663  }
664 
671  byte_interval_subrange Intervals = findByteIntervalsOn(A);
672  return code_block_range(
673  code_block_range::iterator(
674  boost::make_transform_iterator(Intervals.begin(),
675  FindCodeBlocksAt<ByteInterval>(A)),
676  boost::make_transform_iterator(Intervals.end(),
677  FindCodeBlocksAt<ByteInterval>(A))),
678  code_block_range::iterator());
679  }
680 
688  std::vector<ByteInterval::code_block_range> Ranges;
689  for (ByteInterval& BI : findByteIntervalsOn(Low))
690  Ranges.push_back(BI.findCodeBlocksAt(Low, High));
691  for (ByteInterval& BI : findByteIntervalsAt(Low + 1, High))
692  Ranges.push_back(BI.findCodeBlocksAt(Low, High));
694  }
695 
702  const_byte_interval_subrange Intervals = findByteIntervalsOn(A);
703  return const_code_block_range(
704  const_code_block_range::iterator(
705  boost::make_transform_iterator(
706  Intervals.begin(), FindCodeBlocksAt<const ByteInterval>(A)),
707  boost::make_transform_iterator(
708  Intervals.end(), FindCodeBlocksAt<const ByteInterval>(A))),
709  const_code_block_range::iterator());
710  }
711 
719  std::vector<ByteInterval::const_code_block_range> Ranges;
720  for (const ByteInterval& BI : findByteIntervalsOn(Low))
721  Ranges.push_back(BI.findCodeBlocksAt(Low, High));
722  for (const ByteInterval& BI : findByteIntervalsAt(Low + 1, High))
723  Ranges.push_back(BI.findCodeBlocksAt(Low, High));
726  }
727 
732  using data_block_iterator =
733  MergeSortedIterator<ByteInterval::data_block_iterator, AddressLess>;
738  using data_block_range = boost::iterator_range<data_block_iterator>;
744  using data_block_subrange = boost::iterator_range<MergeSortedIterator<
745  ByteInterval::data_block_subrange::iterator, AddressLess>>;
751  MergeSortedIterator<ByteInterval::const_data_block_iterator, AddressLess>;
756  using const_data_block_range =
757  boost::iterator_range<const_data_block_iterator>;
763  using const_data_block_subrange = boost::iterator_range<MergeSortedIterator<
764  ByteInterval::const_data_block_subrange::iterator, AddressLess>>;
765 
768  return data_block_iterator(
769  boost::make_transform_iterator(this->byte_intervals_begin(),
770  NodeToDataBlockRange<ByteInterval>()),
771  boost::make_transform_iterator(this->byte_intervals_end(),
772  NodeToDataBlockRange<ByteInterval>()));
773  }
774 
778 
781  return boost::make_iterator_range(data_blocks_begin(), data_blocks_end());
782  }
783 
787  boost::make_transform_iterator(
788  this->byte_intervals_begin(),
789  NodeToDataBlockRange<const ByteInterval>()),
790  boost::make_transform_iterator(
791  this->byte_intervals_end(),
792  NodeToDataBlockRange<const ByteInterval>()));
793  }
794 
798  return const_data_block_iterator();
799  }
800 
803  return boost::make_iterator_range(data_blocks_begin(), data_blocks_end());
804  }
805 
813  byte_interval_subrange Intervals = findByteIntervalsOn(A);
814  return data_block_subrange(
815  data_block_subrange::iterator(
816  boost::make_transform_iterator(Intervals.begin(),
817  FindDataBlocksIn<ByteInterval>(A)),
818  boost::make_transform_iterator(Intervals.end(),
819  FindDataBlocksIn<ByteInterval>(A))),
820  data_block_subrange::iterator());
821  }
822 
830  const_byte_interval_subrange Intervals = findByteIntervalsOn(A);
832  const_data_block_subrange::iterator(
833  boost::make_transform_iterator(
834  Intervals.begin(), FindDataBlocksIn<const ByteInterval>(A)),
835  boost::make_transform_iterator(
836  Intervals.end(), FindDataBlocksIn<const ByteInterval>(A))),
837  const_data_block_subrange::iterator());
838  }
839 
846  byte_interval_subrange Intervals = findByteIntervalsOn(A);
847  return data_block_range(
848  data_block_range::iterator(
849  boost::make_transform_iterator(Intervals.begin(),
850  FindDataBlocksAt<ByteInterval>(A)),
851  boost::make_transform_iterator(Intervals.end(),
852  FindDataBlocksAt<ByteInterval>(A))),
853  data_block_range::iterator());
854  }
855 
863  std::vector<ByteInterval::data_block_range> Ranges;
864  for (ByteInterval& BI : findByteIntervalsOn(Low))
865  Ranges.push_back(BI.findDataBlocksAt(Low, High));
866  for (ByteInterval& BI : findByteIntervalsAt(Low + 1, High))
867  Ranges.push_back(BI.findDataBlocksAt(Low, High));
869  }
870 
877  const_byte_interval_subrange Intervals = findByteIntervalsOn(A);
878  return const_data_block_range(
879  const_data_block_range::iterator(
880  boost::make_transform_iterator(
881  Intervals.begin(), FindDataBlocksAt<const ByteInterval>(A)),
882  boost::make_transform_iterator(
883  Intervals.end(), FindDataBlocksAt<const ByteInterval>(A))),
884  const_data_block_range::iterator());
885  }
886 
894  std::vector<ByteInterval::const_data_block_range> Ranges;
895  for (const ByteInterval& BI : findByteIntervalsOn(Low))
896  Ranges.push_back(BI.findDataBlocksAt(Low, High));
897  for (const ByteInterval& BI : findByteIntervalsAt(Low + 1, High))
898  Ranges.push_back(BI.findDataBlocksAt(Low, High));
901  }
902 
906  using symbolic_expression_iterator =
907  MergeSortedIterator<ByteInterval::symbolic_expression_iterator,
913  boost::iterator_range<symbolic_expression_iterator>;
917  using const_symbolic_expression_iterator = MergeSortedIterator<
924  boost::iterator_range<const_symbolic_expression_iterator>;
925 
929  boost::make_transform_iterator(
930  this->byte_intervals_begin(),
931  NodeToSymbolicExpressionRange<ByteInterval>()),
932  boost::make_transform_iterator(
933  this->byte_intervals_end(),
934  NodeToSymbolicExpressionRange<ByteInterval>()));
935  }
936 
941  }
942 
945  return boost::make_iterator_range(symbolic_expressions_begin(),
946  symbolic_expressions_end());
947  }
948 
952  boost::make_transform_iterator(
953  this->byte_intervals_begin(),
954  NodeToSymbolicExpressionRange<const ByteInterval>()),
955  boost::make_transform_iterator(
956  this->byte_intervals_end(),
957  NodeToSymbolicExpressionRange<const ByteInterval>()));
958  }
959 
964  }
965 
968  return boost::make_iterator_range(symbolic_expressions_begin(),
969  symbolic_expressions_end());
970  }
971 
980  symbolic_expression_range::iterator(
981  boost::make_transform_iterator(this->byte_intervals_begin(),
982  FindSymExprsAt<ByteInterval>(A)),
983  boost::make_transform_iterator(this->byte_intervals_end(),
984  FindSymExprsAt<ByteInterval>(A))),
985  symbolic_expression_range::iterator());
986  }
987 
998  symbolic_expression_range::iterator(
999  boost::make_transform_iterator(
1000  this->byte_intervals_begin(),
1001  FindSymExprsBetween<ByteInterval>(Low, High)),
1002  boost::make_transform_iterator(
1003  this->byte_intervals_end(),
1004  FindSymExprsBetween<ByteInterval>(Low, High))),
1005  symbolic_expression_range::iterator());
1006  }
1007 
1016  const_symbolic_expression_range::iterator(
1017  boost::make_transform_iterator(
1018  this->byte_intervals_begin(),
1019  FindSymExprsAt<const ByteInterval>(A)),
1020  boost::make_transform_iterator(
1021  this->byte_intervals_end(),
1022  FindSymExprsAt<const ByteInterval>(A))),
1023  const_symbolic_expression_range::iterator());
1024  }
1025 
1035  Addr High) const {
1037  const_symbolic_expression_range::iterator(
1038  boost::make_transform_iterator(
1039  this->byte_intervals_begin(),
1040  FindSymExprsBetween<const ByteInterval>(Low, High)),
1041  boost::make_transform_iterator(
1042  this->byte_intervals_end(),
1043  FindSymExprsBetween<const ByteInterval>(Low, High))),
1044  const_symbolic_expression_range::iterator());
1045  }
1046 
1048  static bool classof(const Node* N) { return N->getKind() == Kind::Section; }
1050 
1051 private:
1052  Module* Parent{nullptr};
1053  SectionObserver* Observer{nullptr};
1054  std::string Name;
1055  ByteIntervalSet ByteIntervals;
1056  ByteIntervalIntMap ByteIntervalAddrs;
1057  std::optional<AddrRange> Extent;
1058  std::set<SectionFlag> Flags;
1059 
1060  std::unique_ptr<ByteIntervalObserver> BIO;
1061 
1063  void removeByteIntervalAddrs(ByteInterval* BI);
1064 
1069  void insertByteIntervalAddrs(ByteInterval* BI);
1070 
1072  ChangeStatus updateExtent();
1073 
1074  void setParent(Module* M, SectionObserver* O) {
1075  Parent = M;
1076  Observer = O;
1077  }
1078 
1080  using MessageType = proto::Section;
1081 
1087  void toProtobuf(MessageType* Message) const;
1088 
1095  static ErrorOr<Section*> fromProtobuf(Context& C, const MessageType& Message);
1096 
1097  // Present for testing purposes only.
1098  void save(std::ostream& Out) const;
1099 
1100  // Present for testing purposes only.
1101  static Section* load(Context& C, std::istream& In);
1102 
1103  friend class Context; // Allow Context to construct sections.
1104  friend class Module; // Allow Module to call setModule, Create, etc.
1105  // Allows serializaton from Module via sequenceToProtobuf.
1106  template <typename T> friend typename T::MessageType toProtobuf(const T&);
1107  friend class SerializationTestHarness; // Testing support.
1108 };
1109 
1114 
1116 public:
1117  virtual ~SectionObserver() = default;
1118 
1128  virtual ChangeStatus nameChange(Section* S, const std::string& OldName,
1129  const std::string& NewName) = 0;
1130 
1139  virtual ChangeStatus addCodeBlocks(Section* S,
1140  Section::code_block_range Blocks) = 0;
1141 
1150  virtual ChangeStatus moveCodeBlocks(Section* S,
1151  Section::code_block_range Blocks) = 0;
1152 
1161  virtual ChangeStatus removeCodeBlocks(Section* S,
1162  Section::code_block_range Blocks) = 0;
1163 
1172  virtual ChangeStatus addDataBlocks(Section* S,
1173  Section::data_block_range Blocks) = 0;
1174 
1183  virtual ChangeStatus moveDataBlocks(Section* S,
1184  Section::data_block_range Blocks) = 0;
1185 
1194  virtual ChangeStatus removeDataBlocks(Section* S,
1195  Section::data_block_range Blocks) = 0;
1196 
1206  virtual ChangeStatus changeExtent(Section* S,
1207  std::function<void(Section*)> Callback) = 0;
1208 };
1209 
1210 inline void Section::setName(const std::string& X) {
1211  if (Observer) {
1212  std::string OldName = X;
1213  std::swap(Name, OldName);
1214  [[maybe_unused]] ChangeStatus status =
1215  Observer->nameChange(this, OldName, Name);
1216  // The known observers do not reject insertions. If that changes, this
1217  // method must be updated.
1218  assert(status != ChangeStatus::Rejected &&
1219  "recovering from rejected name change is unimplemented");
1220  } else {
1221  Name = X;
1222  }
1223 }
1224 } // namespace gtirb
1225 
1226 #endif // GTIRB_SECTION_H
gtirb::Section::const_byte_interval_range
boost::iterator_range< const_byte_interval_iterator > const_byte_interval_range
Const range of ByteInterval objects.
Definition: Section.hpp:177
gtirb::Section::symbolic_expressions
const_symbolic_expression_range symbolic_expressions() const
Return a range of all the SymbolicExpression objects.
Definition: Section.hpp:967
gtirb::ByteInterval::Create
static ByteInterval * Create(Context &C)
Create an unitialized ByteInterval object.
Definition: ByteInterval.hpp:215
gtirb::Section::getName
const std::string & getName() const
Get the name of a Section.
Definition: Section.hpp:122
gtirb::Section::code_block_range
boost::iterator_range< code_block_iterator > code_block_range
Range of CodeBlock objects.
Definition: Section.hpp:550
gtirb::Section::findSymbolicExpressionsAt
symbolic_expression_range findSymbolicExpressionsAt(Addr A)
Find all the symbolic expressions that start at an address.
Definition: Section.hpp:978
gtirb::Context::Create
NodeTy * Create(Args &&... TheArgs)
Create an object of type T.
Definition: Context.hpp:126
gtirb::Section::findCodeBlocksAt
code_block_range findCodeBlocksAt(Addr Low, Addr High)
Find all the code blocks that start between a range of addresses.
Definition: Section.hpp:687
gtirb::Section::const_data_block_subrange
boost::iterator_range< MergeSortedIterator< ByteInterval::const_data_block_subrange::iterator, AddressLess > > const_data_block_subrange
Sub-range of DataBlock objects overlapping an address or range of addreses.
Definition: Section.hpp:764
gtirb::Section::findDataBlocksAt
const_data_block_range findDataBlocksAt(Addr A) const
Find all the data blocks that start at an address.
Definition: Section.hpp:876
gtirb::Node
Represents the base of the Node class hierarchy.
Definition: Node.hpp:39
gtirb::Section::findCodeBlocksAt
code_block_range findCodeBlocksAt(Addr A)
Find all the code blocks that start at an address.
Definition: Section.hpp:670
gtirb::Section::byte_intervals_end
byte_interval_iterator byte_intervals_end()
Return an iterator to the element following the last ByteInterval.
Definition: Section.hpp:193
gtirb::Section::findByteIntervalsAt
const_byte_interval_range findByteIntervalsAt(Addr A) const
Find all the intervals that start at an address.
Definition: Section.hpp:276
gtirb::Section::findCodeBlocksAt
const_code_block_range findCodeBlocksAt(Addr Low, Addr High) const
Find all the code blocks that start between a range of addresses.
Definition: Section.hpp:718
gtirb::Section::block_subrange
boost::iterator_range< MergeSortedIterator< ByteInterval::block_subrange::iterator, BlockAddressLess > > block_subrange
Sub-range of blocks overlapping an address or range of addreses.
Definition: Section.hpp:383
gtirb::SectionObserver::nameChange
virtual ChangeStatus nameChange(Section *S, const std::string &OldName, const std::string &NewName)=0
Notify the parent when this Section's name changes.
gtirb::Section::blocks_begin
const_block_iterator blocks_begin() const
Return an iterator to the first block.
Definition: Section.hpp:421
gtirb::Section::blocks_end
block_iterator blocks_end()
Return an iterator to the element following the last block.
Definition: Section.hpp:413
gtirb::UUID
boost::uuids::uuid UUID
Represents a universally unique identifier used to identify Node objects across serialization boundar...
Definition: Context.hpp:36
gtirb::Section::symbolic_expressions_begin
symbolic_expression_iterator symbolic_expressions_begin()
Return an iterator to the first SymbolicExpression.
Definition: Section.hpp:927
gtirb::Addr
A special class to store an Effective Address.
Definition: Addr.hpp:37
gtirb::ChangeStatus::Rejected
@ Rejected
gtirb::Section::findSymbolicExpressionsAt
symbolic_expression_range findSymbolicExpressionsAt(Addr Low, Addr High)
Find all the symbolic expressions that start between a range of addresses.
Definition: Section.hpp:996
gtirb::Section::symbolic_expressions
symbolic_expression_range symbolic_expressions()
Return a range of all the SymbolicExpression objects.
Definition: Section.hpp:944
gtirb::Section::findByteIntervalsAt
byte_interval_range findByteIntervalsAt(Addr A)
Find all the intervals that start at an address.
Definition: Section.hpp:248
gtirb::const_block_iterator
cfg_node_cast_iter< const CodeBlock > const_block_iterator
Constant iterator over blocks (Block).
Definition: CFG.hpp:198
gtirb::Section::blocks
block_range blocks()
Return a range of all the blocks.
Definition: Section.hpp:416
gtirb::Section::findSymbolicExpressionsAt
const_symbolic_expression_range findSymbolicExpressionsAt(Addr A) const
Find all the symbolic expressions that start at an address.
Definition: Section.hpp:1014
gtirb::Section::flags
const_section_flag_range flags() const
Return a range of the SectionFlag flags set for the Section.
Definition: Section.hpp:159
gtirb::Section::getModule
Module * getModule()
Get the Module this section belongs to.
Definition: Section.hpp:115
gtirb::Section::setName
void setName(const std::string &N)
Set this section's name.
Definition: Section.hpp:1210
gtirb::Context
The context under which GTIRB operations occur.
Definition: Context.hpp:63
gtirb::SectionFlag::Executable
@ Executable
gtirb::Section::findBlocksAt
block_range findBlocksAt(Addr A)
Find all the blocks that start at an address.
Definition: Section.hpp:479
gtirb::Section::code_blocks
code_block_range code_blocks()
Return a range of all the CodeBlock objects.
Definition: Section.hpp:605
gtirb::Section::addFlag
void addFlag(SectionFlag F)
Adds the flag to the Section.
Definition: Section.hpp:127
Node.hpp
Class gtirb::Node.
gtirb::SectionFlag::Loaded
@ Loaded
gtirb::Section::byte_intervals_begin
const_byte_interval_iterator byte_intervals_begin() const
Return a const iterator to the first ByteInterval.
Definition: Section.hpp:188
gtirb::Section::code_block_iterator
MergeSortedIterator< ByteInterval::code_block_iterator, AddressLess > code_block_iterator
Iterator over CodeBlock objects.
Definition: Section.hpp:545
gtirb::Section::const_symbolic_expression_iterator
MergeSortedIterator< ByteInterval::const_symbolic_expression_iterator, ByteInterval::ConstSymbolicExpressionElement::AddressLess > const_symbolic_expression_iterator
Iterator over SymbolicExpressionElement objects.
Definition: Section.hpp:919
gtirb::Section::Create
static Section * Create(Context &C, const std::string &Name)
Create a Section object.
Definition: Section.hpp:104
gtirb::Section::data_blocks_begin
const_data_block_iterator data_blocks_begin() const
Return an iterator to the first DataBlock.
Definition: Section.hpp:785
gtirb::Section::findBlocksOn
block_subrange findBlocksOn(Addr A)
Find all the blocks that have bytes that lie within the address specified.
Definition: Section.hpp:444
gtirb::Section::findCodeBlocksOn
const_code_block_subrange findCodeBlocksOn(Addr A) const
Find all the code blocks that have bytes that lie within the address specified.
Definition: Section.hpp:654
gtirb::operator==
std::enable_if_t< std::is_error_code_enum< E >::value||std::is_error_condition_enum< E >::value, bool > operator==(const ErrorOr< T > &Err, E Code)
Definition: ErrorOr.hpp:277
gtirb::Section
Represents a named section of the binary.
Definition: Section.hpp:66
gtirb::SectionFlag::Readable
@ Readable
gtirb::Section::findBlocksAt
const_block_range findBlocksAt(Addr Low, Addr High) const
Find all the blocks that start between a range of addresses.
Definition: Section.hpp:530
gtirb::Section::const_code_block_subrange
boost::iterator_range< MergeSortedIterator< ByteInterval::const_code_block_subrange::iterator, AddressLess > > const_code_block_subrange
Sub-range of CodeBlock objects overlapping an address or range of addreses.
Definition: Section.hpp:576
gtirb::Section::const_byte_interval_iterator
boost::indirect_iterator< ByteIntervalSet::const_iterator, const ByteInterval > const_byte_interval_iterator
Const iterator over ByteInterval objects.
Definition: Section.hpp:174
DataBlock.hpp
Class gtirb::DataBlock.
gtirb::SymAttribute::S
@ S
gtirb::Section::const_data_block_iterator
MergeSortedIterator< ByteInterval::const_data_block_iterator, AddressLess > const_data_block_iterator
Iterator over DataBlock objects.
Definition: Section.hpp:751
GTIRB_EXPORT_API
#define GTIRB_EXPORT_API
This macro controls the visibility of exported symbols (i.e. classes) in shared libraries....
Definition: Export.hpp:52
gtirb::Section::findBlocksAt
const_block_range findBlocksAt(Addr A) const
Find all the blocks that start at an address.
Definition: Section.hpp:512
gtirb::Section::findBlocksAt
block_range findBlocksAt(Addr Low, Addr High)
Find all the blocks that start between a range of addresses.
Definition: Section.hpp:497
gtirb::Section::symbolic_expressions_begin
const_symbolic_expression_iterator symbolic_expressions_begin() const
Return an iterator to the first SymbolicExpression.
Definition: Section.hpp:950
gtirb
Main namespace for the GTIRB API.
Definition: Addr.hpp:28
gtirb::Section::findCodeBlocksAt
const_code_block_range findCodeBlocksAt(Addr A) const
Find all the code blocks that start at an address.
Definition: Section.hpp:701
gtirb::SectionFlag::Undefined
@ Undefined
gtirb::Section::const_section_flag_iterator
std::set< SectionFlag >::const_iterator const_section_flag_iterator
Iterator over SectionFlag flags.
Definition: Section.hpp:148
gtirb::Section::findDataBlocksOn
const_data_block_subrange findDataBlocksOn(Addr A) const
Find all the data blocks that have bytes that lie within the address specified.
Definition: Section.hpp:829
gtirb::Section::symbolic_expressions_end
symbolic_expression_iterator symbolic_expressions_end()
Return an iterator to the element following the last SymbolicExpression.
Definition: Section.hpp:939
gtirb::Section::symbolic_expression_range
boost::iterator_range< symbolic_expression_iterator > symbolic_expression_range
Range of SymbolicExpressionElement objects.
Definition: Section.hpp:913
gtirb::Section::data_blocks
const_data_block_range data_blocks() const
Return a range of all the DataBlock objects.
Definition: Section.hpp:802
gtirb::block_iterator
cfg_node_cast_iter< CodeBlock > block_iterator
Iterator over blocks (Block).
Definition: CFG.hpp:194
gtirb::SectionFlag
SectionFlag
Idenfities the flags used for a section.
Definition: Section.hpp:50
ByteInterval.hpp
Class gtirb::ByteInterval.
gtirb::Section::const_block_iterator
MergeSortedIterator< ByteInterval::const_block_iterator, BlockAddressLess > const_block_iterator
Const iterator over blocks.
Definition: Section.hpp:389
gtirb::SectionFlag::Writable
@ Writable
gtirb::Section::findByteIntervalsAt
const_byte_interval_range findByteIntervalsAt(Addr Low, Addr High) const
Find all the intervals that start between a range of addresses.
Definition: Section.hpp:290
gtirb::Section::const_section_flag_range
boost::iterator_range< const_section_flag_iterator > const_section_flag_range
Range of SectionFlag flags.
Definition: Section.hpp:151
gtirb::Section::data_block_iterator
MergeSortedIterator< ByteInterval::data_block_iterator, AddressLess > data_block_iterator
Iterator over DataBlock objects.
Definition: Section.hpp:733
gtirb::Section::data_blocks_end
data_block_iterator data_blocks_end()
Return an iterator to the element following the last DataBlock.
Definition: Section.hpp:777
gtirb::Section::byte_intervals_end
const_byte_interval_iterator byte_intervals_end() const
Return a const iterator to the element following the last ByteInterval.
Definition: Section.hpp:196
gtirb::Section::const_data_block_range
boost::iterator_range< const_data_block_iterator > const_data_block_range
Range of DataBlock objects.
Definition: Section.hpp:757
gtirb::ByteInterval::SymbolicExpressionElementBase::AddressLess
A comparison function object to order symbolic expression elements by the address in which they occur...
Definition: ByteInterval.hpp:1090
gtirb::Section::findBlocksOn
const_block_subrange findBlocksOn(Addr A) const
Find all the blocks that have bytes that lie within the address specified.
Definition: Section.hpp:462
gtirb::Section::findDataBlocksOn
data_block_subrange findDataBlocksOn(Addr A)
Find all the data blocks that have bytes that lie within the address specified.
Definition: Section.hpp:812
gtirb::SectionFlag::Initialized
@ Initialized
gtirb::ChangeStatus::Accepted
@ Accepted
gtirb::Section::code_blocks_begin
const_code_block_iterator code_blocks_begin() const
Return an iterator to the first CodeBlock.
Definition: Section.hpp:610
gtirb::Section::code_blocks_begin
code_block_iterator code_blocks_begin()
Return an iterator to the first CodeBlock.
Definition: Section.hpp:592
gtirb::Section::const_block_subrange
boost::iterator_range< MergeSortedIterator< ByteInterval::const_block_subrange::iterator, BlockAddressLess > > const_block_subrange
Const sub-range of blocks overlapping an address or range of addreses.
Definition: Section.hpp:401
gtirb::Section::symbolic_expressions_end
const_symbolic_expression_iterator symbolic_expressions_end() const
Return an iterator to the element following the last SymbolicExpression.
Definition: Section.hpp:962
gtirb::Section::addByteInterval
ByteInterval * addByteInterval(Context &C, Args &&... A)
Creates a new ByteInterval in this section.
Definition: Section.hpp:353
gtirb::Section::byte_interval_subrange
boost::iterator_range< boost::indirect_iterator< ByteIntervalIntMap::codomain_type::iterator > > byte_interval_subrange
Sub-range of ByteInterval objects overlapping addresses.
Definition: Section.hpp:170
gtirb::ByteInterval::symbolic_expression_iterator
boost::transform_iterator< SymExprPairToElement< SymbolicExpressionElement >, SymbolicExpressionMap::iterator > symbolic_expression_iterator
Iterator over SymbolicExpressionElement objects.
Definition: ByteInterval.hpp:1148
gtirb::Section::byte_intervals_begin
byte_interval_iterator byte_intervals_begin()
Return an iterator to the first ByteInterval.
Definition: Section.hpp:184
gtirb::Section::code_blocks
const_code_block_range code_blocks() const
Return a range of all the CodeBlock objects.
Definition: Section.hpp:627
gtirb::Section::getAddress
std::optional< Addr > getAddress() const
Return the address of this section, if known.
Definition: Section.hpp:309
gtirb::Section::removeFlag
void removeFlag(SectionFlag F)
Removes the flag from the Section.
Definition: Section.hpp:137
gtirb::ByteInterval::const_symbolic_expression_iterator
boost::transform_iterator< SymExprPairToElement< ConstSymbolicExpressionElement >, SymbolicExpressionMap::const_iterator > const_symbolic_expression_iterator
Const iterator over SymbolicExpressionElement objects.
Definition: ByteInterval.hpp:1159
gtirb::Section::byte_intervals
const_byte_interval_range byte_intervals() const
Return a const range of the ByteInterval objects in this section.
Definition: Section.hpp:206
gtirb::Section::getModule
const Module * getModule() const
Get the Module this section belongs to.
Definition: Section.hpp:117
gtirb::Section::const_symbolic_expression_range
boost::iterator_range< const_symbolic_expression_iterator > const_symbolic_expression_range
Range of SymbolicExpressionElement objects.
Definition: Section.hpp:924
gtirb::Section::findSymbolicExpressionsAt
const_symbolic_expression_range findSymbolicExpressionsAt(Addr Low, Addr High) const
Find all the symbolic expressions that start between a range of addresses.
Definition: Section.hpp:1034
gtirb::Section::byte_interval_range
boost::iterator_range< byte_interval_iterator > byte_interval_range
Range of ByteInterval objects.
Definition: Section.hpp:167
gtirb::Section::data_blocks_end
const_data_block_iterator data_blocks_end() const
Return an iterator to the element following the last DataBlock.
Definition: Section.hpp:797
gtirb::Section::data_blocks_begin
data_block_iterator data_blocks_begin()
Return an iterator to the first DataBlock.
Definition: Section.hpp:767
gtirb::Section::findCodeBlocksOn
code_block_subrange findCodeBlocksOn(Addr A)
Find all the code blocks that have bytes that lie within the address specified.
Definition: Section.hpp:637
gtirb::Section::findDataBlocksAt
data_block_range findDataBlocksAt(Addr A)
Find all the data blocks that start at an address.
Definition: Section.hpp:845
gtirb::Section::findByteIntervalsOn
const_byte_interval_subrange findByteIntervalsOn(Addr A) const
Find all the intervals that have bytes that lie within the address specified.
Definition: Section.hpp:234
gtirb::Section::Create
static Section * Create(Context &C)
Create an unitialized Section object.
Definition: Section.hpp:96
gtirb::Section::blocks_end
const_block_iterator blocks_end() const
Return an iterator to the element following the last block.
Definition: Section.hpp:430
gtirb::Section::block_iterator
MergeSortedIterator< ByteInterval::block_iterator, BlockAddressLess > block_iterator
Iterator over blocks.
Definition: Section.hpp:372
gtirb::Section::isFlagSet
bool isFlagSet(SectionFlag F) const
Tests whether the given flag is set for the Section.
Definition: Section.hpp:143
gtirb::Section::findDataBlocksAt
const_data_block_range findDataBlocksAt(Addr Low, Addr High) const
Find all the data blocks that start between a range of addresses.
Definition: Section.hpp:893
gtirb::Section::const_code_block_iterator
MergeSortedIterator< ByteInterval::const_code_block_iterator, AddressLess > const_code_block_iterator
Iterator over CodeBlock objects.
Definition: Section.hpp:563
gtirb::Module
Represents a single binary (library or executable).
Definition: Module.hpp:107
gtirb::Section::findDataBlocksAt
data_block_range findDataBlocksAt(Addr Low, Addr High)
Find all the data blocks that start between a range of addresses.
Definition: Section.hpp:862
gtirb::Section::flags_end
const_section_flag_iterator flags_end() const
Return a const iterator to the element following the last SectionFlag.
Definition: Section.hpp:157
gtirb::Section::code_block_subrange
boost::iterator_range< MergeSortedIterator< ByteInterval::code_block_subrange::iterator, AddressLess > > code_block_subrange
Sub-range of CodeBlock objects overlapping an address or range of addreses.
Definition: Section.hpp:557
gtirb::Section::const_code_block_range
boost::iterator_range< const_code_block_iterator > const_code_block_range
Range of CodeBlock objects.
Definition: Section.hpp:569
gtirb::SectionFlag::ThreadLocal
@ ThreadLocal
gtirb::Section::flags_begin
const_section_flag_iterator flags_begin() const
Return a const iterator to the first SectionFlag.
Definition: Section.hpp:154
gtirb::SectionObserver
Interface for notifying observers when the Section is modified.
Definition: Section.hpp:1115
gtirb::Section::code_blocks_end
const_code_block_iterator code_blocks_end() const
Return an iterator to the element following the last CodeBlock.
Definition: Section.hpp:622
gtirb::ByteInterval
A contiguous region of bytes in a binary.
Definition: ByteInterval.hpp:116
Observer.hpp
gtirb::Section::data_blocks
data_block_range data_blocks()
Return a range of all the DataBlock objects.
Definition: Section.hpp:780
CodeBlock.hpp
Class gtirb::CodeBlock.
gtirb::Section::getSize
std::optional< uint64_t > getSize() const
Return the size of this section, if known.
Definition: Section.hpp:325
gtirb::Section::const_byte_interval_subrange
boost::iterator_range< boost::indirect_iterator< ByteIntervalIntMap::codomain_type::const_iterator > > const_byte_interval_subrange
Const sub-range of ByteInterval objects overlapping addresses.
Definition: Section.hpp:181
Addr.hpp
Class gtirb::Addr and related functions.
gtirb::Section::findByteIntervalsOn
byte_interval_subrange findByteIntervalsOn(Addr A)
Find all the intervals that have bytes that lie within the address specified.
Definition: Section.hpp:218
gtirb::Section::byte_intervals
byte_interval_range byte_intervals()
Return a range of the ByteInterval objects in this section.
Definition: Section.hpp:200
gtirb::Section::data_block_subrange
boost::iterator_range< MergeSortedIterator< ByteInterval::data_block_subrange::iterator, AddressLess > > data_block_subrange
Sub-range of DataBlock objects overlapping an address or range of addreses.
Definition: Section.hpp:745
gtirb::Section::findByteIntervalsAt
byte_interval_range findByteIntervalsAt(Addr Low, Addr High)
Find all the intervals that start between a range of addresses.
Definition: Section.hpp:261
gtirb::ChangeStatus
ChangeStatus
Definition: Observer.hpp:19
gtirb::Section::blocks
const_block_range blocks() const
Return a range of all the blocks.
Definition: Section.hpp:433
gtirb::Section::addFlags
void addFlags(Fs... F)
Adds all of the flags to the Section.
Definition: Section.hpp:132
gtirb::Section::byte_interval_iterator
boost::indirect_iterator< ByteIntervalSet::iterator > byte_interval_iterator
Iterator over ByteInterval objects.
Definition: Section.hpp:165
gtirb::Section::symbolic_expression_iterator
MergeSortedIterator< ByteInterval::symbolic_expression_iterator, ByteInterval::SymbolicExpressionElement::AddressLess > symbolic_expression_iterator
Iterator over SymbolicExpressionElement objects.
Definition: Section.hpp:908
Utility.hpp
gtirb::Section::blocks_begin
block_iterator blocks_begin()
Return an iterator to the first block.
Definition: Section.hpp:404
gtirb::Section::const_block_range
boost::iterator_range< const_block_iterator > const_block_range
Const range of blocks.
Definition: Section.hpp:394
gtirb::Section::code_blocks_end
code_block_iterator code_blocks_end()
Return an iterator to the element following the last CodeBlock.
Definition: Section.hpp:602
gtirb::Section::block_range
boost::iterator_range< block_iterator > block_range
Range of blocks.
Definition: Section.hpp:377
gtirb::Section::data_block_range
boost::iterator_range< data_block_iterator > data_block_range
Range of DataBlock objects.
Definition: Section.hpp:738