Functions and defines to create and manipulate instruction operands. More...
Typedefs | |
typedef ushort | reg_id_t |
typedef byte | opnd_size_t |
typedef enum _dr_shift_type_t | dr_shift_type_t |
typedef enum _dr_extend_type_t | dr_extend_type_t |
typedef enum _dr_opnd_flags_t | dr_opnd_flags_t |
Functions and defines to create and manipulate instruction operands.
#define DR_NUM_GPR_REGS (DR_REG_STOP_GPR - DR_REG_START_GPR + 1) |
Number of general registers
#define DR_REG_LAST_ENUM DR_REG_YMM15 |
Last value of register enums
#define DR_REG_LAST_VALID_ENUM DR_REG_YMM15 |
Last valid register enum value. Note: DR_REG_INVALID is now smaller than this value.
#define DR_REG_START_16 DR_REG_AX |
Start of 16-bit general register enum values \
#define DR_REG_START_32 DR_REG_EAX |
Start of 32-bit general register enum values
#define DR_REG_START_64 DR_REG_RAX |
Start of 64-bit general register enum values
#define DR_REG_START_8 DR_REG_AL |
Start of 8-bit general register enum values
#define DR_REG_START_8HL DR_REG_AL |
Start of 8-bit high-low register enum values
#define DR_REG_START_CR DR_REG_CR0 |
Start of control register enum values
#define DR_REG_START_DR DR_REG_DR0 |
Start of debug register enum values
#define DR_REG_START_FLOAT DR_REG_ST0 |
Start of floating-point-register enum values
#define DR_REG_START_GPR DR_REG_XAX |
Start of general register enum values
#define DR_REG_START_MMX DR_REG_MM0 |
Start of mmx register enum values
#define DR_REG_START_SEGMENT DR_SEG_ES |
Start of segment register enum values
#define DR_REG_START_x64_8 DR_REG_SPL |
Start of 8-bit x64-only register enum values
#define DR_REG_START_x86_8 DR_REG_AH |
Start of 8-bit x86-only register enum values
#define DR_REG_START_XMM DR_REG_XMM0 |
Start of xmm register enum values
#define DR_REG_START_YMM DR_REG_YMM0 |
Start of ymm register enum values
#define DR_REG_STOP_16 DR_REG_R15W |
End of 16-bit general register enum values \
#define DR_REG_STOP_32 DR_REG_R15D |
End of 32-bit general register enum values \
#define DR_REG_STOP_64 DR_REG_R15 |
End of 64-bit general register enum values
#define DR_REG_STOP_8 DR_REG_DIL |
End of 8-bit general register enum values
#define DR_REG_STOP_8HL DR_REG_BH |
End of 8-bit high-low register enum values
#define DR_REG_STOP_CR DR_REG_CR15 |
End of control register enum values
#define DR_REG_STOP_DR DR_REG_DR15 |
End of debug register enum values
#define DR_REG_STOP_FLOAT DR_REG_ST7 |
End of floating-point-register enum values
#define DR_REG_STOP_GPR DR_REG_R15 |
End of general register enum values
#define DR_REG_STOP_MMX DR_REG_MM7 |
End of mmx register enum values
#define DR_REG_STOP_SEGMENT DR_SEG_GS |
End of segment register enum values
#define DR_REG_STOP_x64_8 DR_REG_DIL |
Stop of 8-bit x64-only register enum values
#define DR_REG_STOP_x86_8 DR_REG_BH |
Stop of 8-bit x86-only register enum values
#define DR_REG_STOP_XMM DR_REG_XMM15 |
End of xmm register enum values
#define DR_REG_STOP_YMM DR_REG_YMM15 |
End of ymm register enum values
#define DR_REG_XAX DR_REG_RAX |
Platform-independent way to refer to rax/eax.
#define DR_REG_XBP DR_REG_RBP |
Platform-independent way to refer to rbp/ebp.
#define DR_REG_XBX DR_REG_RBX |
Platform-independent way to refer to rbx/ebx.
#define DR_REG_XCX DR_REG_RCX |
Platform-independent way to refer to rcx/ecx.
#define DR_REG_XDI DR_REG_RDI |
Platform-independent way to refer to rdi/edi.
#define DR_REG_XDX DR_REG_RDX |
Platform-independent way to refer to rdx/edx.
#define DR_REG_XSI DR_REG_RSI |
Platform-independent way to refer to rsi/esi.
#define DR_REG_XSP DR_REG_RSP |
Platform-independent way to refer to rsp/esp.
#define OPSZ_bound OPSZ_8_short4 |
Operand size for bound memory reference.
#define OPSZ_call OPSZ_ret |
Operand size for push portion of call.
#define OPSZ_clflush OPSZ_1 |
Operand size for clflush memory reference.
#define OPSZ_fldenv OPSZ_28_short14 |
Operand size for fldenv memory reference.
#define OPSZ_fnsave OPSZ_108_short94 |
Operand size for fnsave memory reference.
#define OPSZ_fnstenv OPSZ_28_short14 |
Operand size for fnstenv memory reference.
#define OPSZ_frstor OPSZ_108_short94 |
Operand size for frstor memory reference.
#define OPSZ_fxrstor OPSZ_512 |
Operand size for fxrstor memory reference.
#define OPSZ_fxsave OPSZ_512 |
Operand size for fxsave memory reference.
#define OPSZ_invlpg OPSZ_0 |
Operand size for invlpg memory reference.
#define OPSZ_lea OPSZ_0 |
Operand size for lea memory reference.
#define OPSZ_lgdt OPSZ_6x10 |
Operand size for lgdt memory reference.
#define OPSZ_lidt OPSZ_6x10 |
Operand size for lidt memory reference.
#define OPSZ_maskmovdqu OPSZ_16 |
Operand size for maskmovdqu memory reference.
#define OPSZ_maskmovq OPSZ_8 |
Operand size for maskmovq memory reference.
#define OPSZ_prefetch OPSZ_1 |
Operand size for prefetch memory references.
#define OPSZ_PTR OPSZ_8 |
Operand size for pointer values.
#define OPSZ_PTR_DBL OPSZ_16 |
Double-pointer-sized.
#define OPSZ_PTR_HALF OPSZ_4 |
Half-pointer-sized.
#define OPSZ_ret OPSZ_4x8_short2xi8 |
Operand size for ret instruction.
#define OPSZ_sgdt OPSZ_6x10 |
Operand size for sgdt memory reference.
#define OPSZ_sidt OPSZ_6x10 |
Operand size for sidt memory reference.
#define OPSZ_STACK OPSZ_8 |
Operand size for stack push/pop operand sizes.
#define OPSZ_VARSTACK OPSZ_4x8_short2 |
Operand size for prefix-varying stack \ push/pop operand sizes.
#define OPSZ_xlat OPSZ_1 |
Operand size for xlat memory reference.
typedef enum _dr_extend_type_t dr_extend_type_t |
These flags describe how the index register in a memory reference is extended before being optionally shifted and added to the base register. They also describe how a general source register is extended before being used in its containing instruction.
typedef enum _dr_opnd_flags_t dr_opnd_flags_t |
These flags describe operations performed on the value of a source register before it is combined with other sources as part of the behavior of the containing instruction, or operations performed on an index register or displacement before it is added to or subtracted from the base register.
typedef enum _dr_shift_type_t dr_shift_type_t |
These flags describe how the index register in a memory reference is shifted before being added to or subtracted from the base register. They also describe how a general source register is shifted before being used in its containing instruction.
typedef byte opnd_size_t |
The type of an OPSZ_ enum value.
typedef ushort reg_id_t |
The type of a DR_REG_ enum value.
anonymous enum |
Register identifiers.
anonymous enum |
enum _dr_extend_type_t |
These flags describe how the index register in a memory reference is extended before being optionally shifted and added to the base register. They also describe how a general source register is extended before being used in its containing instruction.
enum _dr_opnd_flags_t |
These flags describe operations performed on the value of a source register before it is combined with other sources as part of the behavior of the containing instruction, or operations performed on an index register or displacement before it is added to or subtracted from the base register.
Enumerator | |
---|---|
DR_OPND_NEGATED | This register's value is negated prior to use in the containing instruction. |
DR_OPND_SHIFTED | This register's value is shifted prior to use in the containing instruction. This flag is for informational purposes only and is not guaranteed to be consistent with the shift type of an index register or displacement if the latter are set without using opnd_set_index_shift() or if an instruction is created without using high-level API routines. This flag is also ignored for encoding and will not apply a shift on its own. |
DR_OPND_MULTI_PART | This operand should be combined with an adjacent operand to create a single value. This flag is typically used on immediates: e.g., for ARM's OP_vbic_i64, two 32-bit immediate operands should be interpreted as the low and high parts of a 64-bit value. |
DR_OPND_IS_SHIFT | This immediate integer operand should be interpreted as an ARM/AArch64 shift type. |
DR_OPND_IN_LIST | A hint indicating that this register operand is part of a register list. |
DR_OPND_EXTENDED | This register's value is extended prior to use in the containing instruction. This flag is for informational purposes only and is not guaranteed to be consistent with the shift type of an index register or displacement if the latter are set without using opnd_set_index_extend() or if an instruction is created without using high-level API routines. This flag is also ignored for encoding and will not apply a shift on its own. |
DR_OPND_IS_EXTEND | This immediate integer operand should be interpreted as an AArch64 extend type. |
DR_OPND_IS_CONDITION | This immediate integer operand should be interpreted as an AArch64 condition. |
enum _dr_shift_type_t |
These flags describe how the index register in a memory reference is shifted before being added to or subtracted from the base register. They also describe how a general source register is shifted before being used in its containing instruction.
const char* get_register_name | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ 32-bit register constant. Returns the string name for reg
.
opnd_t opnd_add_flags | ( | opnd_t | opnd, |
dr_opnd_flags_t | flags | ||
) |
Assumes opnd
is a register operand, base+disp memory reference, or an immediate integer. Sets the flags describing additional properties of the operand to be the current flags plus the flags
parameter and returns the new operand value.
app_pc opnd_compute_address | ( | opnd_t | opnd, |
dr_mcontext_t * | mc | ||
) |
Returns the effective address of opnd
, computed using the passed-in register values. If opnd
is a far address, ignores that aspect except for TLS references on Windows (fs: for 32-bit, gs: for 64-bit) or typical fs: or gs: references on Linux. For far addresses the calling thread's segment selector is used. mc->flags
must include DR_MC_CONTROL and DR_MC_INTEGER.
opnd_t opnd_create_abs_addr | ( | void * | addr, |
opnd_size_t | data_size | ||
) |
Returns a memory reference operand that refers to the address addr
. The operand has data size data_size
(must be a OPSZ_ constant).
If addr
<= 2^32 (which is always true in 32-bit mode), this routine is equivalent to opnd_create_base_disp(DR_REG_NULL, DR_REG_NULL, 0, (int)addr, data_size).
Otherwise, this routine creates a separate operand type with an absolute 64-bit memory address. Such an operand can only be guaranteed to be encodable in absolute form as a load or store from or to the rax (or eax) register. It will automatically be converted to a pc-relative operand (as though opnd_create_rel_addr() had been called) if it is used in any other way.
opnd_t opnd_create_base_disp | ( | reg_id_t | base_reg, |
reg_id_t | index_reg, | ||
int | scale, | ||
int | disp, | ||
opnd_size_t | data_size | ||
) |
Returns a memory reference operand that refers to the address:
or, in other words,
The operand has data size data_size (must be a OPSZ_ constant). Both base_reg
and index_reg
must be DR_REG_ constants. scale
must be either 0, 1, 2, 4, or 8. On ARM, opnd_set_index_shift() can be used for further manipulation of the index register. On ARM, a negative value for disp
will be converted into a positive value with DR_OPND_NEGATED set in opnd_get_flags(). On ARM, either index_reg
must be DR_REG_NULL or disp must be 0.
opnd_t opnd_create_base_disp_aarch64 | ( | reg_id_t | base_reg, |
reg_id_t | index_reg, | ||
dr_extend_type_t | extend_type, | ||
bool | scaled, | ||
int | disp, | ||
dr_opnd_flags_t | flags, | ||
opnd_size_t | size | ||
) |
Returns a memory reference operand that refers to either a base register with a constant displacement:
Or a base register plus an optionally extended and shifted index register:
The shift_amount is zero or, if scaled
, a value determined by the size of the operand.
The resulting operand has data size size
(must be an OPSZ_ constant). Both base_reg
and index_reg
must be DR_REG_ constants. Either index_reg
must be DR_REG_NULL or disp must be 0.
opnd_t opnd_create_base_disp_arm | ( | reg_id_t | base_reg, |
reg_id_t | index_reg, | ||
dr_shift_type_t | shift_type, | ||
uint | shift_amount, | ||
int | disp, | ||
dr_opnd_flags_t | flags, | ||
opnd_size_t | size | ||
) |
Returns a memory reference operand that refers to either a base register plus or minus a constant displacement:
Or a base register plus or minus an optionally shifted index register:
For an index register, the plus or minus is determined by the presence or absence of DR_OPND_NEGATED in flags
.
The resulting operand has data size size
(must be an OPSZ_ constant). Both base_reg
and index_reg
must be DR_REG_ constants. A negative value for disp
will be converted into a positive value with DR_OPND_NEGATED set in opnd_get_flags(). Either index_reg
must be DR_REG_NULL or disp must be 0.
opnd_t opnd_create_base_disp_ex | ( | reg_id_t | base_reg, |
reg_id_t | index_reg, | ||
int | scale, | ||
int | disp, | ||
opnd_size_t | size, | ||
bool | encode_zero_disp, | ||
bool | force_full_disp, | ||
bool | disp_short_addr | ||
) |
Returns a memory reference operand that refers to the address:
or, in other words,
The operand has data size data_size
(must be a OPSZ_ constant). Both base_reg
and index_reg
must be DR_REG_ constants. scale
must be either 0, 1, 2, 4, or 8. On ARM, a negative value for disp
will be converted into a positive value with DR_OPND_NEGATED set in opnd_get_flags(). On ARM, either index_reg
must be DR_REG_NULL or disp must be 0.
On x86, three boolean parameters give control over encoding optimizations (these are ignored on other architectures):
encode_zero_disp
, a zero value for disp will not be omitted;force_full_disp
, a small value for disp will not occupy only one byte.disp_short_addr
, short (16-bit for 32-bit mode, 32-bit for 64-bit mode) addressing will be used (note that this normally only needs to be specified for an absolute address; otherwise, simply use the desired short registers for base and/or index).(The encoding optimization flags are all false when using opnd_create_base_disp()).
opnd_t opnd_create_far_abs_addr | ( | reg_id_t | seg, |
void * | addr, | ||
opnd_size_t | data_size | ||
) |
Returns a memory reference operand that refers to the address seg:
addr
. The operand has data size data_size
(must be a OPSZ_ constant).
If addr
<= 2^32 (which is always true in 32-bit mode), this routine is equivalent to opnd_create_far_base_disp(seg, DR_REG_NULL, DR_REG_NULL, 0, (int)addr, data_size).
Otherwise, this routine creates a separate operand type with an absolute 64-bit memory address. Such an operand can only be guaranteed to be encodable in absolute form as a load or store from or to the rax (or eax) register. It will automatically be converted to a pc-relative operand (as though opnd_create_far_rel_addr() had been called) if it is used in any other way.
opnd_t opnd_create_far_base_disp | ( | reg_id_t | seg, |
reg_id_t | base_reg, | ||
reg_id_t | index_reg, | ||
int | scale, | ||
int | disp, | ||
opnd_size_t | data_size | ||
) |
Returns a far memory reference operand that refers to the address:
or, in other words,
The operand has data size data_size
(must be a OPSZ_ constant). seg
must be a DR_SEG_ constant. Both base_reg
and index_reg
must be DR_REG_ constants. scale
must be either 0, 1, 2, 4, or 8. On ARM, a negative value for disp
will be converted into a positive value with DR_OPND_NEGATED set in opnd_get_flags(). On ARM, either index_reg
must be DR_REG_NULL or disp must be 0.
opnd_t opnd_create_far_base_disp_ex | ( | reg_id_t | seg, |
reg_id_t | base_reg, | ||
reg_id_t | index_reg, | ||
int | scale, | ||
int | disp, | ||
opnd_size_t | size, | ||
bool | encode_zero_disp, | ||
bool | force_full_disp, | ||
bool | disp_short_addr | ||
) |
Returns a far memory reference operand that refers to the address:
or, in other words,
The operand has data size size
(must be an OPSZ_ constant). seg
must be a DR_SEG_ constant. Both base_reg
and index_reg
must be DR_REG_ constants. scale must be either 0, 1, 2, 4, or 8. On ARM, a negative value for disp
will be converted into a positive value with DR_OPND_NEGATED set in opnd_get_flags(). On ARM, either index_reg
must be DR_REG_NULL or disp must be 0.
On x86, three boolean parameters give control over encoding optimizations (these are ignored on ARM):
encode_zero_disp
, a zero value for disp will not be omitted;force_full_disp
, a small value for disp will not occupy only one byte.disp_short_addr
, short (16-bit for 32-bit mode, 32-bit for 64-bit mode) addressing will be used (note that this normally only needs to be specified for an absolute address; otherwise, simply use the desired short registers for base and/or index).(All of these are false when using opnd_create_far_base_disp()).
Returns a far instr_t pointer address with value seg_selector:instr
. seg_selector
is a segment selector, not a DR_SEG_ constant.
opnd_t opnd_create_far_pc | ( | ushort | seg_selector, |
app_pc | pc | ||
) |
Returns a far program address operand with value seg_selector:pc
. seg_selector
is a segment selector, not a DR_SEG_ constant.
opnd_t opnd_create_far_rel_addr | ( | reg_id_t | seg, |
void * | addr, | ||
opnd_size_t | data_size | ||
) |
Returns a memory reference operand that refers to the address seg
: addr
, but will be encoded as a pc-relative address. It is up to the caller to ensure that the resulting address is reachable via a 32-bit signed displacement from the next instruction at emit time.
DR guarantees that all of its code caches, all client libraries and Extensions (though not copies of system libraries), and all client memory allocated through dr_thread_alloc(), dr_global_alloc(), dr_nonheap_alloc(), or dr_custom_alloc() with DR_ALLOC_CACHE_REACHABLE, can reach each other with a 32-bit displacement. Thus, any normally-allocated data or any static data or code in a client library is guaranteed to be reachable from code cache code. Memory allocated through system libraries (including malloc, operator new, and HeapAlloc) is not guaranteed to be reachable: only memory directly allocated via DR's API. The runtime option -reachable_heap can be used to guarantee that all memory is reachable.
If addr
is not pc-reachable at encoding time and this operand is used in a load or store to or from the rax (or eax) register, an absolute form will be used (as though opnd_create_far_abs_addr() had been called).
The operand has data size data_size
(must be a OPSZ_ constant).
To represent a 32-bit address (i.e., what an address size prefix indicates), simply zero out the top 32 bits of the address before passing it to this routine.
opnd_t opnd_create_immed_float | ( | float | f | ) |
Returns an immediate float operand with value f
. The caller's code should use proc_save_fpstate() or be inside a clean call that has requested to preserve the floating-point state.
opnd_t opnd_create_immed_int | ( | ptr_int_t | i, |
opnd_size_t | data_size | ||
) |
Returns a signed immediate integer operand with value i
and size data_size
; data_size
must be a OPSZ_ constant.
opnd_t opnd_create_immed_int64 | ( | int64 | i, |
opnd_size_t | data_size | ||
) |
Returns an unsigned immediate integer operand with value i
and size data_size
; data_size
must be a OPSZ_ constant. This operand can be distinguished from a regular immediate integer operand by the flag DR_OPND_MULTI_PART in opnd_get_flags() which tells the caller to use opnd_get_immed_int64() to retrieve the full value.
opnd_t opnd_create_immed_uint | ( | ptr_uint_t | i, |
opnd_size_t | data_size | ||
) |
Returns an unsigned immediate integer operand with value i
and size data_size
; data_size
must be a OPSZ_ constant.
Returns an operand whose value will be the encoded address of instr
. This operand can be used as an immediate integer or as a direct call or jump target. Its size is always OPSZ_PTR.
opnd_t opnd_create_instr_ex | ( | instr_t * | instr, |
opnd_size_t | size, | ||
ushort | shift | ||
) |
Returns an operand whose value will be the encoded address of instr
. This operand can be used as an immediate integer or as a direct call or jump target. Its size is the specified size
. Its value can be optionally right-shifted by shift
from the encoded address.
opnd_t opnd_create_mem_instr | ( | instr_t * | instr, |
short | disp, | ||
opnd_size_t | data_size | ||
) |
Returns a memory reference operand whose value will be the encoded address of instr
plus the 16-bit displacement disp
. For 32-bit mode, it will be encoded just like an absolute address (opnd_create_abs_addr()); for 64-bit mode, it will be encoded just like a pc-relative address (opnd_create_rel_addr()). This operand can be used anywhere a regular memory operand can be used. Its size is data_size
.
INSTR_INLINE opnd_t opnd_create_null | ( | void | ) |
Returns an empty operand.
INSTR_INLINE opnd_t opnd_create_pc | ( | app_pc | pc | ) |
Returns a program address operand with value pc
.
Returns a register operand (r
must be a DR_REG_ constant).
INSTR_INLINE opnd_t opnd_create_reg_ex | ( | reg_id_t | r, |
opnd_size_t | subsize, | ||
dr_opnd_flags_t | flags | ||
) |
Returns a register operand with additional properties specified by flags
. If subsize
is 0, creates a full-sized register; otherwise, creates a partial register in the manner of opnd_create_reg_partial().
INSTR_INLINE opnd_t opnd_create_reg_partial | ( | reg_id_t | r, |
opnd_size_t | subsize | ||
) |
Returns a register operand corresponding to a part of the register represented by the DR_REG_ constant r
.
On x86, r
must be a multimedia (mmx, xmm, or ymm) register. For partial general-purpose registers on x86, use the appropriate sub-register name with opnd_create_reg() instead.
opnd_t opnd_create_rel_addr | ( | void * | addr, |
opnd_size_t | data_size | ||
) |
Returns a memory reference operand that refers to the address addr
, but will be encoded as a pc-relative address. At emit time, if addr
is out of reach of the maximum encodable displacement (signed 32-bit for x86) from the next instruction, encoding will fail.
DR guarantees that all of its code caches, all client libraries and Extensions (though not copies of system libraries), and all client memory allocated through dr_thread_alloc(), dr_global_alloc(), dr_nonheap_alloc(), or dr_custom_alloc() with DR_ALLOC_CACHE_REACHABLE, can reach each other with a 32-bit displacement. Thus, any normally-allocated data or any static data or code in a client library is guaranteed to be reachable from code cache code. Memory allocated through system libraries (including malloc, operator new, and HeapAlloc) is not guaranteed to be reachable: only memory directly allocated via DR's API. The runtime option -reachable_heap can be used to guarantee that all memory is reachable.
On x86, if addr
is not pc-reachable at encoding time and this operand is used in a load or store to or from the rax (or eax) register, an absolute form will be used (as though opnd_create_abs_addr() had been called).
The operand has data size data_size (must be a OPSZ_ constant).
To represent a 32-bit address (i.e., what an address size prefix indicates), simply zero out the top 32 bits of the address before passing it to this routine.
On ARM, the resulting operand will not contain an explicit PC register, and thus will not return true on queries to whether the operand reads the PC. Explicit use of opnd_is_rel_addr() is required. However, DR does not decode any PC-using instructions into this type of relative address operand: decoding will always produce a regular base + displacement operand.
Returns true iff def
, considered as a write, affects use
. Is conservative, so if both def
and use
are memory references, will return true unless it can disambiguate them based on their registers and displacement.
void opnd_disassemble | ( | void * | drcontext, |
opnd_t | opnd, | ||
file_t | outfile | ||
) |
Prints the operand opnd
to file outfile
. The default is to use DR's custom syntax (see disassemble_set_syntax()).
size_t opnd_disassemble_to_buffer | ( | void * | drcontext, |
opnd_t | opnd, | ||
char * | buf, | ||
size_t | bufsz | ||
) |
Prints the operand opnd
to the buffer buf
. Always null-terminates, and will not print more than bufsz
characters, which includes the final null character. Returns the number of characters printed, not including the final null. The default is to use DR's custom syntax (see disassemble_set_syntax()).
void* opnd_get_addr | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) absolute or pc-relative memory reference, or a base+disp memory reference with no base or index register. Returns opnd's
absolute address (which will be pc-relativized on encoding for pc-relative memory references).
Assumes opnd
is a (near or far) base+disp memory reference. Returns the base register (a DR_REG_ constant).
int opnd_get_disp | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) base+disp memory reference. Returns the displacement. On ARM, the displacement is always a non-negative value, and the presence or absence of DR_OPND_NEGATED in opnd_get_flags() determines whether to add or subtract from the base register.
dr_opnd_flags_t opnd_get_flags | ( | opnd_t | opnd | ) |
Assumes opnd
is a register operand, base+disp memory reference, or an immediate integer. Returns the flags describing additional properties of the register, the index register or displacement component of the memory reference, or the immediate operand opnd
.
float opnd_get_immed_float | ( | opnd_t | opnd | ) |
Assumes opnd
is an immediate float and returns its value. The caller's code should use proc_save_fpstate() or be inside a clean call that has requested to preserve the floating-point state.
ptr_int_t opnd_get_immed_int | ( | opnd_t | opnd | ) |
Assumes opnd is an immediate integer and returns its value.
int64 opnd_get_immed_int64 | ( | opnd_t | opnd | ) |
Assumes opnd is an immediate integer with DR_OPND_MULTI_PART set. Returns its value.
Assumes opnd
is a (near or far) base+disp memory reference. Returns the index register (a DR_REG_ constant).
dr_extend_type_t opnd_get_index_extend | ( | opnd_t | opnd, |
OUT bool * | scaled, | ||
OUT uint * | amount | ||
) |
Assumes opnd
is a base+disp memory reference. Returns the extension type, whether the offset is scaled
, and the shift amount
. The register offset will be extended, then shifted, then added to the base register. If there is no extension and no shift the values returned will be DR_EXTEND_UXTX, false, and zero.
dr_shift_type_t opnd_get_index_shift | ( | opnd_t | opnd, |
uint *amount | OUT | ||
) |
Assumes opnd
is a (near or far) base+disp memory reference. Returns DR_SHIFT_NONE if the index register is not shifted. Returns the shift type and amount
if the index register is shifted (this shift will occur prior to being added to or subtracted from the base register).
Assumes opnd
is an instr_t (near, far, or memory) operand and returns its value.
short opnd_get_mem_instr_disp | ( | opnd_t | opnd | ) |
Assumes opnd
is a memory instr operand. Returns its displacement.
app_pc opnd_get_pc | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) program address and returns its value.
Assumes opnd
is a register operand. Returns the register it refers to (a DR_REG_ constant).
Used in conjunction with opnd_num_regs_used(), this routine can be used to iterate through all registers used by opnd
. The index values begin with 0 and proceed through opnd_num_regs_used(opnd)-1.
int opnd_get_scale | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) base+disp memory reference. Returns the scale.
Assumes opnd
is a (near or far) memory reference of any type. Returns opnd's
segment (a DR_SEG_ constant), or DR_REG_NULL if it is a near memory reference.
ushort opnd_get_segment_selector | ( | opnd_t | opnd | ) |
Assumes opnd
is a far program address. Returns opnd's
segment, a segment selector (not a DR_SEG_ constant).
ushort opnd_get_shift | ( | opnd_t | opnd | ) |
Assumes opnd
is a near instr_t operand and returns its shift value.
opnd_size_t opnd_get_size | ( | opnd_t | opnd | ) |
Return the data size of opnd
as a OPSZ_ constant. Returns OPSZ_NA if opnd
does not have a valid size.
bool opnd_is_abs_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) absolute address operand. Returns true for both base-disp operands with no base or index and 64-bit non-base-disp absolute address operands.
bool opnd_is_base_disp | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) base+disp memory reference operand.
bool opnd_is_disp_encode_zero | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) base+disp memory reference; returns whether encode_zero_disp has been specified for opnd
.
bool opnd_is_disp_force_full | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) base+disp memory reference; returns whether force_full_disp has been specified for opnd
.
bool opnd_is_disp_short_addr | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) base+disp memory reference; returns whether disp_short_addr has been specified for opnd
.
bool opnd_is_far_abs_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far absolute address operand. Returns true for both base-disp operands with no base or index and 64-bit non-base-disp absolute address operands.
INSTR_INLINE bool opnd_is_far_base_disp | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far base+disp memory reference operand.
bool opnd_is_far_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far instr_t pointer address operand.
bool opnd_is_far_memory_reference | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far memory reference operand of any type: base-disp, absolute address, or pc-relative address.
bool opnd_is_far_pc | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far program address operand.
INSTR_INLINE bool opnd_is_far_rel_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far pc-relative memory reference operand.
INSTR_INLINE bool opnd_is_immed | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an immediate (integer or float) operand.
bool opnd_is_immed_float | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an immediate float operand.
bool opnd_is_immed_int | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an immediate integer operand.
bool opnd_is_immed_int64 | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a special 64-bit immediate integer operand on a 32-bit architecture.
INSTR_INLINE bool opnd_is_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) instr_t pointer address operand.
bool opnd_is_mem_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a memory reference to an instr_t address operand.
bool opnd_is_memory_reference | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) memory reference operand of any type: base-disp, absolute address, or pc-relative address.
This routine (along with all other opnd_ routines) does consider multi-byte nops that use addressing operands, or the OP_lea instruction's source operand, to be memory references: i.e., it only considers whether the operand calculates an address. Use instr_reads_memory() to operate on a higher semantic level and rule out these corner cases.
bool opnd_is_near_abs_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near (i.e., default segment) absolute address operand. Returns true for both base-disp operands with no base or index and 64-bit non-base-disp absolute address operands.
INSTR_INLINE bool opnd_is_near_base_disp | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near (i.e., default segment) base+disp memory reference operand.
bool opnd_is_near_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near instr_t pointer address operand.
bool opnd_is_near_memory_reference | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near memory reference operand of any type: base-disp, absolute address, or pc-relative address.
bool opnd_is_near_pc | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near (i.e., default segment) program address operand.
INSTR_INLINE bool opnd_is_near_rel_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near (i.e., default segment) pc-relative memory reference operand.
bool opnd_is_null | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an empty operand.
INSTR_INLINE bool opnd_is_pc | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) program address operand.
bool opnd_is_reg | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a register operand.
bool opnd_is_reg_32bit | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a register operand that refers to a 32-bit general-purpose register.
bool opnd_is_reg_64bit | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a register operand that refers to a 64-bit general-purpose register.
bool opnd_is_reg_partial | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a partial multimedia register operand.
bool opnd_is_reg_pointer_sized | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a register operand that refers to a pointer-sized general-purpose register.
bool opnd_is_rel_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) pc-relative memory reference operand. Returns true for base-disp operands on ARM that use the PC as the base register.
bool opnd_is_vsib | ( | opnd_t | opnd | ) |
Returns true iff opnd
uses vector indexing via a VSIB byte. This memory addressing form was introduced in Intel AVX2.
int opnd_num_regs_used | ( | opnd_t | opnd | ) |
Returns the number of registers referred to by opnd
. This will only be non-zero for register operands and memory references.
Assumes that both old_reg
and new_reg
are DR_REG_ constants. Replaces all occurrences of old_reg
in *opnd
with new_reg
.
Returns true iff op1
and op2
are indistinguishable. If either uses variable operand sizes, the default size is assumed.
Returns true iff op1
and op2
are both memory references and they are indistinguishable, ignoring data size.
void opnd_set_disp | ( | opnd_t * | opnd, |
int | disp | ||
) |
Set the displacement of a memory reference operand opnd
to disp
. On ARM, a negative value for disp
will be converted into a positive value with DR_OPND_NEGATED set in opnd_get_flags().
void opnd_set_disp_ex | ( | opnd_t * | opnd, |
int | disp, | ||
bool | encode_zero_disp, | ||
bool | force_full_disp, | ||
bool | disp_short_addr | ||
) |
Set the displacement and the encoding controls of a memory reference operand:
encode_zero_disp
, a zero value for disp
will not be omitted;force_full_disp
, a small value for disp
will not occupy only one byte.disp_short_addr
, short (16-bit for 32-bit mode, 32-bit for 64-bit mode) addressing will be used (note that this normally only needs to be specified for an absolute address; otherwise, simply use the desired short registers for base and/or index). void opnd_set_flags | ( | opnd_t * | opnd, |
dr_opnd_flags_t | flags | ||
) |
Assumes opnd
is a register operand, base+disp memory reference, or an immediate integer. Sets the flags describing additional properties of the operand to flags
.
bool opnd_set_index_extend | ( | opnd_t * | opnd, |
dr_extend_type_t | extend, | ||
bool | scaled | ||
) |
Assumes opnd
is a base+disp memory reference. Sets the index register to be extended by extend
and optionally scaled
. Returns whether successful. If the offset is scaled the amount it is shifted by is determined by the size of the memory operand.
bool opnd_set_index_shift | ( | opnd_t * | opnd, |
dr_shift_type_t | shift, | ||
uint | amount | ||
) |
Assumes opnd
is a near base+disp memory reference. Sets the index register to be shifted by amount
according to shift
. Returns whether successful. If the shift amount is out of allowed ranges, returns false.
void opnd_set_size | ( | opnd_t * | opnd, |
opnd_size_t | newsize | ||
) |
Sets the data size of opnd
. Assumes opnd
is an immediate integer, a memory reference, or an instr_t pointer address operand.
Returns true iff there exists some register that is referred to (directly or overlapping) by both op1
and op2
.
Shrinks all 32-bit registers in opnd
to their 16-bit versions. Also shrinks the size of immediate integers and memory references from OPSZ_4 to OPSZ_2.
Shrinks all 64-bit registers in opnd
to their 32-bit versions. Also shrinks the size of immediate integers and memory references from OPSZ_8 to OPSZ_4.
opnd_size_t opnd_size_from_bytes | ( | uint | bytes | ) |
Returns the appropriate OPSZ_ constant for the given number of bytes. Returns OPSZ_NA if there is no such constant. The intended use case is something like "opnd_size_in_bytes(sizeof(foo))" for integer/pointer types. This routine returns simple single-size types and will not return complex/variable size types.
uint opnd_size_in_bits | ( | opnd_size_t | size | ) |
Assumes size
is an OPSZ_ constant, typically obtained from opnd_get_size() or reg_get_size(). Returns the number of bits the OPSZ_ constant represents. If OPSZ_ is a variable-sized size, returns the default size, which may or may not match the actual size decided up on at encoding time (that final size depends on other operands).
uint opnd_size_in_bytes | ( | opnd_size_t | size | ) |
Assumes size
is an OPSZ_ constant, typically obtained from opnd_get_size() or reg_get_size(). Returns the number of bytes the OPSZ_ constant represents. If OPSZ_ is a variable-sized size, returns the default size, which may or may not match the actual size decided up on at encoding time (that final size depends on other operands).
Assumes that reg
is a DR_REG_ constant. Returns true iff opnd
refers to reg directly or refers to a register that overlaps reg
(e.g., DR_REG_AX overlaps DR_REG_EAX).
Assumes that reg
is a DR_REG_ 32-bit register constant. Returns the 16-bit version of reg
.
Assumes that reg
is a DR_REG_ 32-bit register constant. Returns the 64-bit version of reg
.
Assumes that reg
is a DR_REG_ 32-bit register constant. Returns the 8-bit version of reg
(the least significant byte: DR_REG_AL instead of DR_REG_AH if passed DR_REG_EAX, e.g.). For 32-bit DR builds, returns DR_REG_NULL if passed DR_REG_ESP, DR_REG_EBP, DR_REG_ESI, or DR_REG_EDI.
reg_id_t reg_32_to_opsz | ( | reg_id_t | reg, |
opnd_size_t | sz | ||
) |
Assumes that reg
is a DR_REG_ 32-bit register constant. If sz
== OPSZ_2, returns the 16-bit version of reg
. For 64-bit versions of this library, if sz
== OPSZ_8, returns the 64-bit version of reg
. Returns DR_REG_NULL
when trying to get the 8-bit subregister of DR_REG_ESI
, DR_REG_EDI
, DR_REG_EBP
, or DR_REG_ESP
in 32-bit mode.
Assumes that reg
is a DR_REG_ 64-bit register constant. Returns the 32-bit version of reg
.
byte reg_get_bits | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns reg's
representation as 3 bits in a modrm byte (the 3 bits are the lower-order bits in the return value).
opnd_size_t reg_get_size | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns the OPSZ_ constant corresponding to the register size. Returns OPSZ_NA if reg is not a DR_REG_ constant.
reg_t reg_get_value | ( | reg_id_t | reg, |
dr_mcontext_t * | mc | ||
) |
Returns the value of the register reg
, selected from the passed-in register values. Supports only general-purpose registers. mc->flags
must include DR_MC_CONTROL and DR_MC_INTEGER.
bool reg_get_value_ex | ( | reg_id_t | reg, |
dr_mcontext_t * | mc, | ||
OUT byte * | val | ||
) |
Returns the value of the register reg
as stored in mc
, or for an mmx register as stored in the physical register. Up to sizeof(dr_ymm_t) bytes will be written to val
.
This routine does not support floating-point registers.
mc->flags
must include the appropriate flag for the requested register. bool reg_is_32bit | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a 32-bit general-purpose register.
bool reg_is_64bit | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a 64-bit general-purpose register.
bool reg_is_extended | ( | reg_id_t | reg | ) |
Returns true iff reg
refers to an extended register only available in 64-bit mode and not in 32-bit mode (e.g., R8-R15, XMM8-XMM15, etc.)
bool reg_is_fp | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a floating-point register.
bool reg_is_gpr | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a General Purpose Register, i.e., rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, or a subset.
bool reg_is_mmx | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to an mmx (64-bit) register.
bool reg_is_pointer_sized | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a pointer-sized general-purpose register.
bool reg_is_segment | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a segment (i.e., it's really a DR_SEG_ constant).
bool reg_is_simd | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a multimedia register used for SIMD instructions.
bool reg_is_stolen | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff reg
is stolen by DynamoRIO for internal use.
bool reg_is_xmm | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to an xmm (128-bit SSE/SSE2) register or a ymm (256-bit multimedia) register.
bool reg_is_ymm | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a ymm (256-bit multimedia) register.
Assumes that r1
and r2
are both DR_REG_ constants. Returns true iff r1's
register overlaps r2's
register (e.g., if r1
== DR_REG_AX and r2
== DR_REG_EAX).
int reg_parameter_num | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ register constant. If reg is used as part of the calling convention, returns which parameter ordinal it matches (0-based); otherwise, returns -1.
reg_id_t reg_resize_to_opsz | ( | reg_id_t | reg, |
opnd_size_t | sz | ||
) |
Given a general-purpose register of any size, returns a register in the same class of the given size. For example, given DR_REG_AX
or DR_REG_RAX
and OPSZ_1
, this routine will return DR_REG_AL
. Returns DR_REG_NULL
when trying to get the 8-bit subregister of DR_REG_ESI
, DR_REG_EDI
, DR_REG_EBP
, or DR_REG_ESP
in 32-bit mode. For 64-bit versions of this library, if sz
== OPSZ_8, returns the 64-bit version of reg
.
void reg_set_value | ( | reg_id_t | reg, |
dr_mcontext_t * | mc, | ||
reg_t | value | ||
) |
Sets the register reg
in the passed in mcontext mc
to value
. mc->flags
must include DR_MC_CONTROL and DR_MC_INTEGER.