Handle frame pointer omission (#21), part 1: ContainedRangeMap. r=bryner.

- ContainedRangeMap is the data structure that will be used to store and
   look up debugging information for frames by instruction address.  The
   debugging information includes a way to locate the calling frame in
   the absence of a saved frame pointer.
 - Restructure RangeMap into an -inl file to match ContainedRangeMap.

http://groups.google.com/group/airbag-dev/browse_thread/thread/c5823bfc1828ed42


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@29 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
mmentovai 2006-09-20 16:20:15 +00:00
parent 82a6c6037b
commit 8c2a4def4e
13 changed files with 7956 additions and 6065 deletions

View file

@ -72,81 +72,14 @@ class RangeMap {
// Convenience types.
typedef std::map<AddressType, Range> AddressToRangeMap;
typedef typename AddressToRangeMap::const_iterator const_iterator;
typedef typename AddressToRangeMap::value_type value_type;
typedef typename AddressToRangeMap::const_iterator MapConstIterator;
typedef typename AddressToRangeMap::value_type MapValue;
// Maps the high address of each range to a EntryType.
AddressToRangeMap map_;
};
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
const AddressType &size,
const EntryType &entry) {
AddressType high = base + size - 1;
// Check for undersize or overflow.
if (size <= 0 || high < base)
return false;
// Ensure that this range does not overlap with another one already in the
// map.
const_iterator iterator_base = map_.lower_bound(base);
const_iterator iterator_high = map_.lower_bound(high);
if (iterator_base != iterator_high) {
// Some other range begins in the space used by this range. It may be
// contained within the space used by this range, or it may extend lower.
// Regardless, it is an error.
return false;
}
if (iterator_high != map_.end()) {
if (iterator_high->second.base() <= high) {
// The range above this one overlaps with this one. It may fully
// contain this range, or it may begin within this range and extend
// higher. Regardless, it's an error.
return false;
}
}
// Store the range in the map by its high address, so that lower_bound can
// be used to quickly locate a range by address.
map_.insert(value_type(high, Range(base, entry)));
return true;
}
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::RetrieveRange(
const AddressType &address, EntryType *entry) const {
if (!entry)
return false;
const_iterator iterator = map_.lower_bound(address);
if (iterator == map_.end())
return false;
// The map is keyed by the high address of each range, so |address| is
// guaranteed to be lower than the range's high address. If |range| is
// not directly preceded by another range, it's possible for address to
// be below the range's low address, though. When that happens, address
// references something not within any range, so return false.
if (address < iterator->second.base())
return false;
*entry = iterator->second.entry();
return true;
}
template<typename AddressType, typename EntryType>
void RangeMap<AddressType, EntryType>::Clear() {
map_.clear();
}
} // namespace google_airbag