ROSE  0.11.132.0
RegisterDictionary.h
1 #ifndef ROSE_BinaryAnalysis_RegisterDictionary_H
2 #define ROSE_BinaryAnalysis_RegisterDictionary_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/RegisterDescriptor.h>
7 #include <Rose/BinaryAnalysis/RegisterParts.h>
8 
9 #include <Sawyer/SharedPointer.h>
10 #include <Sawyer/SharedObject.h>
11 
12 #include <boost/serialization/access.hpp>
13 #include <boost/serialization/map.hpp>
14 #include <boost/serialization/string.hpp>
15 #include <map>
16 #include <ostream>
17 #include <queue>
18 #include <string>
19 #include <vector>
20 
21 namespace Rose {
22 namespace BinaryAnalysis {
23 
45 
47  // Types
49 public:
52 
54  using Entries = std::map<std::string/*name*/, RegisterDescriptor>;
55 
58 
59 private:
60  // a descriptor can have more than one name
61  using Reverse = std::map<RegisterDescriptor, std::vector<std::string>>;
62 
64  // Data members
66 private:
67  std::string name_; // name of the dictionary, usually an architecture name like 'i386'
68  Entries forward_; // N:1 forward lookup from name to descriptor
69  Reverse reverse_; // 1:N reverse lookup from descriptor to names
70 
72  // Serialization
74 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
75 private:
76  friend class boost::serialization::access;
77 
78  template<class S>
79  void serialize(S &s, const unsigned /*version*/) {
80  s & BOOST_SERIALIZATION_NVP(name_);
81  s & BOOST_SERIALIZATION_NVP(forward_);
82  s & BOOST_SERIALIZATION_NVP(reverse_);
83  }
84 #endif
85 
87  // Constructors and destructor
89 protected:
91 
92  RegisterDictionary(const std::string &name);
93 
95 
96 public:
98  static Ptr instance(const std::string &name);
99 
101  static Ptr instanceNull();
102 
112  static Ptr instanceI8086();
113 
117  static Ptr instanceI8088();
118 
122  static Ptr instanceI286();
123 
130  static Ptr instanceI386();
131 
133  static Ptr instanceI386Math();
134 
138  static Ptr instanceI486();
139 
143  static Ptr instancePentium();
144 
149  static Ptr instancePentiumiii();
150 
152  static Ptr instancePentium4();
153 
165  static Ptr instanceAmd64();
166 
167 #ifdef ROSE_ENABLE_ASM_AARCH64
168 
173  static Ptr instanceAarch64();
174 #endif
175 
176 #ifdef ROSE_ENABLE_ASM_AARCH32
177 
180  static Ptr instanceAarch32();
181 #endif
182 
184  static Ptr instancePowerpc32();
185 
187  static Ptr instancePowerpc64();
188 
192  static Ptr instanceMips32();
193 
201 
203  static Ptr instanceM68000();
204 
207 
209  static Ptr instanceColdfire();
210 
212  static Ptr instanceColdfireEmac();
213 
215  static Ptr instanceCil();
216 
218  static Ptr instanceJvm();
219 
230  // Properties
233 public:
234 
238  const std::string &name() const;
239  void name(const std::string&);
243  const Entries& registers() const;
244 
246  size_t size() const;
247 
249  // Mutators
251 public:
252 
257  void insert(const std::string &name, RegisterDescriptor);
258 
263  void insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits);
264 
269  void insert(const Ptr&);
270 
276  void resize(const std::string &name, unsigned new_nbits);
277 
279  // Lookup
281 public:
286  RegisterDescriptor find(const std::string &name) const;
287 
292  RegisterDescriptor findOrThrow(const std::string &name) const;
293 
298  const std::string& lookup(RegisterDescriptor) const;
299 
304  bool exists(RegisterDescriptor) const;
305 
313  RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const;
314 
316  // Register names
318 
322  Sawyer::Optional<std::string> name(RegisterDescriptor) const;
323 
328  std::string nameOrQuad(RegisterDescriptor) const;
329 
334  std::string nameAndQuad(RegisterDescriptor) const;
335 
340  std::string quadAndName(RegisterDescriptor) const;
341 
343  // Other queries
345 
354 
360 
362  unsigned firstUnusedMajor() const;
363 
365  unsigned firstUnusedMinor(unsigned majr) const;
366 
378  class SortBySize {
379  public:
380  enum Direction { ASCENDING, DESCENDING };
381  explicit SortBySize(Direction d=DESCENDING): direction(d) {}
382  bool operator()(RegisterDescriptor a, RegisterDescriptor b) const {
383  return ASCENDING==direction ?
384  a.nBits() < b.nBits() :
385  a.nBits() > b.nBits();
386  }
387  protected:
388  Direction direction;
389  };
390 
417  template<class Compare>
419  Compare order = SortBySize(),
420  bool reconsiderParts = true);
421 
437 
453 
455  // Debugging
457 
464  void print(std::ostream&) const;
465  friend std::ostream& operator<<(std::ostream&, const RegisterDictionary&);
467 };
468 
469 std::ostream&
470 operator<<(std::ostream&, const RegisterDictionary&);
471 
472 template<class Compare>
474 RegisterDictionary::filterNonoverlapping(RegisterDescriptors desc, Compare order, bool reconsiderParts) {
475  RegisterDescriptors retval;
476  Map<std::pair<int/*major*/, int/*minor*/>, ExtentMap> have_bits; // the union of the bits of descriptors we will return
477 
478  // Process the descriptors in the order specified.
479  std::priority_queue<RegisterDescriptor, RegisterDescriptors, Compare> heap(order, desc);
480  while (!heap.empty()) {
481  const RegisterDescriptor cur_desc = heap.top();
482  heap.pop();
483  const std::pair<int, int> cur_majmin(cur_desc.majorNumber(), cur_desc.minorNumber());
484  const Extent cur_extent(cur_desc.offset(), cur_desc.nBits());
485  ExtentMap &have_extents = have_bits[cur_majmin];
486  if (have_extents.distinct(cur_extent)) {
487  // We're not returning any of these bits yet, so add the whole descriptor
488  retval.push_back(cur_desc);
489  have_extents.insert(cur_extent);
490  } else if (reconsiderParts) {
491  // We're already returning some (or all) of these bits. Split the cur_extent into sub-parts by subtracting the
492  // stuff we're already returning.
493  ExtentMap parts;
494  parts.insert(cur_extent);
495  parts.erase_ranges(have_extents);
496  for (ExtentMap::iterator pi = parts.begin(); pi != parts.end(); ++pi) {
497  const Extent &part = pi->first;
498  RegisterDescriptor part_desc(cur_desc.majorNumber(), cur_desc.minorNumber(), part.first(), part.size());
499  heap.push(part_desc);
500  }
501  }
502  }
503  return retval;
504 }
505 
506 } // namespace
507 } // namespace
508 
509 #endif
510 #endif
static Ptr instance(const std::string &name)
Allocating constructor for an empty dictionary.
unsigned majorNumber() const
Property: Major number.
static Ptr instanceI486()
Intel 80486 registers.
const Entries & registers() const
Returns the list of all register definitions in the dictionary.
size_t nBits() const
Property: Size in bits.
Rose::BinaryAnalysis::RegisterParts getAllParts() const
Returns all register parts.
std::string nameOrQuad(RegisterDescriptor) const
Name or quad.
static Ptr instanceColdfire()
FreeScale ColdFire generic hardware registers.
const std::string & lookup(RegisterDescriptor) const
Returns a register name for a given descriptor.
A contiguous range of values.
Definition: rangemap.h:50
InsSetArchitecture
Instruction sets organized by families.
RegisterDescriptor findOrThrow(const std::string &name) const
Find a register by name.
std::string nameAndQuad(RegisterDescriptor) const
Name and quad.
Sawyer::SharedPointer< RegisterDictionary > RegisterDictionaryPtr
Reference counting pointer.
static Ptr instanceMips32AlternateNames()
MIPS32 Release 1 with special registers.
static Ptr instanceI386()
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.
Compares number of bits in register descriptors.
const std::string & name() const
Property: Architecture name.
iterator insert(Range new_range, Value new_value=Value(), bool make_hole=true)
Insert a range/value pair into the map.
Definition: rangemap.h:1188
Rose::BinaryAnalysis::RegisterDescriptors RegisterDescriptors
List of register descriptors in dictionary.
void insert(const std::string &name, RegisterDescriptor)
Insert a definition into the dictionary.
static Ptr instancePentium()
Intel Pentium registers.
static Ptr instanceI8088()
Intel 8088 registers.
std::vector< RegisterDescriptor > RegisterDescriptors
List of register descriptors in dictionary.
static Ptr instanceM68000()
Motorola M68330 register names.
void erase_ranges(const OtherMap &other)
Erase ranges from this map.
Definition: rangemap.h:1177
unsigned firstUnusedMajor() const
Returns the first unused major register number.
static Ptr instanceAmd64()
Amd64 registers.
Describes (part of) a physical CPU register.
RegisterDescriptor find(const std::string &name) const
Find a register by name.
static Ptr instancePentiumiii()
Intel Pentium III registers.
static Ptr instanceJvm()
JVM register names.
static Ptr instanceNull()
Mostly empty dictionary for the null ISA.
iterator begin()
First-item iterator.
Definition: rangemap.h:901
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
RegisterDescriptors getLargestRegisters() const
Returns a list of the largest non-overlapping registers.
static Ptr instancePowerpc32()
PowerPC-32 registers.
RegisterDescriptors getDescriptors() const
Returns the list of all register descriptors.
Extends std::map with methods that return optional values.
Definition: Map.h:10
static RegisterDescriptors filterNonoverlapping(RegisterDescriptors reglist, Compare order=SortBySize(), bool reconsiderParts=true)
Returns the list of non-overlapping registers or register parts.
unsigned firstUnusedMinor(unsigned majr) const
Returns the first unused minor register number.
static Ptr instanceI286()
Intel 80286 registers.
iterator end()
End-item iterator.
Definition: rangemap.h:913
static Ptr instanceMips32()
MIPS32 Release 1.
RegisterDescriptors getSmallestRegisters() const
Returns a list of the smallest non-overlapping registers.
bool exists(RegisterDescriptor) const
Determine if a register descriptor exists.
RegisterDictionaryPtr Ptr
Reference counting pointer.
std::map< std::string, RegisterDescriptor > Entries
List of registers in dictionary.
Base class for reference counted objects.
Definition: SharedObject.h:64
static Ptr instanceCil()
CIL register names.
static Ptr instanceM68000AlternateNames()
Motorola M68330 alternate registers.
static Ptr instanceI386Math()
Intel 80386 with 80387 math co-processor.
static Ptr instanceForIsa(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
Defines registers available for a particular architecture.
void resize(const std::string &name, unsigned new_nbits)
Changes the size of a register.
unsigned minorNumber() const
Property: Minor number.
static Ptr instancePentium4()
Intel Pentium 4 registers.
friend std::ostream & operator<<(std::ostream &, const RegisterDictionary &)
Prints the contents of this register dictionary.
Represents an interpretation of a binary container.
static Ptr instancePowerpc64()
PowerPC-64 registers.
static Ptr instanceColdfireEmac()
Registers for FreeScale ColdFire CPUs with EMAC (extended multiply-accumulate) unit.
std::string quadAndName(RegisterDescriptor) const
Quad and name.
static Ptr instanceI8086()
Intel 8086 registers.
RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const
Finds the first largest register with specified major and minor number.