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)); }
static inline void check_translation(instrlist_t *ilist, instr_t *inst) { if (ilist->translation_target != NULL && instr_get_translation(inst) == NULL) { instr_set_translation(inst, ilist->translation_target); } if (instrlist_get_our_mangling(ilist)) instr_set_our_mangling(inst, true); #if defined(CLIENT_INTERFACE) && defined(ARM) if (instr_is_meta(inst)) { dr_pred_type_t auto_pred = ilist->auto_pred; if (instr_predicate_is_cond(auto_pred)) { CLIENT_ASSERT(!instr_is_cti(inst), "auto-predication does not support cti's"); CLIENT_ASSERT( !TESTANY(EFLAGS_WRITE_NZCV, instr_get_arith_flags(inst, DR_QUERY_INCLUDE_COND_SRCS)), "cannot auto predicate a meta-inst that writes to NZCV"); if (!instr_is_predicated(inst)) instr_set_predicate(inst, auto_pred); } } #endif }
void test_dr_insert_it_instrs_cbr(void *dcontext) { instrlist_t *ilist = instrlist_create(dcontext); instr_t *where = INSTR_CREATE_label(dcontext); instr_t *instr_it1, *instr_it2, *instr_it3; byte buffer[4096]; instrlist_append(ilist, where); instrlist_preinsert(ilist, where, XINST_CREATE_move (dcontext, opnd_create_reg(DR_REG_R1), opnd_create_reg(DR_REG_R2))); instrlist_preinsert(ilist, where, XINST_CREATE_jump (dcontext, opnd_create_instr(where))); instrlist_preinsert(ilist, where, XINST_CREATE_move (dcontext, opnd_create_reg(DR_REG_R1), opnd_create_reg(DR_REG_R2))); instrlist_preinsert(ilist, where, XINST_CREATE_move (dcontext, opnd_create_reg(DR_REG_R1), opnd_create_reg(DR_REG_R2))); instrlist_preinsert(ilist, where, XINST_CREATE_jump (dcontext, opnd_create_instr(where))); instrlist_preinsert(ilist, where, XINST_CREATE_move (dcontext, opnd_create_reg(DR_REG_R1), opnd_create_reg(DR_REG_R2))); instrlist_preinsert(ilist, where, XINST_CREATE_move (dcontext, opnd_create_reg(DR_REG_R1), opnd_create_reg(DR_REG_R2))); instrlist_preinsert(ilist, where, XINST_CREATE_move (dcontext, opnd_create_reg(DR_REG_R1), opnd_create_reg(DR_REG_R2))); instrlist_preinsert(ilist, where, XINST_CREATE_jump (dcontext, opnd_create_instr(where))); /* set them all to be predicated and reinstate it instrs */ for (where = instrlist_first(ilist); where; where = instr_get_next(where)) { bool ok = instr_set_isa_mode(where, DR_ISA_ARM_THUMB); DR_ASSERT(ok); instr_set_predicate(where, DR_PRED_LS); } dr_insert_it_instrs(dcontext, ilist); /* Make sure it was encoded properly, noting that the branches * should *not* be in any IT-block. * it * mov.ls r1, r2 * b.ls @0x47366864 * itt * mov.ls r1, r2 * mov.ls r1, r2 * b.ls @0x47366864 * ittt * mov.ls r1, r2 * mov.ls r1, r2 * mov.ls r1, r2 * b.ls @0x47366864 */ instr_it1 = instrlist_first(ilist); instr_it2 = instr_get_next(instr_get_next(instr_get_next(instr_it1))); instr_it3 = instr_get_next(instr_get_next(instr_get_next(instr_get_next(instr_it2)))); DR_ASSERT(instr_get_opcode(instr_it1) == OP_it); DR_ASSERT(instr_it_block_get_count(instr_it1) == 1); DR_ASSERT(instr_get_opcode(instr_it2) == OP_it); DR_ASSERT(instr_it_block_get_count(instr_it2) == 2); DR_ASSERT(instr_get_opcode(instr_it3) == OP_it); DR_ASSERT(instr_it_block_get_count(instr_it3) == 3); instrlist_encode(dcontext, ilist, buffer, true); }