/* insert inline code to add a memory reference info entry into the buffer */ static void instrument_mem(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t ref, bool write) { /* We need two scratch registers */ reg_id_t reg_ptr, reg_tmp; 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; } /* save_addr should be called first as reg_ptr or reg_tmp maybe used in ref */ insert_save_addr(drcontext, ilist, where, ref, reg_ptr, reg_tmp); insert_save_type(drcontext, ilist, where, reg_ptr, reg_tmp, write ? REF_TYPE_WRITE : REF_TYPE_READ); insert_save_size(drcontext, ilist, where, reg_ptr, reg_tmp, (ushort)drutil_opnd_mem_size_in_bytes(ref, 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); }
int offline_instru_t::instrument_memref(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg_ptr, reg_id_t reg_tmp, int adjust, opnd_t ref, bool write, dr_pred_type_t pred) { // Post-processor distinguishes read, write, prefetch, flush, and finds size. instr_t *label = INSTR_CREATE_label(drcontext); MINSERT(ilist, where, label); insert_save_addr(drcontext, ilist, where, reg_ptr, reg_tmp, adjust, ref); #ifdef ARM // X86 does not support general predicated execution if (pred != DR_PRED_NONE) { instr_t *instr; for (instr = instr_get_prev(where); instr != label; instr = instr_get_prev(instr)) { DR_ASSERT(!instr_is_predicated(instr)); instr_set_predicate(instr, pred); } } #endif return (adjust + sizeof(offline_entry_t)); }