DynamoRIO API
dr_ir_utils.h File Reference

Code transformation utilities. More...

#include "dr_ir_instr.h"

Macros

#define SPILL_SLOT_REDIRECT_NATIVE_TGT   SPILL_SLOT_1
 

Typedefs

typedef enum _dr_isa_mode_t dr_isa_mode_t
 

Enumerations

enum  _dr_isa_mode_t {
  DR_ISA_IA32,
  DR_ISA_X86 = DR_ISA_IA32,
  DR_ISA_AMD64,
  DR_ISA_ARM_A32,
  DR_ISA_ARM_THUMB,
  DR_ISA_ARM_A64
}
 
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
}
 
enum  dr_cleancall_save_t {
  DR_CLEANCALL_SAVE_FLOAT = 0x0001,
  DR_CLEANCALL_NOSAVE_FLAGS = 0x0002,
  DR_CLEANCALL_NOSAVE_XMM = 0x0004,
  DR_CLEANCALL_NOSAVE_XMM_NONPARAM = 0x0008,
  DR_CLEANCALL_NOSAVE_XMM_NONRET = 0x0010,
  DR_CLEANCALL_INDIRECT = 0x0020 ,
  DR_CLEANCALL_ALWAYS_OUT_OF_LINE = 0x0080
}
 
enum  dr_disasm_flags_t {
  DR_DISASM_DR = 0x0,
  DR_DISASM_INTEL = 0x1,
  DR_DISASM_ATT = 0x2,
  DR_DISASM_STRICT_INVALID = 0x4,
  DR_DISASM_NO_OPND_SIZE = 0x8,
  DR_DISASM_ARM = 0x10
}
 

Functions

bool dr_set_isa_mode (void *drcontext, dr_isa_mode_t new_mode, dr_isa_mode_t *old_mode OUT)
 
dr_isa_mode_t dr_get_isa_mode (void *drcontext)
 
void dr_save_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg, dr_spill_slot_t slot)
 
void dr_restore_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg, dr_spill_slot_t slot)
 
dr_spill_slot_t dr_max_opnd_accessible_spill_slot (void)
 
opnd_t dr_reg_spill_slot_opnd (void *drcontext, dr_spill_slot_t slot)
 
reg_t dr_read_saved_reg (void *drcontext, dr_spill_slot_t slot)
 
void dr_write_saved_reg (void *drcontext, dr_spill_slot_t slot, reg_t value)
 
void dr_save_arith_flags (void *drcontext, instrlist_t *ilist, instr_t *where, dr_spill_slot_t slot)
 
void dr_restore_arith_flags (void *drcontext, instrlist_t *ilist, instr_t *where, dr_spill_slot_t slot)
 
void dr_save_arith_flags_to_xax (void *drcontext, instrlist_t *ilist, instr_t *where)
 
void dr_restore_arith_flags_from_xax (void *drcontext, instrlist_t *ilist, instr_t *where)
 
void dr_save_arith_flags_to_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg)
 
void dr_restore_arith_flags_from_reg (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg)
 
void dr_insert_read_tls_field (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg)
 
void dr_insert_write_tls_field (void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg)
 
void instrlist_meta_preinsert (instrlist_t *ilist, instr_t *where, instr_t *instr)
 
void instrlist_meta_postinsert (instrlist_t *ilist, instr_t *where, instr_t *instr)
 
void instrlist_meta_append (instrlist_t *ilist, instr_t *instr)
 
void instrlist_meta_fault_preinsert (instrlist_t *ilist, instr_t *where, instr_t *instr)
 
void instrlist_meta_fault_postinsert (instrlist_t *ilist, instr_t *where, instr_t *instr)
 
void instrlist_meta_fault_append (instrlist_t *ilist, instr_t *instr)
 
void dr_insert_clean_call (void *drcontext, instrlist_t *ilist, instr_t *where, void *callee, bool save_fpstate, uint num_args,...)
 
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,...)
 
void dr_insert_call (void *drcontext, instrlist_t *ilist, instr_t *where, void *callee, uint num_args,...)
 
