/* insert inline code to add an instruction entry into the buffer */ static void instrument_instr(void *drcontext, instrlist_t *ilist, instr_t *where) { /* We need two scratch registers */ reg_id_t reg_ptr, reg_tmp; /* we don't want to predicate this, because an instruction fetch always occurs */ instrlist_set_auto_predicate(ilist, DR_PRED_NONE); if (drreg_reserve_register(drcontext, ilist, where, NULL, ®_ptr) != DRREG_SUCCESS || drreg_reserve_register(drcontext, ilist, where, NULL, ®_tmp) != DRREG_SUCCESS) { DR_ASSERT(false); /* cannot recover */ return; } insert_load_buf_ptr(drcontext, ilist, where, reg_ptr); insert_save_type(drcontext, ilist, where, reg_ptr, reg_tmp, (ushort)instr_get_opcode(where)); insert_save_size(drcontext, ilist, where, reg_ptr, reg_tmp, (ushort)instr_length(drcontext, where)); insert_save_pc(drcontext, ilist, where, reg_ptr, reg_tmp, instr_get_app_pc(where)); insert_update_buf_ptr(drcontext, ilist, where, reg_ptr, sizeof(mem_ref_t)); /* Restore scratch registers */ if (drreg_unreserve_register(drcontext, ilist, where, reg_ptr) != DRREG_SUCCESS || drreg_unreserve_register(drcontext, ilist, where, reg_tmp) != DRREG_SUCCESS) DR_ASSERT(false); instrlist_set_auto_predicate(ilist, instr_get_predicate(where)); }
static void insert_save_addr(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t ref, reg_id_t reg_ptr, reg_id_t reg_addr) { bool ok; /* we use reg_ptr as scratch to get addr */ ok = drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg_addr, reg_ptr); DR_ASSERT(ok); insert_load_buf_ptr(drcontext, ilist, where, reg_ptr); MINSERT(ilist, where, XINST_CREATE_store(drcontext, OPND_CREATE_MEMPTR(reg_ptr, offsetof(mem_ref_t, addr)), opnd_create_reg(reg_addr))); }
void offline_instru_t::insert_save_addr(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg_ptr, reg_id_t reg_addr, int adjust, opnd_t ref) { bool ok; int disp = adjust; if (opnd_uses_reg(ref, reg_ptr)) drreg_get_app_value(drcontext, ilist, where, reg_ptr, reg_ptr); if (opnd_uses_reg(ref, reg_addr)) drreg_get_app_value(drcontext, ilist, where, reg_addr, reg_addr); // We use reg_ptr as scratch to get the address. ok = drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg_addr, reg_ptr); DR_ASSERT(ok); // drutil_insert_get_mem_addr may clobber reg_ptr, so we need to re-load reg_ptr. // XXX i#2001: determine whether we have to and avoid it when we don't. insert_load_buf_ptr(drcontext, ilist, where, reg_ptr); MINSERT(ilist, where, XINST_CREATE_store(drcontext, OPND_CREATE_MEMPTR(reg_ptr, disp), opnd_create_reg(reg_addr))); // We allow either 0 or all 1's as the type so no need to write anything else. }