ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Registers.h
Go to the documentation of this file.
1 #ifndef ROSE_BINARY_REGISTERS_H
2 #define ROSE_BINARY_REGISTERS_H
3 
4 #include <map>
5 #include <queue>
6 #include <string>
7 
27 public:
28  typedef std::map<std::string/*name*/, RegisterDescriptor> Entries;
29  typedef std::vector<RegisterDescriptor> RegisterDescriptors;
30 
31  /* Functions that return a dictionary for a particular machine architecute. (See implementation for documentation.) */
32  static const RegisterDictionary *dictionary_i8086();
33  static const RegisterDictionary *dictionary_i8088();
34  static const RegisterDictionary *dictionary_i286();
35  static const RegisterDictionary *dictionary_i386();
37  static const RegisterDictionary *dictionary_i486();
38  static const RegisterDictionary *dictionary_pentium();
40  static const RegisterDictionary *dictionary_amd64();
41  static const RegisterDictionary *dictionary_arm7();
42  static const RegisterDictionary *dictionary_powerpc();
43  static const RegisterDictionary *dictionary_mips32();
45 
46  RegisterDictionary(const std::string &name)
47  :name(name) {}
49  *this = other;
50  }
51 
60  const std::string &get_architecture_name() const {
61  return name;
62  }
63 
66  void set_architecture_name(const std::string &name) {
67  this->name = name;
68  }
69 
72  void insert(const std::string &name, const RegisterDescriptor&);
73 
76  void insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits);
77 
80  void insert(const RegisterDictionary*);
81 
84  void insert(const RegisterDictionary&);
85 
89  void resize(const std::string &name, unsigned new_nbits);
90 
94  const RegisterDescriptor *lookup(const std::string &name) const;
95 
99  const std::string& lookup(const RegisterDescriptor&) const;
100 
103  const Entries& get_registers() const;
110 
122  class SortBySize {
123  public:
126  bool operator()(const RegisterDescriptor &a, const RegisterDescriptor &b) const {
127  return ASCENDING==direction ?
128  a.get_nbits() < b.get_nbits() :
129  a.get_nbits() > b.get_nbits();
130  }
131  protected:
133  };
134 
160  template<class Compare>
162  Compare order=SortBySize(),
163  bool reconsider_parts=true);
164 
178 
191 
194  void print(std::ostream&) const;
195  friend std::ostream& operator<<(std::ostream&, const RegisterDictionary&);
196 
198  size_t size() const { return forward.size(); }
199 
200 private:
201  typedef std::map<uint64_t/*desc_hash*/, std::vector<std::string> > Reverse;
202  static uint64_t hash(const RegisterDescriptor&);
203  std::string name; /*name of the dictionary, usually an architecture name like 'i386'*/
206 };
207 
211 public:
213  explicit RegisterNames(const RegisterDictionary *dict=NULL)
214  : dflt_dict(dict), prefix("REG"), show_offset(-1), offset_prefix("@"), show_size(false) {}
215 
218  std::string operator()(const RegisterDescriptor&, const RegisterDictionary *dict=NULL) const;
219 
221  std::string prefix;
222  std::string suffix;
224  std::string offset_prefix;
225  std::string offset_suffix;
226  bool show_size;
227  std::string size_prefix;
228  std::string size_suffix;
229 };
230 
231 /*******************************************************************************************************************************
232  * Template definitions
233  *******************************************************************************************************************************/
234 
235 
236 
237 template<class Compare>
239 RegisterDictionary::filter_nonoverlapping(RegisterDescriptors desc, Compare order, bool reconsider_parts)
240 {
241  RegisterDescriptors retval;
242  Map<std::pair<int/*major*/, int/*minor*/>, ExtentMap> have_bits; // the union of the bits of descriptors we will return
243 
244  // Process the descriptors in the order specified.
245  std::priority_queue<RegisterDescriptor, RegisterDescriptors, Compare> heap(order, desc);
246  while (!heap.empty()) {
247  const RegisterDescriptor cur_desc = heap.top();
248  heap.pop();
249  const std::pair<int, int> cur_majmin(cur_desc.get_major(), cur_desc.get_minor());
250  const Extent cur_extent(cur_desc.get_offset(), cur_desc.get_nbits());
251  ExtentMap &have_extents = have_bits[cur_majmin];
252  if (have_extents.distinct(cur_extent)) {
253  // We're not returning any of these bits yet, so add the whole descriptor
254  retval.push_back(cur_desc);
255  have_extents.insert(cur_extent);
256  } else if (reconsider_parts) {
257  // We're already returning some (or all) of these bits. Split the cur_extent into sub-parts by subtracting the
258  // stuff we're already returning.
259  ExtentMap parts;
260  parts.insert(cur_extent);
261  parts.erase_ranges(have_extents);
262  for (ExtentMap::iterator pi=parts.begin(); pi!=parts.end(); ++pi) {
263  const Extent &part = pi->first;
264  RegisterDescriptor part_desc(cur_desc.get_major(), cur_desc.get_minor(), part.first(), part.size());
265  heap.push(part_desc);
266  }
267  }
268  }
269  return retval;
270 }
271 
272 #endif