bool dr_insert_call_ex (void *drcontext, instrlist_t *ilist, instr_t *where, byte *encode_pc, void *callee, uint num_args,...)
 
uint dr_prepare_for_call (void *drcontext, instrlist_t *ilist, instr_t *instr)
 
void dr_cleanup_after_call (void *drcontext, instrlist_t *ilist, instr_t *where, uint sizeof_param_area)
 
void dr_swap_to_clean_stack (void *drcontext, instrlist_t *ilist, instr_t *where)
 
void dr_restore_app_stack (void *drcontext, instrlist_t *ilist, instr_t *where)
 
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)
 
void dr_insert_call_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee)
 
void dr_insert_mbr_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee, dr_spill_slot_t scratch_slot)
 
void dr_insert_cbr_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee)
 
void dr_insert_cbr_instrumentation_ex (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee, opnd_t user_data)
 
void dr_insert_ubr_instrumentation (void *drcontext, instrlist_t *ilist, instr_t *instr, void *callee)
 
bool dr_clobber_retaddr_after_read (void *drcontext, instrlist_t *ilist, instr_t *instr, ptr_uint_t value)
 
bool dr_mcontext_xmm_fields_valid (void)
 
bool dr_get_mcontext (void *drcontext, dr_mcontext_t *context)
 
bool dr_set_mcontext (void *drcontext, dr_mcontext_t *context)
 
bool dr_redirect_execution (dr_mcontext_t *context)
 
byte * dr_redirect_native_target (void *drcontext)
 
bool dr_mcontext_to_context (CONTEXT *dst, dr_mcontext_t *src)
 
void instrlist_insert_mov_immed_ptrsz (void *drcontext, ptr_int_t val, opnd_t dst, instrlist_t *ilist, instr_t *where, instr_t **first OUT, instr_t **last OUT)
 
void instrlist_insert_push_immed_ptrsz (void *drcontext, ptr_int_t val, instrlist_t *ilist, instr_t *where, instr_t **first OUT, instr_t **last OUT)
 
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 OUT, instr_t **last OUT)
 
void instrlist_insert_push_instr_addr (void *drcontext, instr_t *src_inst, byte *encode_estimate, instrlist_t *ilist, instr_t *where, instr_t **first OUT, instr_t **last OUT)
 
reg_id_t dr_get_stolen_reg (void)
 
bool dr_insert_get_stolen_reg_value (void *drcontext, instrlist_t *ilist, instr_t *instr, reg_id_t reg)
 
bool dr_insert_set_stolen_reg_value (void *drcontext, instrlist_t *ilist, instr_t *instr, reg_id_t reg)
 
int dr_remove_it_instrs (void *drcontext, instrlist_t *ilist)
 
int dr_insert_it_instrs (void *drcontext, instrlist_t *ilist)
 
app_pc decode_memory_reference_size (void *drcontext, app_pc pc, uint *size_in_bytes)
 
byte * decode_eflags_usage (void *drcontext, byte *pc, uint *usage, dr_opnd_query_flags_t flags)
 
byte * decode (void *drcontext, byte *pc, instr_t *instr)
 
byte * decode_from_copy (void *drcontext, byte *copy_pc, byte *orig_pc, instr_t *instr)
 
instrlist_t * decode_as_bb (void *drcontext, byte *start_pc)
 
instrlist_t * decode_trace (void *drcontext, void *tag)
 
byte decode_first_opcode_byte (int opcode)
 
const char * decode_opcode_name (int opcode)
 
bool set_x86_mode (void *drcontext, bool x86)
 
bool get_x86_mode (void *drcontext)
 
app_pc dr_app_pc_as_jump_target (dr_isa_mode_t isa_mode, app_pc pc)
 
app_pc dr_app_pc_as_load_target (dr_isa_mode_t isa_mode, app_pc pc)
 
int decode_sizeof (void *drcontext, byte *pc, int *num_prefixes _IF_X86_64(uint *rip_rel_pos))
 
byte * decode_next_pc (void *drcontext, byte *pc)
 
void disassemble_set_syntax (dr_disasm_flags_t flags)
 
byte * disassemble (void *drcontext, byte *pc, file_t outfile)
 
