ROSE  0.11.28.0
Registers.h
1 #ifndef ROSE_BinaryAnalysis_Registers_H
2 #define ROSE_BinaryAnalysis_Registers_H
3 
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 
7 #include "RegisterParts.h"
8 
9 #include <boost/serialization/access.hpp>
10 #include <boost/serialization/map.hpp>
11 #include <boost/serialization/string.hpp>
12 
13 #include <queue>
14 
15 namespace Rose {
16 namespace BinaryAnalysis {
17 
39 public:
40  typedef std::map<std::string/*name*/, RegisterDescriptor> Entries;
41  typedef std::vector<RegisterDescriptor> RegisterDescriptors;
42 
44  static const RegisterDictionary *dictionary_null();
45 
55  static const RegisterDictionary *dictionary_i8086();
56 
60  static const RegisterDictionary *dictionary_i8088();
61 
65  static const RegisterDictionary *dictionary_i286();
66 
73  static const RegisterDictionary *dictionary_i386();
74 
77 
81  static const RegisterDictionary *dictionary_i486();
82 
86  static const RegisterDictionary *dictionary_pentium();
87 
93 
96 
108  static const RegisterDictionary *dictionary_amd64();
109 
110 #ifdef ROSE_ENABLE_ASM_AARCH64
111 
116  static const RegisterDictionary* dictionary_aarch64();
117 #endif
118 
119 #ifdef ROSE_ENABLE_ASM_AARCH32
120 
123  static const RegisterDictionary* dictionary_aarch32();
124 #endif
125 
128 
131 
135  static const RegisterDictionary *dictionary_mips32();
136 
144 
146  static const RegisterDictionary *dictionary_m68000();
147 
150 
152  static const RegisterDictionary *dictionary_coldfire();
153 
156 
157 private:
158  typedef std::map<RegisterDescriptor, std::vector<std::string> > Reverse; // a descriptor can have more than one name
159  std::string name; /*name of the dictionary, usually an architecture name like 'i386'*/
160  Entries forward;
161  Reverse reverse;
162 
163 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
164 private:
165  friend class boost::serialization::access;
166 
167  template<class S>
168  void serialize(S &s, const unsigned /*version*/) {
169  s & BOOST_SERIALIZATION_NVP(name);
170  s & BOOST_SERIALIZATION_NVP(forward);
171  s & BOOST_SERIALIZATION_NVP(reverse);
172  }
173 #endif
174 
175 protected:
176  // needed for serialization
177  RegisterDictionary() {}
178 
179 public:
180  RegisterDictionary(const std::string &name)
181  :name(name) {}
182  RegisterDictionary(const RegisterDictionary& other) {
183  *this = other;
184  }
185 
194  const std::string &get_architecture_name() const {
195  return name;
196  }
197 
200  void set_architecture_name(const std::string &name) {
201  this->name = name;
202  }
203 
206  void insert(const std::string &name, RegisterDescriptor);
207 
210  void insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits);
211 
214  void insert(const RegisterDictionary*);
215 
218  void insert(const RegisterDictionary&);
219 
223  void resize(const std::string &name, unsigned new_nbits);
224 
229  RegisterDescriptor find(const std::string &name) const;
230 
235  RegisterDescriptor findOrThrow(const std::string &name) const;
236 
237  // Deprecated 2020-04-17 because it returns a raw pointer and leaves it up to the caller to check it.
238  /* Returns a descriptor for a given register name. Returns the null pointer if the name is not found. It is not possible
239  * to modify a descriptor in the dictionary because doing so would interfere with the dictionary's data structures for
240  * reverse lookups. */
241  const RegisterDescriptor *lookup(const std::string &name) const ROSE_DEPRECATED("use find or findOrThrow");
242 
246  const std::string& lookup(RegisterDescriptor) const;
247 
254 
262  RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const;
263 
272 
275  const Entries& get_registers() const;
276  Entries& get_registers();
281  RegisterDescriptors get_descriptors() const;
282 
284  unsigned firstUnusedMajor() const;
285 
287  unsigned firstUnusedMinor(unsigned majr) const;
288 
300  class SortBySize {
301  public:
302  enum Direction { ASCENDING, DESCENDING };
303  explicit SortBySize(Direction d=DESCENDING): direction(d) {}
304  bool operator()(RegisterDescriptor a, RegisterDescriptor b) const {
305  return ASCENDING==direction ?
306  a.nBits() < b.nBits() :
307  a.nBits() > b.nBits();
308  }
309  protected:
310  Direction direction;
311  };
312 
338  template<class Compare>
339  static RegisterDescriptors filter_nonoverlapping(RegisterDescriptors reglist,
340  Compare order=SortBySize(),
341  bool reconsider_parts=true);
342 
355  RegisterDescriptors get_largest_registers() const;
356 
368  RegisterDescriptors get_smallest_registers() const;
369 
372  void print(std::ostream&) const;
373  friend std::ostream& operator<<(std::ostream&, const RegisterDictionary&);
374 
376  size_t size() const { return forward.size(); }
377 };
378 
382 public:
384  explicit RegisterNames(const RegisterDictionary *dict=NULL)
385  : dflt_dict(dict), prefix("REG"), show_offset(-1), offset_prefix("@"), show_size(-1), size_prefix("+") {}
386 
389  std::string operator()(RegisterDescriptor, const RegisterDictionary *dict=NULL) const;
390 
392  std::string prefix;
393  std::string suffix;
395  std::string offset_prefix;
396  std::string offset_suffix;
397  int show_size;
398  std::string size_prefix;
399  std::string size_suffix;
400 };
401 
402 /*******************************************************************************************************************************
403  * Template definitions
404  *******************************************************************************************************************************/
405 
406 
407 
408 template<class Compare>
409 RegisterDictionary::RegisterDescriptors
410 RegisterDictionary::filter_nonoverlapping(RegisterDescriptors desc, Compare order, bool reconsider_parts)
411 {
412  RegisterDescriptors retval;
413  Map<std::pair<int/*major*/, int/*minor*/>, ExtentMap> have_bits; // the union of the bits of descriptors we will return
414 
415  // Process the descriptors in the order specified.
416  std::priority_queue<RegisterDescriptor, RegisterDescriptors, Compare> heap(order, desc);
417  while (!heap.empty()) {
418  const RegisterDescriptor cur_desc = heap.top();
419  heap.pop();
420  const std::pair<int, int> cur_majmin(cur_desc.majorNumber(), cur_desc.minorNumber());
421  const Extent cur_extent(cur_desc.offset(), cur_desc.nBits());
422  ExtentMap &have_extents = have_bits[cur_majmin];
423  if (have_extents.distinct(cur_extent)) {
424  // We're not returning any of these bits yet, so add the whole descriptor
425  retval.push_back(cur_desc);
426  have_extents.insert(cur_extent);
427  } else if (reconsider_parts) {
428  // We're already returning some (or all) of these bits. Split the cur_extent into sub-parts by subtracting the
429  // stuff we're already returning.
430  ExtentMap parts;
431  parts.insert(cur_extent);
432  parts.erase_ranges(have_extents);
433  for (ExtentMap::iterator pi=parts.begin(); pi!=parts.end(); ++pi) {
434  const Extent &part = pi->first;
435  RegisterDescriptor part_desc(cur_desc.majorNumber(), cur_desc.minorNumber(), part.first(), part.size());
436  heap.push(part_desc);
437  }
438  }
439  }
440  return retval;
441 }
442 
443 } // namespace
444 } // namespace
445 
446 #endif
447 #endif
int show_size
0=>never; positive=>always; negative=>when offset is non-zero
Definition: Registers.h:397
const RegisterDescriptor * exists(RegisterDescriptor) const
Determine if a register descriptor exists.
static const RegisterDictionary * dictionary_i8088()
Intel 8088 registers.
static const RegisterDictionary * dictionary_pentium()
Intel Pentium registers.
unsigned majorNumber() const
Property: Major number.
static const RegisterDictionary * dictionary_coldfire_emac()
Registers for FreeScale ColdFire CPUs with EMAC (extended multiply-accumulate) unit.
size_t nBits() const
Property: Size in bits.
RegisterDescriptors get_largest_registers() const
Returns a list of the largest non-overlapping registers.
RegisterDescriptors get_descriptors() const
Returns the list of all register descriptors.
std::string offset_prefix
String printed before the offset when the offset is shown.
Definition: Registers.h:395
Rose::BinaryAnalysis::RegisterParts getAllParts() const
Returns all register parts.
static const RegisterDictionary * dictionary_i386_387()
Intel 80386 with 80387 math co-processor.
static const RegisterDictionary * dictionary_powerpc32()
PowerPC-32 registers.
const Entries & get_registers() const
Returns the list of all register definitions in the dictionary.
A contiguous range of values.
Definition: rangemap.h:50
std::string offset_suffix
String printed after the offset when the offset is shown.
Definition: Registers.h:396
InsSetArchitecture
Instruction sets organized by families.
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:410
RegisterDescriptor findOrThrow(const std::string &name) const
Find a register by name.
static const RegisterDictionary * dictionary_m68000()
Motorola M68330 register names.
static const RegisterDictionary * dictionary_pentium4()
Intel Pentium 4 registers.
static const RegisterDictionary * dictionary_i386()
Intel 80386 registers.
Main namespace for the ROSE library.
Holds a set of registers without regard for register boundaries.
Definition: RegisterParts.h:28
void print(std::ostream &) const
Prints the contents of this register dictionary.
size_t size() const
Return the number of entries in the dictionary.
Definition: Registers.h:376
Compares number of bits in register descriptors.
Definition: Registers.h:300
RegisterNames(const RegisterDictionary *dict=NULL)
Constructor.
Definition: Registers.h:384
static const RegisterDictionary * dictionary_m68000_altnames()
Motorola M68330 alternate registers.
int show_offset
0=>never show offset; positive=>always show; negative=>show only when non-zero
Definition: Registers.h:394
iterator insert(Range new_range, Value new_value=Value(), bool make_hole=true)
Insert a range/value pair into the map.
Definition: rangemap.h:1192
std::string size_prefix
String printed prior to the size when the size is printed.
Definition: Registers.h:398
static const RegisterDictionary * dictionary_coldfire()
FreeScale ColdFire generic hardware registers.
const std::string & get_architecture_name() const
Obtain the name of the dictionary.
Definition: Registers.h:194
void insert(const std::string &name, RegisterDescriptor)
Insert a definition into the dictionary.
std::string operator()(RegisterDescriptor, const RegisterDictionary *dict=NULL) const
Obtain a name for a register descriptor.
void erase_ranges(const OtherMap &other)
Erase ranges from this map.
Definition: rangemap.h:1181
unsigned firstUnusedMajor() const
Returns the first unused major register number.
std::string suffix
String to print at the very end of the generated name.
Definition: Registers.h:393
Describes (part of) a physical CPU register.
static const RegisterDictionary * dictionary_for_isa(SgAsmExecutableFileFormat::InsSetArchitecture)
Class method to choose an appropriate register dictionary for an instruction set architecture.
std::string size_suffix
String printed after the size when the size is printed.
Definition: Registers.h:399
RegisterDescriptors get_smallest_registers() const
Returns a list of the smallest non-overlapping registers.
RegisterDescriptor find(const std::string &name) const
Find a register by name.
static const RegisterDictionary * dictionary_i486()
Intel 80486 registers.
Prints a register name even when no dictionary is available or when the dictionary doesn't contain an...
Definition: Registers.h:381
iterator begin()
First-item iterator.
Definition: rangemap.h:905
void set_architecture_name(const std::string &name)
Set the name of the dictionary.
Definition: Registers.h:200
size_t offset() const
Property: Offset to least-significant bit.
Value size() const
Returns the number of values represented by the range.
Definition: rangemap.h:147
std::string prefix
The leading part of a register name.
Definition: Registers.h:392
Extends std::map with methods that return optional values.
Definition: Map.h:10
const RegisterDictionary * dflt_dict
Dictionary supplied to the constructor.
Definition: Registers.h:391
unsigned firstUnusedMinor(unsigned majr) const
Returns the first unused minor register number.
static const RegisterDictionary * dictionary_null()
Mostly empty dictionary for the null ISA.
iterator end()
End-item iterator.
Definition: rangemap.h:917
static const RegisterDictionary * dictionary_powerpc64()
PowerPC-64 registers.
static const RegisterDictionary * dictionary_i8086()
Intel 8086 registers.
static const RegisterDictionary * dictionary_amd64()
Amd64 registers.
static const RegisterDictionary * dictionary_pentiumiii()
Intel Pentium III registers.
void first(const Value &first)
Accessor for the first value of a range.
Definition: rangemap.h:103
Defines registers available for a particular architecture.
Definition: Registers.h:38
static const RegisterDictionary * dictionary_mips32()
MIPS32 Release 1.
void resize(const std::string &name, unsigned new_nbits)
Changes the size of a register.
static const RegisterDictionary * dictionary_i286()
Intel 80286 registers.
unsigned minorNumber() const
Property: Minor number.
Represents an interpretation of a binary container.
static const RegisterDictionary * dictionary_mips32_altnames()
MIPS32 Release 1 with special registers.
RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const
Finds the first largest register with specified major and minor number.