ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RegisterDictionary Class Reference

Defines registers available for a particular architecture. More...

#include <Registers.h>

Collaboration diagram for RegisterDictionary:

Classes

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

Public Types

typedef std::map< std::string,
RegisterDescriptor
Entries
 
typedef std::vector
< RegisterDescriptor
RegisterDescriptors
 

Public Member Functions

 RegisterDictionary (const std::string &name)
 
 RegisterDictionary (const RegisterDictionary &other)
 
const std::string & get_architecture_name () const
 Obtain the name of the dictionary. More...
 
void set_architecture_name (const std::string &name)
 Set the name of the dictionary. More...
 
void insert (const std::string &name, const 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 RegisterDictionary *)
 Inserts definitions from another dictionary into this dictionary. More...
 
void insert (const RegisterDictionary &)
 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...
 
const RegisterDescriptorlookup (const std::string &name) const
 Returns a descriptor for a given register name. More...
 
const std::string & lookup (const RegisterDescriptor &) const
 Returns a register name for a given descriptor. More...
 
RegisterDescriptors get_descriptors () const
 Returns the list of all register descriptors. More...
 
RegisterDescriptors get_largest_registers () const
 Returns a list of the largest non-overlapping registers. More...
 
RegisterDescriptors get_smallest_registers () const
 Returns a list of the smallest non-overlapping registers. More...
 
void print (std::ostream &) const
 Prints the contents of this register dictionary. More...
 
size_t size () const
 Return the number of entries in the dictionary. More...
 
template<class Compare >
RegisterDictionary::RegisterDescriptors filter_nonoverlapping (RegisterDescriptors desc, Compare order, bool reconsider_parts)
 
const Entriesget_registers () const
 Returns the list of all register definitions in the dictionary. More...
 
Entriesget_registers ()
 Returns the list of all register definitions in the dictionary. More...
 

Static Public Member Functions

static const RegisterDictionarydictionary_i8086 ()
 Intel 8086 registers. More...
 
static const RegisterDictionarydictionary_i8088 ()
 Intel 8088 registers. More...
 
static const RegisterDictionarydictionary_i286 ()
 Intel 80286 registers. More...
 
static const RegisterDictionarydictionary_i386 ()
 Intel 80386 registers. More...
 
static const RegisterDictionarydictionary_i386_387 ()
 Intel 80386 with 80387 math co-processor. More...
 
static const RegisterDictionarydictionary_i486 ()
 Intel 80486 registers. More...
 
static const RegisterDictionarydictionary_pentium ()
 Intel Pentium registers. More...
 
static const RegisterDictionarydictionary_pentium4 ()
 Intel Pentium 4 registers. More...
 
static const RegisterDictionarydictionary_amd64 ()
 Amd64 registers. More...
 
static const RegisterDictionarydictionary_arm7 ()
 ARM7 registers. More...
 
static const RegisterDictionarydictionary_powerpc ()
 PowerPC registers. More...
 
static const RegisterDictionarydictionary_mips32 ()
 MIPS32 Release 1. More...
 
static const RegisterDictionarydictionary_mips32_altnames ()
 MIPS32 Release 1 with special register names. More...
 
template<class Compare >
static RegisterDescriptors filter_nonoverlapping (RegisterDescriptors reglist, Compare order=SortBySize(), bool reconsider_parts=true)
 Returns the list of non-overlapping registers or register parts. More...
 
static const RegisterDictionarydictionary_for_isa (SgAsmExecutableFileFormat::InsSetArchitecture)
 Class method to choose an appropriate register dictionary for an instruction set architecture. More...
 
static const RegisterDictionarydictionary_for_isa (SgAsmInterpretation *)
 Class method to choose an appropriate register dictionary for an instruction set architecture. More...
 

Private Types

typedef std::map< uint64_t,
std::vector< std::string > > 
Reverse
 

Static Private Member Functions

static uint64_t hash (const RegisterDescriptor &)
 

Private Attributes

std::string name
 
Entries forward
 
Reverse reverse
 

Friends

std::ostream & operator<< (std::ostream &, const RegisterDictionary &)
 

