|  | // Copyright (c) 2006, Google Inc. | 
|  | // All rights reserved. | 
|  | // | 
|  | // Redistribution and use in source and binary forms, with or without | 
|  | // modification, are permitted provided that the following conditions are | 
|  | // met: | 
|  | // | 
|  | //     * Redistributions of source code must retain the above copyright | 
|  | // notice, this list of conditions and the following disclaimer. | 
|  | //     * Redistributions in binary form must reproduce the above | 
|  | // copyright notice, this list of conditions and the following disclaimer | 
|  | // in the documentation and/or other materials provided with the | 
|  | // distribution. | 
|  | //     * Neither the name of Google Inc. nor the names of its | 
|  | // contributors may be used to endorse or promote products derived from | 
|  | // this software without specific prior written permission. | 
|  | // | 
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  |  | 
|  | // contained_range_map.h: Hierarchically-organized range maps. | 
|  | // | 
|  | // A contained range map is similar to a standard range map, except it allows | 
|  | // objects to be organized hierarchically.  A contained range map allows | 
|  | // objects to contain other objects.  It is not sensitive to the order that | 
|  | // objects are added to the map: larger, more general, containing objects | 
|  | // may be added either before or after smaller, more specific, contained | 
|  | // ones. | 
|  | // | 
|  | // Contained range maps guarantee that each object may only contain smaller | 
|  | // objects than itself, and that a parent object may only contain child | 
|  | // objects located entirely within the parent's address space.  Attempts | 
|  | // to introduce objects (via StoreRange) that violate these rules will fail. | 
|  | // Retrieval (via RetrieveRange) always returns the most specific (smallest) | 
|  | // object that contains the address being queried.  Note that while it is | 
|  | // not possible to insert two objects into a map that have exactly the same | 
|  | // geometry (base address and size), it is possible to completely mask a | 
|  | // larger object by inserting smaller objects that entirely fill the larger | 
|  | // object's address space. | 
|  | // | 
|  | // Internally, contained range maps are implemented as a tree.  Each tree | 
|  | // node except for the root node describes an object in the map.  Each node | 
|  | // maintains its list of children in a map similar to a standard range map, | 
|  | // keyed by the highest address that each child occupies.  Each node's | 
|  | // children occupy address ranges entirely within the node.  The root node | 
|  | // is the only node directly accessible to the user, and represents the | 
|  | // entire address space. | 
|  | // | 
|  | // Author: Mark Mentovai | 
|  |  | 
|  | #ifndef PROCESSOR_CONTAINED_RANGE_MAP_H__ | 
|  | #define PROCESSOR_CONTAINED_RANGE_MAP_H__ | 
|  |  | 
|  |  | 
|  | #include <map> | 
|  |  | 
|  |  | 
|  | namespace google_breakpad { | 
|  |  | 
|  | // Forward declarations (for later friend declarations of specialized template). | 
|  | template<class, class> class ContainedRangeMapSerializer; | 
|  |  | 
|  | template<typename AddressType, typename EntryType> | 
|  | class ContainedRangeMap { | 
|  | public: | 
|  | // The default constructor creates a ContainedRangeMap with no geometry | 
|  | // and no entry, and as such is only suitable for the root node of a | 
|  | // ContainedRangeMap tree. | 
|  | ContainedRangeMap() : base_(), entry_(), map_(NULL) {} | 
|  |  | 
|  | ~ContainedRangeMap(); | 
|  |  | 
|  | // Inserts a range into the map.  If the new range is encompassed by | 
|  | // an existing child range, the new range is passed into the child range's | 
|  | // StoreRange method.  If the new range encompasses any existing child | 
|  | // ranges, those child ranges are moved to the new range, becoming | 
|  | // grandchildren of this ContainedRangeMap.  Returns false for a | 
|  | // parameter error, or if the ContainedRangeMap hierarchy guarantees | 
|  | // would be violated. | 
|  | bool StoreRange(const AddressType &base, | 
|  | const AddressType &size, | 
|  | const EntryType &entry); | 
|  |  | 
|  | // Retrieves the most specific (smallest) descendant range encompassing | 
|  | // the specified address.  This method will only return entries held by | 
|  | // child ranges, and not the entry contained by |this|.  This is necessary | 
|  | // to support a sparsely-populated root range.  If no descendant range | 
|  | // encompasses the address, returns false. | 
|  | bool RetrieveRange(const AddressType &address, EntryType *entry) const; | 
|  |  | 
|  | // Removes all children.  Note that Clear only removes descendants, | 
|  | // leaving the node on which it is called intact.  Because the only | 
|  | // meaningful things contained by a root node are descendants, this | 
|  | // is sufficient to restore an entire ContainedRangeMap to its initial | 
|  | // empty state when called on the root node. | 
|  | void Clear(); | 
|  |  | 
|  | private: | 
|  | friend class ContainedRangeMapSerializer<AddressType, EntryType>; | 
|  | friend class ModuleComparer; | 
|  |  | 
|  | // AddressToRangeMap stores pointers.  This makes reparenting simpler in | 
|  | // StoreRange, because it doesn't need to copy entire objects. | 
|  | typedef std::map<AddressType, ContainedRangeMap *> AddressToRangeMap; | 
|  | typedef typename AddressToRangeMap::const_iterator MapConstIterator; | 
|  | typedef typename AddressToRangeMap::iterator MapIterator; | 
|  | typedef typename AddressToRangeMap::value_type MapValue; | 
|  |  | 
|  | // Creates a new ContainedRangeMap with the specified base address, entry, | 
|  | // and initial child map, which may be NULL.  This is only used internally | 
|  | // by ContainedRangeMap when it creates a new child. | 
|  | ContainedRangeMap(const AddressType &base, const EntryType &entry, | 
|  | AddressToRangeMap *map) | 
|  | : base_(base), entry_(entry), map_(map) {} | 
|  |  | 
|  | // The base address of this range.  The high address does not need to | 
|  | // be stored, because it is used as the key to an object in its parent's | 
|  | // map, and all ContainedRangeMaps except for the root range are contained | 
|  | // within maps.  The root range does not actually contain an entry, so its | 
|  | // base_ field is meaningless, and the fact that it has no parent and thus | 
|  | // no key is unimportant.  For this reason, the base_ field should only be | 
|  | // is accessed on child ContainedRangeMap objects, and never on |this|. | 
|  | const AddressType base_; | 
|  |  | 
|  | // The entry corresponding to this range.  The root range does not | 
|  | // actually contain an entry, so its entry_ field is meaningless.  For | 
|  | // this reason, the entry_ field should only be accessed on child | 
|  | // ContainedRangeMap objects, and never on |this|. | 
|  | const EntryType entry_; | 
|  |  | 
|  | // The map containing child ranges, keyed by each child range's high | 
|  | // address.  This is a pointer to avoid allocating map structures for | 
|  | // leaf nodes, where they are not needed. | 
|  | AddressToRangeMap *map_; | 
|  | }; | 
|  |  | 
|  |  | 
|  | }  // namespace google_breakpad | 
|  |  | 
|  |  | 
|  | #endif  // PROCESSOR_CONTAINED_RANGE_MAP_H__ |