pub unsafe extern "C" fn dr_insert_clean_call(
drcontext: *mut c_void,
ilist: *mut instrlist_t,
where_: *mut instr_t,
callee: *mut c_void,
save_fpstate: bool_,
num_args: uint,
...
)Expand description
Inserts into \p ilist prior to \p 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 \p 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 \p num_args equal to the value of \p 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 \c 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: \ref page_drreg), 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 \p 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, \p 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 \ref op_cleancall “-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 \p 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 \c callee’s return point.
\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.
\note 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.
\note 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.
\note For 64-bit mode, variable-sized argument operands may not work properly.
\note Arguments that reference sub-register portions of DR_REG_XSP are not supported (full DR_REG_XSP is supported).