byte * disassemble_with_info (void *drcontext, byte *pc, file_t outfile, bool show_pc, bool show_bytes)
 
byte * disassemble_from_copy (void *drcontext, byte *copy_pc, byte *orig_pc, file_t outfile, bool show_pc, bool show_bytes)
 
byte * disassemble_to_buffer (void *drcontext, byte *pc, byte *orig_pc, bool show_pc, bool show_bytes, char *buf, size_t bufsz, int *printed OUT)
 

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

Typedef Documentation

◆ dr_isa_mode_t

Specifies which processor mode to use when decoding or encoding.

Enumeration Type Documentation

◆ _dr_isa_mode_t

Specifies which processor mode to use when decoding or encoding.

Enumerator
DR_ISA_IA32 

IA-32 (Intel/AMD 32-bit mode).

DR_ISA_X86 

Alis for DR_ISA_IA32.

DR_ISA_AMD64 

AMD64 (Intel/AMD 64-bit mode).

DR_ISA_ARM_A32 

ARM A32 (AArch32 ARM).

DR_ISA_ARM_THUMB 

Thumb (ARM T32).

DR_ISA_ARM_A64 

ARM A64 (AArch64).

◆ dr_cleancall_save_t

Flags to request non-default preservation of state in a clean call as well as other call options.

Enumerator
DR_CLEANCALL_SAVE_FLOAT 

Save floating-point state (x86-specific). 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).

DR_CLEANCALL_NOSAVE_FLAGS 

Skip saving the flags and skip clearing the flags (including DF) for client execution. Note that this can cause problems if dr_redirect_execution() is called from a clean call, as an uninitialized flags value can cause subtle errors.

DR_CLEANCALL_NOSAVE_XMM 

Skip saving any XMM or YMM registers.

DR_CLEANCALL_NOSAVE_XMM_NONPARAM 

Skip saving any XMM or YMM registers that are never used as parameters.

DR_CLEANCALL_NOSAVE_XMM_NONRET 

Skip saving any XMM or YMM registers that are never used as return values.

DR_CLEANCALL_INDIRECT 

Requests that an indirect call be used to ensure reachability, both for reaching the callee and for any out-of-line helper routine calls. Only honored for 64-bit mode, where r11 will be used for the indirection.

DR_CLEANCALL_ALWAYS_OUT_OF_LINE 

Requests that out-of-line state save and restore routines be used even when a subset of the state does not need to be preserved for this callee. Also disables inlining. This helps guarantee that the inserted code remains small.

◆ dr_disasm_flags_t

Flags controlling disassembly style

Enumerator
DR_DISASM_DR 

The default: displays all operands, including implicit operands. Lists source operands first, then "->", and then destination operands.

DR_DISASM_INTEL 

Requests Intel syntax for disassembly. This sets the same option that is controlled by the runtime option -syntax_intel. Implicit operands are not displayed.

DR_DISASM_ATT 

Requests AT&T syntax for disassembly. This sets the same option that is controlled by the runtime option -syntax_att. Implicit operands are not displayed.

DR_DISASM_STRICT_INVALID 

Certain reserved or unspecified opcodes are in a gray area where they could be decoded with their length and operands understood, but they are not fully defined and in fact they may raise an illegal instruction fault when executed. By default, DR does not treat them as invalid. If this option is set, DR tightens up its decoding and does treat them as invalid.

DR_DISASM_NO_OPND_SIZE 

This flag only applies to the default DR style (i.e., it does not apply when DR_DISASM_INTEL or DR_DISASM_ATT is selected). That style by default displays the size of memory or sub-register operands via a suffix "[Nbytes]". Setting this flag removes that suffix.

DR_DISASM_ARM 

Requests standard ARM assembler syntax for disassembly. This sets the same option that is controlled by the runtime option -syntax_arm. Implicit operands are not displayed.

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

spill slot for register save/restore routines

SPILL_SLOT_3 

spill slot for register save/restore routines

SPILL_SLOT_4 

spill slot for register save/restore routines

SPILL_SLOT_5 

spill slot for register save/restore routines

SPILL_SLOT_6 

spill slot for register save/restore routines

