ROSE  0.9.9.109
Registers.h
1 #ifndef ROSE_BINARY_REGISTERS_H
2 #define ROSE_BINARY_REGISTERS_H
3 
4 #include "RegisterParts.h"
5 
6 #include <boost/serialization/access.hpp>
7 #include <boost/serialization/map.hpp>
8 #include <boost/serialization/string.hpp>
9 
10 #include <queue>
11 
33 public:
34  typedef std::map<std::string/*name*/, RegisterDescriptor> Entries;
35  typedef std::vector<RegisterDescriptor> RegisterDescriptors;
36 
37 
47  static const RegisterDictionary *dictionary_i8086();
48 
52  static const RegisterDictionary *dictionary_i8088();
53 
57  static const RegisterDictionary *dictionary_i286();
58 
65  static const RegisterDictionary *dictionary_i386();
66 
69 
73  static const RegisterDictionary *dictionary_i486();
74 
78  static const RegisterDictionary *dictionary_pentium();
79 
85 
88 
100  static const RegisterDictionary *dictionary_amd64();
101 
113  static const RegisterDictionary *dictionary_arm7();
114 
116  static const RegisterDictionary *dictionary_powerpc();
117 
121  static const RegisterDictionary *dictionary_mips32();
122 
130 
132  static const RegisterDictionary *dictionary_m68000();
133 
136 
138  static const RegisterDictionary *dictionary_coldfire();
139 
142 
143 private:
144  typedef std::map<RegisterDescriptor, std::vector<std::string> > Reverse; // a descriptor can have more than one name
145  std::string name; /*name of the dictionary, usually an architecture name like 'i386'*/
146  Entries forward;
147  Reverse reverse;
148 
149 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
150 private:
151  friend class boost::serialization::access;
152 
153  template<class S>
154  void serialize(S &s, const unsigned version) {
155  s & BOOST_SERIALIZATION_NVP(name);
156  s & BOOST_SERIALIZATION_NVP(forward);
157  s & BOOST_SERIALIZATION_NVP(reverse);
158  }
159 #endif
160 
161 protected:
162  // needed for serialization
163  RegisterDictionary() {}
164 
165 public:
166  RegisterDictionary(const std::string &name)
167  :name(name) {}
168  RegisterDictionary(const RegisterDictionary& other) {
169  *this = other;
170  }
171 
180  const std::string &get_architecture_name() const {
181  return name;
182  }
183 
186  void set_architecture_name(const std::string &name) {
187  this->name = name;
188  }
189 
192  void insert(const std::string &name, RegisterDescriptor);
193 
196  void insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits);
197 
200  void insert(const RegisterDictionary*);
201 
204  void insert(const RegisterDictionary&);
205 
209  void resize(const std::string &name, unsigned new_nbits);
210 
214  const RegisterDescriptor *lookup(const std::string &name) const;
215 
219  const std::string& lookup(RegisterDescriptor) const;
220 
227 
235  RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const;
236 
245 
248  const Entries& get_registers() const;
249  Entries& get_registers();
254  RegisterDescriptors get_descriptors() const;
255 
257  unsigned firstUnusedMajor() const;
258 
260  unsigned firstUnusedMinor(unsigned majr) const;
261 
273  class SortBySize {
274  public:
275  enum Direction { ASCENDING, DESCENDING };
276  explicit SortBySize(Direction d=DESCENDING): direction(d) {}
277  bool operator()(RegisterDescriptor a, RegisterDescriptor b) const {
278  return ASCENDING==direction ?
279  a.get_nbits() < b.get_nbits() :
280  a.get_nbits() > b.get_nbits();
281  }
282  protected:
283  Direction direction;
284  };
285 
311  template<class Compare>
312  static RegisterDescriptors filter_nonoverlapping(RegisterDescriptors reglist,
313  Compare order=SortBySize(),
314  bool reconsider_parts=true);
315 
328  RegisterDescriptors get_largest_registers() const;
329 
341  RegisterDescriptors get_smallest_registers() const;
342 
345  void print(std::ostream&) const;
346  friend std::ostream& operator<<(std::ostream&, const RegisterDictionary&);
347 
349  size_t size() const { return forward.size(); }
350 };
351 
355 public:
357  explicit RegisterNames(const RegisterDictionary *dict=NULL)
358  : dflt_dict(dict), prefix("REG"), show_offset(-1), offset_prefix("@"), show_size(-1), size_prefix("+") {}
359 
362  std::string operator()(RegisterDescriptor, const RegisterDictionary *dict=NULL) const;
363 
365  std::string prefix;
366  std::string suffix;
368  std::string offset_prefix;
369  std::string offset_suffix;
370  int show_size;
371  std::string size_prefix;
372  std::string size_suffix;
373 };
374 
375 /*******************************************************************************************************************************
376  * Template definitions
377  *******************************************************************************************************************************/
378 
379 
380 
381 template<class Compare>
382 RegisterDictionary::RegisterDescriptors
383 RegisterDictionary::filter_nonoverlapping(RegisterDescriptors desc, Compare order, bool reconsider_parts)
384 {
385  RegisterDescriptors retval;
386  Map<std::pair<int/*major*/, int/*minor*/>, ExtentMap> have_bits; // the union of the bits of descriptors we will return
387 
388  // Process the descriptors in the order specified.
389  std::priority_queue<RegisterDescriptor, RegisterDescriptors, Compare> heap(order, desc);
390  while (!heap.empty()) {
391  const RegisterDescriptor cur_desc = heap.top();
392  heap.pop();
393  const std::pair<int, int> cur_majmin(cur_desc.get_major(), cur_desc.get_minor());
394  const Extent cur_extent(cur_desc.get_offset(), cur_desc.get_nbits());
395  ExtentMap &have_extents = have_bits[cur_majmin];
396  if (have_extents.distinct(cur_extent)) {
397  // We're not returning any of these bits yet, so add the whole descriptor
398  retval.push_back(cur_desc);
399  have_extents.insert(cur_extent);
400  } else if (reconsider_parts) {
401  // We're already returning some (or all) of these bits. Split the cur_extent into sub-parts by subtracting the
402  // stuff we're already returning.
403  ExtentMap parts;
404  parts.insert(cur_extent);
405  parts.erase_ranges(have_extents);
406  for (ExtentMap::iterator pi=parts.begin(); pi!=parts.end(); ++pi) {
407  const Extent &part = pi->first;
408  RegisterDescriptor part_desc(cur_desc.get_major(), cur_desc.get_minor(), part.first(), part.size());
409  heap.push(part_desc);
410  }
411  }
412  }
413  return retval;
414 }
415 
416 #endif
void set_architecture_name(const std::string &name)
Set the name of the dictionary.
Definition: Registers.h:186
static const RegisterDictionary * dictionary_i8088()
Intel 8088 registers.
size_t size() const
Return the number of entries in the dictionary.
Definition: Registers.h:349
static const RegisterDictionary * dictionary_i8086()
Intel 8086 registers.
RegisterDescriptors get_smallest_registers() const
Returns a list of the smallest non-overlapping registers.
RegisterNames(const RegisterDictionary *dict=NULL)
Constructor.
Definition: Registers.h:357
static const RegisterDictionary * dictionary_arm7()
ARM7 registers.
std::string operator()(RegisterDescriptor, const RegisterDictionary *dict=NULL) const
Obtain a name for a register descriptor.
static const RegisterDictionary * dictionary_i386_387()
Intel 80386 with 80387 math co-processor.
static const RegisterDictionary * dictionary_coldfire_emac()
Registers for FreeScale ColdFire CPUs with EMAC (extended multiply-accumulate) unit.
static const RegisterDictionary * dictionary_m68000()
Motorola M68330 register names.
const std::string & get_architecture_name() const
Obtain the name of the dictionary.
Definition: Registers.h:180
static const RegisterDictionary * dictionary_pentiumiii()
Intel Pentium III registers.
const Entries & get_registers() const
Returns the list of all register definitions in the dictionary.
static const RegisterDictionary * dictionary_amd64()
Amd64 registers.
A contiguous range of values.
Definition: rangemap.h:50
InsSetArchitecture
Instruction sets organized by families.
unsigned firstUnusedMajor() const
Returns the first unused major register number.
void resize(const std::string &name, unsigned new_nbits)
Changes the size of a register.
int show_offset
0=>never show offset; positive=>always show; negative=>show only when non-zero
Definition: Registers.h:367
std::string prefix
The leading part of a register name.
Definition: Registers.h:365
Describes (part of) a physical CPU register.
Holds a set of registers without regard for register boundaries.
Definition: RegisterParts.h:25
const RegisterDescriptor * exists(RegisterDescriptor) const
Determine if a register descriptor exists.
static const RegisterDictionary * dictionary_coldfire()
FreeScale ColdFire generic hardware registers.
RegisterDescriptors get_descriptors() const
Returns the list of all register descriptors.
iterator insert(Range new_range, Value new_value=Value(), bool make_hole=true)
Insert a range/value pair into the map.
Definition: rangemap.h:1193
static const RegisterDictionary * dictionary_i486()
Intel 80486 registers.
void erase_ranges(const OtherMap &other)
Erase ranges from this map.
Definition: rangemap.h:1182
RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const
Finds the first largest register with specified major and minor number.
const RegisterDictionary * dflt_dict
Dictionary supplied to the constructor.
Definition: Registers.h:364
Compares number of bits in register descriptors.
Definition: Registers.h:273
static const RegisterDictionary * dictionary_m68000_altnames()
Motorola M68330 alternate registers.
void insert(const std::string &name, RegisterDescriptor)
Insert a definition into the dictionary.
iterator begin()
First-item iterator.
Definition: rangemap.h:906
static const RegisterDictionary * dictionary_powerpc()
PowerPC registers.
Value size() const
Returns the number of values represented by the range.
Definition: rangemap.h:147
Extends std::map with methods that return optional values.
Definition: Map.h:10
Defines registers available for a particular architecture.
Definition: Registers.h:32
Prints a register name even when no dictionary is available or when the dictionary doesn't contain an...
Definition: Registers.h:354
static const RegisterDictionary * dictionary_mips32()
MIPS32 Release 1.
static const RegisterDictionary * dictionary_mips32_altnames()
MIPS32 Release 1 with special registers.
static const RegisterDictionary * dictionary_i286()
Intel 80286 registers.
iterator end()
End-item iterator.
Definition: rangemap.h:918
static RegisterDescriptors filter_nonoverlapping(RegisterDescriptors reglist, Compare order=SortBySize(), bool reconsider_parts=true)
Returns the list of non-overlapping registers or register parts.
Definition: Registers.h:383
static const RegisterDictionary * dictionary_pentium4()
Intel Pentium 4 registers.
std::string offset_prefix
String printed before the offset when the offset is shown.
Definition: Registers.h:368
void print(std::ostream &) const
Prints the contents of this register dictionary.
std::string offset_suffix
String printed after the offset when the offset is shown.
Definition: Registers.h:369
static const RegisterDictionary * dictionary_pentium()
Intel Pentium registers.
std::string size_prefix
String printed prior to the size when the size is printed.
Definition: Registers.h:371
RegisterDescriptors get_largest_registers() const
Returns a list of the largest non-overlapping registers.
static const RegisterDictionary * dictionary_for_isa(SgAsmExecutableFileFormat::InsSetArchitecture)
Class method to choose an appropriate register dictionary for an instruction set architecture.
void first(const Value &first)
Accessor for the first value of a range.
Definition: rangemap.h:103
std::string suffix
String to print at the very end of the generated name.
Definition: Registers.h:366
Represents an interpretation of a binary container.
int show_size
0=>never; positive=>always; negative=>when offset is non-zero
Definition: Registers.h:370
const RegisterDescriptor * lookup(const std::string &name) const
Returns a descriptor for a given register name.
std::string size_suffix
String printed after the size when the size is printed.
Definition: Registers.h:372
unsigned firstUnusedMinor(unsigned majr) const
Returns the first unused minor register number.
static const RegisterDictionary * dictionary_i386()
Intel 80386 registers.
Rose::BinaryAnalysis::RegisterParts getAllParts() const
Returns all register parts.