core/x86/instrument.c
/* Inserts a complete call to callee with the passed-in arguments, wrapped
 * by an app save and restore.
 * If "save_fpstate" is true, saves the fp/mmx/sse state.
 *
 * NOTE : this routine clobbers TLS_XAX_SLOT and the XSP mcontext slot via
 * dr_prepare_for_clean_call(). We guarantee to clients that all other slots
 * (except the XAX mcontext slot) will remain untouched.
 */
Inserts a complete call to callee with the passed-in arguments, wrapped
by an app save and restore.
If "save_fpstate" is true, saves the fp/mmx/sse state.

NOTE : this routine clobbers TLS_XAX_SLOT and the XSP mcontext slot via
dr_prepare_for_clean_call(). We guarantee to clients that all other slots
(except the XAX mcontext slot) will remain untouched.
Inserts a complete call to callee with the passed - in arguments wrapped by an app save and restore . If " save_fpstate " is true saves the fp / mmx / sse state . NOTE : this routine clobbers TLS_XAX_SLOT and the XSP mcontext slot via dr_prepare_for_clean_call () . We guarantee to clients that all other slots ( except the XAX mcontext slot ) will remain untouched .
void
dr_insert_clean_call(void *drcontext, instrlist_t *ilist, instr_t *where,
                     void *callee, bool save_fpstate, uint num_args, ...)
{
    dcontext_t *dcontext = (dcontext_t *) drcontext;
    uint dstack_offs, pad = 0;
    size_t buf_sz = 0;
    va_list ap;
    CLIENT_ASSERT(drcontext != NULL, "dr_insert_clean_call: drcontext cannot be NULL");
    va_start(ap, num_args);
    dstack_offs = dr_prepare_for_call(dcontext, ilist, where);
#ifdef X64
    CLIENT_ASSERT(ALIGNED(dstack_offs, 16), "internal error: bad stack alignment");
#endif
    if (save_fpstate) {
        buf_sz = proc_fpstate_save_size();
        pad = ALIGN_FORWARD_UINT(dstack_offs, 16) - dstack_offs;
        IF_X64(CLIENT_ASSERT(CHECK_TRUNCATE_TYPE_int(buf_sz + pad),
                             "dr_insert_clean_call: internal truncation error"));
        MINSERT(ilist, where, INSTR_CREATE_sub(dcontext, opnd_create_reg(REG_XSP),
                                               OPND_CREATE_INT32((int)(buf_sz + pad))));
        dr_insert_save_fpstate(drcontext, ilist, where,
                               opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0,
                                                     OPSZ_512));
    }
    instrlist_set_our_mangling(ilist, true);
    insert_meta_call_vargs(dcontext, ilist, where, true, callee, num_args, ap);
    instrlist_set_our_mangling(ilist, false);
    if (save_fpstate) {
        dr_insert_restore_fpstate(drcontext, ilist, where,
                                  opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0,
                                                        OPSZ_512));
        MINSERT(ilist, where, INSTR_CREATE_add(dcontext, opnd_create_reg(REG_XSP),
                                               OPND_CREATE_INT32(buf_sz + pad)));
    }
    dr_cleanup_after_call(dcontext, ilist, where, 0);
    va_end(ap);
}
void dr_insert_clean_call ( void * drcontext , instrlist_t * ilist , instr_t * where , void * callee , bool save_fpstate , uint num_args , ... ) { dcontext_t * dcontext = ( dcontext_t * ) drcontext ; uint dstack_offs , pad = 0 ; size_t buf_sz = 0 ; va_list ap ; CLIENT_ASSERT ( drcontext != NULL , " " ) ; va_start ( ap , num_args ) ; dstack_offs = dr_prepare_for_call ( dcontext , ilist , where ) ; #ifdef X64 CLIENT_ASSERT ( ALIGNED ( dstack_offs , 16 ) , " " ) ; #endif if ( save_fpstate ) { buf_sz = proc_fpstate_save_size ( ) ; pad = ALIGN_FORWARD_UINT ( dstack_offs , 16 ) - dstack_offs ; IF_X64 ( CLIENT_ASSERT ( CHECK_TRUNCATE_TYPE_int ( buf_sz + pad ) , " " ) ) ; MINSERT ( ilist , where , INSTR_CREATE_sub ( dcontext , opnd_create_reg ( REG_XSP ) , OPND_CREATE_INT32 ( ( int ) ( buf_sz + pad ) ) ) ) ; dr_insert_save_fpstate ( drcontext , ilist , where , opnd_create_base_disp ( REG_XSP , REG_NULL , 0 , 0 , OPSZ_512 ) ) ; } instrlist_set_our_mangling ( ilist , true ) ; insert_meta_call_vargs ( dcontext , ilist , where , true , callee , num_args , ap ) ; instrlist_set_our_mangling ( ilist , false ) ; if ( save_fpstate ) { dr_insert_restore_fpstate ( drcontext , ilist , where , opnd_create_base_disp ( REG_XSP , REG_NULL , 0 , 0 , OPSZ_512 ) ) ; MINSERT ( ilist , where , INSTR_CREATE_add ( dcontext , opnd_create_reg ( REG_XSP ) , OPND_CREATE_INT32 ( buf_sz + pad ) ) ) ; } dr_cleanup_after_call ( dcontext , ilist , where , 0 ) ; va_end ( ap ) ; }
Inserts a complete call to callee with the passed-in arguments, wrapped
 by an app save and restore.
Inserts a complete call to callee with the passed - in arguments wrapped by an app save and restore .
/* we don't check for GLOBAL_DCONTEXT since DR internally calls this */ /* PR 218790: we assume that dr_prepare_for_call() leaves stack 16-byte
     * aligned, which is what insert_meta_call_vargs requires. */ /* save on the stack: xref PR 202669 on clients using more stack */ /* we need 16-byte-alignment */ /* PR 302951: restore state if clean call args reference app memory.
     * We use a hack here: this is the only instance where we mark as our-mangling
     * but do not have a translation target set, which indicates to the restore
     * routines that this is a clean call.  If the client adds instrs in the middle
     * translation will fail; if the client modifies any instr, the our-mangling
     * flag will disappear and translation will fail.
     */ /*clean*/