DynamoRIO
|
Code transformation utilities. More...
Macros | |
#define | SPILL_SLOT_REDIRECT_NATIVE_TGT SPILL_SLOT_1 |
Enumerations | |
enum | dr_spill_slot_t { , SPILL_SLOT_2 = 1, SPILL_SLOT_3 = 2, SPILL_SLOT_4 = 3, SPILL_SLOT_5 = 4, SPILL_SLOT_6 = 5, SPILL_SLOT_7 = 6, SPILL_SLOT_8 = 7, SPILL_SLOT_9 = 8, SPILL_SLOT_10 = 9, SPILL_SLOT_11 = 10, SPILL_SLOT_12 = 11, SPILL_SLOT_13 = 12, SPILL_SLOT_14 = 13, SPILL_SLOT_15 = 14, SPILL_SLOT_16 = 15, SPILL_SLOT_17 = 16, SPILL_SLOT_MAX = SPILL_SLOT_17 } |
Functions | |
DR_API void | dr_save_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg, dr_spill_slot_t slot) |
DR_API void | dr_restore_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg, dr_spill_slot_t slot) |
DR_API dr_spill_slot_t | dr_max_opnd_accessible_spill_slot (void) |
DR_API opnd_t | dr_reg_spill_slot_opnd (void *drcontext, dr_spill_slot_t slot) |
DR_API reg_t | dr_read_saved_reg (void *drcontext, dr_spill_slot_t slot) |
DR_API void | dr_write_saved_reg (void *drcontext, dr_spill_slot_t slot, reg_t value) |
DR_API void | dr_save_arith_flags (void *drcontext, instrlist_t *ilist, instr_t *where, dr_spill_slot_t slot) |
DR_API void | dr_restore_arith_flags (void *drcontext, instrlist_t *ilist, instr_t *where, dr_spill_slot_t slot) |
DR_API void | dr_save_arith_flags_to_xax (void *drcontext, instrlist_t *ilist, instr_t *where) |
DR_API void | dr_restore_arith_flags_from_xax (void *drcontext, instrlist_t *ilist, instr_t *where) |
DR_API void | dr_save_arith_flags_to_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg) |
DR_API void | dr_restore_arith_flags_from_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg) |
DR_API reg_t | dr_merge_arith_flags (reg_t cur_xflags, reg_t saved_xflag) |
DR_API void | dr_insert_read_tls_field (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg) |
DR_API void | dr_insert_write_tls_field (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg) |
DR_API void | instrlist_meta_preinsert (instrlist_t *ilist, instr_t *where, instr_t *instr) |
DR_API void | instrlist_meta_postinsert (instrlist_t *ilist, instr_t *where, instr_t *instr) |
DR_API void | instrlist_meta_append (instrlist_t *ilist, instr_t *instr) |
DR_API void | instrlist_meta_fault_preinsert (instrlist_t *ilist, instr_t *where, instr_t *instr) |
DR_API void | instrlist_meta_fault_postinsert (instrlist_t *ilist, instr_t *where, instr_t *instr) |
DR_API void | instrlist_meta_fault_append (instrlist_t *ilist, instr_t *instr) |
DR_API void | dr_insert_clean_call (void *drcontext, instrlist_t *ilist, instr_t *where, void *callee, bool save_fpstate, uint num_args,...) |
DR_API void | dr_insert_clean_call_ex (void *drcontext, instrlist_t *ilist, instr_t *where, void *callee, dr_cleancall_save_t save_flags, uint num_args,...) |
DR_API void | dr_insert_call (void *drcontext, instrlist_t *ilist, instr_t *where, void *callee, uint num_args,...) |
DR_API bool | dr_insert_call_ex (void *drcontext, instrlist_t *ilist, instr_t *where, byte *encode_pc, void *callee, uint num_args,...) |
DR_API uint | dr_prepare_for_call (void *drcontext, instrlist_t *ilist, instr_t *instr) |
DR_API void | dr_cleanup_after_call (void *drcontext, instrlist_t *ilist, instr_t *where, uint sizeof_param_area) |
DR_API void | dr_swap_to_clean_stack (void *drcontext, instrlist_t *ilist, instr_t *where) |
DR_API void | dr_restore_app_stack (void *drcontext, instrlist_t *ilist, instr_t *where) |
DR_API void * | dr_call_on_clean_stack (void *drcontext, void *(*func)(void), void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6, void *arg7, void *arg8) |
DR_API void | dr_insert_call_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee) |
DR_API void | dr_insert_mbr_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee, dr_spill_slot_t scratch_slot) |
DR_API void | dr_insert_cbr_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee) |
DR_API void | dr_insert_cbr_instrumentation_ex (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee, opnd_t user_data) |
DR_API void | dr_insert_ubr_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee) |
DR_API bool | dr_clobber_retaddr_after_read (void *drcontext, instrlist_t *ilist, instr_t *instr, ptr_uint_t value) |
DR_API bool | dr_mcontext_xmm_fields_valid (void) |
DR_API bool | dr_mcontext_zmm_fields_valid (void) |
DR_API bool | dr_get_mcontext (void *drcontext, dr_mcontext_t *context) |
DR_API bool | dr_set_mcontext (void *drcontext, dr_mcontext_t *context) |
DR_API bool | dr_redirect_execution (dr_mcontext_t *context) |
DR_API byte * | dr_redirect_native_target (void *drcontext) |
DR_API bool | dr_mcontext_to_context (CONTEXT *dst, dr_mcontext_t *src) |
DR_API void | instrlist_insert_mov_immed_ptrsz (void *drcontext, ptr_int_t val, opnd_t dst, instrlist_t *ilist, instr_t *where, instr_t **first DR_PARAM_OUT, instr_t **last DR_PARAM_OUT) |
DR_API void | instrlist_insert_push_immed_ptrsz (void *drcontext, ptr_int_t val, instrlist_t *ilist, instr_t *where, instr_t **first DR_PARAM_OUT, instr_t **last DR_PARAM_OUT) |
DR_API void | instrlist_insert_mov_instr_addr (void *drcontext, instr_t *src_inst, byte *encode_estimate, opnd_t dst, instrlist_t *ilist, instr_t *where, instr_t **first DR_PARAM_OUT, instr_t **last DR_PARAM_OUT) |
DR_API void | instrlist_insert_push_instr_addr (void *drcontext, instr_t *src_inst, byte *encode_estimate, instrlist_t *ilist, instr_t *where, instr_t **first DR_PARAM_OUT, instr_t **last DR_PARAM_OUT) |
DR_API reg_id_t | dr_get_stolen_reg (void) |
DR_API bool | dr_insert_get_stolen_reg_value (void *drcontext, instrlist_t *ilist, instr_t *instr, reg_id_t reg) |
DR_API bool | dr_insert_set_stolen_reg_value (void *drcontext, instrlist_t *ilist, instr_t *instr, reg_id_t reg) |
DR_API int | dr_remove_it_instrs (void *drcontext, instrlist_t *ilist) |
DR_API int | dr_insert_it_instrs (void *drcontext, instrlist_t *ilist) |
DR_API bool | dr_insert_get_app_tls (void *drcontext, instrlist_t *ilist, instr_t *instr, reg_id_t tls_reg, reg_id_t reg) |
DR_API void | dr_insert_save_fpstate (void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t buf) |
DR_API void | dr_insert_restore_fpstate (void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t buf) |
DR_API bool | dr_insert_get_seg_base (void *drcontext, instrlist_t *ilist, instr_t *instr, reg_id_t seg, reg_id_t reg) |
Detailed Description
Code transformation utilities.
Macro Definition Documentation
◆ SPILL_SLOT_REDIRECT_NATIVE_TGT
#define SPILL_SLOT_REDIRECT_NATIVE_TGT SPILL_SLOT_1 |
Flags to request non-default preservation of state in a clean call
Enumeration Type Documentation
◆ dr_spill_slot_t
enum dr_spill_slot_t |
An enum of spill slots to use with dr_save_reg(), dr_restore_reg(), dr_save_arith_flags(), dr_restore_arith_flags() and dr_insert_mbr_instrumentation(). Values stored in spill slots remain valid only until the next non-meta (i.e. application) instruction. Spill slots can be accessed/modifed during clean calls and restore_state_events (see dr_register_restore_state_event()) with dr_read_saved_reg() and dr_write_saved_reg().
Spill slots <= dr_max_opnd_accessible_spill_slot() can be directly accessed from client inserted instructions with dr_reg_spill_slot_opnd().
- Note
- Some spill slots may be faster to access than others. Currently spill slots 1-3 are significantly faster to access than the others when running without -thread_private. When running with -thread_private all spill slots are expected to have similar performance. This is subject to change in future releases, but clients may assume that smaller numbered spill slots are faster or the same cost to access as larger numbered spill slots.
- The number of spill slots may change in future releases.
Function Documentation
◆ dr_call_on_clean_stack()
DR_API void* dr_call_on_clean_stack | ( | void * | drcontext, |
void *(*)(void) | func, | ||
void * | arg1, | ||
void * | arg2, | ||
void * | arg3, | ||
void * | arg4, | ||
void * | arg5, | ||
void * | arg6, | ||
void * | arg7, | ||
void * | arg8 | ||
) |
Calls the specified function func
after switching to the DR stack for the thread corresponding to drcontext
. Passes in 8 arguments. Uses the C calling convention, so func
will work just fine even if if takes fewer than 8 args. Swaps the stack back upon return and returns the value returned by func
.
On Windows, this routine does swap the TEB stack fields, avoiding issues with fault handling on Windows 8.1. This means there is no need for the callee to use dr_switch_to_dr_state_ex() with DR_STATE_STACK_BOUNDS.
◆ dr_cleanup_after_call()
DR_API void dr_cleanup_after_call | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
uint | sizeof_param_area | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore state after a call.
◆ dr_clobber_retaddr_after_read()
DR_API bool dr_clobber_retaddr_after_read | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
ptr_uint_t | value | ||
) |
Causes DynamoRIO to insert code that stores value
into the return address slot on the stack immediately after the original value is read by the return instruction instr
. instr
must be a return instruction or this routine will fail.
On ARM, value
is ignored and instead a value that is guaranteed to not look like a return address is used. This is for efficiency reasons, as on ARM it would require an extra register spill in order to write an arbitrary value.
- Note
- This is meant to make it easier to obtain efficient callstacks by eliminating stale return addresses from prior stack frames. However, it is possible that writing to the application stack could result in incorrect application behavior, so use this at your own risk.
- Returns
- whether successful.
◆ dr_get_mcontext()
DR_API bool dr_get_mcontext | ( | void * | drcontext, |
dr_mcontext_t * | context | ||
) |
Copies the fields of the current application machine context selected by the flags
field of context
into context
.
This routine may only be called from:
- A clean call invoked by dr_insert_clean_call() or dr_prepare_for_call(). If register reservation code is in use (e.g., via the drreg extension library Register Management), dr_insert_clean_call_ex() must be used with its flags argument including DR_CLEANCALL_READS_APP_CONTEXT (and possibly DR_CLEANCALL_MULTIPATH)to ensure proper interaction with register reservations.
- A pre- or post-syscall event (dr_register_pre_syscall_event(), dr_register_post_syscall_event())
- Basic block or trace creation events (dr_register_bb_event(), dr_register_trace_event()), but for basic block creation only when the basic block callback parameters
for_trace
andtranslating
are false, and for trace creation only whentranslating
is false. - A nudge callback (dr_register_nudge_event()) on Linux. (On Windows nudges happen in separate dedicated threads.)
- A thread or process exit event (dr_register_thread_exit_event(), dr_register_exit_event())
- A thread init event (dr_register_thread_init_event()) for all but the initial thread.
- A kernel transfer event (dr_register_kernel_xfer_event()). Here the obtained context is the target context of the transfer, not the source (about to be changed) context. For Windows system call event types DR_XFER_CONTINUE and DR_XFER_SET_CONTEXT_THREAD, only the portions of the context selected by the application are available. The
flags
field ofcontext
is adjusted to reflect which fields were returned. Given the disparity in how Ebp/Rbp is handled (in DR_MC_INTEGER but in CONTEXT_CONTROL), clients that care about that register are better off using system call events instead of kernel transfer events to take actions on these two system calls.
Even when DR_MC_CONTROL is specified, does NOT copy the pc field, except for system call events, when it will point at the post-syscall address, and kernel transfer events, when it will point to the target pc.
Returns false if called from the init event or the initial thread's init event; returns true otherwise (cannot distinguish whether the caller is in a clean call so it is up to the caller to ensure it is used properly).
The size field of context
must be set to the size of the structure as known at compile time. If the size field is invalid, this routine will return false.
The flags field of context
must be set to the desired amount of information using the dr_mcontext_flags_t values. Asking for multimedia registers incurs a higher performance cost. An invalid flags value will return false.
- Note
- NUM_SIMD_SLOTS in the dr_mcontext_t.xmm array are filled in, but only if dr_mcontext_xmm_fields_valid() returns true and DR_MC_MULTIMEDIA is set in the flags field.
- The context is the context saved at the dr_insert_clean_call() or dr_prepare_for_call() points. It does not correct for any registers saved with dr_save_reg(). To access registers saved with dr_save_reg() from a clean call use dr_read_saved_reg().
- System data structures are swapped to private versions prior to invoking clean calls or client events. Use dr_switch_to_app_state() to examine the application version of system state.
◆ dr_get_stolen_reg()
DR_API reg_id_t dr_get_stolen_reg | ( | void | ) |
Returns the register that is stolen and used by DynamoRIO. Reference Register Stolen by DynamoRIO for more information.
◆ dr_insert_call()
DR_API void dr_insert_call | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
void * | callee, | ||
uint | num_args, | ||
... | |||
) |
Inserts into ilist
prior to where
meta-instruction(s) to set up the passed-in parameters, make a call to callee
, and clean up the parameters.
The callee must use the standard C calling convention that matches the underlying 32-bit or 64-bit binary interface convention ("cdecl"). Other calling conventions, such as "fastcall" and "stdcall", are not supported.
This routine uses the existing stack. In 64-bit mode, this routine assumes that the stack pointer is currently 16-byte aligned.
The application state is NOT saved or restored (use dr_prepare_for_call() and dr_cleanup_after_call(), or replace this routine with dr_insert_clean_call()). The parameter set-up may write to registers if the calling convention so dictates. The registers are NOT saved beforehand (to do so, use dr_insert_clean_call()).
It is up to the caller of this routine to preserve any caller-saved registers that the callee might modify.
DR does not support translating a fault in an argument. For fault transparency, the client must perform the translation (see dr_register_restore_state_event()), or use dr_insert_clean_call().
For 64-bit, for purposes of reachability, this call is assumed to be destined for encoding into DR's code cache-reachable memory region. This includes the code cache as well as memory allocated with dr_thread_alloc(), dr_global_alloc(), dr_nonheap_alloc(), or dr_custom_alloc() with DR_ALLOC_CACHE_REACHABLE. The call used here will be direct if it is reachable from those locations; if it is not reachable, an indirect call through r11 will be used (with r11's contents being clobbered). Use dr_insert_call_ex() when encoding to a location other than DR's regular code region.
- Note
- This routine only supports passing arguments that are integers or pointers of a size equal to the register size: i.e., no floating-point, multimedia, or aggregate data types. The routine also supports immediate integers that are smaller than the register size, and for 64-bit mode registers or memory references that are OPSZ_4.
- For 64-bit mode, passing arguments that use calling convention registers (for Windows, RCX, RDX, R8, R9; for Linux, RDI, RSI, RDX, RCX, R8 and R9) are supported but may incur additional stack usage.
- For 64-bit mode, if a 32-bit immediate integer is specified as an argument and it has its top bit set, we assume it is intended to be sign-extended to 64-bits; otherwise we zero-extend it.
- For 64-bit mode, variable-sized argument operands may not work properly.
- Arguments that reference DR_REG_XSP are not supported in 64-bit mode.
◆ dr_insert_call_ex()
DR_API bool dr_insert_call_ex | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
byte * | encode_pc, | ||
void * | callee, | ||
uint | num_args, | ||
... | |||
) |
Identical to dr_insert_call() except it takes in encode_pc
indicating roughly where the call sequence will be encoded. If callee
is not reachable from encode_pc
plus or minus one page, an indirect call will be used instead of the direct call used by dr_insert_call(). The indirect call overwrites the r11 register.
- Returns
- true if the inserted call is direct and false if indirect.
◆ dr_insert_call_instrumentation()
DR_API void dr_insert_call_instrumentation | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
void * | callee | ||
) |
Assumes that instr
is a near call. Inserts into ilist
prior to instr
instruction(s) to call callee passing two arguments:
- address of call instruction (caller)
- target address of call (callee)
- Note
- Sets DR_CLEANCALL_READS_APP_CONTEXT and DR_CLEANCALL_WRITES_APP_CONTEXT. Conditionally skipping the instrumentation inserted by this routine is not supported (i.e., DR_CLEANCALL_MULTIPATH is not supported here).
◆ dr_insert_cbr_instrumentation()
DR_API void dr_insert_cbr_instrumentation | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
void * | callee | ||
) |
Assumes that instr
is a conditional branch Inserts into ilist
prior to instr
instruction(s) to call callee passing three arguments:
- address of branch instruction
- target address of branch
- 0 if the branch is not taken, 1 if it is taken
- Note
- Sets DR_CLEANCALL_READS_APP_CONTEXT and DR_CLEANCALL_WRITES_APP_CONTEXT. Conditionally skipping the instrumentation inserted by this routine is not supported (i.e., DR_CLEANCALL_MULTIPATH is not supported here).
◆ dr_insert_cbr_instrumentation_ex()
DR_API void dr_insert_cbr_instrumentation_ex | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
void * | callee, | ||
opnd_t | user_data | ||
) |
Assumes that instr
is a conditional branch Inserts into ilist
prior to instr
instruction(s) to call callee passing four arguments:
- address of branch instruction
- target address of branch
- fall-through address of branch
- 0 if the branch is not taken, 1 if it is taken
- user defined operand (e.g., TLS slot, immed value, register, etc.)
- Note
- The user defined operand cannot use register ebx!
- Sets DR_CLEANCALL_READS_APP_CONTEXT and DR_CLEANCALL_WRITES_APP_CONTEXT. Conditionally skipping the instrumentation inserted by this routine is not supported (i.e., DR_CLEANCALL_MULTIPATH is not supported here).
◆ dr_insert_clean_call()
DR_API void dr_insert_clean_call | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
void * | callee, | ||
bool | save_fpstate, | ||
uint | num_args, | ||
... | |||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save state for a call, switch to this thread's DR stack, set up the passed-in parameters, make a call to callee
, clean up the parameters, and then restore the saved state.
The callee must use the standard C calling convention that matches the underlying 32-bit or 64-bit binary interface convention ("cdecl"). Other calling conventions, such as "fastcall" and "stdcall", are not supported.
This routine expects to be passed a number of arguments beyond num_args
equal to the value of num_args
. Each of those arguments is a parameter to pass to the clean call, in the order passed to this routine. Each argument should be of type opnd_t and will be copied into the proper location for that argument slot as specified by the calling convention.
Stores the application state information on the DR stack, where it can be accessed from callee
using dr_get_mcontext() and modified using dr_set_mcontext(). However, if register reservation code is in use (e.g., via the drreg extension library: Register Management), dr_insert_clean_call_ex() must be called with its flags argument including DR_CLEANCALL_READS_APP_CONTEXT (for dr_get_mcontext() use) and/or DR_CLEANCALL_WRITES_APP_CONTEXT (for dr_set_mcontext() use) (and possibly DR_CLEANCALL_MULTIPATH) to ensure proper interaction with register reservations.
On x86, if save_fpstate
is true, preserves the x87 floating-point and MMX state on the DR stack. Note that it is relatively expensive to save this state (on the order of 200 cycles) and that it typically takes 512 bytes to store it (see proc_fpstate_save_size()). The last floating-point instruction address in the saved state is left in an untranslated state (i.e., it may point into the code cache). This optional floating-point state preservation is specific to x87; floating-point values in XMM, YMM, or ZMM registers, or any SIMD register on any non-x86 architecture, are always preserved. Thus, on ARM/AArch64, save_fpstate
is ignored.
DR does support translating a fault in an argument (e.g., an argument that references application memory); such a fault will be treated as an application exception.
The clean call sequence will be optimized based on the runtime option -opt_cleancall.
For 64-bit, for purposes of reachability, this call is assumed to be destined for encoding into DR's code cache-reachable memory region. This includes the code cache as well as memory allocated with dr_thread_alloc(), dr_global_alloc(), dr_nonheap_alloc(), or dr_custom_alloc() with DR_ALLOC_CACHE_REACHABLE. The call used here will be direct if it is reachable from those locations; if it is not reachable, an indirect call through r11 will be used (with r11's contents being clobbered). Use dr_insert_clean_call_ex() with DR_CLEANCALL_INDIRECT to ensure reachability when encoding to a location other than DR's regular code region. See also dr_insert_call_ex().
- Note
- The stack used to save state and call
callee
is limited to 20KB by default; this can be changed with the -stack_size DR runtime parameter. This stack cannot be used to store state that persists beyondcallee's
return point. - This routine only supports passing arguments that are integers or pointers of a size equal to the register size: i.e., no floating-point, multimedia, or aggregate data types. The routine also supports immediate integers that are smaller than the register size, and for 64-bit mode registers or memory references that are OPSZ_4.
- For 64-bit mode, passing arguments that use calling convention registers (for Windows, RCX, RDX, R8, R9; for Linux, RDI, RSI, RDX, RCX, R8 and R9) are supported but may incur additional stack usage.
- For 64-bit mode, if a 32-bit immediate integer is specified as an argument and it has its top bit set, we assume it is intended to be sign-extended to 64-bits; otherwise we zero-extend it.
- For 64-bit mode, variable-sized argument operands may not work properly.
- Arguments that reference sub-register portions of DR_REG_XSP are not supported (full DR_REG_XSP is supported).
◆ dr_insert_clean_call_ex()
DR_API void dr_insert_clean_call_ex | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
void * | callee, | ||
dr_cleancall_save_t | save_flags, | ||
uint | num_args, | ||
... | |||
) |
Identical to dr_insert_clean_call() except it takes in save_flags
which allows requests to not save certain state. This is intended for use at application call entry points or other contexts where a client is comfortable making assumptions. Keep in mind that any register that is not saved will not be present in a context obtained from dr_get_mcontext().
◆ dr_insert_get_app_tls()
DR_API bool dr_insert_get_app_tls | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
reg_id_t | tls_reg, | ||
reg_id_t | reg | ||
) |
Insert code to get the application value of the thread pointer register into register reg
.
- Returns
- whether successful.
- Note
- RISCV-only
◆ dr_insert_get_seg_base()
DR_API bool dr_insert_get_seg_base | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
reg_id_t | seg, | ||
reg_id_t | reg | ||
) |
Insert code to get the segment base address pointed to by seg into register reg. In Linux, it is only supported with -mangle_app_seg option. In Windows, it only supports getting base address of the TLS segment.
- Returns
- whether successful.
◆ dr_insert_get_stolen_reg_value()
DR_API bool dr_insert_get_stolen_reg_value | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
reg_id_t | reg | ||
) |
Insert code to get the application value of the register stolen by DynamoRIO into register reg
. Reference Register Stolen by DynamoRIO for more information.
- Returns
- whether successful.
- Note
- ARM-only
◆ dr_insert_it_instrs()
DR_API int dr_insert_it_instrs | ( | void * | drcontext, |
instrlist_t * | ilist | ||
) |
Inserts enough OP_it instructions with proper parameters into ilist
to make all predicated instructions in ilist
legal in Thumb mode (DR_ISA_ARM_THUMB). Treats predicated app and tool instructions identically, but marks inserted OP_it instructions as app instructions (see instr_set_app()).
- Returns
- the number of OP_it instructions inserted; -1 on error.
- Note
- ARM-only
◆ dr_insert_mbr_instrumentation()
DR_API void dr_insert_mbr_instrumentation | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
void * | callee, | ||
dr_spill_slot_t | scratch_slot | ||
) |
Assumes that instr
is an indirect branch. Inserts into ilist
prior to instr
instruction(s) to call callee passing two arguments:
- address of branch instruction
- target address of branch
- Note
- Only the address portion of a far indirect branch is considered.
-
scratch_slot
must be <= dr_max_opnd_accessible_spill_slot().scratch_slot
is used internally to this routine and will be clobbered. - Sets DR_CLEANCALL_READS_APP_CONTEXT and DR_CLEANCALL_WRITES_APP_CONTEXT. Conditionally skipping the instrumentation inserted by this routine is not supported (i.e., DR_CLEANCALL_MULTIPATH is not supported here).
◆ dr_insert_read_tls_field()
DR_API void dr_insert_read_tls_field | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
reg_id_t | reg | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to read into the general-purpose full-size register reg
from the user-controlled drcontext field for this thread. Reads from the same field as dr_get_tls_field().
◆ dr_insert_restore_fpstate()
DR_API void dr_insert_restore_fpstate | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
opnd_t | buf | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore the x87 floating point state from the 16-byte-aligned buffer referred to by buf, which must be 512 bytes for processors with the FXSR feature, and 108 bytes for those without (where this routine does not support 16-bit operand sizing). buf
should have size of OPSZ_512; this routine will automatically adjust it to OPSZ_108 if necessary.
- Note
- proc_fpstate_save_size() can be used to determine the particular size needed.
When the FXSR feature is present, the fxsave format matches the bitwidth of the ISA mode of the current thread (see dr_get_isa_mode()).
◆ dr_insert_save_fpstate()
DR_API void dr_insert_save_fpstate | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
opnd_t | buf | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save the x87 floating point state into the 16-byte-aligned buffer referred to by buf
, which must be 512 bytes for processors with the FXSR feature, and 108 bytes for those without (where this routine does not support 16-bit operand sizing). buf
should have size of OPSZ_512; this routine will automatically adjust it to OPSZ_108 if necessary.
- Note
- proc_fpstate_save_size() can be used to determine the particular size needed.
When the FXSR feature is present, the fxsave format matches the bitwidth of the ISA mode of the current thread (see dr_get_isa_mode()).
The last floating-point instruction address is left in an untranslated state (i.e., it may point into the code cache).
◆ dr_insert_set_stolen_reg_value()
DR_API bool dr_insert_set_stolen_reg_value | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
reg_id_t | reg | ||
) |
Insert code to set the value of register reg
as the application value of the register stolen by DynamoRIO Reference Register Stolen by DynamoRIO for more information.
- Returns
- whether successful.
- Note
- ARM-only
◆ dr_insert_ubr_instrumentation()
DR_API void dr_insert_ubr_instrumentation | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr, | ||
void * | callee | ||
) |
Assumes that instr
is a direct, near, unconditional branch. Inserts into ilist
prior to instr
instruction(s) to call callee passing two arguments:
- address of branch instruction
- target address of branch
- Warning
- Basic block eliding is controlled by -max_elide_jmp. If that option is set to non-zero, ubrs may never be seen.
- Note
- Sets DR_CLEANCALL_READS_APP_CONTEXT and DR_CLEANCALL_WRITES_APP_CONTEXT. Conditionally skipping the instrumentation inserted by this routine is not supported (i.e., DR_CLEANCALL_MULTIPATH is not supported here).
◆ dr_insert_write_tls_field()
DR_API void dr_insert_write_tls_field | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
reg_id_t | reg | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to write the general-purpose full-size register reg
to the user-controlled drcontext field for this thread. Writes to the same field as dr_set_tls_field().
◆ dr_max_opnd_accessible_spill_slot()
DR_API dr_spill_slot_t dr_max_opnd_accessible_spill_slot | ( | void | ) |
Returns the largest dr_spill_slot_t that can be accessed with an opnd_t from dr_reg_spill_slot_opnd().
◆ dr_mcontext_to_context()
DR_API bool dr_mcontext_to_context | ( | CONTEXT * | dst, |
dr_mcontext_t * | src | ||
) |
Copies the machine state in src
into dst
. Sets the ContextFlags
field of dst
to reflect the flags
field of src
. However, CONTEXT_CONTROL includes Ebp/Rbp, while that's under DR_MC_INTEGER, so we recommend always setting both DR_MC_INTEGER and DR_MC_CONTROL when calling this routine.
It is up to the caller to ensure that dst
is allocated and initialized properly in order to contain multimedia processor state, if DR_MC_MULTIMEDIA is set in the flags
field of src
.
The current segment register values are filled in under the assumption that this context is for the calling thread.
- Note
- floating-point values are not filled in for
dst
. - Windows only.
- Returns
- false if unsuccessful; if successful, does not return.
◆ dr_mcontext_xmm_fields_valid()
DR_API bool dr_mcontext_xmm_fields_valid | ( | void | ) |
Returns true if the simd fields in dr_mcontext_t are valid xmm, ymm, or zmm values (i.e., whether the underlying processor supports SSE).
- Note
- If DR_MC_MULTIMEDIA is not specified when calling dr_get_mcontext(), the simd fields will not be filled in regardless of the return value of this routine.
◆ dr_mcontext_zmm_fields_valid()
DR_API bool dr_mcontext_zmm_fields_valid | ( | void | ) |
Returns true if the simd fields in dr_mcontext_t are valid zmm values (i.e., whether the underlying processor and OS support AVX-512 and AVX-512 code is present).
- Note
- If DR_MC_MULTIMEDIA is not specified when calling dr_get_mcontext(), the simd fields will not be filled in regardless of the return value of this routine.
◆ dr_merge_arith_flags()
DR_API reg_t dr_merge_arith_flags | ( | reg_t | cur_xflags, |
reg_t | saved_xflag | ||
) |
A convenience routine to aid restoring the arith flags done by outlined code, such as when handling restore state events. The routine takes the current value of the flags register cur_xflags
, as well as the saved value saved_xflag
, in order to return the original app value.
◆ dr_prepare_for_call()
DR_API uint dr_prepare_for_call | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | instr | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save state for a call. Stores the application state information on the DR stack. Returns the size of the data stored on the DR stack (in case the caller needs to align the stack pointer).
- Warning
- On x86, this routine does NOT save the x87 floating-point or MMX state: to do that the instrumentation routine should call proc_save_fpstate() to save and then proc_restore_fpstate() to restore (or use dr_insert_clean_call()).
- Note
- The preparation modifies the DR_REG_XSP and DR_REG_XAX registers (after saving them). Use dr_insert_clean_call() instead if an argument to the subsequent call that references DR_REG_XAX is desired.
- The stack used to save the state is limited to 20KB by default; this can be changed with the -stack_size DR runtime parameter. This stack cannot be used to store state that persists beyond a single clean call, code cache execution, or probe callback function execution.
◆ dr_read_saved_reg()
DR_API reg_t dr_read_saved_reg | ( | void * | drcontext, |
dr_spill_slot_t | slot | ||
) |
Can be used from a clean call or a restore_state_event (see dr_register_restore_state_event()) to see the value saved in spill slot slot
by dr_save_reg().
◆ dr_redirect_execution()
DR_API bool dr_redirect_execution | ( | dr_mcontext_t * | context | ) |
Immediately resumes application execution from a clean call out of the cache (see dr_insert_clean_call() or dr_prepare_for_call()) or an exception event with the state specified in mcontext
(including pc, and including the xmm fields that are valid according to dr_mcontext_xmm_fields_valid()). The flags field of context
must contain DR_MC_ALL; using a partial set of fields is not suported.
For 32-bit ARM, be sure to use dr_app_pc_as_jump_target() to properly set the ISA mode for the continuation pc if it was obtained from instr_get_app_pc() or a similar source rather than from dr_get_proc_address(). This will set the least significant bit of the mcontext pc field to 1 when in Thumb mode (DR_ISA_ARM_THUMB), Thumb Mode Addresses for more information.
- Note
- dr_get_mcontext() can be used to get the register state (except pc) saved in dr_insert_clean_call() or dr_prepare_for_call().
- If x87 floating point state was saved by dr_prepare_for_call() or dr_insert_clean_call() it is not restored (other than the valid xmm fields according to dr_mcontext_xmm_fields_valid(), if DR_MC_MULTIMEDIA is specified in the flags field). The caller should instead manually save and restore the floating point state with proc_save_fpstate() and proc_restore_fpstate() if necessary.
- If the caller wishes to set any other state (such as xmm registers that are not part of the mcontext) they may do so by just setting that state in the current thread before making this call. To set system data structures, use dr_switch_to_app_state(), make the changes, and then switch back with dr_switch_to_dr_state() before calling this routine.
- This routine may only be called from a clean call from the cache. It can not be called from any registered event callback except the exception event (dr_register_exception_event()). From a signal event callback, use the DR_SIGNAL_REDIRECT return value rather than calling this routine.
- If control is being redirected to a new pc (determined using drsyms, dr_get_proc_address, or any other way) ensure that the app state (such as the register values) are set as expected by the transfer point.
- Returns
- false if unsuccessful; if successful, does not return.
◆ dr_redirect_native_target()
DR_API byte* dr_redirect_native_target | ( | void * | drcontext | ) |
Returns the target to use for a native context transfer to a target application address.
Normally, redirection is performed from a client context in a clean call or event callback by invoking dr_redirect_execution(). In some circumstances, redirection from an application (or "native") context is desirable without creating an application control transfer in a basic block.
To accomplish such a redirection, store the target application address in SPILL_SLOT_REDIRECT_NATIVE_TGT by calling dr_write_saved_reg(). Set up any other application state as desired directly in the current machine context. Then jump to the target returned by this routine. By default, the target is global and can be cached globally. However, if traces are thread-private, or if traces are disabled and basic blocks are thread-private, there will be a separate target per drcontext
.
If a basic block is exited via such a redirection, the block should be emitted with the flag DR_EMIT_MUST_END_TRACE in order to avoid trace building errors.
For ARM, the address returned by this routine has its least significant bit set to 1 if the target is Thumb.
Returns null on error.
◆ dr_reg_spill_slot_opnd()
DR_API opnd_t dr_reg_spill_slot_opnd | ( | void * | drcontext, |
dr_spill_slot_t | slot | ||
) |
Returns an opnd_t that directly accesses the spill slot slot
. Only slots <= dr_max_opnd_accessible_spill_slot() can be used with this routine.
- Note
slot
must be <= dr_max_opnd_accessible_spill_slot()
◆ dr_remove_it_instrs()
DR_API int dr_remove_it_instrs | ( | void * | drcontext, |
instrlist_t * | ilist | ||
) |
Removes all OP_it instructions from ilist
without changing the instructions that were inside each IT block. This is intended to be paired with dr_insert_it_instrs(), where a client's examination of the application instruction list and insertion of instrumentation occurs in between the two calls and thus does not have to worry about groups of instructions that cannot be separated or changed. The resulting predicated instructions are not encodable in Thumb mode (DR_ISA_ARM_THUMB): dr_insert_it_instrs() must be called before encoding.
- Returns
- the number of OP_it instructions removed; -1 on error.
- Note
- ARM-only
◆ dr_restore_app_stack()
DR_API void dr_restore_app_stack | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore into esp the value saved by dr_swap_to_clean_stack().
◆ dr_restore_arith_flags()
DR_API void dr_restore_arith_flags | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
dr_spill_slot_t | slot | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore the 6 arithmetic flags, assuming they were saved using dr_save_arith_flags() with slot slot
and that xax holds the same value it did after the save.
- Note
- X86-only
- Deprecated:
- This routine is equivalent to dr_restore_arith_flags_from_xax() followed by dr_restore_reg().
◆ dr_restore_arith_flags_from_reg()
DR_API void dr_restore_arith_flags_from_reg | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
reg_id_t | reg | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore the arithmetic flags (6 arithmetic flags on X86 or APSR on ARM) from reg
. The caller must ensure that reg
contains the program status flags, most likely from dr_save_arith_flags_to_reg().
- Note
- On X86, only DR_REG_XAX should be passed in.
◆ dr_restore_arith_flags_from_xax()
DR_API void dr_restore_arith_flags_from_xax | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore the 6 arithmetic flags from xax. This currently uses DynamoRIO's "add $0x7f %al ;
sahf" code sequence, which is faster and easier than popf. The caller must ensure that xax contains the arithmetic flags, most likely from dr_save_arith_flags_to_xax().
- Note
- X86-only
◆ dr_restore_reg()
DR_API void dr_restore_reg | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
reg_id_t | reg, | ||
dr_spill_slot_t | slot | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to restore the register reg
from the spill slot slot
. See dr_save_reg() for notes on lifetime and alternative access to spill slots.
◆ dr_save_arith_flags()
DR_API void dr_save_arith_flags | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
dr_spill_slot_t | slot | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save the 6 arithmetic flags into xax after first saving xax to the spill slot slot
. This is equivalent to dr_save_reg() of xax to slot
followed by lahf and seto al instructions. See dr_restore_arith_flags().
- Warning
- At completion of the inserted instructions the saved flags are in the xax register. The xax register should not be modified after using this routine unless it is first saved (and later restored prior to using dr_restore_arith_flags()).
- Note
- X86-only
- Deprecated:
- This routine is equivalent to dr_save_reg() followed by dr_save_arith_flags_to_xax().
◆ dr_save_arith_flags_to_reg()
DR_API void dr_save_arith_flags_to_reg | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
reg_id_t | reg | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save the arithmetic flags (6 arithmetic flags on X86 or APSR on ARM) into reg
. If the caller wishes to use reg
between saving and restoring these flags, they must save and restore reg
, potentially using dr_save_reg()/dr_restore_reg(). If the caller needs to save both the current value of reg
and the flags stored to reg
by this routine, they must use separate spill slots, or they will overwrite the original reg
value in memory.
- Note
- On X86, only DR_REG_XAX should be passed in.
- Warning
- Clobbers
reg
; the caller must ensurereg
is dead or saved atwhere
.
◆ dr_save_arith_flags_to_xax()
DR_API void dr_save_arith_flags_to_xax | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save the 6 arithmetic flags into xax. This currently uses DynamoRIO's "lahf ; seto al" code sequence, which is faster and easier than pushf. If the caller wishes to use xax between saving and restoring these flags, they must save and restore xax, potentially using dr_save_reg()/dr_restore_reg(). If the caller needs to save both the current value of xax and the flags stored to xax by this routine, they must use separate spill slots, or they will overwrite the original xax value in memory.
- Note
- X86-only
- Warning
- Clobbers xax; the caller must ensure xax is dead or saved at
where
.
◆ dr_save_reg()
DR_API void dr_save_reg | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where, | ||
reg_id_t | reg, | ||
dr_spill_slot_t | slot | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save the register reg
in the spill slot slot
. See dr_restore_reg(). Use dr_read_saved_reg() and dr_write_saved_reg() to access spill slots from clean calls and restore_state_events (see dr_register_restore_state_event()).
- Note
- The stored value remains available only until the next non-meta (i.e. application) instruction. Use dr_insert_write_tls_field() and dr_insert_read_tls_field() for a persistent (but more costly to access) thread-local-storage location. See also dr_raw_tls_calloc().
Generally, using the Register Management Extension Library instead is recommended. When using custom spills and restores, be sure to look for the labels DR_NOTE_ANNOTATION and DR_NOTE_REG_BARRIER at which all application values should be restored to registers.
◆ dr_set_mcontext()
DR_API bool dr_set_mcontext | ( | void * | drcontext, |
dr_mcontext_t * | context | ||
) |
Sets the fields of the application machine context selected by the flags field of context
to the values in context
.
This routine may only be called from:
- A clean call invoked by dr_insert_clean_call() or dr_prepare_for_call(). If register reservation code is in use (e.g., via the drreg extension library Register Management), dr_insert_clean_call_ex() must be used with its flags argument including DR_CLEANCALL_WRITES_APP_CONTEXT (and possibly DR_CLEANCALL_MULTIPATH) to ensure proper interaction with register reservations.
- A pre- or post-syscall event (dr_register_pre_syscall_event(), dr_register_post_syscall_event()) dr_register_thread_exit_event())
- A kernel transfer event (dr_register_kernel_xfer_event()) other than DR_XFER_CALLBACK_RETURN. Here the modified context is the target context of the transfer, not the source (about to be changed) context. For Windows system call event types DR_XFER_CONTINUE and DR_XFER_SET_CONTEXT_THREAD, only the portions of the context selected by the application can be changed. The
flags
field ofcontext
is adjusted to reflect which fields these are. Given the disparity in how Ebp/Rbp is handled (in DR_MC_INTEGER but in CONTEXT_CONTROL), clients that care about that register are better off using system call events instead of kernel transfer events to take actions on these two system calls. - Basic block or trace creation events (dr_register_bb_event(), dr_register_trace_event()), but for basic block creation only when the basic block callback parametersfor_trace
andtranslating
are false, and for trace creation only whentranslating
is false.
Ignores the pc field, except for kernel transfer events.
If the size field of context
is invalid, this routine will return false. A dr_mcontext_t obtained from DR will have the size field set.
The flags field of context
must be set to select the desired fields for copying, using the dr_mcontext_flags_t values. Asking to copy multimedia registers incurs a higher performance cost. An invalid flags value will return false.
- Returns
- whether successful.
- Note
- The xmm fields are only set for processes where the underlying processor supports them (and when DR_MC_MULTIMEDIA is set in the flags field). For dr_insert_clean_call() that requested
save_fpstate
, the xmm values set here override that saved state. Use dr_mcontext_xmm_fields_valid() to determine whether the xmm fields are valid.
◆ dr_swap_to_clean_stack()
DR_API void dr_swap_to_clean_stack | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
instr_t * | where | ||
) |
Inserts into ilist
prior to where
meta-instruction(s) to save the current esp and switch to this thread's DR stack.
- Note
- The DR stack is limited to 20KB by default; this can be changed with the -stack_size DR runtime parameter. This stack cannot be used to store state that persists beyond a single clean call, code cache execution, or probe callback function execution.
◆ dr_write_saved_reg()
DR_API void dr_write_saved_reg | ( | void * | drcontext, |
dr_spill_slot_t | slot, | ||
reg_t | value | ||
) |
Can be used from a clean call to modify the value saved in the spill slot slot
by dr_save_reg() such that a later dr_restore_reg() will see the new value.
- Note
- This routine should only be used during a clean call out of the cache. Use at any other time could corrupt application or DynamoRIO state.
◆ instrlist_insert_mov_immed_ptrsz()
DR_API void instrlist_insert_mov_immed_ptrsz | ( | void * | drcontext, |
ptr_int_t | val, | ||
opnd_t | dst, | ||
instrlist_t * | ilist, | ||
instr_t * | where, | ||
instr_t **first | DR_PARAM_OUT, | ||
instr_t **last | DR_PARAM_OUT | ||
) |
Create meta instructions for storing pointer-size integer val
to dst
, and then insert them into ilist
prior to where
. Pointers to the first and last created meta instructions are returned in first
and last
, unless only one meta instruction is created, in which case NULL is returned in last. If the instruction is a no-op (when dst is the zero register on AArch64) then no instructions are created and NULL is returned in first and last.
◆ instrlist_insert_mov_instr_addr()
DR_API void instrlist_insert_mov_instr_addr | ( | void * | drcontext, |
instr_t * | src_inst, | ||
byte * | encode_estimate, | ||
opnd_t | dst, | ||
instrlist_t * | ilist, | ||
instr_t * | where, | ||
instr_t **first | DR_PARAM_OUT, | ||
instr_t **last | DR_PARAM_OUT | ||
) |
Create meta instructions for storing the address of src_inst
to dst
, and then insert them into ilist
prior to where
. The encode_estimate
parameter, used only for 64-bit mode, indicates whether the final address of src_inst
, when it is encoded later, will fit in 32 bits or needs 64 bits. If the encoding will be in DynamoRIO's code cache, pass NULL. If the final encoding location is unknown, pass a high address to be on the safe side. Pointers to the first and last created meta instructions are returned in first
and last
, unless only one meta instruction is created, in which case NULL is returned in last. If the instruction is a no-op (when dst is the zero register on AArch64) then no instructions are created and NULL is returned in first and last.
◆ instrlist_insert_push_immed_ptrsz()
DR_API void instrlist_insert_push_immed_ptrsz | ( | void * | drcontext, |
ptr_int_t | val, | ||
instrlist_t * | ilist, | ||
instr_t * | where, | ||
instr_t **first | DR_PARAM_OUT, | ||
instr_t **last | DR_PARAM_OUT | ||
) |
Create meta instructions for pushing pointer-size integer val
on the stack, and then insert them into ilist
prior to where
. Pointers to the first and last created meta instructions are returned in first
and last
, unless only one meta instruction is created, in which case NULL is returned in last.
◆ instrlist_insert_push_instr_addr()
DR_API void instrlist_insert_push_instr_addr | ( | void * | drcontext, |
instr_t * | src_inst, | ||
byte * | encode_estimate, | ||
instrlist_t * | ilist, | ||
instr_t * | where, | ||
instr_t **first | DR_PARAM_OUT, | ||
instr_t **last | DR_PARAM_OUT | ||
) |
Create meta instructions for pushing the address of src_inst
on the stack, and then insert them into ilist
prior to where
. The encode_estimate
parameter, used only for 64-bit mode, indicates whether the final address of src_inst
, when it is encoded later, will fit in 32 bits or needs 64 bits. If the encoding will be in DynamoRIO's code cache, pass NULL. If the final encoding location is unknown, pass a high address to be on the safe side. Pointers to the first and last created meta instructions are returned in first
and last
, unless only one meta instruction is created, in which case NULL is returned in last.
◆ instrlist_meta_append()
DR_API void instrlist_meta_append | ( | instrlist_t * | ilist, |
instr_t * | instr | ||
) |
Inserts instr
as a non-application instruction onto the end of ilist
◆ instrlist_meta_fault_append()
DR_API void instrlist_meta_fault_append | ( | instrlist_t * | ilist, |
instr_t * | instr | ||
) |
Inserts instr
as a non-application instruction that can fault (see instr_set_meta_may_fault()) onto the end of ilist
.
- Deprecated:
- Essentially equivalent to instrlist_meta_append()
◆ instrlist_meta_fault_postinsert()
DR_API void instrlist_meta_fault_postinsert | ( | instrlist_t * | ilist, |
instr_t * | where, | ||
instr_t * | instr | ||
) |
Inserts instr
as a non-application instruction that can fault (see instr_set_meta_may_fault()) into ilist
after where
.
- Deprecated:
- Essentially equivalent to instrlist_meta_postinsert()
◆ instrlist_meta_fault_preinsert()
DR_API void instrlist_meta_fault_preinsert | ( | instrlist_t * | ilist, |
instr_t * | where, | ||
instr_t * | instr | ||
) |
Inserts instr
as a non-application instruction that can fault (see instr_set_meta_may_fault()) into ilist
prior to where
.
- Deprecated:
- Essentially equivalent to instrlist_meta_preinsert()
◆ instrlist_meta_postinsert()
DR_API void instrlist_meta_postinsert | ( | instrlist_t * | ilist, |
instr_t * | where, | ||
instr_t * | instr | ||
) |
Inserts instr
as a non-application instruction into ilist
after where
.
◆ instrlist_meta_preinsert()
DR_API void instrlist_meta_preinsert | ( | instrlist_t * | ilist, |
instr_t * | where, | ||
instr_t * | instr | ||
) |
Inserts instr
as a non-application instruction into ilist
prior to where
.