bool instr_is_cti_short_rewrite(instr_t *instr, byte *pc) { /* We assume all app's cbz/cbnz have been mangled. * See comments in x86/'s version of this routine. */ dcontext_t *dcontext; dr_isa_mode_t old_mode; if (pc == NULL) { if (instr == NULL || !instr_has_allocated_bits(instr) || instr->length != CTI_SHORT_REWRITE_LENGTH) return false; pc = instr_get_raw_bits(instr); } if (instr != NULL && instr_opcode_valid(instr)) { int opc = instr_get_opcode(instr); if (opc != OP_cbz && opc != OP_cbnz) return false; } if ((*(pc+1) != CBNZ_BYTE_A && *(pc+1) != CBZ_BYTE_A) || /* Further verify by checking for a disp of 1 */ (*pc & 0xf8) != 0x08) return false; /* XXX: this would be easier if decode_raw_is_jmp took in isa_mode */ dcontext = get_thread_private_dcontext(); if (instr != NULL) dr_set_isa_mode(dcontext, instr_get_isa_mode(instr), &old_mode); if (!decode_raw_is_jmp(dcontext, pc + CTI_SHORT_REWRITE_B_OFFS)) return false; if (instr != NULL) dr_set_isa_mode(dcontext, old_mode, NULL); return true; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *next_instr; #ifdef VERBOSE dr_printf("in dr_basic_block(tag="PFX")\n", tag); # if VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first_app(bb); instr != NULL; instr = next_instr) { next_instr = instr_get_next_app(instr); if (!instr_opcode_valid(instr)) continue; /* instrument calls and returns -- ignore far calls/rets */ if (instr_is_call_direct(instr)) { dr_insert_call_instrumentation(drcontext, bb, instr, (app_pc)at_call); } else if (instr_is_call_indirect(instr)) { dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_call_ind, SPILL_SLOT_1); } else if (instr_is_return(instr)) { dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_return, SPILL_SLOT_1); } } return DR_EMIT_DEFAULT; }