ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExtentMap.C
Go to the documentation of this file.
1 /* The ExtentMap class. This class is similar std::map<rose_addr_t,rose_addr_t> where the two addresses are the starting
2  * offset and size. The main difference is that if two adjacent extents are added to the map they will be condensed into a
3  * single extent. This class is used to keep track of what parts of a binary file have been parsed, and is also used to
4  * manage string table free lists, among other things. */
5 
6 #include "sage3basic.h"
7 
17 char
18 ExtentMap::category(const Extent &a, const Extent &b)
19 {
20  if (a.relaxed_first()==b.relaxed_first() && a.size()==b.size())
21  return 'C';
22  if (a.relaxed_first()+a.size() <= b.relaxed_first())
23  return 'L';
24  if (a.relaxed_first() >= b.relaxed_first()+b.size())
25  return 'R';
26  if (a.relaxed_first() <= b.relaxed_first() && a.relaxed_first()+a.size() >= b.relaxed_first()+b.size())
27  return 'O';
28  if (a.relaxed_first() >= b.relaxed_first() && a.relaxed_first()+a.size() <= b.relaxed_first()+b.size())
29  return 'I';
30  if (a.relaxed_first() <= b.relaxed_first()) /*already know a.first+a.size > b.first*/
31  return 'B';
32  return 'E';
33 }
34 
36 Extent
38 {
39  iterator found = best_fit(size, begin());
40  if (found==end())
41  throw std::bad_alloc();
42  Extent retval(found->first.first(), size);
43  erase(retval);
44  return retval;
45 }
46 
48 Extent
50 {
51  iterator found = first_fit(size, begin());
52  if (found==end())
53  throw std::bad_alloc();
54  Extent retval(found->first.first(), size);
55  erase(retval);
56  return retval;
57 }
58 
60 void
62 {
63  ROSE_ASSERT(subtract_from(request).size()==0); /*entire request should be on free list*/
64  erase(request);
65 }
66 
67 #if 0 /* NOT NEEDED BY ANYTHING? [RPM 2011-10-18] */
68 
71 void
72 ExtentMap::precipitate(rose_addr_t reagent)
73 {
74  abort(); // NOT IMPLEMENTED
75  ExtentMap result;
76  for (iterator i=begin(); i!=end(); /*void*/) {
77  ExtentPair left = *i++;
78  for (/*void*/; i!=end() && left.first+left.second+reagent >= i->first; i++)
79  left.second = (i->first + i->second) - left.first;
80  result.insert(left);
81  }
82  *this = result;
83 }
84 #endif
85 
86 #if 0 /* NOT NEEDED BY ANYTHING? [RPM 2011-10-18] */
87 
88 ExtentPair
89 ExtentMap::find_address(rose_addr_t addr) const
90 {
91  const_iterator i = upper_bound(addr);
92  RangeMapType::const_iterator i2 = ranges.find(addr);
93  if (i==begin()) {
94  assert(i2==ranges.end());
95  throw std::bad_alloc();
96  }
97  --i;
98  if (i->first+i->second <= addr) {
99  assert(i2==ranges.end());
100  throw std::bad_alloc();
101  }
102 
103  assert(i->first==i2->first.begin);
104  assert(i->second==i2->first.size);
105  return *i;
106 }
107 #endif
108 
109 #if 0 /* NOT NEEDED BY ANYTHING? [RPM 2011-10-18] */
110 
112 bool
113 ExtentMap::exists_all(ExtentPair what) const
114 {
115  while (what.second>0) {
116  try {
117  ExtentPair found = find_address(what.first);
118  assert(found.second > 0);
119  assert(found.first <= what.first);
120  assert(what.first <= found.first + found.second);
121  rose_addr_t nfound = std::min(what.second, found.second-(what.first-found.first));
122  what.first = found.first + found.second;
123  what.second -= nfound;
124  } catch (const std::bad_alloc&) { // thrown by find_address()
125  assert(!ranges.contains(RangeType(what.first, what.second)));
126  return false;
127  }
128  }
129  assert(ranges.contains(RangeType(what.first, what.second)));
130  return true;
131 }
132 #endif
133 
134 void
135 ExtentMap::dump_extents(std::ostream &o, const std::string &prefix, const std::string &label) const
136 {
137  using namespace StringUtility;
138  size_t idx=0;
139  for (const_iterator i=begin(); i!=end(); ++i, ++idx) {
140  o <<prefix <<(label.empty()?std::string("Extent"):label) <<"[" <<idx <<"]"
141  <<" = offset " <<unsignedToHex(i->first.first())
142  <<" for " <<unsignedToHex(i->first.size()) <<(1==i->first.size()?" byte":" bytes")
143  <<" ending at " <<unsignedToHex(i->first.first() + i->first.size()) <<"\n";
144  }
145 }
146 
147 
149 void
150 ExtentMap::dump_extents(FILE *f, const char *prefix, const char *label, bool pad) const
151 {
152  char p[4096];
153  size_t idx=0;
154  for (const_iterator i=begin(); i!=end(); ++i, ++idx) {
155  if (!label) label = "Extent";
156  sprintf(p, "%s%s[%zd]", prefix, label, idx);
157  int w = pad ? std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p)) : 1;
158  fprintf(f, "%s%-*s = offset 0x%08"PRIx64" (%"PRIu64"),"
159  " for 0x%08"PRIx64" (%"PRIu64") byte%s,"
160  " ending at 0x%08"PRIx64" (%"PRIu64")\n",
161  p, w, "", i->first.first(), i->first.first(),
162  i->first.size(), i->first.size(), 1==i->first.size()?"":"s",
163  i->first.first()+i->first.size(), i->first.first()+i->first.size());
164  }
165 }