SPILL_SLOT_7 

spill slot for register save/restore routines

SPILL_SLOT_8 

spill slot for register save/restore routines

SPILL_SLOT_9 

spill slot for register save/restore routines

SPILL_SLOT_10 

spill slot for register save/restore routines

SPILL_SLOT_11 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_12 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_13 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_14 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_15 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_16 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_17 

spill slot for register save/restore routines

Note
x64 only
SPILL_SLOT_MAX 

spill slot for register save/restore routines

Note
x64 only

Function Documentation

◆ decode()

byte* decode ( void *  drcontext,
byte *  pc,
instr_t instr 
)

Decodes the instruction at address pc into instr, filling in the instruction's opcode, eflags usage, prefixes, and operands. The instruction's raw bits are set to valid and pointed at pc (xref instr_get_raw_bits()). Assumes that instr is already initialized, but uses the x86/x64 mode for the thread dcontext rather than that set in instr. If caller is re-using same instr_t struct over multiple decodings, caller should call instr_reset() or instr_reuse(). Returns the address of the next byte after the decoded instruction. Returns NULL on decoding an invalid instr and sets opcode to OP_INVALID.

◆ decode_as_bb()

instrlist_t* decode_as_bb ( void *  drcontext,
byte *  start_pc 
)

Client routine to decode instructions at an arbitrary app address, following all the rules that DynamoRIO follows internally for terminating basic blocks. Note that DynamoRIO does not validate that start_pc is actually the first instruction of a basic block.

Note
Caller is reponsible for freeing the list and its instrs!

◆ decode_eflags_usage()

byte* decode_eflags_usage ( void *  drcontext,
byte *  pc,
uint *  usage,
dr_opnd_query_flags_t  flags 
)

Decodes only enough of the instruction at address pc to determine its eflags usage, which is returned in usage as EFLAGS_ constants or'ed together. Returns the address of the next byte after the decoded instruction. Returns NULL on decoding an invalid instruction.

◆ decode_first_opcode_byte()

byte decode_first_opcode_byte ( int  opcode)

Given an OP_ constant, returns the first byte of its opcode when encoded as an IA-32 instruction.

◆ decode_from_copy()

byte* decode_from_copy ( void *  drcontext,
byte *  copy_pc,
byte *  orig_pc,
instr_t instr 
)

Decodes the instruction at address copy_pc into instr as though it were located at address orig_pc. Any pc-relative operands have their values calculated as though the instruction were actually at orig_pc, though that address is never de-referenced. The instruction's raw bits are not valid, but its application address field (see instr_get_app_pc()) is set to orig_pc. The instruction's opcode, eflags usage, prefixes, and operands are all filled in. Assumes that instr is already initialized, but uses the x86/x64 mode for the thread dcontext rather than that set in instr. If caller is re-using same instr_t struct over multiple decodings, caller should call instr_reset() or instr_reuse(). Returns the address of the next byte after the decoded instruction copy at copy_pc. Returns NULL on decoding an invalid instr and sets opcode to OP_INVALID.

◆ decode_memory_reference_size()

app_pc decode_memory_reference_size ( void *  drcontext,
app_pc  pc,
uint *  size_in_bytes 
)

Calculates the size, in bytes, of the memory read or write of the instr at pc. If the instruction is a repeating string instruction, considers only one iteration. Returns the pc of the following instruction. If the instruction at pc does not reference memory, or is invalid, returns NULL.

◆ decode_next_pc()

byte* decode_next_pc ( void *  drcontext,
byte *  pc 
)

Decodes only enough of the instruction at address pc to determine its size. Returns the address of the byte following the instruction. May return NULL on decoding certain invalid instructions.

◆ decode_opcode_name()

const char* decode_opcode_name ( int  opcode)

Given an OP_ constant, returns the string name of its opcode.

◆ decode_sizeof()

int decode_sizeof ( void *  drcontext,
byte *  pc,
int *num_prefixes   _IF_X86_64uint *rip_rel_pos 
)