Detailed 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. Looking up the "eax" register in one dictionary may return a different descriptor than "eax" looked up in a different dictionary. Components of the ROSE binary support that generate RegisterDescriptors provide a mechanism for obtaining (and possibly setting) the register dictionary. For instance, the Disassembler class has get_registers() and set_registers() methods.

Definition at line 26 of file Registers.h.

Member Typedef Documentation

typedef std::map<std::string, RegisterDescriptor> RegisterDictionary::Entries

Definition at line 28 of file Registers.h.

Definition at line 29 of file Registers.h.

typedef std::map<uint64_t, std::vector<std::string> > RegisterDictionary::Reverse
private

Definition at line 201 of file Registers.h.

Constructor & Destructor Documentation

RegisterDictionary::RegisterDictionary ( const RegisterDictionary other)
inline

Definition at line 48 of file Registers.h.

Member Function Documentation

const RegisterDictionary * RegisterDictionary::dictionary_i8086 ( )
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.

Definition at line 261 of file Registers.C.

References insert(), RegisterDictionary(), x86_gpr_ax, x86_gpr_bp, x86_gpr_bx, x86_gpr_cx, x86_gpr_di, x86_gpr_dx, x86_gpr_si, x86_gpr_sp, x86_regclass_flags, x86_regclass_gpr, x86_regclass_ip, x86_regclass_segment, x86_segreg_cs, x86_segreg_ds, x86_segreg_es, and x86_segreg_ss.

Referenced by dictionary_i286(), and dictionary_i8088().

const RegisterDictionary * RegisterDictionary::dictionary_i8088 ( )
static

Intel 8088 registers.

Intel 8088 has the same set of registers as Intel 8086.

Definition at line 326 of file Registers.C.

References dictionary_i8086(), insert(), and RegisterDictionary().

const RegisterDictionary * RegisterDictionary::dictionary_i286 ( )
static

Intel 80286 registers.

The 80286 has the same registers as the 8086 but adds two new flags to the "flags" register.

Definition at line 340 of file Registers.C.

References dictionary_i8086(), insert(), RegisterDictionary(), and x86_regclass_flags.

Referenced by dictionary_for_isa(), dictionary_i386(), and DisassemblerX86::init().

const RegisterDictionary * RegisterDictionary::dictionary_i386 ( )
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.

Definition at line 359 of file Registers.C.

References dictionary_i286(), insert(), RegisterDictionary(), x86_gpr_ax, x86_gpr_bp, x86_gpr_bx, x86_gpr_cx, x86_gpr_di, x86_gpr_dx, x86_gpr_si, x86_gpr_sp, x86_regclass_cr, x86_regclass_dr, x86_regclass_flags, x86_regclass_gpr, x86_regclass_ip, x86_regclass_segment, x86_segreg_fs, and x86_segreg_gs.

Referenced by dictionary_i386_387().

const RegisterDictionary * RegisterDictionary::dictionary_i386_387 ( )
static

Intel 80386 with 80387 math co-processor.

Definition at line 407 of file Registers.C.

References dictionary_i386(), insert(), RegisterDictionary(), and x86_regclass_st.

Referenced by dictionary_for_isa(), and dictionary_i486().

const RegisterDictionary * RegisterDictionary::dictionary_i486 ( )
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.

Definition at line 435 of file Registers.C.

References dictionary_i386_387(), insert(), RegisterDictionary(), and x86_regclass_flags.

Referenced by dictionary_for_isa(), and dictionary_pentium().

const RegisterDictionary * RegisterDictionary::dictionary_pentium ( )
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.

Definition at line 450 of file Registers.C.

References dictionary_i486(), insert(), RegisterDictionary(), x86_regclass_flags, and x86_regclass_mm.

Referenced by dictionary_for_isa(), and dictionary_pentium4().

const RegisterDictionary * RegisterDictionary::dictionary_pentium4 ( )
static

Intel Pentium 4 registers.

The Pentium 4 has the same register set as the Pentium but adds the xmm0 through xmm7 registers for the SSE instruction set.

Definition at line 483 of file Registers.C.

References dictionary_pentium(), insert(), RegisterDictionary(), and x86_regclass_xmm.

Referenced by dictionary_amd64(), dictionary_for_isa(), DisassemblerX86::init(), and SgAsmx86Instruction::is_function_call().

const RegisterDictionary * RegisterDictionary::dictionary_amd64 ( )
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.

