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;
 
 
 
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.