DynamoRIO
|
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_pred_constr_type_t | dr_pred_constr_type_t |
typedef enum _dr_pred_type_t | dr_pred_type_t |
typedef enum _dr_opnd_flags_t | dr_opnd_flags_t |
Detailed Description
Functions and defines to create and manipulate instruction operands.
Macro Definition Documentation
◆ DR_NUM_GPR_REGS
#define DR_NUM_GPR_REGS (DR_REG_STOP_GPR - DR_REG_START_GPR + 1) |
Number of general registers
◆ DR_NUM_SIMD_VECTOR_REGS
#define DR_NUM_SIMD_VECTOR_REGS (DR_REG_STOP_ZMM - DR_REG_START_ZMM + 1) |
The number of SIMD vector registers.
◆ DR_REG_LAST_ENUM
#define DR_REG_LAST_ENUM DR_REG_BND3 |
Last value of register enums
◆ DR_REG_LAST_VALID_ENUM
#define DR_REG_LAST_VALID_ENUM DR_REG_K7 |
Last valid register enum value. Note: DR_REG_INVALID is now smaller than this value.
◆ DR_REG_START_16
#define DR_REG_START_16 DR_REG_AX |
Start of 16-bit general register enum values \
◆ DR_REG_START_32
#define DR_REG_START_32 DR_REG_EAX |
Start of 32-bit general register enum values
◆ DR_REG_START_64
#define DR_REG_START_64 DR_REG_RAX |
Start of 64-bit general register enum values
◆ DR_REG_START_8
#define DR_REG_START_8 DR_REG_AL |
Start of 8-bit general register enum values
◆ DR_REG_START_8HL
#define DR_REG_START_8HL DR_REG_AL |
Start of 8-bit high-low register enum values
◆ DR_REG_START_BND
#define DR_REG_START_BND DR_REG_BND0 |
Start of bounds register enum values
◆ DR_REG_START_CR
#define DR_REG_START_CR DR_REG_CR0 |
Start of control register enum values
◆ DR_REG_START_DR
#define DR_REG_START_DR DR_REG_DR0 |
Start of debug register enum values
◆ DR_REG_START_FLOAT
#define DR_REG_START_FLOAT DR_REG_ST0 |
Start of floating-point-register enum values
◆ DR_REG_START_GPR
#define DR_REG_START_GPR DR_REG_XAX |
Start of general register enum values
◆ DR_REG_START_MMX
#define DR_REG_START_MMX DR_REG_MM0 |
Start of mmx register enum values
◆ DR_REG_START_OPMASK
#define DR_REG_START_OPMASK DR_REG_K0 |
Start of opmask register enum values
◆ DR_REG_START_SEGMENT
#define DR_REG_START_SEGMENT DR_SEG_ES |
Start of segment register enum values
◆ DR_REG_START_SEGMENT_x64
#define DR_REG_START_SEGMENT_x64 DR_SEG_FS |
Start of segment register enum values for x64
◆ DR_REG_START_x64_8
#define DR_REG_START_x64_8 DR_REG_SPL |
Start of 8-bit x64-only register enum values
◆ DR_REG_START_x86_8
#define DR_REG_START_x86_8 DR_REG_AH |
Start of 8-bit x86-only register enum values
◆ DR_REG_START_XMM
#define DR_REG_START_XMM DR_REG_XMM0 |
Start of sse xmm register enum values
◆ DR_REG_START_YMM
#define DR_REG_START_YMM DR_REG_YMM0 |
Start of ymm register enum values
◆ DR_REG_START_ZMM
#define DR_REG_START_ZMM DR_REG_ZMM0 |
Start of zmm register enum values
◆ DR_REG_STOP_16
#define DR_REG_STOP_16 DR_REG_R15W |
End of 16-bit general register enum values \
◆ DR_REG_STOP_32
#define DR_REG_STOP_32 DR_REG_R15D |
End of 32-bit general register enum values \
◆ DR_REG_STOP_64
#define DR_REG_STOP_64 DR_REG_R15 |
End of 64-bit general register enum values
◆ DR_REG_STOP_8
#define DR_REG_STOP_8 DR_REG_DIL |
End of 8-bit general register enum values
◆ DR_REG_STOP_8HL
#define DR_REG_STOP_8HL DR_REG_BH |
End of 8-bit high-low register enum values
◆ DR_REG_STOP_BND
#define DR_REG_STOP_BND DR_REG_BND3 |
End of bounds register enum values
◆ DR_REG_STOP_CR
#define DR_REG_STOP_CR DR_REG_CR15 |
End of control register enum values
◆ DR_REG_STOP_DR
#define DR_REG_STOP_DR DR_REG_DR15 |
End of debug register enum values
◆ DR_REG_STOP_FLOAT
#define DR_REG_STOP_FLOAT DR_REG_ST7 |
End of floating-point-register enum values
◆ DR_REG_STOP_GPR
#define DR_REG_STOP_GPR DR_REG_R15 |
End of general register enum values
◆ DR_REG_STOP_MMX
#define DR_REG_STOP_MMX DR_REG_MM7 |
End of mmx register enum values
◆ DR_REG_STOP_OPMASK
#define DR_REG_STOP_OPMASK DR_REG_K7 |
End of opmask register enum values
◆ DR_REG_STOP_SEGMENT
#define DR_REG_STOP_SEGMENT DR_SEG_GS |
End of segment register enum values
◆ DR_REG_STOP_x64_8
#define DR_REG_STOP_x64_8 DR_REG_DIL |
Stop of 8-bit x64-only register enum values
◆ DR_REG_STOP_x86_8
#define DR_REG_STOP_x86_8 DR_REG_BH |
Stop of 8-bit x86-only register enum values
◆ DR_REG_STOP_XMM
#define DR_REG_STOP_XMM DR_REG_XMM31 |
End of sse xmm register enum values
◆ DR_REG_STOP_YMM
#define DR_REG_STOP_YMM DR_REG_YMM31 |
End of ymm register enum values
◆ DR_REG_STOP_ZMM
#define DR_REG_STOP_ZMM DR_REG_ZMM31 |
End of zmm register enum values
◆ DR_REG_XAX
#define DR_REG_XAX DR_REG_RAX |
Platform-independent way to refer to rax/eax.
◆ DR_REG_XBP
#define DR_REG_XBP DR_REG_RBP |
Platform-independent way to refer to rbp/ebp.
◆ DR_REG_XBX
#define DR_REG_XBX DR_REG_RBX |
Platform-independent way to refer to rbx/ebx.
◆ DR_REG_XCX
#define DR_REG_XCX DR_REG_RCX |
Platform-independent way to refer to rcx/ecx.
◆ DR_REG_XDI
#define DR_REG_XDI DR_REG_RDI |
Platform-independent way to refer to rdi/edi.
◆ DR_REG_XDX
#define DR_REG_XDX DR_REG_RDX |
Platform-independent way to refer to rdx/edx.
◆ DR_REG_XSI
#define DR_REG_XSI DR_REG_RSI |
Platform-independent way to refer to rsi/esi.
◆ DR_REG_XSP
#define DR_REG_XSP DR_REG_RSP |
Platform-independent way to refer to rsp/esp.
◆ OPSZ_bnd
#define OPSZ_bnd OPSZ_0 |
Operand size for bndldx, bndstx memory reference.
◆ OPSZ_bound
#define OPSZ_bound OPSZ_8_short4 |
Operand size for bound memory reference.
◆ OPSZ_call
#define OPSZ_call OPSZ_ret |
Operand size for push portion of call.
◆ OPSZ_clflush
#define OPSZ_clflush OPSZ_1 |
Operand size for clflush memory reference.
◆ OPSZ_fldenv
#define OPSZ_fldenv OPSZ_28_short14 |
Operand size for fldenv memory reference.
◆ OPSZ_fnsave
#define OPSZ_fnsave OPSZ_108_short94 |
Operand size for fnsave memory reference.
◆ OPSZ_fnstenv
#define OPSZ_fnstenv OPSZ_28_short14 |
Operand size for fnstenv memory reference.
◆ OPSZ_frstor
#define OPSZ_frstor OPSZ_108_short94 |
Operand size for frstor memory reference.
◆ OPSZ_fxrstor
#define OPSZ_fxrstor OPSZ_512 |
Operand size for fxrstor memory reference.
◆ OPSZ_fxsave
#define OPSZ_fxsave OPSZ_512 |
Operand size for fxsave memory reference.
◆ OPSZ_invlpg
#define OPSZ_invlpg OPSZ_0 |
Operand size for invlpg memory reference.
◆ OPSZ_lea
#define OPSZ_lea OPSZ_0 |
Operand size for lea memory reference.
◆ OPSZ_lgdt
#define OPSZ_lgdt OPSZ_6x10 |
Operand size for lgdt memory reference.
◆ OPSZ_lidt
#define OPSZ_lidt OPSZ_6x10 |
Operand size for lidt memory reference.
◆ OPSZ_maskmovdqu
#define OPSZ_maskmovdqu OPSZ_16 |
Operand size for maskmovdqu memory reference.
◆ OPSZ_maskmovq
#define OPSZ_maskmovq OPSZ_8 |
Operand size for maskmovq memory reference.
◆ OPSZ_prefetch
#define OPSZ_prefetch OPSZ_1 |
Operand size for prefetch memory references.
◆ OPSZ_PTR
#define OPSZ_PTR OPSZ_8 |
Operand size for pointer values.
◆ OPSZ_PTR_DBL
#define OPSZ_PTR_DBL OPSZ_16 |
Double-pointer-sized.
◆ OPSZ_PTR_HALF
#define OPSZ_PTR_HALF OPSZ_4 |
Half-pointer-sized.
◆ OPSZ_ptwrite
#define OPSZ_ptwrite OPSZ_4_rex8 |
Operand size for ptwrite memory reference.
◆ OPSZ_ret
#define OPSZ_ret OPSZ_4x8_short2xi8 |
Operand size for ret instruction.
◆ OPSZ_sgdt
#define OPSZ_sgdt OPSZ_6x10 |
Operand size for sgdt memory reference.
◆ OPSZ_sidt
#define OPSZ_sidt OPSZ_6x10 |
Operand size for sidt memory reference.
◆ OPSZ_STACK
#define OPSZ_STACK OPSZ_8 |
Operand size for stack push/pop operand sizes.
◆ OPSZ_sys
#define OPSZ_sys OPSZ_1 |
Operand size for sys instruction memory reference.
◆ OPSZ_VARSTACK
#define OPSZ_VARSTACK OPSZ_4x8_short2 |
Operand size for prefix-varying stack \ push/pop operand sizes.
◆ OPSZ_xlat
#define OPSZ_xlat OPSZ_1 |
Operand size for xlat memory reference.
Typedef Documentation
◆ dr_extend_type_t
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.
◆ dr_opnd_flags_t
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.
◆ dr_pred_constr_type_t
typedef enum _dr_pred_constr_type_t dr_pred_constr_type_t |
These flags describe the values for "pattern" operands for aarch64 predicate count instructions. They are always set for imms with the flag DR_OPND_IS_PREDICATE_CONSTRAINT
◆ dr_pred_type_t
typedef enum _dr_pred_type_t dr_pred_type_t |
Triggers used for conditionally executed instructions.
◆ dr_shift_type_t
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.
◆ opnd_size_t
typedef byte opnd_size_t |
The type of an OPSZ_ enum value.
◆ reg_id_t
typedef ushort reg_id_t |
The type of a DR_REG_ enum value.
Enumeration Type Documentation
◆ anonymous enum
anonymous enum |
◆ anonymous enum
anonymous enum |
Register identifiers.
◆ anonymous enum
anonymous enum |
Virtual register identifiers for DR_ISA_REGDEPS.
Enumerator | |
---|---|
DR_REG_VIRT0 | The first virtual register. Note that all virtual registers named here are valid. |
◆ _dr_extend_type_t
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.
◆ _dr_opnd_flags_t
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_DEFAULT | Default (no additional flags). |
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. |
DR_OPND_IS_VECTOR | Registers with this flag should be considered vectors and have an element size representing their element size. |
DR_OPND_IS_MERGE_PREDICATE | SVE predicate registers can either be merging, zero or neither. If one of these are set then they are either a merge or zero otherwise aren't either. |
DR_OPND_IS_PREDICATE_CONSTRAINT | This immediate integer operand should be treated as an AArch64 SVE predicate constraint |
DR_OPND_IMM_PRINT_DECIMAL | This is used by RISCV64 for immediates display format. |
DR_OPND_IMPLICIT | The register number is not in the instruction encoding but is calculated based on another register |
DR_OPND_IS_GOVERNING | The register is a SVE governing predicate register: it is used to select which elements of a vector are actually read or written to in AArch64 SVE |
◆ _dr_pred_constr_type_t
These flags describe the values for "pattern" operands for aarch64 predicate count instructions. They are always set for imms with the flag DR_OPND_IS_PREDICATE_CONSTRAINT
◆ _dr_pred_type_t
enum _dr_pred_type_t |
Triggers used for conditionally executed instructions.
◆ _dr_shift_type_t
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.
Function Documentation
◆ get_register_name()
const DR_API 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
.
- Note
- It uses the global dcontext_t to determine the ISA mode. If the ISA mode is a synthetic one (e.g., DR_ISA_REGDEPS), it returns the name of a DR_REG_VIRT0 etc. virtual register.
◆ opnd_add_flags()
DR_API 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.
◆ opnd_compute_address()
DR_API 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.
- Note
- This routine does not support vector addressing (via VSIB, introduced in AVX2). Use instr_compute_address(), instr_compute_address_ex(), or instr_compute_address_ex_pos() instead.
◆ opnd_create_abs_addr()
DR_API 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_create_base_disp()
DR_API 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:
- disp(base_reg, index_reg, scale)
or, in other words,
- base_reg + index_reg*scale + disp
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.
Also use this function to create VSIB operands, passing a SIMD register as the index register.
◆ opnd_create_base_disp_aarch64()
DR_API 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 | ||
) |
Same as opnd_create_base_disp_shift_aarch64 but if scaled
is true then the extend amount is calculated from the operand size (otherwise it is zero).
- Note
- AArch64-only.
◆ opnd_create_base_disp_arm()
DR_API 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:
- [base_reg, disp]
Or a base register plus or minus an optionally shifted index register:
- [base_reg, index_reg, shift_type, shift_amount]
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.
- Note
- ARM-only.
◆ opnd_create_base_disp_ex()
DR_API 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:
- disp(base_reg, index_reg, scale)
or, in other words,
- base_reg + index_reg*scale + disp
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):
- If
encode_zero_disp
, a zero value for disp will not be omitted; - If
force_full_disp
, a small value for disp will not occupy only one byte. - If
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_create_base_disp_shift_aarch64()
DR_API opnd_t opnd_create_base_disp_shift_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, | ||
uint | shift | ||
) |
Returns a memory reference operand that refers to either a base register with a constant displacement:
- [base_reg, disp]
Or a base register plus an optionally extended and shifted index register:
- [base_reg, index_reg, extend_type, shift_amount]
If scaled
is enabled, shift
determines the shift amount.
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.
TODO i#3044: WARNING this function may change during SVE development of DynamoRIO. The function will be considered stable when this warning has been removed.
- Note
- AArch64-only.
◆ opnd_create_cond()
DR_API opnd_t opnd_create_cond | ( | dr_pred_type_t | cond | ) |
Returns an unsigned immediate integer operand that can be used as a condition code operand for instructions such as ccmp.
- Parameters
-
cond A dr_pred_type_t value corresponding to a condition code.
◆ opnd_create_far_abs_addr()
DR_API 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_create_far_base_disp()
DR_API 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:
- seg : disp(base_reg, index_reg, scale)
or, in other words,
- seg : base_reg + index_reg*scale + disp
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_create_far_base_disp_ex()
DR_API 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:
- seg : disp(base_reg, index_reg, scale)
or, in other words,
- seg : base_reg + index_reg*scale + disp
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):
- If
encode_zero_disp
, a zero value for disp will not be omitted; - If
force_full_disp
, a small value for disp will not occupy only one byte. - If
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()).
◆ opnd_create_far_instr()
Returns a far instr_t pointer address with value seg_selector:instr
. seg_selector
is a segment selector, not a DR_SEG_ constant.
◆ opnd_create_far_pc()
DR_API 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_create_far_rel_addr()
DR_API 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.
- Note
- For 64-bit X86 DR builds only.
◆ opnd_create_immed_float()
DR_API 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_create_immed_int()
DR_API 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_create_immed_int64()
DR_API 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.
- Note
- 32-bit only: use opnd_create_immed_int() for 64-bit architectures.
◆ opnd_create_immed_pred_constr()
DR_API opnd_t opnd_create_immed_pred_constr | ( | dr_pred_constr_type_t | p | ) |
Returns an immediate operand for use in SVE predicate constraint operands.
◆ opnd_create_immed_uint()
DR_API 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.
◆ opnd_create_increment_reg()
Creates a reg incremented from an existing opnd
by the increment
value, modulo the reg size. Returns the new reg.
◆ opnd_create_instr()
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_create_instr_ex()
DR_API 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_create_mem_instr()
DR_API 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
.
- Note
- This operand will return false to opnd_is_instr(), opnd_is_rel_addr(), and opnd_is_abs_addr(). It is a separate type.
◆ opnd_create_null()
DR_API INSTR_INLINE opnd_t opnd_create_null | ( | void | ) |
Returns an empty operand.
◆ opnd_create_pc()
DR_API INSTR_INLINE opnd_t opnd_create_pc | ( | app_pc | pc | ) |
Returns a program address operand with value pc
.
◆ opnd_create_predicate_reg()
Returns a SVE predicate register for use as a governing predicate with either "/m" merge mode set or "/z" zeroing mode set depending on /p is_merge For creating general (non-governing) predicate registers, use opnd_create_reg() for scalar predicates and opnd_create_reg_element_vector() for vector predicates.
◆ opnd_create_reg()
Returns a register operand (r
must be a DR_REG_ constant).
◆ opnd_create_reg_element_vector()
DR_API INSTR_INLINE opnd_t opnd_create_reg_element_vector | ( | reg_id_t | r, |
opnd_size_t | element_size | ||
) |
Returns a register operand corresponding to a vector register that has an element size.
◆ opnd_create_reg_ex()
DR_API 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().
◆ opnd_create_reg_partial()
DR_API 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, ymm, zmm) register. For partial general-purpose registers on x86, use the appropriate sub-register name with opnd_create_reg() instead.
◆ opnd_create_rel_addr()
DR_API 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.
- Note
- For ARM or 64-bit X86 DR builds only.
◆ opnd_create_vector_base_disp_aarch64()
DR_API opnd_t opnd_create_vector_base_disp_aarch64 | ( | reg_id_t | base_reg, |
reg_id_t | index_reg, | ||
opnd_size_t | element_size, | ||
dr_extend_type_t | extend_type, | ||
bool | scaled, | ||
int | disp, | ||
dr_opnd_flags_t | flags, | ||
opnd_size_t | size, | ||
uint | shift | ||
) |
Same as opnd_create_base_disp_shift_aarch64 but creates an operand that uses vector registers for the base and/or index. At least one of base_reg
and index_reg
should be a vector register. element_size
indicates the element size for any vector registers used and must be one of: OPSZ_4 (single, 32-bit) OPSZ_8 (double, 64-bit)
TODO i#3044: WARNING this function may change during SVE development of DynamoRIO. The function will be considered stable when this warning has been removed.
- Note
- AArch64-only.
◆ opnd_defines_use()
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.
◆ opnd_get_addr()
DR_API 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).
◆ opnd_get_base()
Assumes opnd
is a (near or far) base+disp memory reference. Returns the base register (a DR_REG_ constant).
◆ opnd_get_cond()
DR_API dr_pred_type_t opnd_get_cond | ( | opnd_t | opnd | ) |
Get the dr_pred_type_t value for a condition code operand used in instructions such as ccmp.
◆ opnd_get_disp()
DR_API 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.
◆ opnd_get_flags()
DR_API 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
.
◆ opnd_get_immed_float()
DR_API 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.
◆ opnd_get_immed_int()
DR_API ptr_int_t opnd_get_immed_int | ( | opnd_t | opnd | ) |
Assumes opnd is an immediate integer and returns its value.
◆ opnd_get_immed_int64()
DR_API int64 opnd_get_immed_int64 | ( | opnd_t | opnd | ) |
Assumes opnd is an immediate integer with DR_OPND_MULTI_PART set. Returns its value.
- Note
- 32-bit only.
◆ opnd_get_index()
Assumes opnd
is a (near or far) base+disp memory reference. Returns the index register (a DR_REG_ constant).
◆ opnd_get_index_extend()
DR_API dr_extend_type_t opnd_get_index_extend | ( | opnd_t | opnd, |
DR_PARAM_OUT bool * | scaled, | ||
DR_PARAM_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.
- Note
- AArch64-only.
◆ opnd_get_index_shift()
DR_API dr_shift_type_t opnd_get_index_shift | ( | opnd_t | opnd, |
uint *amount | DR_PARAM_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).
- Note
- ARM-only.
◆ opnd_get_instr()
Assumes opnd
is an instr_t (near, far, or memory) operand and returns its value.
◆ opnd_get_mem_instr_disp()
DR_API short opnd_get_mem_instr_disp | ( | opnd_t | opnd | ) |
Assumes opnd
is a memory instr operand. Returns its displacement.
◆ opnd_get_pc()
DR_API app_pc opnd_get_pc | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) program address and returns its value.
◆ opnd_get_reg()
Assumes opnd
is a register operand. Returns the register it refers to (a DR_REG_ constant).
◆ opnd_get_reg_used()
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.
◆ opnd_get_scale()
DR_API int opnd_get_scale | ( | opnd_t | opnd | ) |
Assumes opnd
is a (near or far) base+disp memory reference. Returns the scale.
- Note
- x86-only. On ARM use opnd_get_index_shift().
◆ opnd_get_segment()
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.
◆ opnd_get_segment_selector()
DR_API 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).
◆ opnd_get_shift()
DR_API ushort opnd_get_shift | ( | opnd_t | opnd | ) |
Assumes opnd
is a near instr_t operand and returns its shift value.
◆ opnd_get_size()
DR_API 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.
- Note
- A register operand may have a size smaller than the full size of its DR_REG_* register specifier.
◆ opnd_get_vector_element_size()
DR_API opnd_size_t opnd_get_vector_element_size | ( | opnd_t | opnd | ) |
Return the element size of opnd
as a OPSZ_ constant. Returns OPSZ_NA if opnd
does not have a valid size.
◆ opnd_invert_immed_int()
Performs a bitwise NOT operation on the integer value in opnd
, but only on the LSB bits provided by opnd_size_in_bits(opnd). opnd
must carry an immed integer.
◆ opnd_is_abs_addr()
DR_API 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.
◆ opnd_is_base_disp()
DR_API bool opnd_is_base_disp | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) base+disp memory reference operand.
◆ opnd_is_disp_encode_zero()
DR_API 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
.
◆ opnd_is_disp_force_full()
DR_API 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
.
◆ opnd_is_disp_short_addr()
DR_API 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
.
◆ opnd_is_element_vector_reg()
DR_API INSTR_INLINE bool opnd_is_element_vector_reg | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a vector reg operand.
◆ opnd_is_far_abs_addr()
DR_API 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.
◆ opnd_is_far_base_disp()
DR_API INSTR_INLINE bool opnd_is_far_base_disp | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far base+disp memory reference operand.
◆ opnd_is_far_instr()
DR_API bool opnd_is_far_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far instr_t pointer address operand.
◆ opnd_is_far_memory_reference()
DR_API 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.
◆ opnd_is_far_pc()
DR_API bool opnd_is_far_pc | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far program address operand.
◆ opnd_is_far_rel_addr()
DR_API INSTR_INLINE bool opnd_is_far_rel_addr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a far pc-relative memory reference operand.
- Note
- For 64-bit x86 DR builds only. Always returns false on ARM.
◆ opnd_is_governing()
DR_API INSTR_INLINE bool opnd_is_governing | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an SVE governing predicate register.
◆ opnd_is_immed()
DR_API INSTR_INLINE bool opnd_is_immed | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an immediate (integer or float) operand.
◆ opnd_is_immed_float()
DR_API bool opnd_is_immed_float | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an immediate float operand.
◆ opnd_is_immed_int()
DR_API bool opnd_is_immed_int | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an immediate integer operand.
◆ opnd_is_immed_int64()
DR_API 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.
◆ opnd_is_instr()
DR_API INSTR_INLINE bool opnd_is_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) instr_t pointer address operand.
◆ opnd_is_mem_instr()
DR_API bool opnd_is_mem_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a memory reference to an instr_t address operand.
◆ opnd_is_memory_reference()
DR_API 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.
◆ opnd_is_near_abs_addr()
DR_API 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.
◆ opnd_is_near_base_disp()
DR_API 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.
◆ opnd_is_near_instr()
DR_API bool opnd_is_near_instr | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near instr_t pointer address operand.
◆ opnd_is_near_memory_reference()
DR_API 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.
◆ opnd_is_near_pc()
DR_API bool opnd_is_near_pc | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a near (i.e., default segment) program address operand.
◆ opnd_is_near_rel_addr()
DR_API 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.
- Note
- For 64-bit x86 DR builds only. Equivalent to opnd_is_rel_addr() for ARM.
◆ opnd_is_null()
DR_API bool opnd_is_null | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an empty operand.
◆ opnd_is_pc()
DR_API INSTR_INLINE bool opnd_is_pc | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a (near or far) program address operand.
◆ opnd_is_predicate_merge()
DR_API INSTR_INLINE bool opnd_is_predicate_merge | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a n SVE merging predicate register.
◆ opnd_is_predicate_reg()
DR_API INSTR_INLINE bool opnd_is_predicate_reg | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an SVE predicate register.
◆ opnd_is_predicate_zero()
DR_API INSTR_INLINE bool opnd_is_predicate_zero | ( | opnd_t | opnd | ) |
Returns true iff opnd
is an SVE zeroing predicate register.
◆ opnd_is_reg()
DR_API bool opnd_is_reg | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a register operand.
◆ opnd_is_reg_32bit()
DR_API 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.
◆ opnd_is_reg_64bit()
DR_API 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.
◆ opnd_is_reg_partial()
DR_API bool opnd_is_reg_partial | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a partial multimedia register operand.
◆ opnd_is_reg_pointer_sized()
DR_API 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.
◆ opnd_is_rel_addr()
DR_API 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.
◆ opnd_is_vector_base_disp()
DR_API bool opnd_is_vector_base_disp | ( | opnd_t | opnd | ) |
Returns true iff opnd
is a base+disp memory reference operand which uses vector registers.
◆ opnd_is_vsib()
DR_API 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.
◆ opnd_num_regs_used()
DR_API 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.
◆ opnd_replace_reg()
Assumes that both old_reg
and new_reg
are DR_REG_ constants. Replaces all occurrences of old_reg
in *opnd
with new_reg
. Only replaces exact matches (use opnd_replace_reg_resize() to match size variants). Returns whether it replaced anything.
◆ opnd_replace_reg_resize()
Replaces all instances of old_reg
(or any size variant) in *opnd
with new_reg
. Resizes new_reg
to match sub-full-size uses of old_reg
. Returns whether it replaced anything.
◆ opnd_same()
Returns true iff op1
and op2
are indistinguishable. If either uses variable operand sizes, the default size is assumed.
◆ opnd_same_address()
Returns true iff op1
and op2
are both memory references and they are indistinguishable, ignoring data size.
◆ opnd_set_disp()
DR_API 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().
◆ opnd_set_disp_ex()
DR_API 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:
- If
encode_zero_disp
, a zero value fordisp
will not be omitted; - If
force_full_disp
, a small value fordisp
will not occupy only one byte. - If
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).- Note
- x86-only.
◆ opnd_set_flags()
DR_API 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
.
◆ opnd_set_index_extend()
DR_API 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 scaled
is zero, the offset is not scaled; otherwise is calculated from the operand size.
- Note
- AArch64-only.
◆ opnd_set_index_extend_value()
DR_API bool opnd_set_index_extend_value | ( | opnd_t * | opnd, |
dr_extend_type_t | extend, | ||
bool | scaled, | ||
uint | scaled_value | ||
) |
Assumes opnd
is a base+disp memory reference. Sets the index register to be extended by extend
and optionally scaled
. Returns whether successful. If scaled
is zero, the offset is not scaled.
- Note
- AArch64-only.
◆ opnd_set_index_shift()
DR_API 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.
- Note
- ARM-only.
◆ opnd_set_size()
DR_API 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.
◆ opnd_share_reg()
Returns true iff there exists some register that is referred to (directly or overlapping) by both op1
and op2
.
◆ opnd_shrink_to_16_bits()
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.
◆ opnd_shrink_to_32_bits()
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.
- Note
- For 64-bit DR builds only.
◆ opnd_size_from_bytes()
DR_API 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.
◆ opnd_size_in_bits()
DR_API 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).
◆ opnd_size_in_bytes()
DR_API 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).
◆ opnd_size_to_shift_amount()
DR_API uint opnd_size_to_shift_amount | ( | opnd_size_t | size | ) |
Returns the left shift amount from size
.
◆ opnd_uses_reg()
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).
◆ reg_32_to_16()
Assumes that reg
is a DR_REG_ 32-bit register constant. Returns the 16-bit version of reg
.
- Note
- x86-only.
◆ reg_32_to_64()
Assumes that reg
is a DR_REG_ 32-bit register constant. Returns the 64-bit version of reg
.
- Note
- For 64-bit DR builds only.
◆ reg_32_to_8()
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.
- Note
- x86-only.
◆ reg_32_to_opsz()
DR_API 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.
- Deprecated:
- Prefer reg_resize_to_opsz() which is more general.
◆ reg_64_to_32()
Assumes that reg
is a DR_REG_ 64-bit register constant. Returns the 32-bit version of reg
.
- Note
- For 64-bit DR builds only.
◆ reg_get_bits()
DR_API 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).
◆ reg_get_size()
DR_API 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_get_value()
DR_API 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.
◆ reg_get_value_ex()
DR_API bool reg_get_value_ex | ( | reg_id_t | reg, |
dr_mcontext_t * | mc, | ||
DR_PARAM_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_zmm_t) bytes will be written to val
.
This routine also supports reading AVX-512 mask registers. In this case, sizeof(dr_opmask_t) bytes will be written to val
.
This routine does not support floating-point registers.
- Note
mc->flags
must include the appropriate flag for the requested register.
◆ reg_is_32bit()
DR_API 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.
◆ reg_is_64bit()
DR_API 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.
◆ reg_is_avx512_extended()
DR_API bool reg_is_avx512_extended | ( | reg_id_t | reg | ) |
Returns true iff reg
refers to an extended AVX-512 register only available in 64-bit mode and not in 32-bit mode (e.g., XMM16-XMM31, ZMM16-ZMM31 etc.)
- Note
- For 64-bit DR builds only.
◆ reg_is_bnd()
DR_API bool reg_is_bnd | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to an x86 MPX bounds register.
◆ reg_is_extended()
DR_API 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. For AVX-512, it also returns true for the upper 8 SIMD registers (e.g., R8-R15, XMM8-XMM15, XMM24-XMM31, ZMM24-ZMM31 etc.)
- Note
- For 64-bit DR builds only.
◆ reg_is_fp()
DR_API 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.
◆ reg_is_gpr()
DR_API 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.
◆ reg_is_mmx()
DR_API 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.
◆ reg_is_opmask()
DR_API bool reg_is_opmask | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to an opmask x86 register.
◆ reg_is_pointer_sized()
DR_API 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 register. reg
is a general purpose register for all architectures apart from AArch64. For AArch64, reg
can also be a scalable vector (SVE) Z register. Although Z registers are supported from 128 to 512 bits in length on DynamoRIO, addressing uses 32 or 64 bit elements of a vector for scatter/gather instructions, e.g. LD1SB Z0.D, P0/Z, [Z1.D]. See also issue 6750
◆ reg_is_segment()
DR_API 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).
◆ reg_is_simd()
DR_API 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.
◆ reg_is_stolen()
DR_API 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.
- Note
- The register stolen by DynamoRIO may not be used by the client for instrumentation. Use dr_insert_get_stolen_reg() and dr_insert_set_stolen_reg() to get and set the application value of the stolen register in the instrumentation. Reference Register Stolen by DynamoRIO for more information.
◆ reg_is_strictly_xmm()
DR_API bool reg_is_strictly_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) x86 register.
◆ reg_is_strictly_ymm()
DR_API bool reg_is_strictly_ymm | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a ymm (256-bit multimedia) x86 register.
◆ reg_is_strictly_zmm()
DR_API bool reg_is_strictly_zmm | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a zmm (512-bit multimedia) x86 register.
◆ reg_is_vector_simd()
DR_API bool reg_is_vector_simd | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to an SSE or AVX register. In particular, the register must be either an xmm, ymm, or zmm for the function to return true.
This function is subject to include any future vector register that x86 may add.
◆ reg_is_xmm()
DR_API 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) x86 register or a ymm (256-bit multimedia) register.
◆ reg_is_ymm()
DR_API 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) x86 register.
- Deprecated:
- Prefer reg_is_strictly_ymm().
◆ reg_is_z()
DR_API bool reg_is_z | ( | reg_id_t | reg | ) |
Assumes that reg
is a DR_REG_ constant. Returns true iff it refers to a Z (SVE scalable vector) register.
◆ reg_overlap()
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).
◆ reg_parameter_num()
DR_API 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_resize_to_opsz()
DR_API reg_id_t reg_resize_to_opsz | ( | reg_id_t | reg, |
opnd_size_t | sz | ||
) |
Given a general-purpose or SIMD 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
. Given DR_REG_XMM0
and OPSZ_64
, it will return DR_REG_ZMM0
.
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
.
MMX registers are not yet supported. Moreover, ARM is not yet supported for resizing SIMD registers.
◆ reg_set_value()
DR_API 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.
- Note
- This function is limited to setting pointer-sized registers only (no sub-registers, and no non-general-purpose registers). See
reg_set_value_ex
for setting other register values.
◆ reg_set_value_ex()
DR_API bool reg_set_value_ex | ( | reg_id_t | reg, |
dr_mcontext_t * | mc, | ||
DR_PARAM_IN byte * | val_buf | ||
) |
Sets the register reg
in the passed in mcontext mc
to the value stored in the buffer val_buf
.
mc->flags
must include DR_MC_CONTROL and DR_MC_INTEGER.
Unlike reg_set_value
, this function supports not only general purpose registers, but SIMD registers too. Does not yet support MMX registers.
Up to sizeof(dr_zmm_t) bytes will be read from val_buf
. It is up to the user to ensure correct buffer size.
Returns false if the register is not supported.