Definition at line 513 of file Registers.C.

References dictionary_pentium4(), insert(), name, StringUtility::numberToString(), RegisterDictionary(), resize(), x86_gpr_ax, x86_gpr_bp, x86_gpr_bx, x86_gpr_cx, x86_gpr_di, x86_gpr_dx, x86_gpr_si, x86_gpr_sp, x86_regclass_cr, x86_regclass_flags, x86_regclass_gpr, x86_regclass_ip, and x86_regclass_xmm.

Referenced by dictionary_for_isa(), Partitioner::discover_jump_table(), and DisassemblerX86::init().

const RegisterDictionary * RegisterDictionary::dictionary_arm7 ( )
static

ARM7 registers.

The CPU has a total of 37 registers, each 32 bits wide: 31 general purpose registers named and six status registers named. At most 16 (8 in Thumb mode) general purpose registers are visible at a time depending on the mode of operation. They have names rN where N is an integer between 0 and 15, inclusive and are mapped onto a subset of the 31 physical general purpose registers. Register r13 and r14 are, by convention, a stack pointer and link register (the link register holds the return address for a function call). Register r15 is the instruction pointer. Also, at most two status registers are available at a time.

The major number of a RegisterDescriptor is used to indicate the type of register: 0=general purpose, 1=status. The minor number indicates the register number: 0-15 for general purpose, 0 or 1 for status.

Definition at line 576 of file Registers.C.

References insert(), StringUtility::numberToString(), and RegisterDictionary().

Referenced by dictionary_for_isa(), and DisassemblerArm::init().

const RegisterDictionary * RegisterDictionary::dictionary_powerpc ( )
static

PowerPC registers.

Definition at line 619 of file Registers.C.

References insert(), StringUtility::numberToString(), and RegisterDictionary().

Referenced by dictionary_for_isa().

const RegisterDictionary * RegisterDictionary::dictionary_mips32 ( )
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).

Definition at line 729 of file Registers.C.

References insert(), mips_fcsr_all, mips_fcsr_fccr, mips_fcsr_fenr, mips_fcsr_fexr, mips_regclass_fcsr, mips_regclass_fpr, mips_regclass_gpr, mips_regclass_spr, mips_spr_fir, mips_spr_hi, mips_spr_lo, mips_spr_pc, StringUtility::numberToString(), and RegisterDictionary().

Referenced by dictionary_mips32_altnames().

const RegisterDictionary * RegisterDictionary::dictionary_mips32_altnames ( )
static

MIPS32 Release 1 with special register names.

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.

Definition at line 813 of file Registers.C.

References dictionary_mips32(), insert(), mips_regclass_gpr, and RegisterDictionary().

Referenced by dictionary_for_isa().

const RegisterDictionary * RegisterDictionary::dictionary_for_isa ( SgAsmExecutableFileFormat::InsSetArchitecture  isa)
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.

Definition at line 210 of file Registers.C.

References dictionary_amd64(), dictionary_arm7(), dictionary_i286(), dictionary_i386_387(), dictionary_i486(), dictionary_mips32_altnames(), dictionary_pentium(), dictionary_pentium4(), and dictionary_powerpc().

Referenced by dictionary_for_isa(), and SgAsmx86Instruction::is_function_call().

const RegisterDictionary * RegisterDictionary::dictionary_for_isa ( SgAsmInterpretation interp)
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.

Definition at line 245 of file Registers.C.

References dictionary_for_isa(), SgAsmInterpretation::get_headers(), and SgAsmGenericHeaderList::get_headers().

const std::string& RegisterDictionary::get_architecture_name ( ) const
inline

Obtain the name of the dictionary.

Definition at line 60 of file Registers.h.

References name.

void RegisterDictionary::set_architecture_name ( const std::string &  name)
inline

Set the name of the dictionary.

Dictionary names are generally architecture names. Dictionaries created by one of the built-in static methods of this class have the same name as the method that created it.

Definition at line 66 of file Registers.h.

References name.

void RegisterDictionary::insert ( const std::string &  name,
const RegisterDescriptor rdesc 
)

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.

Definition at line 90 of file Registers.C.

References SageInterface::find(), forward, hash(), name, and reverse.

