ROSE 0.11.145.147
Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
Rose::BinaryAnalysis::RegisterDictionary Class Reference

Description

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 46 of file RegisterDictionary.h.

#include <Rose/BinaryAnalysis/RegisterDictionary.h>

Inheritance diagram for Rose::BinaryAnalysis::RegisterDictionary:
Inheritance graph
[legend]
Collaboration diagram for Rose::BinaryAnalysis::RegisterDictionary:
Collaboration graph
[legend]

Classes

class  SortBySize
 Compares number of bits in register descriptors. More...
 

Public Types

using Ptr = RegisterDictionaryPtr
 Reference counting pointer.
 
using Entries = std::map< std::string, RegisterDescriptor >
 List of registers in dictionary.
 
using RegisterDescriptors = Rose::BinaryAnalysis::RegisterDescriptors
 List of register descriptors in dictionary.
 

Public Member Functions

const Entriesregisters () const
 Returns the list of all register definitions in the dictionary.
 
size_t size () const
 Return the number of entries in the dictionary.
 
void insert (const std::string &name, RegisterDescriptor)
 Insert a definition into the dictionary.
 
void insert (const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits)
 Insert a definition into the dictionary.
 
void insert (const Ptr &)
 Inserts definitions from another dictionary into this dictionary.
 
void resize (const std::string &name, unsigned new_nbits)
 Changes the size of a register.
 
RegisterDescriptor find (const std::string &name) const
 Find a register by name.
 
RegisterDescriptor findOrThrow (const std::string &name) const
 Find a register by name.
 
const std::string & lookup (RegisterDescriptor) const
 Returns a register name for a given descriptor.
 
bool exists (RegisterDescriptor) const
 Determine if a register descriptor exists.
 
RegisterDescriptor findLargestRegister (unsigned major, unsigned minor, size_t maxWidth=0) const
 Finds the first largest register with specified major and minor number.
 
Sawyer::Optional< std::string > name (RegisterDescriptor) const
 Name of the register or nothing.
 
std::string nameOrQuad (RegisterDescriptor) const
 Name or quad.
 
std::string nameAndQuad (RegisterDescriptor) const
 Name and quad.
 
std::string quadAndName (RegisterDescriptor) const
 Quad and name.
 
Rose::BinaryAnalysis::RegisterParts getAllParts () const
 Returns all register parts.
 
RegisterDescriptors getDescriptors () const
 Returns the list of all register descriptors.
 
unsigned firstUnusedMajor () const
 Returns the first unused major register number.
 
unsigned firstUnusedMinor (unsigned majr) const
 Returns the first unused minor register number.
 
RegisterDescriptors getLargestRegisters () const
 Returns a list of the largest non-overlapping registers.
 
RegisterDescriptors getSmallestRegisters () const
 Returns a list of the smallest non-overlapping registers.
 
const std::string & name () const
 Property: Architecture name.
 
void name (const std::string &)
 Property: Architecture name.
 
RegisterDescriptor instructionPointerRegister () const
 Property: The register that points to instructions.
 
void instructionPointerRegister (RegisterDescriptor)
 Property: The register that points to instructions.
 
void instructionPointerRegister (const std::string &)
 Property: The register that points to instructions.
 
RegisterDescriptor stackPointerRegister () const
 Property: The register that points to the stack.
 
void stackPointerRegister (RegisterDescriptor)
 Property: The register that points to the stack.
 
void stackPointerRegister (const std::string &)
 Property: The register that points to the stack.
 
RegisterDescriptor stackFrameRegister () const
 Property: The register that ponts to the stack frame.
 
void stackFrameRegister (RegisterDescriptor)
 Property: The register that ponts to the stack frame.
 
void stackFrameRegister (const std::string &)
 Property: The register that ponts to the stack frame.
 
RegisterDescriptor stackSegmentRegister () const
 Property: The segment register for accessing the stack.
 
void stackSegmentRegister (RegisterDescriptor)
 Property: The segment register for accessing the stack.
 
void stackSegmentRegister (const std::string &)
 Property: The segment register for accessing the stack.
 
RegisterDescriptor callReturnRegister () const
 Property: The register that holds the return address for a function.
 
void callReturnRegister (RegisterDescriptor)
 Property: The register that holds the return address for a function.
 
void callReturnRegister (const std::string &)
 Property: The register that holds the return address for a function.
 
- Public Member Functions inherited from Sawyer::SharedObject
 SharedObject ()
 Default constructor.
 
 SharedObject (const SharedObject &)
 Copy constructor.
 
virtual ~SharedObject ()
 Virtual destructor.
 
SharedObjectoperator= (const SharedObject &)
 Assignment.
 

Static Public Member Functions

static Ptr instance (const std::string &name)
 Allocating constructor for an empty dictionary.
 
static Ptr instanceNull ()
 Mostly empty dictionary for the null ISA.
 
template<class Compare >
static RegisterDescriptors filterNonoverlapping (RegisterDescriptors reglist, Compare order=SortBySize(), bool reconsiderParts=true)
 Returns the list of non-overlapping registers or register parts.
 

Protected Member Functions

 RegisterDictionary (const std::string &name)
 
 RegisterDictionary (const RegisterDictionary &other)
 
void print (std::ostream &) const
 Prints the contents of this register dictionary.
 

Member Typedef Documentation

◆ Ptr

Reference counting pointer.

Definition at line 53 of file RegisterDictionary.h.

◆ Entries

List of registers in dictionary.

Definition at line 56 of file RegisterDictionary.h.