Decodes only enough of the instruction at address pc to determine its size. Returns that size. If num_prefixes is non-NULL, returns the number of prefix bytes. If rip_rel_pos is non-NULL, returns the offset into the instruction of a rip-relative addressing displacement (for data only: ignores control-transfer relative addressing), or 0 if none. May return 0 size for certain invalid instructions.

◆ decode_trace()

instrlist_t* decode_trace ( void *  drcontext,
void *  tag 
)

Decodes the trace with tag tag, and returns an instrlist_t of the instructions comprising that fragment. If tag is not a valid tag for an existing trace, the routine returns NULL. Clients can use dr_trace_exists_at() to determine whether the trace exists.

Note
Unlike the instruction list presented by the trace event, the list here does not include any existing client modifications. If client-modified instructions are needed, it is the responsibility of the client to record or recreate that list itself.
This routine does not support decoding thread-private traces created by other than the calling thread.

◆ disassemble()

byte* disassemble ( void *  drcontext,
byte *  pc,
file_t  outfile 
)

Decodes and then prints the instruction at address pc to file outfile. The default is to use DR's custom syntax (see disassemble_set_syntax()). Returns the address of the subsequent instruction, or NULL if the instruction at pc is invalid.

◆ disassemble_from_copy()

byte* disassemble_from_copy ( void *  drcontext,
byte *  copy_pc,
byte *  orig_pc,
file_t  outfile,
bool  show_pc,
bool  show_bytes 
)

Decodes the instruction at address copy_pc as though it were located at address orig_pc, and then prints the instruction to file outfile. Prior to the instruction the address orig_pc is printed if show_pc and the raw bytes are printed if show_bytes. The default is to use DR's custom syntax (see disassemble_set_syntax()). Returns the address of the subsequent instruction after the copy at copy_pc, or NULL if the instruction at copy_pc is invalid.

◆ disassemble_set_syntax()

void disassemble_set_syntax ( dr_disasm_flags_t  flags)

Sets the disassembly style and decoding options. The default is to use DR's custom syntax, unless one of the -syntax_intel, -syntax_att, or -syntax_arm runtime options is specified.

◆ disassemble_to_buffer()

byte* disassemble_to_buffer ( void *  drcontext,
byte *  pc,
byte *  orig_pc,
bool  show_pc,
bool  show_bytes,
char *  buf,
size_t  bufsz,
int *printed  OUT 
)

Decodes the instruction at address pc as though it were located at address orig_pc, and then prints the instruction to the buffer buf. Always null-terminates, and will not print more than bufsz characters, which includes the final null character. Indicates the number of characters printed, not including the final null, in printed, if printed is non-NULL.

Prior to the instruction the address orig_pc is printed if show_pc and the raw bytes are printed if show_bytes. The default is to use DR's custom syntax (see disassemble_set_syntax()). Returns the address of the subsequent instruction after the copy at copy_pc, or NULL if the instruction at copy_pc is invalid.

◆ disassemble_with_info()

byte* disassemble_with_info ( void *  drcontext,
byte *  pc,
file_t  outfile,
bool  show_pc,
bool  show_bytes 
)

Decodes and then prints the instruction at address pc to file outfile. Prior to the instruction the address is printed if show_pc and the raw bytes are printed if show_bytes. The default is to use DR's custom syntax (see disassemble_set_syntax()). Returns the address of the subsequent instruction, or NULL if the instruction at pc is invalid.

◆ dr_app_pc_as_jump_target()

app_pc dr_app_pc_as_jump_target ( dr_isa_mode_t  isa_mode,
app_pc  pc 
)

Given an application program counter value, returns the corresponding value to use as an indirect branch target for the given isa_mode. For ARM's Thumb mode (DR_ISA_ARM_THUMB), this involves setting the least significant bit of the address.

◆ dr_app_pc_as_load_target()

app_pc dr_app_pc_as_load_target ( dr_isa_mode_t  isa_mode,
app_pc  pc 
)

Given an application program counter value, returns the corresponding value to use as a memory load target for the given isa_mode, or for comparing to the application address inside a basic block or trace. For ARM's Thumb mode (DR_ISA_ARM_THUMB), this involves clearing the least significant bit of the address.

◆ dr_call_on_clean_stack()

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

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

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

