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>
500 traverse(
typename AddressMap::Visitor &visitor,
MatchFlags flags=0)
const {
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);
1325 const Segment &segment = node.value();
1326 if (segment.buffer()==NULL) {
1327 throw std::runtime_error(
"AddressMap null buffer for interval [" +
1328 boost::lexical_cast<std::string>(interval.
least()) +
1329 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"]");
1331 Address bufAvail = segment.buffer()->available(segment.offset());
1332 if (bufAvail < interval.
size()) {
1333 throw std::runtime_error(
"AddressMap segment at [" + boost::lexical_cast<std::string>(interval.
least()) +
1334 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"] points to only " +
1335 boost::lexical_cast<std::string>(bufAvail) + (1==bufAvail?
" value":
" values") +
1336 " but the interval size is " + boost::lexical_cast<std::string>(interval.
size()));
1355 boost::iterator_range<ConstSegmentIterator>
segments()
const {
return this->
values(); }
1377 boost::iterator_range<ConstSegmentIterator>
1379 using namespace AddressMapImpl;
1380 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1381 flags |= MATCH_CONTIGUOUS;
1382 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1383 return boost::iterator_range<ConstSegmentIterator>(m.nodes_.begin(), m.nodes_.end());
1386 boost::iterator_range<SegmentIterator>
1388 using namespace AddressMapImpl;
1389 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1390 flags |= MATCH_CONTIGUOUS;
1391 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1392 return boost::iterator_range<SegmentIterator>(m.nodes_);
1425 boost::iterator_range<ConstNodeIterator>
1427 using namespace AddressMapImpl;
1428 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1429 flags |= MATCH_CONTIGUOUS;
1430 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1434 boost::iterator_range<NodeIterator>
1436 using namespace AddressMapImpl;
1437 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1438 flags |= MATCH_CONTIGUOUS;
1439 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1483 using namespace AddressMapImpl;
1484 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1485 flags |= MATCH_CONTIGUOUS;
1486 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c.
limit(1), flags);
1497 using namespace AddressMapImpl;
1498 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1499 flags |= MATCH_CONTIGUOUS;
1500 return matchConstraints(*
this, c, flags).interval_;
1513 return next(c, flags);
1554 ASSERT_forbid2(nValues == 0,
"cannot determine if this is an overflow or intentional");
1556 if (restriction.isEmpty())
1559 if (0 == (flags & MATCH_BACKWARD)) {
1560 Address minAddr = restriction.least();
1561 while (minAddr <= restriction.greatest()) {
1565 minAddr = alignUp(interval.
least(), alignment);
1566 Address maxAddr = minAddr + (nValues-1);
1567 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1568 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1570 maxAddr <= restriction.greatest()) {
1580 ASSERT_require((flags & MATCH_BACKWARD) != 0);
1581 Address maxAddr = restriction.greatest();
1582 while (maxAddr >= restriction.least()) {
1586 Address minAddr = alignDown(interval.
greatest() - (nValues-1), alignment);
1587 maxAddr = minAddr + (nValues-1);
1588 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1589 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1591 minAddr >= restriction.least()) {
1596 maxAddr = interval.
least() - 1;
1631 template<
typename Functor>
1633 using namespace AddressMapImpl;
1634 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1635 for (
const Node &node: m.nodes_) {
1637 if (!functor(*
this, part))
1642 template<
typename Functor>
1644 using namespace AddressMapImpl;
1645 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1646 for (
const Node &node: m.nodes_) {
1648 if (!functor(*
this, part))
1654 traverse<Visitor>(visitor, c, flags);
1657 traverse<Visitor>(visitor, c, flags);
1701 using namespace AddressMapImpl;
1702 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be read");
1703 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1704 flags |= MATCH_CONTIGUOUS;
1705 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1707 for (
const Node &node: m.nodes_) {
1709 ASSERT_forbid(part.
isEmpty());
1710 Address bufferOffset = part.
least() - node.key().least() + node.value().offset();
1711 Address nValues = node.value().buffer()->read(buf, bufferOffset, part.
size());
1712 if (nValues != part.
size()) {
1714 ASSERT_not_reachable(
"something is wrong with the memory map");
1762 using namespace AddressMapImpl;
1763 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be written");
1764 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1765 flags |= MATCH_CONTIGUOUS;
1766 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
prohibit(Access::IMMUTABLE), flags);
1768 size_t totalWritten = 0;
1769 for (
Node &node: m.nodes_) {
1770 Segment &segment = node.value();
1772 ASSERT_forbid(part.
isEmpty());
1774 ASSERT_not_null(buffer);
1776 if (buffer->copyOnWrite()) {
1778 ASSERT_not_null(newBuffer);
1780 if (iter->value().buffer() == buffer)
1781 iter->value().buffer(newBuffer);
1786 Address bufferOffset = part.
least() - node.key().least() + segment.offset();
1787 Address nValues = buffer->write(buf, bufferOffset, part.
size());
1791 }
else if (nValues != part.
size()) {
1793 ASSERT_not_reachable(
"something is wrong with the memory map");
1796 totalWritten += nValues;
1822 using namespace AddressMapImpl;
1824 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1825 flags |= MATCH_NONCONTIGUOUS;
1826 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1827 for (
const Node &node: m.nodes_) {
1828 if (isSatisfied(node, c))
1829 toErase.
insert(node.key() & m.interval_);
1832 this->
erase(interval);
1849 using namespace AddressMapImpl;
1850 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1851 flags |= MATCH_NONCONTIGUOUS;
1853 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1854 for (
const Node &node: m.nodes_) {
1855 if (isSatisfied(node, c))
1856 toKeep.
insert(node.key() & m.interval_);
1860 this->
erase(interval);
1884 using namespace AddressMapImpl;
1885 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1886 flags |= MATCH_NONCONTIGUOUS;
1887 typedef std::pair<Sawyer::Container::Interval<Address>,
Segment> ISPair;
1888 std::vector<ISPair> newSegments;
1889 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1890 for (
Node &node: m.nodes_) {
1891 Segment &segment = node.value();
1892 if (isSatisfied(node, c)) {
1893 unsigned newAccess = (segment.accessibility() | requiredAccess) & ~prohibitedAccess;
1895 if (toChange == node.key()) {
1896 segment.accessibility(newAccess);
1900 newSegment.
offset(segment.offset() + toChange.
least() - node.key().least());
1901 newSegments.push_back(ISPair(toChange, newSegment));
1905 for (
const ISPair &pair: newSegments)
1906 this->
insert(pair.first, pair.second);
1912 return alignment>0 && x%alignment!=0 ? ((x+alignment-1)/alignment)*alignment : x;
1916 return alignment>0 && x%alignment!=0 ? (x/alignment)*alignment : x;
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.
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.