ROSE  0.11.145.0
AddressMap.h
1 // WARNING: Changes to this file must be contributed back to Sawyer or else they will
2 // be clobbered by the next update from Sawyer. The Sawyer repository is at
3 // https://github.com/matzke1/sawyer.
4 
5 
6 
7 
8 #ifndef Sawyer_AddressMap_H
9 #define Sawyer_AddressMap_H
10 
11 #include <Sawyer/Access.h>
12 #include <Sawyer/AddressSegment.h>
13 #include <Sawyer/Assert.h>
14 #include <Sawyer/BitVector.h>
15 #include <Sawyer/Callbacks.h>
16 #include <Sawyer/Interval.h>
17 #include <Sawyer/IntervalMap.h>
18 #include <Sawyer/IntervalSet.h>
19 #include <Sawyer/Sawyer.h>
20 
21 #include <boost/algorithm/string/predicate.hpp>
22 #include <boost/cstdint.hpp>
23 #include <boost/integer_traits.hpp>
24 #include <boost/lexical_cast.hpp>
25 #include <boost/serialization/access.hpp>
26 #include <boost/serialization/base_object.hpp>
27 #include <boost/serialization/nvp.hpp>
28 
29 #if __cplusplus >= 201103L
30 #include <type_traits>
31 #endif
32 
33 namespace Sawyer {
34 namespace Container {
35 
36 template<class AddressMap>
38  typedef typename AddressMap::NodeIterator NodeIterator;
40 };
41 
42 template<class AddressMap>
46 };
47 
49 typedef unsigned MatchFlags;
50 static const MatchFlags MATCH_BACKWARD = 0x00000001;
51 static const MatchFlags MATCH_CONTIGUOUS = 0x00000002;
52 static const MatchFlags MATCH_NONCONTIGUOUS = 0x00000004;
53 static const MatchFlags MATCH_WHOLE = 0x00000008;
57 template<class A, class T>
59 public:
60  struct Args {
61  const Sawyer::Container::Interval<A> &interval;
62  const AddressSegment<A, T> &segment;
63  Args(const Sawyer::Container::Interval<A> &interval, const AddressSegment<A, T> &segment)
64  : interval(interval), segment(segment) {}
65  };
66 
67  virtual ~SegmentPredicate() {}
68  virtual bool operator()(bool chain, const Args &) = 0;
69 };
70 
78 template<typename AddressMap>
80 public:
81  typedef typename AddressMap::Address Address;
82  typedef typename AddressMap::Value Value;
84 private:
85  AddressMap *map_; // AddressMap<> to which these constraints are bound
86  bool never_; // never match anything (e.g., when least_ > greatest_)
87  // address constraints
88  Optional<Address> least_; // least possible valid address
89  Optional<Address> greatest_; // greatest possible valid address
90  Optional<AddressInterval> anchored_; // anchored least or greatest depending on direction
91  // constraints requiring iteration
92  size_t maxSize_; // result size is limited
93  bool singleSegment_; // do not cross a segment boundary
94  unsigned requiredAccess_; // access bits that must be set in the segment
95  unsigned prohibitedAccess_; // access bits that must be clear in the segment
96  std::string nameSubstring_; // segment name must contain substring
97  Callbacks<SegmentPredicate<Address, Value>*> segmentPredicates_; // user-supplied segment predicates
98 public:
101  : map_(map), never_(false), maxSize_(size_t(-1)), singleSegment_(false), requiredAccess_(0), prohibitedAccess_(0) {}
102 
103 #if __cplusplus >= 201103L
104  // Implicitly construct constraints for a const AddressMap from a non-const address map. The dummy U parameter is to force
105  // type deduction to be delayed to the point where this function is instantiated.
106  template<typename U = AddressMap, typename = typename std::enable_if<!std::is_const<U>::value, void>::type>
107  operator AddressMapConstraints<const U>() const {
109  if (neverMatches())
110  cc = cc.none();
111  if (isAnchored()) {
112  if (anchored().isSingleton()) {
113  cc = cc.at(anchored().least());
114  } else {
115  cc = cc.at(anchored());
116  }
117  }
118  if (least())
119  cc = cc.atOrAfter(*least());
120  if (greatest())
121  cc = cc.atOrBefore(*greatest());
122  cc = cc.limit(limit());
123  if (isSingleSegment())
124  cc = cc.singleSegment();
125  cc = cc.require(required());
126  cc = cc.prohibit(prohibited());
127  cc = cc.substr(substr());
128  cc = cc.segmentPredicates(segmentPredicates());
129  return cc;
130  }
131 #else
132  operator AddressMapConstraints<const AddressMap>() const {
133  AddressMapConstraints<const AddressMap> cc(map_);
134  if (neverMatches())
135  cc = cc.none();
136  if (isAnchored()) {
137  if (anchored().isSingleton()) {
138  cc = cc.at(anchored().least());
139  } else {
140  cc = cc.at(anchored());
141  }
142  }
143  if (least())
144  cc = cc.atOrAfter(*least());
145  if (greatest())
146  cc = cc.atOrBefore(*greatest());
147  cc = cc.limit(limit());
148  if (isSingleSegment())
149  cc = cc.singleSegment();
150  cc = cc.require(required());
151  cc = cc.prohibit(prohibited());
152  cc = cc.substr(substr());
153  cc = cc.segmentPredicates(segmentPredicates());
154  return cc;
155  }
156 #endif
157 
159  void print(std::ostream &out) const {
160  out <<"{map=" <<map_;
161  if (never_)
162  out <<", never";
163  if (least_)
164  out <<", least=" <<*least_;
165  if (greatest_)
166  out <<", greatest=" <<*greatest_;
167  if (anchored_) {
168  out <<", anchored=";
169  AddressInterval a = *anchored_;
170  if (a.isEmpty()) {
171  out <<"empty";
172  } else if (a.least()==a.greatest()) {
173  out <<a.least();
174  } else {
175  out <<"{" <<a.least() <<".." <<a.greatest() <<"}";
176  }
177  }
178  if (maxSize_ != size_t(-1))
179  out <<", limit=" <<maxSize_;
180  if (singleSegment_)
181  out <<", single-segment";
182  if (requiredAccess_!=0) {
183  out <<", required="
184  <<((requiredAccess_ & Access::READABLE) ? "r" : "")
185  <<((requiredAccess_ & Access::WRITABLE) ? "w" : "")
186  <<((requiredAccess_ & Access::EXECUTABLE) ? "x" : "")
187  <<((requiredAccess_ & Access::IMMUTABLE) ? "i" : "");
188  unsigned other = requiredAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
189  if (other)
190  out <<"+0x" <<BitVector(8*sizeof requiredAccess_).fromInteger(other).toHex();
191  }
192  if (prohibitedAccess_!=0) {
193  out <<", required="
194  <<((prohibitedAccess_ & Access::READABLE) ? "r" : "")
195  <<((prohibitedAccess_ & Access::WRITABLE) ? "w" : "")
196  <<((prohibitedAccess_ & Access::EXECUTABLE) ? "x" : "")
197  <<((prohibitedAccess_ & Access::IMMUTABLE) ? "i" : "");
198  unsigned other = prohibitedAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
199  if (other)
200  out <<"+0x" <<BitVector(8*sizeof prohibitedAccess_).fromInteger(other).toHex();
201  }
202  if (!nameSubstring_.empty()) {
203  out <<", substr=\"";
204  for (char ch: nameSubstring_) {
205  switch (ch) {
206  case '\a': out <<"\\a"; break;
207  case '\b': out <<"\\b"; break;
208  case '\t': out <<"\\t"; break;
209  case '\n': out <<"\\n"; break;
210  case '\v': out <<"\\v"; break;
211  case '\f': out <<"\\f"; break;
212  case '\r': out <<"\\r"; break;
213  case '\"': out <<"\\\""; break;
214  case '\\': out <<"\\\\"; break;
215  default:
216  if (isprint(ch)) {
217  out <<ch;
218  } else {
219  char buf[8];
220  snprintf(buf, sizeof(buf), "\\%03o", (unsigned)(unsigned char)ch);
221  out <<buf;
222  }
223  break;
224  }
225  }
226  }
227  if (!segmentPredicates_.isEmpty())
228  out <<", user-def";
229  out <<"}";
230  }
231 
233  friend std::ostream& operator<<(std::ostream &out, const AddressMapConstraints &x) {
234  x.print(out);
235  return out;
236  }
237 
239  // Constraint modifiers
240 public:
242  AddressMapConstraints require(unsigned bits) const {
243  AddressMapConstraints retval = *this;
244  retval.requiredAccess_ |= bits;
245  return retval;
246  }
247 
249  AddressMapConstraints prohibit(unsigned bits) const {
250  AddressMapConstraints retval = *this;
251  retval.prohibitedAccess_ |= bits;
252  return retval;
253  }
254 
256  AddressMapConstraints access(unsigned bits) const {
257  return require(bits).prohibit(~bits);
258  }
259 
261  AddressMapConstraints substr(const std::string &s) const {
262  ASSERT_require(nameSubstring_.empty() || nameSubstring_==s);// substring conjunction not supported
263  AddressMapConstraints retval = *this;
264  retval.nameSubstring_ = s;
265  return retval;
266  }
267 
270  return *this;
271  }
272 
275  AddressMapConstraints retval = *this;
276  retval.never_ = true;
277  return retval;
278  }
279 
281  AddressMapConstraints at(Address x) const {
282  AddressMapConstraints retval = *this;
283  retval.anchored_ = anchored_ ? *anchored_ & AddressInterval(x) : AddressInterval(x);
284  return retval.anchored_->isEmpty() ? retval.none() : retval;
285  }
286 
289  AddressMapConstraints retval = *this;
290  retval.anchored_ = anchored_ ? *anchored_ & x : x;
291  return retval.anchored_->isEmpty() ? retval.none() : retval.atOrAfter(x.least()).atOrBefore(x.greatest());
292  }
293 
295  AddressMapConstraints limit(size_t x) const {
296  AddressMapConstraints retval = *this;
297  retval.maxSize_ = std::min(maxSize_, x);
298  return 0 == retval.maxSize_ ? retval.none() : retval;
299  }
300 
303  AddressMapConstraints retval = *this;
304  if (least_) {
305  retval.least_ = std::max(*least_, least);
306  } else {
307  retval.least_ = least;
308  }
309  if (greatest_ && *greatest_ < *retval.least_)
310  retval.none();
311  return retval;
312  }
313 
316  AddressMapConstraints retval = *this;
317  if (greatest_) {
318  retval.greatest_ = std::min(*greatest_, greatest);
319  } else {
320  retval.greatest_ = greatest;
321  }
322  if (least_ && *least_ > *retval.greatest_)
323  retval.none();
324  return retval;
325  }
326 
329  return x.isEmpty() ? none() : atOrAfter(x.least()).atOrBefore(x.greatest());
330  }
331 
333  AddressMapConstraints within(Address lo, Address hi) const {
334  return lo<=hi ? within(Sawyer::Container::Interval<Address>::hull(lo, hi)) : none();
335  }
336 
338  AddressMapConstraints baseSize(Address base, Address size) const {
339  return size>0 ? atOrAfter(base).atOrBefore(base+size-1) : none();
340  }
341 
343  AddressMapConstraints after(Address x) const {
344  return x==boost::integer_traits<Address>::const_max ? none() : atOrAfter(x+1);
345  }
346 
348  AddressMapConstraints before(Address x) const {
349  return x==boost::integer_traits<Address>::const_min ? none() : atOrBefore(x-1);
350  }
351 
354  AddressMapConstraints retval = *this;
355  retval.singleSegment_ = true;
356  return retval;
357  }
358 
361  if (!p)
362  return none();
363  AddressMapConstraints retval = *this;
364  retval.segmentPredicates_.append(p);
365  return retval;
366  }
367 
369  AddressMapConstraints retval = *this;
370  retval.segmentPredicates_.append(predicates);
371  return retval;
372  }
373 
375  // Constraint queries
376 public:
378  unsigned required() const {
379  return requiredAccess_;
380  }
381 
383  unsigned prohibited() const {
384  return prohibitedAccess_;
385  }
386 
388  const std::string& substr() const {
389  return nameSubstring_;
390  }
391 
395  bool neverMatches() const {
396  return never_;
397  }
398 
400  bool isAnchored() const {
401  return anchored_;
402  }
403 
408  AddressInterval anchored() const {
409  ASSERT_require(isAnchored());
410  return *anchored_;
411  }
412 
414  size_t limit() const {
415  return maxSize_;
416  }
417 
420  const Optional<Address>& least() const {
421  return least_;
422  }
423 
426  const Optional<Address>& greatest() const {
427  return greatest_;
428  }
429 
431  bool isSingleSegment() const {
432  return singleSegment_;
433  }
434 
437  return segmentPredicates_;
438  }
439 
441  AddressMap* map() const {
442  return map_;
443  }
444 
448  return (!never_ &&
449  (requiredAccess_ || prohibitedAccess_ || !nameSubstring_.empty() || maxSize_!=size_t(-1) ||
450  singleSegment_ || !segmentPredicates_.isEmpty()));
451  }
452 
456  AddressMapConstraints c(map_);
457  c.least_ = least_;
458  c.greatest_ = greatest_;
459  c.anchored_ = anchored_;
460  c.maxSize_ = maxSize_;
461  return c;
462  }
463 
465  // Methods that directly call the AddressMap
466 public:
467  boost::iterator_range<typename AddressMapTraits<AddressMap>::NodeIterator>
468  nodes(MatchFlags flags=0) const {
469  return map_->nodes(*this, flags);
470  }
471 
472  boost::iterator_range<typename AddressMapTraits<AddressMap>::SegmentIterator>
473  segments(MatchFlags flags=0) const {
474  return map_->segments(*this, flags);
475  }
476 
477  Optional<typename AddressMap::Address>
478  next(MatchFlags flags=0) const {
479  return map_->next(*this, flags);
480  }
481 
483  available(MatchFlags flags=0) const {
484  return map_->available(*this, flags);
485  }
486 
487  bool
488  exists(MatchFlags flags=0) const {
489  return map_->exists(*this, flags);
490  }
491 
492  typename AddressMapTraits<AddressMap>::NodeIterator
493  findNode(MatchFlags flags=0) const {
494  return map_->findNode(*this, flags);
495  }
496 
497  template<typename Functor>
498  void
499  traverse(Functor &functor, MatchFlags flags=0) const {
500  return map_->traverse(functor, *this, flags);
501  }
502  void
503  traverse(typename AddressMap::Visitor &visitor, MatchFlags flags=0) const {
504  return map_->template traverse<typename AddressMap::Visitor>(visitor, *this, flags);
505  }
506 
508  read(typename AddressMap::Value *buf /*out*/, MatchFlags flags=0) const {
509  return map_->read(buf, *this, flags);
510  }
511 
513  read(std::vector<typename AddressMap::Value> &buf /*out*/,
514  MatchFlags flags=0) const {
515  return map_->read(buf, *this, flags);
516  }
517 
519  write(const typename AddressMap::Value *buf, MatchFlags flags=0) const {
520  return map_->write(buf, *this, flags);
521  }
522 
524  write(const std::vector<typename AddressMap::Value> &buf, MatchFlags flags=0) {
525  return map_->write(buf, *this, flags);
526  }
527 
528  void
529  prune(MatchFlags flags=0) const {
530  return map_->prune(*this, flags);
531  }
532 
533  void
534  keep(MatchFlags flags=0) const {
535  return map_->keep(*this, flags);
536  }
537 
538  void
539  changeAccess(unsigned requiredAccess, unsigned prohibitedAccess, MatchFlags flags=0) const {
540  return map_->changeAccess(requiredAccess, prohibitedAccess, *this, flags);
541  }
542 };
543 
545 // Implementation details
547 namespace AddressMapImpl {
548 
549 // Used internally to split and merge segments
550 template<class A, class T>
552 public:
553  typedef A Address;
554  typedef T Value;
556 
557 private:
558  friend class boost::serialization::access;
559 
560  template<class S>
561  void serialize(S&, const unsigned /*version*/) {
562  // no data to serialize here
563  }
564 
565 public:
566  bool merge(const Sawyer::Container::Interval<Address> &leftInterval, Segment &leftSegment,
567  const Sawyer::Container::Interval<Address> &rightInterval, Segment &rightSegment) {
568  ASSERT_forbid(leftInterval.isEmpty());
569  ASSERT_always_forbid(rightInterval.isEmpty()); // so rightInterval is always used
570  ASSERT_require(leftInterval.greatest() + 1 == rightInterval.least());
571  return (leftSegment.accessibility() == rightSegment.accessibility() &&
572  leftSegment.name() == rightSegment.name() &&
573  leftSegment.buffer() == rightSegment.buffer() &&
574  leftSegment.offset() + leftInterval.size() == rightSegment.offset());
575  }
576 
577  Segment split(const Sawyer::Container::Interval<Address> &interval, Segment &segment, Address splitPoint) {
578  ASSERT_forbid(interval.isEmpty());
579  ASSERT_require(interval.contains(splitPoint));
580  Segment right = segment;
581  right.offset(segment.offset() + splitPoint - interval.least());
582  return right;
583  }
584 
585  void truncate(const Sawyer::Container::Interval<Address> &interval, Segment &/*segment*/, Address splitPoint) {
586  ASSERT_always_forbid(interval.isEmpty()); // so interval is always used
587  ASSERT_always_require(interval.contains(splitPoint)); // ditto for splitPoint
588  }
589 };
590 
591 // The results for matching constraints
592 template<class AddressMap>
594  typedef typename AddressMap::Address Address;
597  boost::iterator_range<NodeIterator> nodes_;
598 };
599 
600 // Finds the minimum possible address and node iterator for the specified constraints in this map and returns that
601 // iterator. Returns the end iterator if the constraints match no address. If a non-end iterator is returned then minAddr
602 // is adjusted to be the minimum address that satisfies the constraint (it will be an address within the returned node, but
603 // not necessarily the least address for the node). If useAnchor is set and the constraints specify an anchor, then the
604 // anchor address must be present in the map and satisfy any address constraints that might also be present.
605 template<class AddressMap>
607 constraintLowerBound(AddressMap &amap, const AddressMapConstraints<AddressMap> &c, bool useAnchor,
608  typename AddressMap::Address &minAddr) {
609  typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
610  if (amap.isEmpty() || c.neverMatches())
611  return amap.nodes().end();
612 
613  if (useAnchor && c.isAnchored()) { // forward matching if useAnchor is set
614  if ((c.least() && *c.least() > c.anchored().least()) || (c.greatest() && *c.greatest() < c.anchored().greatest()))
615  return amap.nodes().end(); // anchor is outside of allowed interval
616  Iterator lb = amap.lowerBound(c.anchored().least());
617  if (lb==amap.nodes().end() || c.anchored().least() < lb->key().least())
618  return amap.nodes().end(); // anchor is not present in this map
619  minAddr = c.anchored().least();
620  return lb;
621  }
622 
623  if (c.least()) {
624  Iterator lb = amap.lowerBound(*c.least());
625  if (lb==amap.nodes().end())
626  return lb; // least is above all segments
627  minAddr = std::max(*c.least(), lb->key().least());
628  return lb;
629  }
630 
631  Iterator lb = amap.nodes().begin();
632  if (lb!=amap.nodes().end())
633  minAddr = lb->key().least();
634  return lb;
635 }
636 
637 // Finds the maximum possible address and node for the specified constraints in this map, and returns an iterator to the
638 // following node. Returns the begin iterator if the constraints match no address. If a non-begin iterator is returned
639 // then maxAddr is adjusted to be the maximum address that satisfies the constraint (it will be an address that belongs to
640 // the node immediately prior to the one pointed to by the returned iterator, but not necessarily the greatest address for
641 // that node). If useAnchor is set and the constraints specify an anchor, then the anchor address must be present in the
642 // map and satisfy any address constraints that might also be present.
643 template<class AddressMap>
644 typename AddressMapTraits<AddressMap>::NodeIterator
645 constraintUpperBound(AddressMap &amap, const AddressMapConstraints<AddressMap> &c, bool useAnchor,
646  typename AddressMap::Address &maxAddr) {
647  typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
648  if (amap.isEmpty() || c.neverMatches())
649  return amap.nodes().begin();
650 
651  if (useAnchor && c.isAnchored()) { // backward matching if useAnchor is set
652  if ((c.least() && *c.least() > c.anchored().least()) || (c.greatest() && *c.greatest() < c.anchored().greatest()))
653  return amap.nodes().begin(); // anchor is outside allowed interval
654  Iterator ub = amap.findPrior(c.anchored().greatest());
655  if (ub==amap.nodes().end() || c.anchored().greatest() > ub->key().greatest())
656  return amap.nodes().begin(); // anchor is not present in this map
657  maxAddr = c.anchored().greatest();
658  return ++ub; // return node after the one containing the anchor
659  }
660 
661  if (c.greatest()) {
662  Iterator ub = amap.findPrior(*c.greatest());
663  if (ub==amap.nodes().end())
664  return amap.nodes().begin(); // greatest is below all segments
665  maxAddr = std::min(ub->key().greatest(), *c.greatest());
666  return ++ub; // return node after the one containing the maximum
667  }
668 
669  maxAddr = amap.hull().greatest();
670  return amap.nodes().end();
671 }
672 
673 // Returns true if the segment satisfies the non-address constraints in c.
674 template<class AddressMap>
675 bool
676 isSatisfied(const typename AddressMap::Node &node, const AddressMapConstraints<AddressMap> &c) {
677  typedef typename AddressMap::Address Address;
678  typedef typename AddressMap::Value Value;
679  typedef typename AddressMap::Segment Segment;
680  const Segment &segment = node.value();
681  if (!segment.isAccessible(c.required(), c.prohibited()))
682  return false; // wrong segment permissions
683  if (!boost::contains(segment.name(), c.substr()))
684  return false; // wrong segment name
685  if (!c.segmentPredicates().apply(true, typename SegmentPredicate<Address, Value>::Args(node.key(), node.value())))
686  return false; // user-supplied predicates failed
687  return true;
688 }
689 
690 // Matches constraints against contiguous addresses in a forward direction.
691 template<class AddressMap>
692 MatchedConstraints<AddressMap>
693 matchForward(AddressMap &amap, const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
694  typedef typename AddressMap::Address Address;
695  typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
696  MatchedConstraints<AddressMap> retval;
697  retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
698  if (c.neverMatches() || amap.isEmpty())
699  return retval;
700 
701  // Find a lower bound for the minimum address
702  Address minAddr = 0;
703  Iterator begin = constraintLowerBound(amap, c, true, minAddr /*out*/);
704  if (begin == amap.nodes().end())
705  return retval;
706 
707  // Find an upper bound for the maximum address.
708  Address maxAddr = 0;
709  Iterator end = constraintUpperBound(amap, c, false, maxAddr /*out*/);
710  if (end==amap.nodes().begin())
711  return retval;
712 
713  // Advance the lower-bound until it satisfies the other (non-address) constraints
714  while (begin!=end && !isSatisfied(*begin, c)) {
715  if (c.isAnchored())
716  return retval; // match is anchored to minAddr
717  ++begin;
718  }
719  if (begin==end)
720  return retval;
721  minAddr = std::max(minAddr, begin->key().least());
722 
723  // Iterate forward until the constraints are no longer satisfied
724  if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
725  Address addr = minAddr;
726  Iterator iter = begin;
727  size_t nElmtsFound = 0;
728  for (/*void*/; iter!=end; ++iter) {
729  if (iter!=begin) { // already tested the first node above
730  if (c.isSingleSegment())
731  break; // we crossed a segment boundary
732  if ((flags & MATCH_CONTIGUOUS)!=0 && addr+1 != iter->key().least())
733  break; // gap between segments
734  if (!isSatisfied(*iter, c)) {
735  if ((flags & MATCH_WHOLE)!=0)
736  return retval; // match is anchored to maxAddr
737  break; // segment does not satisfy constraints
738  }
739  }
740  size_t nElmtsHere = iter->key().greatest() + 1 - std::max(minAddr, iter->key().least());
741  if (nElmtsFound + nElmtsHere >= c.limit()) {
742  size_t nNeed = c.limit() - nElmtsFound;
743  addr = std::max(minAddr, iter->key().least()) + nNeed - 1;
744  ++iter;
745  break; // too many values
746  }
747  addr = iter->key().greatest();
748  nElmtsFound += nElmtsHere;
749  }
750  end = iter;
751  maxAddr = std::min(maxAddr, addr);
752  }
753 
754  // Build the result
755  retval.interval_ = Sawyer::Container::Interval<Address>::hull(minAddr, maxAddr);
756  retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
757  return retval;
758 }
759 
760 // Matches constraints against contiguous addresses in a backward direction.
761 template<class AddressMap>
762 MatchedConstraints<AddressMap>
763 matchBackward(AddressMap &amap, const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
764  typedef typename AddressMap::Address Address;
765  typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
766  MatchedConstraints<AddressMap> retval;
767  retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
768  if (c.neverMatches() || amap.isEmpty())
769  return retval;
770 
771  // Find a lower bound for the minimum address
772  Address minAddr = 0;
773  Iterator begin = constraintLowerBound(amap, c, false, minAddr /*out*/);
774  if (begin == amap.nodes().end())
775  return retval;
776 
777  // Find an upper bound for the maximum address.
778  Address maxAddr = 0;
779  Iterator end = constraintUpperBound(amap, c, true, maxAddr /*out*/);
780  if (end==amap.nodes().begin())
781  return retval;
782 
783  // Decrement the upper bound until constraints are met. End always points to one-past the last matching node.
784  while (end!=begin) {
785  Iterator prev = end; --prev;
786  if (isSatisfied(*prev, c)) {
787  maxAddr = std::min(maxAddr, prev->key().greatest());
788  break;
789  }
790  if (c.isAnchored())
791  return retval; // match is anchored to maxAddr
792  end = prev;
793  }
794  if (end==begin)
795  return retval;
796 
797  // Iterate backward until the constraints are no longer satisfied. Within the loop, iter always points to on-past the
798  // node in question. When the loop exits, iter points to the first node satisfying constraints.
799  if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
800  Address addr = maxAddr;
801  Iterator iter = end;
802  size_t nElmtsFound = 0;
803  for (/*void*/; iter!=begin; --iter) {
804  Iterator prev = iter; --prev; // prev points to the node in question
805  if (iter!=end) { // already tested last node above
806  if (c.isSingleSegment())
807  break; // we crossed a segment boundary
808  if ((flags & MATCH_CONTIGUOUS)!=0 && prev->key().greatest()+1 != addr)
809  break; // gap between segments
810  if (!isSatisfied(*prev, c)) {
811  if ((flags & MATCH_WHOLE)!=0)
812  return retval; // match is anchored to minAddr
813  break; // segment does not satisfy constraints
814  }
815  }
816  size_t nElmtsHere = std::min(maxAddr, prev->key().greatest()) - prev->key().least() + 1;
817  if (nElmtsFound + nElmtsHere >= c.limit()) {
818  size_t nNeed = c.limit() - nElmtsFound;
819  addr = std::min(maxAddr, prev->key().greatest()) - nNeed + 1;
820  iter = prev;
821  break;
822  }
823  addr = prev->key().least();
824  nElmtsFound += nElmtsHere;
825  }
826  begin = iter; // iter points to first matching node
827  minAddr = std::max(minAddr, addr);
828  }
829 
830  // Build the result
831  retval.interval_ = Sawyer::Container::Interval<Address>::hull(minAddr, maxAddr);
832  retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
833  return retval;
834 }
835 
836 // Match constraints forward or backward
837 template<class AddressMap>
838 MatchedConstraints<AddressMap>
839 matchConstraints(AddressMap &amap, const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
840  if ((flags & MATCH_BACKWARD) != 0)
841  return matchBackward(amap, c, flags);
842  return matchForward(amap, c, flags);
843 }
844 
845 } // namespace
846 
847 
1002 template<class A, class T = boost::uint8_t>
1003 class AddressMap: public IntervalMap<Interval<A>, AddressSegment<A, T>, AddressMapImpl::SegmentMergePolicy<A, T> > {
1004  // "Interval" is qualified to work around bug in Microsoft compilers. See doxygen note above.
1006 
1007 public:
1008  typedef A Address;
1009  typedef T Value;
1010  typedef AddressSegment<A, T> Segment;
1012  typedef typename Super::Node Node;
1019 private:
1020  friend class boost::serialization::access;
1021 
1022  template<class S>
1023  void serialize(S &s, const unsigned /*version*/) {
1024  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
1025  }
1026 
1027 public:
1030 
1046  AddressMap(const AddressMap &other, bool copyOnWrite=false): Super(other) {
1047  if (copyOnWrite) {
1048  for (Segment &segment: this->values()) {
1049  if (const typename Buffer::Ptr &buffer = segment.buffer())
1050  buffer->copyOnWrite(true);
1051  }
1052  }
1053  }
1054 
1062  }
1065  }
1075  }
1078  }
1089  }
1091  return AddressMapConstraints<AddressMap>(this).access(x);
1092  }
1100  AddressMapConstraints<const AddressMap> substr(const std::string &x) const {
1102  }
1104  return AddressMapConstraints<AddressMap>(this).substr(x);
1105  }
1116  }
1118  return AddressMapConstraints<AddressMap>(this).at(x);
1119  }
1143  }
1145  return AddressMapConstraints<AddressMap>(this).at(x);
1146  }
1157  }
1159  return AddressMapConstraints<AddressMap>(this).limit(x);
1160  }
1170  }
1173  }
1183  }
1186  }
1196  }
1198  return AddressMapConstraints<AddressMap>(this).within(x);
1199  }
1207  AddressMapConstraints<const AddressMap> within(Address x, Address y) const {
1209  }
1211  return AddressMapConstraints<AddressMap>(this).within(x, y);
1212  }
1221  return AddressMapConstraints<const AddressMap>(this).baseSize(base, size);
1222  }
1224  return AddressMapConstraints<AddressMap>(this).baseSize(base, size);
1225  }
1235  }
1237  return AddressMapConstraints<AddressMap>(this).after(x);
1238  }
1248  }
1250  return AddressMapConstraints<AddressMap>(this).before(x);
1251  }
1261  }
1264  }
1274  }
1277  }
1287  }
1289  return AddressMapConstraints<AddressMap>(this);
1290  }
1300  }
1302  return AddressMapConstraints<AddressMap>(this).none();
1303  }
1313  void checkConsistency() const {
1314  for (const Node &node: nodes()) {
1315  const Sawyer::Container::Interval<Address> &interval = node.key();
1316  const Segment &segment = node.value();
1317  if (segment.buffer()==NULL) {
1318  throw std::runtime_error("AddressMap null buffer for interval [" +
1319  boost::lexical_cast<std::string>(interval.least()) +
1320  "," + boost::lexical_cast<std::string>(interval.greatest()) + "]");
1321  }
1322  Address bufAvail = segment.buffer()->available(segment.offset());
1323  if (bufAvail < interval.size()) {
1324  throw std::runtime_error("AddressMap segment at [" + boost::lexical_cast<std::string>(interval.least()) +
1325  "," + boost::lexical_cast<std::string>(interval.greatest()) + "] points to only " +
1326  boost::lexical_cast<std::string>(bufAvail) + (1==bufAvail?" value":" values") +
1327  " but the interval size is " + boost::lexical_cast<std::string>(interval.size()));
1328  }
1329  }
1330  }
1331 
1338  Address nSegments() const { return this->nIntervals(); }
1339 
1345  boost::iterator_range<SegmentIterator> segments() { return this->values(); }
1346  boost::iterator_range<ConstSegmentIterator> segments() const { return this->values(); }
1347 
1368  boost::iterator_range<ConstSegmentIterator>
1369  segments(const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1370  using namespace AddressMapImpl;
1371  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1372  flags |= MATCH_CONTIGUOUS;
1373  MatchedConstraints<const AddressMap> m = matchConstraints(*this, c, flags);
1374  return boost::iterator_range<ConstSegmentIterator>(m.nodes_.begin(), m.nodes_.end());
1375  }
1376 
1377  boost::iterator_range<SegmentIterator>
1378  segments(const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1379  using namespace AddressMapImpl;
1380  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1381  flags |= MATCH_CONTIGUOUS;
1382  MatchedConstraints<AddressMap> m = matchConstraints(*this, c, flags);
1383  return boost::iterator_range<SegmentIterator>(m.nodes_);
1384  }
1393  boost::iterator_range<NodeIterator> nodes() { return Super::nodes(); }
1394  boost::iterator_range<ConstNodeIterator> nodes() const { return Super::nodes(); }
1416  boost::iterator_range<ConstNodeIterator>
1417  nodes(const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1418  using namespace AddressMapImpl;
1419  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1420  flags |= MATCH_CONTIGUOUS;
1421  MatchedConstraints<const AddressMap> m = matchConstraints(*this, c, flags);
1422  return m.nodes_;
1423  }
1424 
1425  boost::iterator_range<NodeIterator>
1426  nodes(const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1427  using namespace AddressMapImpl;
1428  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1429  flags |= MATCH_CONTIGUOUS;
1430  MatchedConstraints<AddressMap> m = matchConstraints(*this, c, flags);
1431  return m.nodes_;
1432  }
1473  next(const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1474  using namespace AddressMapImpl;
1475  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1476  flags |= MATCH_CONTIGUOUS;
1477  MatchedConstraints<const AddressMap> m = matchConstraints(*this, c.limit(1), flags);
1478  return m.interval_.isEmpty() ? Optional<Address>() : Optional<Address>(m.interval_.least());
1479  }
1480 
1487  available(const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1488  using namespace AddressMapImpl;
1489  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1490  flags |= MATCH_CONTIGUOUS;
1491  return matchConstraints(*this, c, flags).interval_;
1492  }
1493 
1503  bool exists(const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1504  return next(c, flags);
1505  }
1506 
1512  ConstNodeIterator findNode(const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1513  return nodes(c.limit(1), flags).begin();
1514  }
1515  NodeIterator findNode(const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1516  return nodes(c.limit(1), flags).begin();
1517  }
1528  unmapped(Address boundary, MatchFlags flags=0) const {
1529  return (flags & MATCH_BACKWARD) != 0 ? this->lastUnmapped(boundary) : this->firstUnmapped(boundary);
1530  }
1531 
1541  findFreeSpace(size_t nValues, size_t alignment=1,
1543  MatchFlags flags=0) const {
1545  ASSERT_forbid2(nValues == 0, "cannot determine if this is an overflow or intentional");
1546 
1547  if (restriction.isEmpty())
1548  return Nothing();
1549 
1550  if (0 == (flags & MATCH_BACKWARD)) {
1551  Address minAddr = restriction.least();
1552  while (minAddr <= restriction.greatest()) {
1553  Sawyer::Container::Interval<Address> interval = unmapped(minAddr, 0 /*forward*/);
1554  if (interval.isEmpty())
1555  return Nothing();
1556  minAddr = alignUp(interval.least(), alignment);
1557  Address maxAddr = minAddr + (nValues-1);
1558  if ((nValues <= interval.size() || 0==interval.size()/*overflow*/) &&
1559  minAddr >= interval.least()/*overflow*/ && maxAddr >= interval.least()/*overflow*/ &&
1560  maxAddr <= interval.greatest() &&
1561  maxAddr <= restriction.greatest()) {
1562  return minAddr;
1563  }
1564  if (interval.greatest() == whole.greatest())
1565  return Nothing(); // to avoid overflow in next statement
1566  minAddr = interval.greatest() + 1;
1567  }
1568  return Nothing();
1569  }
1570 
1571  ASSERT_require((flags & MATCH_BACKWARD) != 0);
1572  Address maxAddr = restriction.greatest();
1573  while (maxAddr >= restriction.least()) {
1574  Sawyer::Container::Interval<Address> interval = unmapped(maxAddr, MATCH_BACKWARD);
1575  if (interval.isEmpty())
1576  return Nothing();
1577  Address minAddr = alignDown(interval.greatest() - (nValues-1), alignment);
1578  maxAddr = minAddr + (nValues-1);
1579  if ((nValues <= interval.size() || 0==interval.size()/*overflow*/) &&
1580  minAddr >= interval.least()/*overflow*/ && maxAddr >= interval.least()/*overflow*/ &&
1581  maxAddr <= interval.greatest() &&
1582  minAddr >= restriction.least()) {
1583  return minAddr;
1584  }
1585  if (interval.least() == whole.least())
1586  return Nothing(); // to avoid overflow in next statement
1587  maxAddr = interval.least() - 1;
1588  }
1589  return Nothing();
1590  }
1591 
1593  class Visitor {
1594  public:
1595  virtual ~Visitor() {}
1596  virtual bool operator()(const AddressMap&, const Sawyer::Container::Interval<Address>&) = 0;
1597  };
1598 
1622  template<typename Functor>
1623  void traverse(Functor &functor, const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1624  using namespace AddressMapImpl;
1625  MatchedConstraints<const AddressMap> m = matchConstraints(*this, c, flags);
1626  for (const Node &node: m.nodes_) {
1627  Sawyer::Container::Interval<Address> part = m.interval_ & node.key();
1628  if (!functor(*this, part))
1629  return;
1630  }
1631  return;
1632  }
1633  template<typename Functor>
1634  void traverse(Functor &functor, const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1635  using namespace AddressMapImpl;
1636  MatchedConstraints<AddressMap> m = matchConstraints(*this, c, flags);
1637  for (const Node &node: m.nodes_) {
1638  Sawyer::Container::Interval<Address> part = m.interval_ & node.key();
1639  if (!functor(*this, part))
1640  return;
1641  }
1642  return;
1643  }
1644  void traverse(Visitor &visitor, const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1645  traverse<Visitor>(visitor, c, flags);
1646  }
1647  void traverse(Visitor &visitor, const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1648  traverse<Visitor>(visitor, c, flags);
1649  }
1691  read(Value *buf /*out*/, const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1692  using namespace AddressMapImpl;
1693  ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS), "only contiguous addresses can be read");
1694  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1695  flags |= MATCH_CONTIGUOUS;
1696  MatchedConstraints<const AddressMap> m = matchConstraints(*this, c, flags);
1697  if (buf) {
1698  for (const Node &node: m.nodes_) {
1699  Sawyer::Container::Interval<Address> part = m.interval_ & node.key(); // part of segment to read
1700  ASSERT_forbid(part.isEmpty());
1701  Address bufferOffset = part.least() - node.key().least() + node.value().offset();
1702  Address nValues = node.value().buffer()->read(buf, bufferOffset, part.size());
1703  if (nValues != part.size()) {
1704  checkConsistency();
1705  ASSERT_not_reachable("something is wrong with the memory map");
1706  }
1707  buf += nValues;
1708  }
1709  }
1710  return m.interval_;
1711  }
1712 
1714  read(std::vector<Value> &buf /*out*/, const AddressMapConstraints<const AddressMap> &c, MatchFlags flags=0) const {
1715  return buf.empty() ? Sawyer::Container::Interval<Address>() : read(&buf[0], c.limit(buf.size()), flags);
1716  }
1752  write(const Value *buf, const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1753  using namespace AddressMapImpl;
1754  ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS), "only contiguous addresses can be written");
1755  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1756  flags |= MATCH_CONTIGUOUS;
1757  MatchedConstraints<AddressMap> m = matchConstraints(*this, c.prohibit(Access::IMMUTABLE), flags);
1758  if (buf) {
1759  for (Node &node: m.nodes_) {
1760  Segment &segment = node.value();
1761  Sawyer::Container::Interval<Address> part = m.interval_ & node.key(); // part of segment to write
1762  ASSERT_forbid(part.isEmpty());
1763  typename Buffer::Ptr buffer = segment.buffer();
1764  ASSERT_not_null(buffer);
1765 
1766  if (buffer->copyOnWrite()) {
1767  typename Buffer::Ptr newBuffer = buffer->copy(); // copyOnWrite is cleared in newBuffer
1768  ASSERT_not_null(newBuffer);
1769  for (NodeIterator iter=this->lowerBound(node.key().least()); iter!=nodes().end(); ++iter) {
1770  if (iter->value().buffer() == buffer)
1771  iter->value().buffer(newBuffer);
1772  }
1773  buffer = newBuffer;
1774  }
1775 
1776  Address bufferOffset = part.least() - node.key().least() + segment.offset();
1777  Address nValues = buffer->write(buf, bufferOffset, part.size());
1778  if (nValues != part.size()) {
1779  checkConsistency();
1780  ASSERT_not_reachable("something is wrong with the memory map");
1781  }
1782  buf += nValues;
1783  }
1784  }
1785  return m.interval_;
1786  }
1787 
1789  write(const std::vector<Value> &buf, const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1790  return buf.empty() ? Sawyer::Container::Interval<Address>() : write(&buf[0], c.limit(buf.size()), flags);
1791  }
1806  void prune(const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1807  using namespace AddressMapImpl;
1809  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1810  flags |= MATCH_NONCONTIGUOUS;
1811  MatchedConstraints<AddressMap> m = matchConstraints(*this, c.addressConstraints(), flags);
1812  for (const Node &node: m.nodes_) {
1813  if (isSatisfied(node, c))
1814  toErase.insert(node.key() & m.interval_);
1815  }
1816  for (const Sawyer::Container::Interval<Address> &interval: toErase.intervals())
1817  this->erase(interval);
1818  }
1819 
1833  void keep(const AddressMapConstraints<AddressMap> &c, MatchFlags flags=0) {
1834  using namespace AddressMapImpl;
1835  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1836  flags |= MATCH_NONCONTIGUOUS;
1838  MatchedConstraints<AddressMap> m = matchConstraints(*this, c.addressConstraints(), flags);
1839  for (const Node &node: m.nodes_) {
1840  if (isSatisfied(node, c))
1841  toKeep.insert(node.key() & m.interval_);
1842  }
1843  toKeep.invert();
1844  for (const Sawyer::Container::Interval<Address> &interval: toKeep.intervals())
1845  this->erase(interval);
1846  }
1847 
1867  void changeAccess(unsigned requiredAccess, unsigned prohibitedAccess, const AddressMapConstraints<AddressMap> &c,
1868  MatchFlags flags=0) {
1869  using namespace AddressMapImpl;
1870  if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1871  flags |= MATCH_NONCONTIGUOUS;
1872  typedef std::pair<Sawyer::Container::Interval<Address>, Segment> ISPair;
1873  std::vector<ISPair> newSegments;
1874  MatchedConstraints<AddressMap> m = matchConstraints(*this, c.addressConstraints(), flags);
1875  for (Node &node: m.nodes_) {
1876  Segment &segment = node.value();
1877  if (isSatisfied(node, c)) {
1878  unsigned newAccess = (segment.accessibility() | requiredAccess) & ~prohibitedAccess;
1879  Sawyer::Container::Interval<Address> toChange = node.key() & m.interval_;
1880  if (toChange == node.key()) { // all addresses in segment are selected; change segment in place
1881  segment.accessibility(newAccess);
1882  } else { // insert a new segment, replacing part of the existing one
1883  Segment newSegment(segment);
1884  newSegment.accessibility(newAccess);
1885  newSegment.offset(segment.offset() + toChange.least() - node.key().least());
1886  newSegments.push_back(ISPair(toChange, newSegment));
1887  }
1888  }
1889  }
1890  for (const ISPair &pair: newSegments)
1891  this->insert(pair.first, pair.second);
1892  }
1893 
1894 private:
1895  // Increment x if necessary so it is aligned.
1896  static Address alignUp(Address x, Address alignment) {
1897  return alignment>0 && x%alignment!=0 ? ((x+alignment-1)/alignment)*alignment : x;
1898  }
1899 
1900  static Address alignDown(Address x, Address alignment) {
1901  return alignment>0 && x%alignment!=0 ? (x/alignment)*alignment : x;
1902  }
1903 };
1904 
1905 } // namespace
1906 } // namespace
1907 
1908 #endif
Base class for testing segment constraints.
Definition: AddressMap.h:58
unsigned required() const
Accessibility bits that are required to be set.
Definition: AddressMap.h:378
Interval lastUnmapped(typename Interval::Value maxAddr) const
Find the last unmapped region.
Definition: IntervalMap.h:564
unsigned MatchFlags
Flags for matching constraints.
Definition: AddressMap.h:49
AddressMapConstraints< const AddressMap > substr(const std::string &x) const
Constraint: segment name substring.
Definition: AddressMap.h:1100
NodeIterator findNode(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Find node containing address.
Definition: AddressMap.h:1515
boost::iterator_range< NodeIterator > nodes(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Nodes that overlap with constraints.
Definition: AddressMap.h:1426
const Optional< Address > & least() const
Least possible address.
Definition: AddressMap.h:420
AddressMapConstraints limit(size_t x) const
Limit matching length.
Definition: AddressMap.h:295
AddressMapConstraints at(Address x) const
Anchor at a certain address.
Definition: AddressMap.h:281
A Address
Type for addresses.
Definition: AddressMap.h:1008
AddressMapConstraints< const AddressMap > access(unsigned x) const
Constraint: required and prohibited access bits.
Definition: AddressMap.h:1087
An associative container whose keys are non-overlapping intervals.
Definition: IntervalMap.h:171
AddressMapConstraints< AddressMap > limit(size_t x)
Constraint: limit matched size.
Definition: AddressMap.h:1158
Optional< Address > next(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Minimum or maximum address that satisfies constraints.
Definition: AddressMap.h:1473
Value size() const
Size of interval.
Definition: Interval.h:291
AddressMapConstraints singleSegment() const
Limit matching to single segment.
Definition: AddressMap.h:353
AddressMapConstraints addressConstraints() const
Construct new constraints from existing address constraints.
Definition: AddressMap.h:455
bool neverMatches() const
Returns true if the constraint is not allowed to match anything.
Definition: AddressMap.h:395
AddressMapConstraints< const AddressMap > singleSegment() const
Constraint: single segment.
Definition: AddressMap.h:1259
bool isEmpty() const
True if interval is empty.
Definition: Interval.h:219
Super::ConstIntervalIterator ConstIntervalIterator
Iterates over address intervals in the map.
Definition: AddressMap.h:1015
Value & value()
Value part of key/value node.
Definition: Sawyer/Map.h:105
AddressMapConstraints< AddressMap > atOrAfter(Address x)
Constraint: address lower bound.
Definition: AddressMap.h:1171
void prune(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Prune away addresses that match constraints.
Definition: AddressMap.h:1806
Base class for traversals.
Definition: AddressMap.h:1593
AddressMapConstraints< AddressMap > segmentPredicate(SegmentPredicate< Address, Value > *p)
Constraint: arbitrary segment constraint.
Definition: AddressMap.h:1275
AddressMapConstraints substr(const std::string &s) const
Require certain segment names.
Definition: AddressMap.h:261
T Value
Type of data stored in the address space.
Definition: AddressMap.h:1009
boost::iterator_range< SegmentIterator > segments()
Iterator range for all segments.
Definition: AddressMap.h:1345
AddressMapConstraints segmentPredicate(SegmentPredicate< Address, Value > *p) const
Limit segments.
Definition: AddressMap.h:360
AddressMapConstraints< const AddressMap > at(Address x) const
Constraint: anchor point.
Definition: AddressMap.h:1114
AddressMapConstraints< AddressMap > access(unsigned x)
Constraint: required and prohibited access bits.
Definition: AddressMap.h:1090
AddressMapConstraints< const AddressMap > before(Address x) const
Constraint: address upper bound.
Definition: AddressMap.h:1246
virtual Address available(Address address) const =0
Distance to end of buffer.
boost::iterator_range< ConstNodeIterator > nodes() const
Iterator range for nodes.
Definition: AddressMap.h:1394
AddressMapConstraints any() const
No constraints.
Definition: AddressMap.h:269
Buffer< A, T >::Ptr buffer() const
Property: buffer.
boost::iterator_range< ConstSegmentIterator > segments() const
Iterator range for all segments.
Definition: AddressMap.h:1346
Sawyer::Container::Interval< Address > write(const std::vector< Value > &buf, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Writes data from the supplied buffer.
Definition: AddressMap.h:1789
AddressMapConstraints< const AddressMap > prohibit(unsigned x) const
Constraint: prohibited access bits.
Definition: AddressMap.h:1073
A homogeneous interval of an address space.
AddressMapConstraints< AddressMap > before(Address x)
Constraint: address upper bound.
Definition: AddressMap.h:1249
AddressSegment< A, T > Segment
Type of segments stored by this map.
Definition: AddressMap.h:1010
AddressMapConstraints< const AddressMap > atOrBefore(Address x) const
Constraint: address upper bound.
Definition: AddressMap.h:1181
Super::ValueIterator SegmentIterator
Iterates over segments in the map.
Definition: AddressMap.h:1013
Optional< Address > findFreeSpace(size_t nValues, size_t alignment=1, Sawyer::Container::Interval< Address > restriction=Sawyer::Container::Interval< Address >::whole(), MatchFlags flags=0) const
Find free space.
Definition: AddressMap.h:1541
AddressMapConstraints< AddressMap > singleSegment()
Constraint: single segment.
Definition: AddressMap.h:1262
Interval::Value size() const
Returns the number of values represented by this container.
Definition: IntervalMap.h:681
bool isEmpty() const
Determine if the container is empty.
Definition: IntervalMap.h:665
const Optional< Address > & greatest() const
Greatest possible address.
Definition: AddressMap.h:426
void traverse(Visitor &visitor, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Invoke a function on each address interval.
Definition: AddressMap.h:1647
AddressMapConstraints< const AddressMap > require(unsigned x) const
Constraint: required access bits.
Definition: AddressMap.h:1060
A container holding a set of values.
Definition: IntervalSet.h:55
AddressMapConstraints within(const Sawyer::Container::Interval< Address > &x) const
Limit addresses.
Definition: AddressMap.h:328
boost::iterator_range< ConstSegmentIterator > segments(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Segments that overlap with constraints.
Definition: AddressMap.h:1369
void insert(const Interval2 &interval)
Insert specified values.
Definition: IntervalSet.h:544
Super::ConstValueIterator ConstSegmentIterator
Iterators over segments in the map.
Definition: AddressMap.h:1014
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
BitVector & fromInteger(const BitRange &range, boost::uint64_t value)
Obtain bits from an integer.
Definition: BitVector.h:1321
Name space for the entire library.
Definition: FeasiblePath.h:767
Bidirectional iterator over key/value nodes.
Definition: Sawyer/Map.h:169
Sawyer::Container::Interval< Address > write(const Value *buf, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Writes data from the supplied buffer.
Definition: AddressMap.h:1752
AddressInterval anchored() const
Returns the anchor points.
Definition: AddressMap.h:408
AddressMapConstraints< AddressMap > require(unsigned x)
Constraint: required access bits.
Definition: AddressMap.h:1063
bool exists(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Determines if an address exists with the specified constraints.
Definition: AddressMap.h:1503
const std::string & substr() const
Section name substring.
Definition: AddressMap.h:388
friend std::ostream & operator<<(std::ostream &out, const AddressMapConstraints &x)
Print constraints in a human readable form.
Definition: AddressMap.h:233
bool contains(const Interval &other) const
Containment predicate.
Definition: Interval.h:246
AddressMapConstraints< AddressMap > baseSize(Address base, Address size)
Constraint: address lower and upper bounds.
Definition: AddressMap.h:1223
void traverse(Functor &functor, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Invoke a function on each address interval.
Definition: AddressMap.h:1623
void checkConsistency() const
Check map consistency.
Definition: AddressMap.h:1313
AddressMapConstraints< AddressMap > within(Address x, Address y)
Constraint: address lower and upper bounds.
Definition: AddressMap.h:1210
const Callbacks< SegmentPredicate< Address, Value > * > segmentPredicates() const
Returns the segment predicates.
Definition: AddressMap.h:436
T least() const
Returns lower limit.
Definition: Interval.h:207
Sawyer::Container::Interval< Address > read(Value *buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
Definition: AddressMap.h:1691
const std::string & name() const
Property: name.
AddressMapConstraints< AddressMap > within(const Sawyer::Container::Interval< Address > &x)
Constraint: address lower and upper bounds.
Definition: AddressMap.h:1197
AddressMapConstraints atOrAfter(Address least) const
Limit addresses.
Definition: AddressMap.h:302
unsigned accessibility() const
Property: access rights.
AddressMapConstraints< const AddressMap > any() const
Constraint: matches anything.
Definition: AddressMap.h:1285
AddressMapConstraints none() const
Constraints that match nothing.
Definition: AddressMap.h:274
Bidirectional iterator over values.
Definition: Sawyer/Map.h:253
AddressMapConstraints within(Address lo, Address hi) const
Limit addresses.
Definition: AddressMap.h:333
AddressMapConstraints< const AddressMap > baseSize(Address base, Address size) const
Constraint: address lower and upper bounds.
Definition: AddressMap.h:1220
AddressMapConstraints< AddressMap > atOrBefore(Address x)
Constraint: address upper bound.
Definition: AddressMap.h:1184
void insert(Interval key, Value value, bool makeHole=true)
Insert a key/value pair.
Definition: IntervalMap.h:838
unsigned prohibited() const
Accessibility bits that are required to be clear.
Definition: AddressMap.h:383
A mapping from address space to values.
Definition: AddressMap.h:1003
static Interval whole()
Construct an interval that covers the entire domain.
Definition: Interval.h:180
AddressMapConstraints< AddressMap > at(const Sawyer::Container::Interval< Address > &x)
Constraint: anchored interval.
Definition: AddressMap.h:1144
AddressMapConstraints access(unsigned bits) const
Require and prohibit certain access permissions.
Definition: AddressMap.h:256
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
Definition: Interval.h:151
Super::Node Node
Storage node containing interval/segment pair.
Definition: AddressMap.h:1012
ConstNodeIterator findNode(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Find node containing address.
Definition: AddressMap.h:1512
AddressMapConstraints< AddressMap > after(Address x)
Constraint: address lower bound.
Definition: AddressMap.h:1236
Sawyer::Container::Interval< Address > read(std::vector< Value > &buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
Definition: AddressMap.h:1714
void changeAccess(unsigned requiredAccess, unsigned prohibitedAccess, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Change access bits for addresses that match constraints.
Definition: AddressMap.h:1867
Base class for all buffers.
Definition: Buffer.h:25
AddressMap * map() const
Returns a pointer to the memory map for this constraint object.
Definition: AddressMap.h:441
size_t limit() const
Size limit.
Definition: AddressMap.h:414
AddressMapConstraints< const AddressMap > within(const Sawyer::Container::Interval< Address > &x) const
Constraint: address lower and upper bounds.
Definition: AddressMap.h:1194
bool isAnchored() const
Determines whether constraints are anchored to an address.
Definition: AddressMap.h:400
AddressMapConstraints after(Address x) const
Limit addresses.
Definition: AddressMap.h:343
AddressMapConstraints require(unsigned bits) const
Require certain access permissions.
Definition: AddressMap.h:242
const Key & key() const
Key part of key/value node.
Definition: Sawyer/Map.h:98
AddressMapConstraints< const AddressMap > segmentPredicate(SegmentPredicate< Address, Value > *p) const
Constraint: arbitrary segment constraint.
Definition: AddressMap.h:1272
boost::iterator_range< NodeIterator > nodes()
Iterators for traversing nodes.
Definition: IntervalMap.h:283
AddressMapConstraints prohibit(unsigned bits) const
Prohibit certain access permissions.
Definition: AddressMap.h:249
Bidirectional iterator over values.
Definition: Sawyer/Map.h:278
Sawyer::Container::Interval< Address > unmapped(Address boundary, MatchFlags flags=0) const
Find unmapped interval.
Definition: AddressMap.h:1528
Constraints are used to select addresses from a memory map.
Definition: AddressMap.h:79
AddressMapConstraints before(Address x) const
Limit addreses.
Definition: AddressMap.h:348
AddressMapConstraints baseSize(Address base, Address size) const
Limit addresses.
Definition: AddressMap.h:338
AddressMapConstraints< AddressMap > none()
Constraint: matches nothing.
Definition: AddressMap.h:1301
boost::iterator_range< ConstIntervalIterator > intervals() const
Iterator range for all intervals actually stored by this set.
Definition: IntervalSet.h:225
AddressMapConstraints(AddressMap *map)
Construct a constraint that matches everything.
Definition: AddressMap.h:100
bool isSingleSegment() const
Returns true if the single-segment constraint is set.
Definition: AddressMap.h:431
Super::ConstNodeIterator ConstNodeIterator
Iterates over address interval/segment pairs in the map.
Definition: AddressMap.h:1017
A offset() const
Property: buffer offset.
boost::iterator_range< NodeIterator > nodes()
Iterator range for nodes.
Definition: AddressMap.h:1393
AddressMapConstraints atOrBefore(Address greatest) const
Limit addresses.
Definition: AddressMap.h:315
Super::NodeIterator NodeIterator
Iterates over address interval, segment pairs in the map.
Definition: AddressMap.h:1016
AddressMapConstraints< AddressMap > substr(const std::string &x)
Constraint: segment name substring.
Definition: AddressMap.h:1103
AddressMapConstraints< const AddressMap > atOrAfter(Address x) const
Constraint: address lower bound.
Definition: AddressMap.h:1168
void keep(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Keep only addresses that match constraints.
Definition: AddressMap.h:1833
Sawyer::Container::Interval< Address > available(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Adress interval that satisfies constraints.
Definition: AddressMap.h:1487
Bidirectional iterator over keys.
Definition: Sawyer/Map.h:225
AddressMapConstraints< const AddressMap > at(const Sawyer::Container::Interval< Address > &x) const
Constraint: anchored interval.
Definition: AddressMap.h:1141
bool hasNonAddressConstraints() const
Determines whether non-address constraints are present.
Definition: AddressMap.h:447
AddressMapConstraints< const AddressMap > after(Address x) const
Constraint: address lower bound.
Definition: AddressMap.h:1233
NodeIterator lowerBound(const typename Interval::Value &scalar)
Find the first node whose interval ends at or above the specified scalar key.
Definition: IntervalMap.h:308
AddressMapConstraints at(const Sawyer::Container::Interval< Address > &x) const
Anchor at a certain interval.
Definition: AddressMap.h:288
AddressMapConstraints< const AddressMap > none() const
Constraint: matches nothing.
Definition: AddressMap.h:1298
Represents no value.
Definition: Optional.h:32
T greatest() const
Returns upper limit.
Definition: Interval.h:213
void traverse(Functor &functor, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Invoke a function on each address interval.
Definition: AddressMap.h:1634
AddressMapConstraints< const AddressMap > within(Address x, Address y) const
Constraint: address lower and upper bounds.
Definition: AddressMap.h:1207
Interval firstUnmapped(typename Interval::Value minAddr) const
Find the first unmapped region.
Definition: IntervalMap.h:546
AddressMapConstraints< const AddressMap > limit(size_t x) const
Constraint: limit matched size.
Definition: AddressMap.h:1155
Address nSegments() const
Number of segments contained in the map.
Definition: AddressMap.h:1338
void print(std::ostream &out) const
Print constraints in a human readable form.
Definition: AddressMap.h:159
void traverse(Visitor &visitor, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Invoke a function on each address interval.
Definition: AddressMap.h:1644
AddressMapConstraints< AddressMap > any()
Constraint: matches anything.
Definition: AddressMap.h:1288
AddressMapConstraints< AddressMap > prohibit(unsigned x)
Constraint: prohibited access bits.
Definition: AddressMap.h:1076
boost::iterator_range< SegmentIterator > segments(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Iterator range for all segments.
Definition: AddressMap.h:1378
AddressMapConstraints< AddressMap > at(Address x)
Constraint: anchor point.
Definition: AddressMap.h:1117
std::string toHex(const BitRange &range) const
Convert to a hexadecimal string.
Definition: BitVector.h:1249
boost::iterator_range< ConstNodeIterator > nodes(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Nodes that overlap with constraints.
Definition: AddressMap.h:1417
Type for stored nodes.
Definition: Sawyer/Map.h:89
Bidirectional iterator over key/value nodes.
Definition: Sawyer/Map.h:195
AddressMap(const AddressMap &other, bool copyOnWrite=false)
Copy constructor.
Definition: AddressMap.h:1046
AddressMap()
Constructs an empty address map.
Definition: AddressMap.h:1029