Referenced by dictionary_amd64(), dictionary_arm7(), dictionary_i286(), dictionary_i386(), dictionary_i386_387(), dictionary_i486(), dictionary_i8086(), dictionary_i8088(), dictionary_mips32(), dictionary_mips32_altnames(), dictionary_pentium(), dictionary_pentium4(), dictionary_powerpc(), insert(), and resize().

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

Definition at line 107 of file Registers.C.

References insert().

void RegisterDictionary::insert ( const RegisterDictionary other)

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.

Definition at line 119 of file Registers.C.

References insert().

void RegisterDictionary::insert ( const RegisterDictionary other)

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.

Definition at line 112 of file Registers.C.

References get_registers(), and insert().

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

Definition at line 150 of file Registers.C.

References insert(), lookup(), and RegisterDescriptor::set_nbits().

Referenced by dictionary_amd64().

const RegisterDescriptor * RegisterDictionary::lookup ( const std::string &  name) const

Returns a descriptor for a given register name.

Returns the null pointer if the name is not found. It is not possible to modify a descriptor in the dictionary because doing so would interfere with the dictionary's data structures for reverse lookups.

Definition at line 125 of file Registers.C.

References forward.

Referenced by DisassemblerX86::makeIP(), DisassemblerArm::makePsrFields(), DisassemblerArm::makeRegister(), DisassemblerX86::makeRegister(), RegisterNames::operator()(), and resize().

const std::string & RegisterDictionary::lookup ( const RegisterDescriptor rdesc) 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 either return the empty string (default) or generate a generic name according to the optional supplied NameGenerator.

Definition at line 133 of file Registers.C.

References forward, hash(), name, and reverse.

const RegisterDictionary::Entries & RegisterDictionary::get_registers ( ) const

Returns the list of all register definitions in the dictionary.

Definition at line 159 of file Registers.C.

References forward.

Referenced by get_descriptors(), and insert().

RegisterDictionary::Entries & RegisterDictionary::get_registers ( )

Returns the list of all register definitions in the dictionary.

Definition at line 164 of file Registers.C.

References forward.

RegisterDictionary::RegisterDescriptors RegisterDictionary::get_descriptors ( ) 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.

Definition at line 169 of file Registers.C.

References get_registers().

Referenced by get_largest_registers(), and get_smallest_registers().

template<class Compare >
static RegisterDescriptors RegisterDictionary::filter_nonoverlapping ( RegisterDescriptors  reglist,
Compare  order = SortBySize(),
bool  reconsider_parts = 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 reconsider_parts 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::RegisterDescriptors all_registers = ditionary.get_descriptors();
RegisterDictionary::RegisterDescriptors list = dictionary.filter_nonoverlapping(all_registers, largest_to_smallest, true);

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();

Referenced by get_largest_registers(), and get_smallest_registers().

RegisterDictionary::RegisterDescriptors RegisterDictionary::get_largest_registers ( ) 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.

Definition at line 180 of file Registers.C.

References RegisterDictionary::SortBySize::ASCENDING, filter_nonoverlapping(), and get_descriptors().

RegisterDictionary::RegisterDescriptors RegisterDictionary::get_smallest_registers ( ) 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);

Definition at line 187 of file Registers.C.

References RegisterDictionary::SortBySize::DESCENDING, filter_nonoverlapping(), and get_descriptors().

void RegisterDictionary::print ( std::ostream &  o) 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.

Definition at line 194 of file Registers.C.

References StringUtility::addrToString(), forward, hash(), name, and reverse.

Referenced by operator<<().

size_t RegisterDictionary::size ( ) const
inline

Return the number of entries in the dictionary.

Definition at line 198 of file Registers.h.

References forward.

uint64_t RegisterDictionary::hash ( const RegisterDescriptor d)
staticprivate

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  o,
const RegisterDictionary dict 
)
friend

Definition at line 5 of file Registers.C.

Member Data Documentation

std::string RegisterDictionary::name
private
Entries RegisterDictionary::forward
private

Definition at line 204 of file Registers.h.

Referenced by get_registers(), insert(), lookup(), print(), and size().

Reverse RegisterDictionary::reverse
private

Definition at line 205 of file Registers.h.

Referenced by insert(), lookup(), and print().


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