ROSE 0.11.145.272
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#include <rose_extent.h>
9#include <Map.h> // rose
10
11#include <Sawyer/SharedPointer.h>
12#include <Sawyer/SharedObject.h>
13
14#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
15#include <boost/serialization/access.hpp>
16#include <boost/serialization/map.hpp>
17#include <boost/serialization/string.hpp>
18#endif
19
20#include <map>
21#include <ostream>
22#include <queue>
23#include <string>
24#include <vector>
25
26namespace Rose {
27namespace BinaryAnalysis {
28
50
52 // Types
54public:
57
59 using Entries = std::map<std::string/*name*/, RegisterDescriptor>;
60
63
64private:
65 // a descriptor can have more than one name
66 using Reverse = std::map<RegisterDescriptor, std::vector<std::string>>;
67
69 // Data members
71private:
72 std::string name_; // name of the dictionary, usually an architecture name like 'i386'
73 Entries forward_; // N:1 forward lookup from name to descriptor
74 Reverse reverse_; // 1:N reverse lookup from descriptor to names
75 RegisterDescriptor instructionPointer_; // optional special instruction pointer register
76 RegisterDescriptor stackPointer_; // optional special stack pointer register
77 RegisterDescriptor stackFrame_; // optional special stack frame pointer register
78 RegisterDescriptor stackSegment_; // optional special stack segment register
79 RegisterDescriptor callReturn_; // optional special call return address register
80
82 // Serialization
84#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
85private:
86 friend class boost::serialization::access;
87
88 template<class S>
89 void serialize(S &s, const unsigned /*version*/) {
90 s & BOOST_SERIALIZATION_NVP(name_);
91 s & BOOST_SERIALIZATION_NVP(forward_);
92 s & BOOST_SERIALIZATION_NVP(reverse_);
93 }
94#endif
95
97 // Constructors and destructor
99protected:
101
102 RegisterDictionary(const std::string &name);
103
105 RegisterDictionary& operator=(const RegisterDictionary&) = default;
106
107public:
109 static Ptr instance(const std::string &name);
110
113
115 // Properties
117public:
118
122 const std::string &name() const;
123 void name(const std::string&);
127 const Entries& registers() const;
128
130 size_t size() const;
131
133 // Mutators
135public:
136
141 void insert(const std::string &name, RegisterDescriptor);
142
147 void insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits);
148
153 void insert(const Ptr&);
154
160 void resize(const std::string &name, unsigned new_nbits);
161
163 // Lookup
165public:
170 RegisterDescriptor find(const std::string &name) const;
171
176 RegisterDescriptor findOrThrow(const std::string &name) const;
177
182 const std::string& lookup(RegisterDescriptor) const;
183
189
197 RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const;
198
200 // Register names
202
207
212 std::string nameOrQuad(RegisterDescriptor) const;
213
218 std::string nameAndQuad(RegisterDescriptor) const;
219
224 std::string quadAndName(RegisterDescriptor) const;
225
227 // Special registers
229public:
237 void instructionPointerRegister(const std::string&);
247 void stackPointerRegister(const std::string&);
257 void stackFrameRegister(const std::string&);
267 void stackSegmentRegister(const std::string&);
277 void callReturnRegister(const std::string&);
281 // Other queries
283
292
298
300 unsigned firstUnusedMajor() const;
301
303 unsigned firstUnusedMinor(unsigned majr) const;
304
317 public:
318 enum Direction { ASCENDING, DESCENDING };
319 explicit SortBySize(Direction d=DESCENDING): direction(d) {}
320 bool operator()(RegisterDescriptor a, RegisterDescriptor b) const {
321 return ASCENDING==direction ?
322 a.nBits() < b.nBits() :
323 a.nBits() > b.nBits();
324 }
325 protected:
326 Direction direction;
327 };
328
355 template<class Compare>
357 Compare order = SortBySize(),
358 bool reconsiderParts = true);
359
375
391
393 // Debugging
395
402 void print(std::ostream&) const;
403 friend std::ostream& operator<<(std::ostream&, const RegisterDictionary&);
405};
406
407std::ostream&
408operator<<(std::ostream&, const RegisterDictionary&);
409
410template<class Compare>
412RegisterDictionary::filterNonoverlapping(RegisterDescriptors desc, Compare order, bool reconsiderParts) {
413 RegisterDescriptors retval;
414 Map<std::pair<int/*major*/, int/*minor*/>, ExtentMap> have_bits; // the union of the bits of descriptors we will return
415
416 // Process the descriptors in the order specified.
417 std::priority_queue<RegisterDescriptor, RegisterDescriptors, Compare> heap(order, desc);
418 while (!heap.empty()) {
419 const RegisterDescriptor cur_desc = heap.top();
420 heap.pop();
421 const std::pair<int, int> cur_majmin(cur_desc.majorNumber(), cur_desc.minorNumber());
422 const Extent cur_extent(cur_desc.offset(), cur_desc.nBits());
423 ExtentMap &have_extents = have_bits[cur_majmin];
424 if (have_extents.distinct(cur_extent)) {
425 // We're not returning any of these bits yet, so add the whole descriptor
426 retval.push_back(cur_desc);
427 have_extents.insert(cur_extent);
428 } else if (reconsiderParts) {
429 // We're already returning some (or all) of these bits. Split the cur_extent into sub-parts by subtracting the
430 // stuff we're already returning.
431 ExtentMap parts;
432 parts.insert(cur_extent);
433 parts.erase_ranges(have_extents);
434 for (ExtentMap::iterator pi = parts.begin(); pi != parts.end(); ++pi) {
435 const Extent &part = pi->first;
436 RegisterDescriptor part_desc(cur_desc.majorNumber(), cur_desc.minorNumber(), part.first(), part.size());
437 heap.push(part_desc);
438 }
439 }
440 }
441 return retval;
442}
443
444} // namespace
445} // namespace
446
447#endif
448#endif
Extends std::map with methods that return optional values.
Definition util/Map.h:16
bool distinct(const Range &r) const
Determines if a range map does not contain any part of the specified range.
Definition rangemap.h:1253
iterator begin()
First-item iterator.
Definition rangemap.h:901
void erase_ranges(const OtherMap &other)
Erase ranges from this map.
Definition rangemap.h:1177
iterator end()
End-item iterator.
Definition rangemap.h:913
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
A contiguous range of values.
Definition rangemap.h:50
void first(const Value &first)
Accessor for the first value of a range.
Definition rangemap.h:103
Value size() const
Returns the number of values represented by the range.
Definition rangemap.h:147
Describes (part of) a physical CPU register.
size_t offset() const
Property: Offset to least-significant bit.
unsigned minorNumber() const
Property: Minor number.
unsigned majorNumber() const
Property: Major number.
size_t nBits() const
Property: Size in bits.
Compares number of bits in register descriptors.
Defines registers available for a particular architecture.
RegisterDescriptor stackFrameRegister() const
Property: The register that ponts to the stack frame.
RegisterDescriptors getSmallestRegisters() const
Returns a list of the smallest non-overlapping registers.
void name(const std::string &)
Property: Architecture name.
void stackPointerRegister(RegisterDescriptor)
Property: The register that points to the stack.
Rose::BinaryAnalysis::RegisterParts getAllParts() const
Returns all register parts.
void stackFrameRegister(RegisterDescriptor)
Property: The register that ponts to the stack frame.
void stackSegmentRegister(RegisterDescriptor)
Property: The segment register for accessing the stack.
const std::string & name() const
Property: Architecture name.
static Ptr instance(const std::string &name)
Allocating constructor for an empty dictionary.
void insert(const std::string &name, RegisterDescriptor)
Insert a definition into the dictionary.
bool exists(RegisterDescriptor) const
Determine if a register descriptor exists.
void instructionPointerRegister(RegisterDescriptor)
Property: The register that points to instructions.
static Ptr instanceNull()
Mostly empty dictionary for the null ISA.
RegisterDescriptor findOrThrow(const std::string &name) const
Find a register by name.
void stackSegmentRegister(const std::string &)
Property: The segment register for accessing the stack.
Rose::BinaryAnalysis::RegisterDescriptors RegisterDescriptors
List of register descriptors in dictionary.
std::string quadAndName(RegisterDescriptor) const
Quad and name.
void callReturnRegister(const std::string &)
Property: The register that holds the return address for a function.
unsigned firstUnusedMajor() const
Returns the first unused major register number.
Sawyer::Optional< std::string > name(RegisterDescriptor) const
Name of the register or nothing.
RegisterDescriptors getDescriptors() const
Returns the list of all register descriptors.
void stackFrameRegister(const std::string &)
Property: The register that ponts to the stack frame.
std::string nameAndQuad(RegisterDescriptor) const
Name and quad.
void instructionPointerRegister(const std::string &)
Property: The register that points to instructions.
void callReturnRegister(RegisterDescriptor)
Property: The register that holds the return address for a function.
void print(std::ostream &) const
Prints the contents of this register dictionary.
const std::string & lookup(RegisterDescriptor) const
Returns a register name for a given descriptor.
void insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits)
Insert a definition into the dictionary.
std::map< std::string, RegisterDescriptor > Entries
List of registers in dictionary.
RegisterDescriptor instructionPointerRegister() const
Property: The register that points to instructions.
static RegisterDescriptors filterNonoverlapping(RegisterDescriptors reglist, Compare order=SortBySize(), bool reconsiderParts=true)
Returns the list of non-overlapping registers or register parts.
RegisterDescriptor callReturnRegister() const
Property: The register that holds the return address for a function.
void resize(const std::string &name, unsigned new_nbits)
Changes the size of a register.
void stackPointerRegister(const std::string &)
Property: The register that points to the stack.
const Entries & registers() const
Returns the list of all register definitions in the dictionary.
size_t size() const
Return the number of entries in the dictionary.
friend std::ostream & operator<<(std::ostream &, const RegisterDictionary &)
Prints the contents of this register dictionary.
RegisterDescriptor findLargestRegister(unsigned major, unsigned minor, size_t maxWidth=0) const
Finds the first largest register with specified major and minor number.
RegisterDescriptor stackPointerRegister() const
Property: The register that points to the stack.
unsigned firstUnusedMinor(unsigned majr) const
Returns the first unused minor register number.
RegisterDescriptor stackSegmentRegister() const
Property: The segment register for accessing the stack.
RegisterDescriptors getLargestRegisters() const
Returns a list of the largest non-overlapping registers.
void insert(const Ptr &)
Inserts definitions from another dictionary into this dictionary.
RegisterDescriptor find(const std::string &name) const
Find a register by name.
std::string nameOrQuad(RegisterDescriptor) const
Name or quad.
Holds a set of registers without regard for register boundaries.
Holds a value or nothing.
Definition Optional.h:56
Base class for reference counted objects.
Sawyer::SharedPointer< RegisterDictionary > RegisterDictionaryPtr
Reference counting pointer.
std::vector< RegisterDescriptor > RegisterDescriptors
List of register descriptors in dictionary.
The ROSE library.