/* iterate basic block to find a dead register */ static reg_id_t bb_find_dead_reg(instrlist_t *ilist) { instr_t *instr; int i; bool reg_is_read[DR_NUM_GPR_REGS] = { false,}; for (instr = instrlist_first(ilist); instr != NULL; instr = instr_get_next(instr)) { if (instr_is_syscall(instr) || instr_is_interrupt(instr)) return DR_REG_NULL; for (i = 0; i < DR_NUM_GPR_REGS; i++) { if (!reg_is_read[i] && instr_reads_from_reg(instr, (reg_id_t)(DR_REG_START_GPR + i))) { reg_is_read[i] = true; } if (!reg_is_read[i] && instr_writes_to_exact_reg(instr, (reg_id_t)(DR_REG_START_GPR + i))) { return (reg_id_t)(DR_REG_START_GPR + i); } #ifdef X64 /* in x64, update on 32-bit register kills the whole register */ if (!reg_is_read[i] && instr_writes_to_exact_reg(instr, reg_64_to_32 ((reg_id_t)(DR_REG_START_GPR + i)))) { return (reg_id_t)(DR_REG_START_GPR + i); } #endif } } return DR_REG_NULL; }
static dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr; if (!translating) increment(tag); /* I'm looking for a specific BB in the test .exe. I've marked * it with a couple nops. */ #ifdef WINDOWS if ((app_pc)tag >= start && (app_pc)tag < end) { #endif instr = instrlist_first(bb); if (instr_is_nop(instr)) { instr_t *next = instr_get_next(instr); /* The test app uses two nops as a marker to identify a specific bb. Since * 2 nop instructions in a row aren't that uncommon on Linux (where we can't * restrict our search to just the test.exe module) we use an unusual nop * for the second one: xchg xbp, xbp */ if (next != NULL && instr_is_nop(next) && instr_get_opcode(next) == OP_xchg && instr_writes_to_exact_reg(next, REG_XBP, DR_QUERY_DEFAULT)) { bb_build_count++; if (delay_flush_at_next_build) { delay_flush_at_next_build = false; dr_delay_flush_region((app_pc)tag - 20, 30, callback_count, flush_event); } dr_insert_clean_call(drcontext, bb, instr, (void *)callback, false, 2, OPND_CREATE_INTPTR(tag), OPND_CREATE_INTPTR(instr_get_app_pc(instr))); } } #ifdef WINDOWS } #endif return DR_EMIT_DEFAULT; }