dr_isa_mode_t dr_get_isa_mode ( void *  drcontext)

The decode and encode routines use a per-thread persistent flag that indicates which processor mode to use. This routine returns the value of that flag.

◆ dr_get_mcontext()

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:

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

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

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

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

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:

  1. address of call instruction (caller)
  2. target address of call (callee)

◆ dr_insert_cbr_instrumentation()

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:

  1. address of branch instruction
  2. target address of branch
  3. 0 if the branch is not taken, 1 if it is taken

◆ dr_insert_cbr_instrumentation_ex()

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:

  1. address of branch instruction
  2. target address of branch
  3. fall-through address of branch
  4. 0 if the branch is not taken, 1 if it is taken
  5. user defined operand (e.g., TLS slot, immed value, register, etc.)
    Note
    The user defined operand cannot use register ebx!

◆ dr_insert_clean_call()

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

On x86, if save_fpstate is true, preserves the fp/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).

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 beyond callee'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()

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

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

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

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:

  1. address of branch instruction
  2. 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.

◆ dr_insert_read_tls_field()

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

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

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:

  1. address of branch instruction
  2. 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.

◆ dr_insert_write_tls_field()

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

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

bool dr_mcontext_xmm_fields_valid ( void  )

Returns true if the xmm fields in dr_mcontext_t are valid (i.e., whether the underlying processor supports SSE).

Note
If DR_MC_MULTIMEDIA is not specified when calling dr_get_mcontext(), the xmm fields will not be filled in regardless of the return value of this routine.

◆ dr_prepare_for_call()

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 fp/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()

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

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.

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 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.
For ARM, to redirect execution to a Thumb target (DR_ISA_ARM_THUMB), set the least significant bit of the mcontext pc to 1. Reference Thumb Mode Addresses for more information.
Returns
false if unsuccessful; if successful, does not return.

◆ dr_redirect_native_target()

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

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

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

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

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

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

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

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

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

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 ensure reg is dead or saved at where.

◆ dr_save_arith_flags_to_xax()

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

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

◆ dr_set_isa_mode()

bool dr_set_isa_mode ( void *  drcontext,
dr_isa_mode_t  new_mode,
dr_isa_mode_t *old_mode  OUT 
)

The decode and encode routines use a per-thread persistent flag that indicates which processor mode to use. This routine sets that flag to the indicated value and optionally returns the old value. Be sure to restore the old value prior to any further application execution to avoid problems in mis-interpreting application code.

◆ dr_set_mcontext()

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:

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

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

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.

◆ get_x86_mode()

bool get_x86_mode ( void *  drcontext)

The decode and encode routines use a per-thread persistent flag that indicates whether to treat code as 32-bit (x86) or 64-bit (x64). This routine returns the value of that flag.

Note
For 64-bit DR builds only.
Deprecated:
Replaced by dr_get_isa_mode().

◆ instrlist_insert_mov_immed_ptrsz()

void instrlist_insert_mov_immed_ptrsz ( void *  drcontext,
ptr_int_t  val,
opnd_t  dst,
instrlist_t *  ilist,
instr_t where,
instr_t **first  OUT,
instr_t **last  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()

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  OUT,
instr_t **last  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()

void instrlist_insert_push_immed_ptrsz ( void *  drcontext,
ptr_int_t  val,
instrlist_t *  ilist,
instr_t where,
instr_t **first  OUT,
instr_t **last  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()

void instrlist_insert_push_instr_addr ( void *  drcontext,
instr_t src_inst,
byte *  encode_estimate,
instrlist_t *  ilist,
instr_t where,
instr_t **first  OUT,
instr_t **last  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()

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

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

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

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

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

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.

◆ set_x86_mode()

bool set_x86_mode ( void *  drcontext,
bool  x86 
)

The decode and encode routines use a per-thread persistent flag that indicates whether to treat code as 32-bit (x86) or 64-bit (x64). This routine sets that flag to the indicated value and returns the old value. Be sure to restore the old value prior to any further application execution to avoid problems in mis-interpreting application code.

Note
For 64-bit DR builds only.
Deprecated:
Replaced by dr_set_isa_mode().