◆ RegisterDescriptors

List of register descriptors in dictionary.

Definition at line 59 of file RegisterDictionary.h.

Member Function Documentation

◆ insert() [1/3]

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.

◆ insert() [2/3]

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.

◆ insert() [3/3]

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.

◆ resize()

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.

◆ find()

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.

◆ 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.

◆ lookup()

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.

◆ exists()

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.

◆ findLargestRegister()

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.

◆ name()

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.

◆ nameOrQuad()

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.

◆ nameAndQuad()

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.

◆ quadAndName()

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.

◆ instructionPointerRegister() [1/3]

RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::instructionPointerRegister ( ) const

Property: The register that points to instructions.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ instructionPointerRegister() [2/3]

void Rose::BinaryAnalysis::RegisterDictionary::instructionPointerRegister ( RegisterDescriptor  )

Property: The register that points to instructions.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ instructionPointerRegister() [3/3]

void Rose::BinaryAnalysis::RegisterDictionary::instructionPointerRegister ( const std::string &  )

Property: The register that points to instructions.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackPointerRegister() [1/3]

RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::stackPointerRegister ( ) const

Property: The register that points to the stack.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackPointerRegister() [2/3]

void Rose::BinaryAnalysis::RegisterDictionary::stackPointerRegister ( RegisterDescriptor  )

Property: The register that points to the stack.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackPointerRegister() [3/3]

void Rose::BinaryAnalysis::RegisterDictionary::stackPointerRegister ( const std::string &  )

Property: The register that points to the stack.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackFrameRegister() [1/3]

RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::stackFrameRegister ( ) const

Property: The register that ponts to the stack frame.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackFrameRegister() [2/3]

void Rose::BinaryAnalysis::RegisterDictionary::stackFrameRegister ( RegisterDescriptor  )

Property: The register that ponts to the stack frame.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackFrameRegister() [3/3]

void Rose::BinaryAnalysis::RegisterDictionary::stackFrameRegister ( const std::string &  )

Property: The register that ponts to the stack frame.

If this architecture has no such register (most do) then this property stores an empty register descriptor.

◆ stackSegmentRegister() [1/3]

RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::stackSegmentRegister ( ) const

Property: The segment register for accessing the stack.

If this architecture has no such register (most don't) then this property stores an empty register descriptor.

◆ stackSegmentRegister() [2/3]

void Rose::BinaryAnalysis::RegisterDictionary::stackSegmentRegister ( RegisterDescriptor  )

Property: The segment register for accessing the stack.

If this architecture has no such register (most don't) then this property stores an empty register descriptor.

◆ stackSegmentRegister() [3/3]

void Rose::BinaryAnalysis::RegisterDictionary::stackSegmentRegister ( const std::string &  )

Property: The segment register for accessing the stack.

If this architecture has no such register (most don't) then this property stores an empty register descriptor.

◆ callReturnRegister() [1/3]

RegisterDescriptor Rose::BinaryAnalysis::RegisterDictionary::callReturnRegister ( ) const

Property: The register that holds the return address for a function.

If this architecture has no such register (most don't) then this property stores an empty register descriptor.

◆ callReturnRegister() [2/3]

void Rose::BinaryAnalysis::RegisterDictionary::callReturnRegister ( RegisterDescriptor  )

Property: The register that holds the return address for a function.

If this architecture has no such register (most don't) then this property stores an empty register descriptor.

◆ callReturnRegister() [3/3]

void Rose::BinaryAnalysis::RegisterDictionary::callReturnRegister ( const std::string &  )

Property: The register that holds the return address for a function.

If this architecture has no such register (most don't) then this property stores an empty register descriptor.

◆ getAllParts()

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.

◆ getDescriptors()

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.

◆ filterNonoverlapping()

template<class Compare >
RegisterDictionary::RegisterDescriptors Rose::BinaryAnalysis::RegisterDictionary::filterNonoverlapping ( RegisterDescriptors  reglist,
Compare  order = SortBySize(),
bool  reconsiderParts = true 
)
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:

RegisterDictionary::SortBySize largest_to_smallest(RegisterDictionary::SortBySize::DESCENDING);
RegisterDictionary::RegisterDescriptors all_registers = ditionary.get_descriptors();
RegisterDictionary::RegisterDescriptors list = dictionary.filter_nonoverlapping(all_registers, largest_to_smallest, true);
Compares number of bits in register descriptors.
Rose::BinaryAnalysis::RegisterDescriptors RegisterDescriptors
List of register descriptors in dictionary.

Filtering largest to smallest and reconsidering parts is the default, so the example can be shortened to:

RegisterDictionary::RegisterDescriptors list = dictionary.filter_nonoverlapping(dictionary.get_descriptors());

In fact, it can be shortened even more since this common operation is encapsulated in get_largest_registers():

RegisterDictionary::RegisterDescriptors list = dictionary.get_largest_registers();

Definition at line 408 of file RegisterDictionary.h.

References RangeMap< R, T >::begin(), RangeMap< R, T >::distinct(), 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().

◆ getLargestRegisters()

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:

|XXXXXXXXXXXX....| The "X" register occupies the first 12 bits of a 16-bit register
|....YYYYYYYYYYYY| The "Y" register occupies the last 12 bits of a 16-bit register

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.

◆ getSmallestRegisters()

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:

SortBySize order(SortBySize::ASCENDING);
RegisterDescriptors smallest = dict.filter_nonoverlapping(dict.get_descriptors(), order, false);

◆ print()

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.


The documentation for this class was generated from the following file: