8#ifndef Sawyer_AddressMap_H
9#define Sawyer_AddressMap_H
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>
21#include <boost/algorithm/string/predicate.hpp>
22#include <boost/cstdint.hpp>
23#include <boost/integer_traits.hpp>
24#include <boost/lexical_cast.hpp>
26#if __cplusplus >= 201103L
33template<
class AddressMap>
39template<
class AddressMap>
47static const MatchFlags MATCH_BACKWARD = 0x00000001;
48static const MatchFlags MATCH_CONTIGUOUS = 0x00000002;
49static const MatchFlags MATCH_NONCONTIGUOUS = 0x00000004;
50static const MatchFlags MATCH_WHOLE = 0x00000008;
54template<
class A,
class T>
61 : interval(interval), segment(segment) {}
65 virtual bool operator()(
bool chain,
const Args &) = 0;
75template<
typename AddressMap>
91 unsigned requiredAccess_;
92 unsigned prohibitedAccess_;
93 std::string nameSubstring_;
98 : map_(
map), never_(
false), maxSize_(
size_t(-1)), singleSegment_(
false), requiredAccess_(0), prohibitedAccess_(0) {}
100#if __cplusplus >= 201103L
156 void print(std::ostream &out)
const {
157 out <<
"{map=" <<map_;
161 out <<
", least=" <<*least_;
163 out <<
", greatest=" <<*greatest_;
175 if (maxSize_ !=
size_t(-1))
176 out <<
", limit=" <<maxSize_;
178 out <<
", single-segment";
179 if (requiredAccess_!=0) {
181 <<((requiredAccess_ & Access::READABLE) ?
"r" :
"")
182 <<((requiredAccess_ & Access::WRITABLE) ?
"w" :
"")
183 <<((requiredAccess_ & Access::EXECUTABLE) ?
"x" :
"")
184 <<((requiredAccess_ & Access::IMMUTABLE) ?
"i" :
"");
185 unsigned other = requiredAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
189 if (prohibitedAccess_!=0) {
191 <<((prohibitedAccess_ & Access::READABLE) ?
"r" :
"")
192 <<((prohibitedAccess_ & Access::WRITABLE) ?
"w" :
"")
193 <<((prohibitedAccess_ & Access::EXECUTABLE) ?
"x" :
"")
194 <<((prohibitedAccess_ & Access::IMMUTABLE) ?
"i" :
"");
195 unsigned other = prohibitedAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
199 if (!nameSubstring_.empty()) {
201 for (
char ch: nameSubstring_) {
203 case '\a': out <<
"\\a";
break;
204 case '\b': out <<
"\\b";
break;
205 case '\t': out <<
"\\t";
break;
206 case '\n': out <<
"\\n";
break;
207 case '\v': out <<
"\\v";
break;
208 case '\f': out <<
"\\f";
break;
209 case '\r': out <<
"\\r";
break;
210 case '\"': out <<
"\\\"";
break;
211 case '\\': out <<
"\\\\";
break;
217 snprintf(buf,
sizeof(buf),
"\\%03o", (
unsigned)(
unsigned char)
ch);
224 if (!segmentPredicates_.isEmpty())
241 retval.requiredAccess_ |= bits;
248 retval.prohibitedAccess_ |= bits;
259 ASSERT_require(nameSubstring_.empty() || nameSubstring_==s);
261 retval.nameSubstring_ = s;
287 retval.anchored_ = anchored_ ? *anchored_ & x : x;
294 retval.maxSize_ = std::min(maxSize_, x);
306 if (greatest_ && *greatest_ < *
retval.least_)
319 if (least_ && *least_ > *
retval.greatest_)
341 return x==boost::integer_traits<Address>::const_max ?
none() :
atOrAfter(x+1);
346 return x==boost::integer_traits<Address>::const_min ?
none() :
atOrBefore(x-1);
352 retval.singleSegment_ =
true;
361 retval.segmentPredicates_.append(p);
367 retval.segmentPredicates_.append(predicates);
376 return requiredAccess_;
381 return prohibitedAccess_;
386 return nameSubstring_;
429 return singleSegment_;
434 return segmentPredicates_;
446 (requiredAccess_ || prohibitedAccess_ || !nameSubstring_.empty() || maxSize_!=
size_t(-1) ||
447 singleSegment_ || !segmentPredicates_.isEmpty()));
455 c.greatest_ = greatest_;
456 c.anchored_ = anchored_;
457 c.maxSize_ = maxSize_;
464 boost::iterator_range<typename AddressMapTraits<AddressMap>::NodeIterator>
466 return map_->
nodes(*
this, flags);
469 boost::iterator_range<typename AddressMapTraits<AddressMap>::SegmentIterator>
471 return map_->
segments(*
this, flags);
476 return map_->
next(*
this, flags);
486 return map_->
exists(*
this, flags);
489 typename AddressMapTraits<AddressMap>::NodeIterator
491 return map_->
findNode(*
this, flags);
494 template<
typename Functor>
506 return map_->
read(buf, *
this, flags);
510 read(std::vector<typename AddressMap::Value> &buf ,
512 return map_->
read(buf, *
this, flags);
517 return map_->
write(buf, *
this, flags);
521 write(
const std::vector<typename AddressMap::Value> &buf,
MatchFlags flags=0) {
522 return map_->
write(buf, *
this, flags);
527 return map_->
prune(*
this, flags);
532 return map_->
keep(*
this, flags);
544namespace AddressMapImpl {
547template<
class A,
class T>
554#ifdef SAWYER_HAVE_CEREAL
556 friend class cereal::access;
558 template<
class Archive>
559 void CEREAL_SERIALIZE_FUNCTION_NAME(Archive&) {
564#ifdef SAWYER_HAVE_BOOST_SERIALIZATION
566 friend class boost::serialization::access;
569 void serialize(S&,
const unsigned ) {
577 ASSERT_forbid(leftInterval.
isEmpty());
578 ASSERT_always_forbid(rightInterval.
isEmpty());
579 ASSERT_require(leftInterval.
greatest() + 1 == rightInterval.
least());
581 leftSegment.
name() == rightSegment.
name() &&
587 ASSERT_forbid(interval.
isEmpty());
588 ASSERT_require(interval.
contains(splitPoint));
590 right.
offset(segment.offset() + splitPoint - interval.
least());
595 ASSERT_always_forbid(interval.
isEmpty());
596 ASSERT_always_require(interval.
contains(splitPoint));
601template<
class AddressMap>
606 boost::iterator_range<NodeIterator> nodes_;
614template<
class AddressMap>
620 return amap.
nodes().end();
624 return amap.
nodes().end();
627 return amap.
nodes().end();
634 if (lb==amap.
nodes().end())
636 minAddr = std::max(*c.
least(), lb->key().least());
640 Iterator lb = amap.
nodes().begin();
641 if (lb!=amap.
nodes().end())
642 minAddr = lb->key().least();
652template<
class AddressMap>
653typename AddressMapTraits<AddressMap>::NodeIterator
654constraintUpperBound(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
bool useAnchor,
656 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
657 if (amap.isEmpty() || c.neverMatches())
658 return amap.nodes().begin();
660 if (useAnchor && c.isAnchored()) {
661 if ((c.least() && *c.least() > c.anchored().least()) || (c.greatest() && *c.greatest() < c.anchored().greatest()))
662 return amap.nodes().begin();
663 Iterator ub = amap.findPrior(c.anchored().greatest());
664 if (ub==amap.nodes().end() || c.anchored().greatest() > ub->key().greatest())
665 return amap.nodes().begin();
666 maxAddr = c.anchored().greatest();
671 Iterator ub = amap.findPrior(*c.greatest());
672 if (ub==amap.nodes().end())
673 return amap.nodes().begin();
674 maxAddr = std::min(ub->key().greatest(), *c.greatest());
678 maxAddr = amap.hull().greatest();
679 return amap.nodes().end();
683template<
class AddressMap>
685isSatisfied(
const typename AddressMap::Node &node,
const AddressMapConstraints<AddressMap> &c) {
689 const Segment &segment = node.value();
690 if (!segment.isAccessible(c.required(), c.prohibited()))
692 if (!boost::contains(segment.name(), c.substr()))
694 if (!c.segmentPredicates().apply(
true,
typename SegmentPredicate<Address, Value>::Args(node.key(), node.value())))
700template<
class AddressMap>
701MatchedConstraints<AddressMap>
702matchForward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
MatchFlags flags) {
704 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
705 MatchedConstraints<AddressMap> retval;
706 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
707 if (c.neverMatches() || amap.isEmpty())
712 Iterator begin = constraintLowerBound(amap, c,
true, minAddr );
713 if (begin == amap.nodes().end())
718 Iterator end = constraintUpperBound(amap, c,
false, maxAddr );
719 if (end==amap.nodes().begin())
723 while (begin!=end && !isSatisfied(*begin, c)) {
730 minAddr = std::max(minAddr, begin->key().least());
733 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
735 Iterator iter = begin;
736 size_t nElmtsFound = 0;
737 for (; iter!=end; ++iter) {
739 if (c.isSingleSegment())
741 if ((flags & MATCH_CONTIGUOUS)!=0 && addr+1 != iter->key().least())
743 if (!isSatisfied(*iter, c)) {
744 if ((flags & MATCH_WHOLE)!=0)
749 size_t nElmtsHere = iter->key().greatest() + 1 - std::max(minAddr, iter->key().least());
750 if (nElmtsFound + nElmtsHere >= c.limit()) {
751 size_t nNeed = c.limit() - nElmtsFound;
752 addr = std::max(minAddr, iter->key().least()) + nNeed - 1;
756 addr = iter->key().greatest();
757 nElmtsFound += nElmtsHere;
760 maxAddr = std::min(maxAddr, addr);
765 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
770template<
class AddressMap>
771MatchedConstraints<AddressMap>
772matchBackward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
MatchFlags flags) {
774 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
775 MatchedConstraints<AddressMap> retval;
776 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
777 if (c.neverMatches() || amap.isEmpty())
782 Iterator begin = constraintLowerBound(amap, c,
false, minAddr );
783 if (begin == amap.nodes().end())
788 Iterator end = constraintUpperBound(amap, c,
true, maxAddr );
789 if (end==amap.nodes().begin())
794 Iterator prev = end; --prev;
795 if (isSatisfied(*prev, c)) {
796 maxAddr = std::min(maxAddr, prev->key().greatest());
808 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
811 size_t nElmtsFound = 0;
812 for (; iter!=begin; --iter) {
813 Iterator prev = iter; --prev;
815 if (c.isSingleSegment())
817 if ((flags & MATCH_CONTIGUOUS)!=0 && prev->key().greatest()+1 != addr)
819 if (!isSatisfied(*prev, c)) {
820 if ((flags & MATCH_WHOLE)!=0)
825 size_t nElmtsHere = std::min(maxAddr, prev->key().greatest()) - prev->key().least() + 1;
826 if (nElmtsFound + nElmtsHere >= c.limit()) {
827 size_t nNeed = c.limit() - nElmtsFound;
828 addr = std::min(maxAddr, prev->key().greatest()) - nNeed + 1;
832 addr = prev->key().least();
833 nElmtsFound += nElmtsHere;
836 minAddr = std::max(minAddr, addr);
841 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
846template<
class AddressMap>
847MatchedConstraints<AddressMap>
848matchConstraints(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
MatchFlags flags) {
849 if ((flags & MATCH_BACKWARD) != 0)
850 return matchBackward(amap, c, flags);
851 return matchForward(amap, c, flags);
1011template<
class A,
class T = boost::u
int8_t>
1029 friend class boost::serialization::access;
1032 void serialize(S &s,
const unsigned ) {
1033 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Super);
1058 if (
const typename Buffer::Ptr &buffer = segment.buffer())
1059 buffer->copyOnWrite(
true);
1330 const Segment &segment = node.value();
1331 if (segment.buffer()==NULL) {
1332 throw std::runtime_error(
"AddressMap null buffer for interval [" +
1333 boost::lexical_cast<std::string>(interval.
least()) +
1334 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"]");
1336 Address bufAvail = segment.buffer()->available(segment.offset());
1337 if (bufAvail < interval.
size()) {
1338 throw std::runtime_error(
"AddressMap segment at [" + boost::lexical_cast<std::string>(interval.
least()) +
1339 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"] points to only " +
1340 boost::lexical_cast<std::string>(bufAvail) + (1==bufAvail?
" value":
" values") +
1341 " but the interval size is " + boost::lexical_cast<std::string>(interval.
size()));
1360 boost::iterator_range<ConstSegmentIterator>
segments()
const {
return this->
values(); }
1382 boost::iterator_range<ConstSegmentIterator>
1384 using namespace AddressMapImpl;
1385 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1386 flags |= MATCH_CONTIGUOUS;
1387 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1388 return boost::iterator_range<ConstSegmentIterator>(m.nodes_.begin(), m.nodes_.end());
1391 boost::iterator_range<SegmentIterator>
1393 using namespace AddressMapImpl;
1394 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1395 flags |= MATCH_CONTIGUOUS;
1396 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1397 return boost::iterator_range<SegmentIterator>(m.nodes_);
1430 boost::iterator_range<ConstNodeIterator>
1432 using namespace AddressMapImpl;
1433 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1434 flags |= MATCH_CONTIGUOUS;
1435 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1439 boost::iterator_range<NodeIterator>
1441 using namespace AddressMapImpl;
1442 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1443 flags |= MATCH_CONTIGUOUS;
1444 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1488 using namespace AddressMapImpl;
1489 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1490 flags |= MATCH_CONTIGUOUS;
1491 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c.
limit(1), flags);
1502 using namespace AddressMapImpl;
1503 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1504 flags |= MATCH_CONTIGUOUS;
1505 return matchConstraints(*
this, c, flags).interval_;
1518 return next(c, flags);
1559 ASSERT_forbid2(nValues == 0,
"cannot determine if this is an overflow or intentional");
1561 if (restriction.isEmpty())
1564 if (0 == (flags & MATCH_BACKWARD)) {
1565 Address minAddr = restriction.least();
1566 while (minAddr <= restriction.greatest()) {
1570 minAddr = alignUp(interval.
least(), alignment);
1571 Address maxAddr = minAddr + (nValues-1);
1572 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1573 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1575 maxAddr <= restriction.greatest()) {
1585 ASSERT_require((flags & MATCH_BACKWARD) != 0);
1586 Address maxAddr = restriction.greatest();
1587 while (maxAddr >= restriction.least()) {
1591 Address minAddr = alignDown(interval.
greatest() - (nValues-1), alignment);
1592 maxAddr = minAddr + (nValues-1);
1593 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1594 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1596 minAddr >= restriction.least()) {
1601 maxAddr = interval.
least() - 1;
1636 template<
typename Functor>
1638 using namespace AddressMapImpl;
1639 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1640 for (
const Node &node: m.nodes_) {
1642 if (!functor(*
this, part))
1647 template<
typename Functor>
1649 using namespace AddressMapImpl;
1650 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1651 for (
const Node &node: m.nodes_) {
1653 if (!functor(*
this, part))
1659 traverse<Visitor>(visitor, c, flags);
1662 traverse<Visitor>(visitor, c, flags);
1706 using namespace AddressMapImpl;
1707 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be read");
1708 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1709 flags |= MATCH_CONTIGUOUS;
1710 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1712 for (
const Node &node: m.nodes_) {
1714 ASSERT_forbid(part.
isEmpty());
1715 Address bufferOffset = part.
least() - node.key().least() + node.value().offset();
1716 Address nValues = node.value().buffer()->read(buf, bufferOffset, part.
size());
1717 if (nValues != part.
size()) {
1719 ASSERT_not_reachable(
"something is wrong with the memory map");
1767 using namespace AddressMapImpl;
1768 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be written");
1769 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1770 flags |= MATCH_CONTIGUOUS;
1771 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
prohibit(Access::IMMUTABLE), flags);
1773 size_t totalWritten = 0;
1774 for (
Node &node: m.nodes_) {
1775 Segment &segment = node.value();
1777 ASSERT_forbid(part.
isEmpty());
1779 ASSERT_not_null(buffer);
1781 if (buffer->copyOnWrite()) {
1783 ASSERT_not_null(newBuffer);
1785 if (iter->value().buffer() == buffer)
1786 iter->value().buffer(newBuffer);
1791 Address bufferOffset = part.
least() - node.key().least() + segment.offset();
1792 Address nValues = buffer->write(buf, bufferOffset, part.
size());
1796 }
else if (nValues != part.
size()) {
1798 ASSERT_not_reachable(
"something is wrong with the memory map");
1801 totalWritten += nValues;
1827 using namespace AddressMapImpl;
1829 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1830 flags |= MATCH_NONCONTIGUOUS;
1831 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1832 for (
const Node &node: m.nodes_) {
1833 if (isSatisfied(node, c))
1834 toErase.
insert(node.key() & m.interval_);
1837 this->
erase(interval);
1854 using namespace AddressMapImpl;
1855 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1856 flags |= MATCH_NONCONTIGUOUS;
1858 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1859 for (
const Node &node: m.nodes_) {
1860 if (isSatisfied(node, c))
1861 toKeep.
insert(node.key() & m.interval_);
1865 this->
erase(interval);
1889 using namespace AddressMapImpl;
1890 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1891 flags |= MATCH_NONCONTIGUOUS;
1892 typedef std::pair<Sawyer::Container::Interval<Address>,
Segment> ISPair;
1893 std::vector<ISPair> newSegments;
1894 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1895 for (
Node &node: m.nodes_) {
1896 Segment &segment = node.value();
1897 if (isSatisfied(node, c)) {
1898 unsigned newAccess = (segment.accessibility() | requiredAccess) & ~prohibitedAccess;
1900 if (toChange == node.key()) {
1901 segment.accessibility(newAccess);
1905 newSegment.
offset(segment.offset() + toChange.
least() - node.key().least());
1906 newSegments.push_back(ISPair(toChange, newSegment));
1910 for (
const ISPair &pair: newSegments)
1911 this->
insert(pair.first, pair.second);
1917 return alignment>0 && x%alignment!=0 ? ((x+alignment-1)/alignment)*alignment : x;
1921 return alignment>0 && x%alignment!=0 ? (x/alignment)*alignment : x;
31namespace Container {
…}
Constraints are used to select addresses from a memory map.
bool hasNonAddressConstraints() const
Determines whether non-address constraints are present.
const Optional< Address > & least() const
Least possible address.
AddressMapConstraints within(const Sawyer::Container::Interval< Address > &x) const
Limit addresses.
AddressInterval anchored() const
Returns the anchor points.
AddressMapConstraints limit(size_t x) const
Limit matching length.
bool isSingleSegment() const
Returns true if the single-segment constraint is set.
unsigned required() const
Accessibility bits that are required to be set.
const Optional< Address > & greatest() const
Greatest possible address.
size_t limit() const
Size limit.
const std::string & substr() const
Section name substring.
AddressMapConstraints within(Address lo, Address hi) const
Limit addresses.
AddressMapConstraints addressConstraints() const
Construct new constraints from existing address constraints.
unsigned prohibited() const
Accessibility bits that are required to be clear.
AddressMapConstraints before(Address x) const
Limit addreses.
void print(std::ostream &out) const
Print constraints in a human readable form.
AddressMapConstraints singleSegment() const
Limit matching to single segment.
AddressMapConstraints segmentPredicate(SegmentPredicate< Address, Value > *p) const
Limit segments.
AddressMapConstraints prohibit(unsigned bits) const
Prohibit certain access permissions.
const Callbacks< SegmentPredicate< Address, Value > * > segmentPredicates() const
Returns the segment predicates.
AddressMapConstraints after(Address x) const
Limit addresses.
AddressMapConstraints substr(const std::string &s) const
Require certain segment names.
AddressMapConstraints any() const
No constraints.
bool neverMatches() const
Returns true if the constraint is not allowed to match anything.
bool isAnchored() const
Determines whether constraints are anchored to an address.
AddressMapConstraints(AddressMap *map)
Construct a constraint that matches everything.
AddressMapConstraints require(unsigned bits) const
Require certain access permissions.
AddressMap * map() const
Returns a pointer to the memory map for this constraint object.
AddressMapConstraints none() const
Constraints that match nothing.
AddressMapConstraints atOrBefore(Address greatest) const
Limit addresses.
AddressMapConstraints atOrAfter(Address least) const
Limit addresses.
AddressMapConstraints baseSize(Address base, Address size) const
Limit addresses.
AddressMapConstraints at(Address x) const
Anchor at a certain address.
friend std::ostream & operator<<(std::ostream &out, const AddressMapConstraints &x)
Print constraints in a human readable form.
AddressMapConstraints access(unsigned bits) const
Require and prohibit certain access permissions.
AddressMapConstraints at(const Sawyer::Container::Interval< Address > &x) const
Anchor at a certain interval.
Base class for traversals.
A mapping from address space to values.
Sawyer::Container::Interval< Address > available(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Adress interval that satisfies constraints.
AddressMapConstraints< const AddressMap > within(const Sawyer::Container::Interval< Address > &x) const
Constraint: address lower and upper bounds.
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.
boost::iterator_range< SegmentIterator > segments(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Iterator range for all segments.
Super::ConstIntervalIterator ConstIntervalIterator
Iterates over address intervals in the map.
void traverse(Functor &functor, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Invoke a function on each address interval.
A Address
Type for addresses.
ConstNodeIterator findNode(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Find node containing address.
AddressMapConstraints< const AddressMap > any() const
Constraint: matches anything.
void changeAccess(unsigned requiredAccess, unsigned prohibitedAccess, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Change access bits for addresses that match constraints.
NodeIterator findNode(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Find node containing address.
Sawyer::Container::Interval< Address > write(const std::vector< Value > &buf, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Writes data from the supplied buffer.
AddressMapConstraints< const AddressMap > before(Address x) const
Constraint: address upper bound.
AddressMap(const AddressMap &other, bool copyOnWrite=false)
Copy constructor.
void checkConsistency() const
Check map consistency.
AddressSegment< A, T > Segment
Type of segments stored by this map.
Sawyer::Container::Interval< Address > read(Value *buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
AddressMapConstraints< AddressMap > none()
Constraint: matches nothing.
AddressMap()
Constructs an empty address map.
AddressMapConstraints< AddressMap > singleSegment()
Constraint: single segment.
AddressMapConstraints< const AddressMap > prohibit(unsigned x) const
Constraint: prohibited access bits.
AddressMapConstraints< const AddressMap > atOrAfter(Address x) const
Constraint: address lower bound.
AddressMapConstraints< const AddressMap > singleSegment() const
Constraint: single segment.
AddressMapConstraints< AddressMap > substr(const std::string &x)
Constraint: segment name substring.
AddressMapConstraints< const AddressMap > at(const Sawyer::Container::Interval< Address > &x) const
Constraint: anchored interval.
AddressMapConstraints< AddressMap > within(const Sawyer::Container::Interval< Address > &x)
Constraint: address lower and upper bounds.
AddressMapConstraints< AddressMap > within(Address x, Address y)
Constraint: address lower and upper bounds.
AddressMapConstraints< const AddressMap > at(Address x) const
Constraint: anchor point.
AddressMapConstraints< AddressMap > limit(size_t x)
Constraint: limit matched size.
AddressMapConstraints< const AddressMap > none() const
Constraint: matches nothing.
Address nSegments() const
Number of segments contained in the map.
void prune(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Prune away addresses that match constraints.
void traverse(Visitor &visitor, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Invoke a function on each address interval.
AddressMapConstraints< const AddressMap > substr(const std::string &x) const
Constraint: segment name substring.
boost::iterator_range< ConstNodeIterator > nodes() const
Iterator range for nodes.
boost::iterator_range< SegmentIterator > segments()
Iterator range for all segments.
AddressMapConstraints< const AddressMap > require(unsigned x) const
Constraint: required access bits.
AddressMapConstraints< AddressMap > require(unsigned x)
Constraint: required access bits.
void traverse(Functor &functor, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Invoke a function on each address interval.
AddressMapConstraints< AddressMap > at(const Sawyer::Container::Interval< Address > &x)
Constraint: anchored interval.
void traverse(Visitor &visitor, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Invoke a function on each address interval.
boost::iterator_range< NodeIterator > nodes(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Nodes that overlap with constraints.
Super::ValueIterator SegmentIterator
Iterates over segments in the map.
AddressMapConstraints< const AddressMap > after(Address x) const
Constraint: address lower bound.
AddressMapConstraints< AddressMap > atOrBefore(Address x)
Constraint: address upper bound.
T Value
Type of data stored in the address space.
Super::ConstValueIterator ConstSegmentIterator
Iterators over segments in the map.
AddressMapConstraints< AddressMap > at(Address x)
Constraint: anchor point.
AddressMapConstraints< AddressMap > prohibit(unsigned x)
Constraint: prohibited access bits.
void keep(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Keep only addresses that match constraints.
AddressMapConstraints< AddressMap > access(unsigned x)
Constraint: required and prohibited access bits.
AddressMapConstraints< AddressMap > before(Address x)
Constraint: address upper bound.
Super::ConstNodeIterator ConstNodeIterator
Iterates over address interval/segment pairs in the map.
AddressMapConstraints< AddressMap > any()
Constraint: matches anything.
AddressMapConstraints< const AddressMap > limit(size_t x) const
Constraint: limit matched size.
boost::iterator_range< NodeIterator > nodes()
Iterator range for nodes.
Super::NodeIterator NodeIterator
Iterates over address interval, segment pairs in the map.
Sawyer::Container::Interval< Address > unmapped(Address boundary, MatchFlags flags=0) const
Find unmapped interval.
Sawyer::Container::Interval< Address > write(const Value *buf, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Writes data from the supplied buffer.
AddressMapConstraints< AddressMap > after(Address x)
Constraint: address lower bound.
AddressMapConstraints< AddressMap > segmentPredicate(SegmentPredicate< Address, Value > *p)
Constraint: arbitrary segment constraint.
boost::iterator_range< ConstNodeIterator > nodes(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Nodes that overlap with constraints.
boost::iterator_range< ConstSegmentIterator > segments(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Segments that overlap with constraints.
bool exists(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Determines if an address exists with the specified constraints.
AddressMapConstraints< const AddressMap > atOrBefore(Address x) const
Constraint: address upper bound.
AddressMapConstraints< const AddressMap > access(unsigned x) const
Constraint: required and prohibited access bits.
AddressMapConstraints< const AddressMap > baseSize(Address base, Address size) const
Constraint: address lower and upper bounds.
AddressMapConstraints< const AddressMap > within(Address x, Address y) const
Constraint: address lower and upper bounds.
Sawyer::Container::Interval< Address > read(std::vector< Value > &buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
AddressMapConstraints< AddressMap > baseSize(Address base, Address size)
Constraint: address lower and upper bounds.
Optional< Address > next(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Minimum or maximum address that satisfies constraints.
Super::Node Node
Storage node containing interval/segment pair.
boost::iterator_range< ConstSegmentIterator > segments() const
Iterator range for all segments.
AddressMapConstraints< AddressMap > atOrAfter(Address x)
Constraint: address lower bound.
AddressMapConstraints< const AddressMap > segmentPredicate(SegmentPredicate< Address, Value > *p) const
Constraint: arbitrary segment constraint.
A homogeneous interval of an address space.
const std::string & name() const
Property: name.
A offset() const
Property: buffer offset.
unsigned accessibility() const
Property: access rights.
Buffer< A, T >::Ptr buffer() const
Property: buffer.
BitVector & fromInteger(const BitRange &range, boost::uint64_t value)
Obtain bits from an integer.
std::string toHex(const BitRange &range) const
Convert to a hexadecimal string.
Base class for all buffers.
An associative container whose keys are non-overlapping intervals.
size_t nIntervals() const
Number of nodes in the container.
void insert(Interval key, Value value, bool makeHole=true)
Insert a key/value pair.
Interval firstUnmapped(typename Interval::Value minAddr) const
Find the first unmapped region.
Interval lastUnmapped(typename Interval::Value maxAddr) const
Find the last unmapped region.
boost::iterator_range< NodeIterator > nodes()
Iterators for traversing nodes.
boost::iterator_range< ValueIterator > values()
Iterators for traversing values.
void erase(const Interval &erasure)
Erase the specified interval.
NodeIterator lowerBound(const typename Interval::Value &scalar)
Find the first node whose interval ends at or above the specified scalar key.
bool isEmpty() const
Determine if the container is empty.
Interval::Value size() const
Returns the number of values represented by this container.
IntervalMap & operator=(const IntervalMap< Interval2, T2, Policy2 > &other)
Assignment operator.
A container holding a set of values.
void insert(const Interval2 &interval)
Insert specified values.
boost::iterator_range< ConstIntervalIterator > intervals() const
Iterator range for all intervals actually stored by this set.
Range of values delimited by endpoints.
T greatest() const
Returns upper limit.
static Interval baseSize(T lo, T size)
Construct an interval from one endpoint and a size.
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
bool contains(const Interval &other) const
Containment predicate.
Value size() const
Size of interval.
bool isEmpty() const
True if interval is empty.
T least() const
Returns lower limit.
static Interval whole()
Construct an interval that covers the entire domain.
Bidirectional iterator over keys.
Bidirectional iterator over key/value nodes.
Bidirectional iterator over values.
Bidirectional iterator over key/value nodes.
Bidirectional iterator over values.
Base class for testing segment constraints.
Holds a value or nothing.
Reference-counting intrusive smart pointer.
std::uint64_t Address
Address.
unsigned MatchFlags
Flags for matching constraints.