00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #if ! defined( RANGE_LOOKUP_H )
00032 #define RANGE_LOOKUP_H
00033
00034 #include <map>
00035 #include <vector>
00036 #include <list>
00037 #include <assert.h>
00038 #include "dyntypes.h"
00039 #include "util.h"
00040
00041 namespace Dyninst
00042 {
00043 namespace SymtabAPI
00044 {
00045
00046
00047
00048 class SYMTAB_EXPORT RangeLookupImpl
00049 {
00050 public:
00051 typedef std::pair< Offset, Offset > AddressRange;
00052
00053
00054
00055
00056 struct AddressRangeLess {
00057 bool operator()(const AddressRange &lhs, const AddressRange &rhs) const
00058 {
00059 if ( lhs.first < rhs.first )
00060 {
00061 return true;
00062 }
00063 else if ( lhs.first == rhs.first )
00064 {
00065 if ( lhs.second < rhs.second )
00066 {
00067 return true;
00068 }
00069 else
00070 {
00071 return false;
00072 }
00073 }
00074
00075 return false;
00076 }
00077 };
00078
00079 };
00080
00081 template< class Value, class ValueLess >
00082 class SYMTAB_EXPORT RangeLookup
00083 {
00084 protected:
00085 typedef RangeLookupImpl::AddressRange AddressRange;
00086 typedef RangeLookupImpl::AddressRangeLess AddressRangeLess;
00087
00088 typedef std::multimap< Value, AddressRange, ValueLess > AddressRangeByValue;
00089 typedef std::multimap< AddressRange, Value, AddressRangeLess > ValueByAddressRange;
00090
00091 public:
00092 typedef typename ValueByAddressRange::const_iterator const_iterator;
00093
00094 RangeLookup();
00095
00096
00097 bool addValue( Value v, Offset lowInclusiveAddr, Offset highExclusiveAddr );
00098 bool addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr, Value v );
00099
00100
00101 bool getValues( Offset addressInRange, std::vector< Value *> & values );
00102 bool getAddressRanges( Value v, std::vector< AddressRange > & ranges );
00103
00104 const_iterator begin() const;
00105 const_iterator end() const;
00106
00107 ~RangeLookup();
00108
00109
00110
00111
00112 protected:
00113 ValueByAddressRange valuesByAddressRangeMap;
00114 AddressRangeByValue addressRangesByValueMap;
00115 };
00116
00117 template< class Value, class ValueRange > RangeLookup< Value, ValueRange >::RangeLookup() :
00118 valuesByAddressRangeMap(),
00119 addressRangesByValueMap() {}
00120
00121
00122 template< class M >
00123 bool removeByValue( M & map, const typename M::value_type & value )
00124 {
00125 std::pair< typename M::iterator, typename M::iterator > range = map.equal_range( value.first );
00126 #if 0
00127 #if ! defined( os_windows )
00128 std::pair< typename M::iterator, typename M::iterator > range = map.equal_range( value.first );
00129 #else
00130 std::pair< M::iterator, M::iterator > range = map.equal_range( value.first );
00131 #endif
00132 #endif
00133
00134 for ( ; range.first != range.second && range.first != map.end(); ++range.first )
00135 {
00136 typename M::value_type &cmp = *range.first;
00137 if (cmp == value )
00138 {
00139 map.erase( range.first );
00140 return true;
00141 }
00142 }
00143
00144 return false;
00145
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 template <class Value, class ValueRange>
00187 bool RangeLookup< Value, ValueRange >::addValue(Value v,
00188 Offset lowInclusiveAddr,
00189 Offset highExclusiveAddr)
00190 {
00191
00192 if ( lowInclusiveAddr >= highExclusiveAddr )
00193 {
00194 return false;
00195 }
00196
00197
00198
00199 typedef typename ValueByAddressRange::iterator RangeIterator;
00200 std::pair< RangeIterator, RangeIterator > rangeOfRanges;
00201
00202 rangeOfRanges = valuesByAddressRangeMap.equal_range(AddressRange(lowInclusiveAddr,
00203 highExclusiveAddr));
00204
00205 if ( (rangeOfRanges.first != rangeOfRanges.second)
00206 || (valuesByAddressRangeMap.size() == 0) )
00207 {
00208
00209
00210
00211 valuesByAddressRangeMap.insert( rangeOfRanges.second,
00212 std::make_pair(AddressRange(lowInclusiveAddr,
00213 highExclusiveAddr), v));
00214
00215 addressRangesByValueMap.insert( std::make_pair( v, AddressRange(lowInclusiveAddr,
00216 highExclusiveAddr)));
00217 return true;
00218 }
00219
00220
00221
00222 typedef std::pair< AddressRange, Value > Range;
00223 typedef std::list< Range > RangeList;
00224 RangeIterator downIterator = rangeOfRanges.second;
00225
00226 if (rangeOfRanges.second != valuesByAddressRangeMap.begin())
00227 {
00228 --downIterator;
00229 }
00230
00231 RangeList containingRangeList;
00232 for (; ( (downIterator->first.first <= lowInclusiveAddr)
00233 && (highExclusiveAddr < downIterator->first.second) )
00234 ; --downIterator )
00235 {
00236
00237
00238
00239 containingRangeList.push_back( * downIterator );
00240
00241 if ( downIterator == valuesByAddressRangeMap.begin() )
00242 break;
00243 }
00244
00245
00246 RangeIterator upIterator = rangeOfRanges.second;
00247 RangeList containedRangeList;
00248
00249 for (; (upIterator != valuesByAddressRangeMap.end())
00250 && ((lowInclusiveAddr <= upIterator->first.first)
00251 && (upIterator->first.second < highExclusiveAddr) )
00252 ; ++upIterator )
00253 {
00254
00255
00256
00257 containedRangeList.push_back( * upIterator );
00258 }
00259
00260 if (containingRangeList.size() == 0 && containedRangeList.size() == 0 )
00261 {
00262
00263 valuesByAddressRangeMap.insert(rangeOfRanges.second,
00264 std::make_pair(AddressRange(lowInclusiveAddr,
00265 highExclusiveAddr), v));
00266 addressRangesByValueMap.insert( std::make_pair(v,AddressRange(lowInclusiveAddr,
00267 highExclusiveAddr)));
00268 return true;
00269 }
00270
00271
00272
00273 if (containingRangeList.size() != 0)
00274 {
00275 Offset splitAddress = highExclusiveAddr;
00276
00277
00278 typename RangeList::const_iterator containingIterator = containingRangeList.begin();
00279
00280 for ( ; containingIterator != containingRangeList.end(); ++containingIterator )
00281 {
00282 AddressRange ar = containingIterator->first;
00283 Value lnt = containingIterator->second;
00284
00285
00286
00287 assert( removeByValue( valuesByAddressRangeMap, * containingIterator ) );
00288 assert( removeByValue( addressRangesByValueMap, std::make_pair( lnt, ar ) ) );
00289
00290
00291
00292
00293 valuesByAddressRangeMap.insert(std::make_pair(AddressRange(ar.first,
00294 splitAddress), lnt));
00295 addressRangesByValueMap.insert( std::make_pair(lnt,AddressRange(ar.first,
00296 splitAddress)));
00297
00298
00299
00300 valuesByAddressRangeMap.insert(std::make_pair(AddressRange(splitAddress,
00301 ar.second ), lnt ) );
00302 addressRangesByValueMap.insert(std::make_pair(lnt, AddressRange(splitAddress,
00303 ar.second ) ) );
00304 }
00305
00306
00307
00308
00309 valuesByAddressRangeMap.insert(std::make_pair(AddressRange(lowInclusiveAddr,
00310 highExclusiveAddr ), v ) );
00311 addressRangesByValueMap.insert(std::make_pair(v, AddressRange(lowInclusiveAddr,
00312 highExclusiveAddr ) ) );
00313 return true;
00314 }
00315
00316 if (containedRangeList.size() != 0 )
00317 {
00318
00319 typedef std::list< Offset > AddressList;
00320 AddressList splitAddressList;
00321
00322
00323
00324
00325 typename RangeList::const_iterator containedIterator = containedRangeList.begin();
00326 Offset splitAddress = containedIterator->first.second;
00327 ++containedIterator;
00328
00329 for ( ; containedIterator != containedRangeList.end(); ++containedIterator )
00330 {
00331
00332
00333 if (containedIterator->first.first >= splitAddress)
00334 {
00335
00336
00337
00338 splitAddressList.push_back( splitAddress );
00339
00340
00341 splitAddress = containedIterator->first.second;
00342 }
00343 else
00344 {
00345 splitAddress = containedIterator->first.second;
00346 }
00347 }
00348
00349
00350
00351 splitAddressList.push_back( splitAddress );
00352
00353
00354
00355 Offset lowAddress = lowInclusiveAddr;
00356 AddressList::const_iterator splitAddressIterator = splitAddressList.begin();
00357 Offset highAddress = 0;
00358
00359 for ( ; splitAddressIterator != splitAddressList.end(); ++ splitAddressIterator )
00360 {
00361 highAddress = * splitAddressIterator;
00362
00363
00364
00365 valuesByAddressRangeMap.insert(std::make_pair(AddressRange(lowAddress, highAddress ), v ) );
00366 addressRangesByValueMap.insert(std::make_pair(v, AddressRange(lowAddress, highAddress ) ) );
00367
00368 lowAddress = highAddress;
00369 }
00370
00371
00372
00373 valuesByAddressRangeMap.insert(std::make_pair(AddressRange( highAddress, highExclusiveAddr ), v ) );
00374 addressRangesByValueMap.insert(std::make_pair(v, AddressRange( highAddress, highExclusiveAddr ) ) );
00375
00376
00377 return true;
00378 }
00379
00380
00381 return false;
00382 }
00383
00384 template< class Value, class ValueRange >
00385 bool RangeLookup< Value, ValueRange >::addAddressRange( Offset lowInclusiveAddr,
00386 Offset highExclusiveAddr,
00387 Value v )
00388 {
00389 return addValue( v, lowInclusiveAddr, highExclusiveAddr );
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399 template< class Value, class ValueRange >
00400 bool RangeLookup< Value, ValueRange >::getValues( Offset addressInRange,
00401 std::vector< Value *> & values )
00402 {
00403
00404 if ( valuesByAddressRangeMap.size() == 0 )
00405 return false;
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 typedef typename ValueByAddressRange::const_iterator RangeIterator;
00416 std::pair< RangeIterator, RangeIterator > lowRange
00417 = valuesByAddressRangeMap.equal_range( AddressRange( addressInRange + 1, 0 ) );
00418
00419 if (lowRange.second == valuesByAddressRangeMap.begin())
00420 return false;
00421
00422 assert( lowRange.first == lowRange.second );
00423 RangeIterator hHighEnd = --(lowRange.second);
00424
00425
00426
00427 for ( ; hHighEnd->first.second > addressInRange && hHighEnd != valuesByAddressRangeMap.end();
00428 --hHighEnd )
00429 {
00430 if ( (hHighEnd->first.first <= addressInRange)
00431 && (addressInRange < hHighEnd->first.second) )
00432 {
00433 values.push_back( const_cast<Value *> (& hHighEnd->second) );
00434 }
00435
00436 if (hHighEnd == valuesByAddressRangeMap.begin() )
00437 break;
00438 }
00439
00440 if ( values.size() == 0 )
00441 return false;
00442
00443 return true;
00444 }
00445
00446 template< class Value, class ValueRange >
00447 bool RangeLookup< Value, ValueRange >::getAddressRanges(Value v,
00448 std::vector<AddressRange> &ranges)
00449 {
00450
00451 typedef typename AddressRangeByValue::const_iterator IteratorType;
00452 std::pair< IteratorType, IteratorType > range = addressRangesByValueMap.equal_range( v );
00453
00454
00455
00456 if ( range.first == range.second )
00457 {
00458 return false;
00459 }
00460
00461
00462 for ( IteratorType i = range.first; i != range.second; ++i )
00463 {
00464
00465 ranges.push_back(i->second);
00466 }
00467
00468 return true;
00469 }
00470
00471 template< class Value, class ValueRange >
00472 typename RangeLookup< Value, ValueRange >::const_iterator RangeLookup< Value, ValueRange >::begin() const
00473 {
00474 return valuesByAddressRangeMap.begin();
00475 }
00476
00477 template< class Value, class ValueRange >
00478 typename RangeLookup< Value, ValueRange >::const_iterator RangeLookup< Value, ValueRange >::end() const
00479 {
00480 return valuesByAddressRangeMap.end();
00481 }
00482
00483 template< class Value, class ValueRange >
00484 RangeLookup< Value, ValueRange >::~RangeLookup()
00485 {
00486 }
00487
00488
00489 }
00490 }
00491 #endif