ROSE
0.11.137.0
|
Defines registers available for a particular architecture.
The dictionary maps each register name to a RegisterDescriptor. The RegisterDescriptor describes how a register name maps to (part of) a physical CPU register by providing a major number, minor number, bit offset, and number of bits. The major number is typically a register class number and the minor number is typically an offset within the class. For instance, for x86 the major numbers might indicate whether a register is a general purpose register, an 80-bit floating point register, a 128-bit MMX register, etc.
Users should not assume that the values of a RegisterDescriptor correspond to actual values found in the machine instructions that were disassembled. What they can assume is that two unrelated registers (such as "eax" and "ebx") do not overlap in the RegisterDescriptor address space (major, minor, offset, size). They can also assume that two related registers (such as "eax" and "rax", the 32- and 64-bit versions of a single CPU register) do, in fact, overlap in the RegisterDescriptor address space and that the overlap indicates how the registers are related.
Users should not assume that RegisterDescriptor entries from two separate dictionaries are compatible, although the dictionaries created by the ROSE library do use compatible descriptors across each family. Looking up the "eax" register in one dictionary may return a different descriptor than "eax" looked up in a different dictionary (but not in ROSE-created dictinaries). Components of the ROSE binary support that generate RegisterDescriptors provide a mechanism for obtaining (and possibly setting) the register dictionary. For instance, the Disassembler::Base class has get_registers() and set_registers() methods.
Definition at line 44 of file RegisterDictionary.h.
#include <Rose/BinaryAnalysis/RegisterDictionary.h>
Classes | |
class | SortBySize |
Compares number of bits in register descriptors. More... | |
Public Types | |
using | Ptr = RegisterDictionaryPtr |
Reference counting pointer. More... | |
using | Entries = std::map< std::string, RegisterDescriptor > |
List of registers in dictionary. More... | |
using | RegisterDescriptors = Rose::BinaryAnalysis::RegisterDescriptors |
List of register descriptors in dictionary. More... | |
Public Member Functions | |
const Entries & | registers () const |
Returns the list of all register definitions in the dictionary. More... | |
size_t | size () const |
Return the number of entries in the dictionary. More... | |
void | insert (const std::string &name, RegisterDescriptor) |
Insert a definition into the dictionary. More... | |
void | insert (const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits) |
Insert a definition into the dictionary. More... | |
void | insert (const Ptr &) |
Inserts definitions from another dictionary into this dictionary. More... | |
void | resize (const std::string &name, unsigned new_nbits) |
Changes the size of a register. More... | |
RegisterDescriptor | find (const std::string &name) const |
Find a register by name. More... | |
RegisterDescriptor | findOrThrow (const std::string &name) const |
Find a register by name. More... | |
const std::string & | lookup (RegisterDescriptor) const |
Returns a register name for a given descriptor. More... | |
bool | exists (RegisterDescriptor) const |
Determine if a register descriptor exists. More... | |
RegisterDescriptor | findLargestRegister (unsigned major, unsigned minor, size_t maxWidth=0) const |
Finds the first largest register with specified major and minor number. More... | |
Sawyer::Optional< std::string > | name (RegisterDescriptor) const |
Name of the register or nothing. More... | |
std::string | nameOrQuad (RegisterDescriptor) const |
Name or quad. More... | |
std::string | nameAndQuad (RegisterDescriptor) const |
Name and quad. More... | |
std::string | quadAndName (RegisterDescriptor) const |
Quad and name. More... | |
Rose::BinaryAnalysis::RegisterParts | getAllParts () const |
Returns all register parts. More... | |
RegisterDescriptors | getDescriptors () const |
Returns the list of all register descriptors. More... | |
unsigned | firstUnusedMajor () const |
Returns the first unused major register number. More... | |
unsigned | firstUnusedMinor (unsigned majr) const |
Returns the first unused minor register number. More... | |
RegisterDescriptors | getLargestRegisters () const |
Returns a list of the largest non-overlapping registers. More... | |
RegisterDescriptors | getSmallestRegisters () const |
Returns a list of the smallest non-overlapping registers. More... | |
const std::string & | name () const |
Property: Architecture name. | |
void | name (const std::string &) |
Property: Architecture name. | |
![]() | |
SharedObject () | |
Default constructor. More... | |
SharedObject (const SharedObject &) | |
Copy constructor. More... | |
virtual | ~SharedObject () |
Virtual destructor. More... | |
SharedObject & | operator= (const SharedObject &) |
Assignment. More... | |
Static Public Member Functions | |
static Ptr | instance (const std::string &name) |
Allocating constructor for an empty dictionary. More... | |
static Ptr | instanceNull () |
Mostly empty dictionary for the null ISA. More... | |
static Ptr | instanceI8086 () |
Intel 8086 registers. More... | |
static Ptr | instanceI8088 () |
Intel 8088 registers. More... | |
static Ptr | instanceI286 () |
Intel 80286 registers. More... | |
static Ptr | instanceI386 () |
Intel 80386 registers. More... | |
static Ptr | instanceI386Math () |
Intel 80386 with 80387 math co-processor. More... | |
static Ptr | instanceI486 () |
Intel 80486 registers. More... | |
static Ptr | instancePentium () |
Intel Pentium registers. More... | |
static Ptr | instancePentiumiii () |
Intel Pentium III registers. More... | |
static Ptr | instancePentium4 () |
Intel Pentium 4 registers. More... | |
static Ptr | instanceAmd64 () |
Amd64 registers. More... | |
static Ptr | instancePowerpc32 () |
PowerPC-32 registers. More... | |
static Ptr | instancePowerpc64 () |
PowerPC-64 registers. More... | |
static Ptr | instanceMips32 () |
MIPS32 Release 1. More... | |
static Ptr | instanceMips32AlternateNames () |
MIPS32 Release 1 with special registers. More... | |
static Ptr | instanceM68000 () |
Motorola M68330 register names. | |
static Ptr | instanceM68000AlternateNames () |
Motorola M68330 alternate registers. More... | |
static Ptr | instanceColdfire () |
FreeScale ColdFire generic hardware registers. More... | |
static Ptr | instanceColdfireEmac () |
Registers for FreeScale ColdFire CPUs with EMAC (extended multiply-accumulate) unit. More... | |
static Ptr | instanceCil () |
CIL register names. | |
static Ptr | instanceJvm () |
JVM register names. | |
template<class Compare > | |
static RegisterDescriptors | filterNonoverlapping (RegisterDescriptors reglist, Compare order=SortBySize(), bool reconsiderParts=true) |
Returns the list of non-overlapping registers or register parts. More... | |
static Ptr | instanceForIsa (SgAsmExecutableFileFormat::InsSetArchitecture) |
Class method to choose an appropriate register dictionary for an instruction set architecture. More... | |
static Ptr | instanceForIsa (SgAsmInterpretation *) |
Class method to choose an appropriate register dictionary for an instruction set architecture. More... | |
Protected Member Functions | |
RegisterDictionary (const std::string &name) | |
RegisterDictionary (const RegisterDictionary &other) | |
std::ostream & | operator<< (std::ostream &, const RegisterDictionary &) |
Prints the contents of this register dictionary. More... | |
void | print (std::ostream &) const |
Prints the contents of this register dictionary. More... | |
Reference counting pointer.
Definition at line 51 of file RegisterDictionary.h.
using Rose::BinaryAnalysis::RegisterDictionary::Entries = std::map<std::string, RegisterDescriptor> |
List of registers in dictionary.
Definition at line 54 of file RegisterDictionary.h.
using Rose::BinaryAnalysis::RegisterDictionary::RegisterDescriptors = Rose::BinaryAnalysis::RegisterDescriptors |
List of register descriptors in dictionary.
Definition at line 57 of file RegisterDictionary.h.
|
static |
Allocating constructor for an empty dictionary.
|
static |
Mostly empty dictionary for the null ISA.
|
static |
Intel 8086 registers.
The Intel 8086 has fourteen 16-bit registers. Four of them (AX, BX, CX, DX) are general registers (although each may have an additional purpose; for example only CX can be used as a counter with the loop instruction). Each can be accessed as two separate bytes (thus BX's high byte can be accessed as BH and low byte as BL). Four segment registers (CS, DS, SS and ES) are used to form a memory address. There are two pointer registers. SP points to the bottom of the stack and BP which is used to point at some other place in the stack or the memory(Offset). Two registers (SI and DI) are for array indexing. The FLAGS register contains flags such as carry flag, overflow flag and zero flag. Finally, the instruction pointer (IP) points to the next instruction that will be fetched from memory and then executed.
|
static |
Intel 8088 registers.
Intel 8088 has the same set of registers as Intel 8086.
|
static |
Intel 80286 registers.
The 80286 has the same registers as the 8086 but adds two new flags to the "flags" register.
|
static |
Intel 80386 registers.
The 80386 has the same registers as the 80286 but extends the general-purpose registers, base registers, index registers, instruction pointer, and flags register to 32 bits. Register names from the 80286 refer to the same offsets and sizes while the full 32 bits are accessed by names prefixed with "e" as in "eax" (the "e" means "extended"). Two new segment registers (FS and GS) were added and all segment registers remain 16 bits.
|
static |
Intel 80386 with 80387 math co-processor.
|
static |
Intel 80486 registers.
The 80486 has the same registers as the 80386 with '387 co-processor but adds a new flag to the "eflags" register.
|
static |
Intel Pentium registers.
The Pentium has the same registers as the 80486 but adds a few flags to the "eflags" register and MMX registers.
|
static |
Intel Pentium III registers.
The Pentium III has the same register set as the Pentium but adds the xmm0 through xmm7 registers for the SSE instruction set.
|
static |
Intel Pentium 4 registers.
|
static |
Amd64 registers.
The AMD64 architecture increases the size of the general purpose registers, base registers, index registers, instruction pointer, and flags register to 64-bits. Most register names from the Pentium architecture still exist and refer to 32-bit quantities, while the AMD64 adds new names that start with "r" rather than "e" (such as "rax" for the 64-bit register and "eax" for the 32 low-order bits of the same register). It also adds eight additional 64-bit general purpose registers named "r8" through "r15" along with "b", "w", and "d" suffixes for the low-order 8, 16, and 32 bits, respectively.
The only registers that are not retained are the control registers cr0-cr4, which are replaced by 64-bit registers of the same name, and debug registers dr0-dr7, which are also replaced by 64-bit registers of the same name.
|
static |
PowerPC-32 registers.
|
static |
PowerPC-64 registers.
|
static |
MIPS32 Release 1.
Release 1 of MIPS32 supports only a 32-bit FPU (support for 64-bit FPU was added in MIPS32 Release 2).
|
static |
MIPS32 Release 1 with special registers.
This is the same dictionary as dictionary_mips32(), except additional names are supplied for the general purpose registers (e.g., "zero" for r0, "at" for r1, "gp" for r28, "sp" for r29, "fp" for r30, "ra" for r31, etc.). This is intended mostly for the AsmUnparser; any layer that looks up registers by name should probably use the standard names rather than relying on these alternate names.
|
static |
Motorola M68330 alternate registers.
|
static |
FreeScale ColdFire generic hardware registers.
|
static |
Registers for FreeScale ColdFire CPUs with EMAC (extended multiply-accumulate) unit.
|
static |
Class method to choose an appropriate register dictionary for an instruction set architecture.
Returns the best available register dictionary for any architecture. Returns the null pointer if no dictionary is appropriate.
|
static |
Class method to choose an appropriate register dictionary for an instruction set architecture.
Returns the best available register dictionary for any architecture. Returns the null pointer if no dictionary is appropriate.
const Entries& Rose::BinaryAnalysis::RegisterDictionary::registers | ( | ) | const |
Returns the list of all register definitions in the dictionary.
size_t Rose::BinaryAnalysis::RegisterDictionary::size | ( | ) | const |
Return the number of entries in the dictionary.
void Rose::BinaryAnalysis::RegisterDictionary::insert | ( | const std::string & | name, |
RegisterDescriptor | |||
) |
Insert a definition into the dictionary.
If the name already exists in the dictionary then the new RegisterDescriptor will replace the one that already exists.
void Rose::BinaryAnalysis::RegisterDictionary::insert | ( | const std::string & | name, |
unsigned | majr, | ||
unsigned | minr, | ||
unsigned | offset, | ||
unsigned | nbits | ||
) |
Insert a definition into the dictionary.
If the name already exists in the dictionary then the new RegisterDescriptor will replace the one that already exists.
void Rose::BinaryAnalysis::RegisterDictionary::insert | ( | const Ptr & | ) |
Inserts definitions from another dictionary into this dictionary.
Names in the other dictionary that are the same as names in this dictionary will replace the definitions in this dictionary.
void Rose::BinaryAnalysis::RegisterDictionary::resize | ( | const std::string & | name, |
unsigned | new_nbits | ||
) |
Changes the size of a register.
This is a common enough operation that we have a special method to do it. To change other properties of a register you would look up the register descriptor, change the property, then re-insert the register into the dictionary using the new descriptor. This method does exactly that.
RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::find | ( | const std::string & | name | ) | const |
Find a register by name.
Looks up the descriptor for the register having the specified name. If no descriptor exists for that name then a default constructed invalid descriptor is returned. See also, findOrThrow.
RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::findOrThrow | ( | const std::string & | name | ) | const |
Find a register by name.
Looks up the descriptor for the register having the specified name. If no descriptor exists for that name then a Rose::Exception is thrown. See also find.
const std::string& Rose::BinaryAnalysis::RegisterDictionary::lookup | ( | RegisterDescriptor | ) | const |
Returns a register name for a given descriptor.
If more than one register has the same descriptor then the name added latest is returned. If no register is found then return the empty string.
bool Rose::BinaryAnalysis::RegisterDictionary::exists | ( | RegisterDescriptor | ) | const |
Determine if a register descriptor exists.
This is similar to the lookup method that takes a RegisterDescriptor argument, but instead of returning the name it returns true if found, false if not found.
RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::findLargestRegister | ( | unsigned | major, |
unsigned | minor, | ||
size_t | maxWidth = 0 |
||
) | const |
Finds the first largest register with specified major and minor number.
Returns the first register with the largest width and having the specified major and minor numbers. Registers wider than maxWidth
(if non-zero) are ignored. If no register is found with the major/minor number then an invalid (default-constructed) register is returned.
This function takes O(n) time where n is the number of registers defined.
Sawyer::Optional<std::string> Rose::BinaryAnalysis::RegisterDictionary::name | ( | RegisterDescriptor | ) | const |
Name of the register or nothing.
Returns the non-empty name of the register if available, or nothing.
std::string Rose::BinaryAnalysis::RegisterDictionary::nameOrQuad | ( | RegisterDescriptor | ) | const |
Name or quad.
Returns the name of the register if available, or else the quad. The quad is generated from the RegisterDescriptor::toString method.
std::string Rose::BinaryAnalysis::RegisterDictionary::nameAndQuad | ( | RegisterDescriptor | ) | const |
Name and quad.
If the register has a name, then this function returns the name in quotes using C string literal escapes followed by the quad. Otherwise just the quad is returned. The quad is generated by calling RegisterDescriptor::toString.
std::string Rose::BinaryAnalysis::RegisterDictionary::quadAndName | ( | RegisterDescriptor | ) | const |
Quad and name.
Returns a string containing the register quad. If the register has a name then it follows in quotes using C string literal escapes. The quad is generated by calling RegisterDescriptor::toString.
Rose::BinaryAnalysis::RegisterParts Rose::BinaryAnalysis::RegisterDictionary::getAllParts | ( | ) | const |
Returns all register parts.
Returns all parts of all registers in this dictionary without any regard for register boundaries. For instance, if a diction contains the x86 AX and AL registers where AX is 16 bits and AL is its low-order eight bits, the return value will only contain the fact that the 16 bits corresponding to AX are stored, which also happens to contain the eight bits of AL, but it won't keep track that AX and AL were inserted separately. In other words, erasing AL from the returned container would also erase the low-order 8 bits of AX.
RegisterDescriptors Rose::BinaryAnalysis::RegisterDictionary::getDescriptors | ( | ) | const |
Returns the list of all register descriptors.
The returned list may have overlapping register descriptors. The return value is similar to get_registers() except only the RegisterDescriptor part is returned, not the names.
unsigned Rose::BinaryAnalysis::RegisterDictionary::firstUnusedMajor | ( | ) | const |
Returns the first unused major register number.
unsigned Rose::BinaryAnalysis::RegisterDictionary::firstUnusedMinor | ( | unsigned | majr | ) | const |
Returns the first unused minor register number.
|
static |
Returns the list of non-overlapping registers or register parts.
The list of registers are processed in the reverse specified order and each register is added to the return value if its bits were not already added to the return value by a previous register. If a register under consideration is only partially represented in the return value at the time it is considered, then it is either split into smaller parts to be reconsidered later, or not reconsidered at all. Thus, when reconsiderParts
is true, the return value might contain register descriptors that were not part of the input reglist
, and which might not even have entries/names in the register dictionary (see get_largest_registers() for more explaination).
For example, to get a list of the largest non-overlapping registers one could do the following:
Filtering largest to smallest and reconsidering parts is the default, so the example can be shortened to:
In fact, it can be shortened even more since this common operation is encapsulated in get_largest_registers():
Definition at line 474 of file RegisterDictionary.h.
References RangeMap< R, T >::begin(), RangeMap< R, T >::end(), RangeMap< R, T >::erase_ranges(), Range< T >::first(), RangeMap< R, T >::insert(), Rose::BinaryAnalysis::RegisterDescriptor::majorNumber(), Rose::BinaryAnalysis::RegisterDescriptor::minorNumber(), Rose::BinaryAnalysis::RegisterDescriptor::nBits(), Rose::BinaryAnalysis::RegisterDescriptor::offset(), and Range< T >::size().
RegisterDescriptors Rose::BinaryAnalysis::RegisterDictionary::getLargestRegisters | ( | ) | const |
Returns a list of the largest non-overlapping registers.
For instance, for a 32-bit x86 dictionary the return value will contain registers EAX, EBX, etc. but not AX, AH, AL, BX, BH, BL, etc. Note that some of the returned descriptors might not correspond to actual names in the dictionary; this can happen when the dictionary contains two registers that partially overlap, but are themselves not subsets of a larger register, as in:
If the 16-bit register has no name, and the high- and low-order four-bit parts have no name, then the return value might consist of register "X" and the low four bits. Or it could be register "Y" and the high four bits.
RegisterDescriptors Rose::BinaryAnalysis::RegisterDictionary::getSmallestRegisters | ( | ) | const |
Returns a list of the smallest non-overlapping registers.
For instance, for a 32-bit x86 dictionary the return value will contain AX, AH, AL, BX, BH, BL, etc. rather than EAX and EBX. It will also return the high 16-bit parts of EAX and EBX even though they're not represented with explicit definitions in the dictionary.
This is a one-liner in terms of filter_nonoverlapping. If you don't want the unnamed parts to appear in the return value (e.g., the high-order 16 bits of EAX), then call filter_nonoverlapping() like this:
void Rose::BinaryAnalysis::RegisterDictionary::print | ( | std::ostream & | ) | const |
Prints the contents of this register dictionary.
The first line of output contains the dictionary name. One additional line of output will be generated for each entry in the dictionary.
|
friend |
Prints the contents of this register dictionary.
The first line of output contains the dictionary name. One additional line of output will be generated for each entry in the dictionary.