/* If has_instr_jmp_targets is true, this routine trashes the note field * of each instr_t to store the offset in order to properly encode * the relative pc for an instr_t jump target */ byte * instrlist_encode_to_copy(dcontext_t *dcontext, instrlist_t *ilist, byte *copy_pc, byte *final_pc, byte *max_pc, bool has_instr_jmp_targets) { instr_t *inst; int len = 0; #ifdef ARM /* XXX i#1734: reset encode state to avoid any stale encode state * or dangling pointer. */ if (instr_get_isa_mode(instrlist_first(ilist)) == DR_ISA_ARM_THUMB) encode_reset_it_block(dcontext); #endif /* Do an extra pass over the instrlist so we can determine if an instr opnd * was erroneously used with has_instr_jmp_targets = false. */ DOCHECK(2, { if (!has_instr_jmp_targets) { for (inst = instrlist_first(ilist); inst; inst = instr_get_next(inst)) { if (TEST(INSTR_OPERANDS_VALID, (inst)->flags)) { int i; for (i = 0; i < instr_num_srcs(inst); ++i) { CLIENT_ASSERT(!opnd_is_instr(instr_get_src(inst, i)), "has_instr_jmp_targets was unset " "but an instr opnd was found"); } } } } });
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr; uint num_instrs; #ifdef VERBOSE dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag); # ifdef VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first(bb), num_instrs = 0; instr != NULL; instr = instr_get_next(instr)) { num_instrs++; } dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)inscount, false /* save fpstate */, 1, OPND_CREATE_INT32(num_instrs)); #if defined(VERBOSE) && defined(VERBOSE_VERBOSE) dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, bb, STDOUT); #endif return DR_EMIT_DEFAULT; }
/* If has_instr_jmp_targets is true, this routine trashes the note field * of each instr_t to store the offset in order to properly encode * the relative pc for an instr_t jump target */ byte * instrlist_encode_to_copy(dcontext_t *dcontext, instrlist_t *ilist, byte *copy_pc, byte *final_pc, byte *max_pc, bool has_instr_jmp_targets) { instr_t *inst; int len = 0; if (has_instr_jmp_targets || max_pc != NULL) { /* must set note fields first with offset, or compute length */ for (inst = instrlist_first(ilist); inst; inst = instr_get_next(inst)) { if (has_instr_jmp_targets) instr_set_note(inst, (void *)(ptr_int_t)len); len += instr_length(dcontext, inst); } } if (max_pc != NULL && (copy_pc + len > max_pc || POINTER_OVERFLOW_ON_ADD(copy_pc, len))) return NULL; for (inst = instrlist_first(ilist); inst != NULL; inst = instr_get_next(inst)) { byte *pc = instr_encode_to_copy(dcontext, inst, copy_pc, final_pc); if (pc == NULL) return NULL; final_pc += pc - copy_pc; copy_pc = pc; } return copy_pc; }
dr_emit_flags_t inscount_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, bool for_trace, bool translating, void *user_data) { instr_t *first = instrlist_first(bb); uint num_instrs = 0; if(instr != first) return DR_EMIT_DEFAULT; if(filter_from_list(head,instr,client_arg->filter_mode)){ for(instr = first ; instr!=NULL ; instr = instr_get_next(instr)){ num_instrs++; } bbcount++; } if(num_instrs > 0){ dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)inscount, false /* save fpstate */, 1, OPND_CREATE_INT32(num_instrs)); } return DR_EMIT_DEFAULT; }
instrlist_t* instrlist_clone(dcontext_t *dcontext, instrlist_t *old) { instr_t *inst, *copy; instrlist_t *newlist = instrlist_create(dcontext); inst = instrlist_first(old); while (inst != NULL) { copy = instr_clone(dcontext, inst); /* to copy instr targets we temporarily clobber note field */ instr_set_note(inst, (void *)copy); instrlist_append(newlist, copy); inst = instr_get_next(inst); } /* Fix up instr src if it is an instr and restore note field */ /* Note: we do not allows instruction update code cache, * which is very dangerous. * So we do not support instr as dst opnd and won't fix up here if any. */ for (inst = instrlist_first(old), copy = instrlist_first(newlist); inst != NULL && copy != NULL; inst = instr_get_next(inst), copy = instr_get_next(copy)) { int i; for (i = 0; i < inst->num_srcs; i++) { instr_t *tgt; opnd_t op = instr_get_src(copy, i); if (!opnd_is_instr(op)) continue; CLIENT_ASSERT(opnd_get_instr(op) != NULL, "instrlist_clone: NULL instr operand"); tgt = (instr_t *) instr_get_note(opnd_get_instr(op)); CLIENT_ASSERT(tgt != NULL, "instrlist_clone: operand instr not in instrlist"); if (opnd_is_far_instr(op)) { instr_set_src(copy, i, opnd_create_far_instr (opnd_get_segment_selector(op), tgt)); } else instr_set_src(copy, i, opnd_create_instr(tgt)); } } for (inst = instrlist_first(old), copy = instrlist_first(newlist); inst != NULL && copy != NULL; inst = instr_get_next(inst), copy = instr_get_next(copy)) { /* restore note field */ instr_set_note(inst, instr_get_note(copy)); } #ifdef CLIENT_INTERFACE newlist->fall_through_bb = old->fall_through_bb; #endif return newlist; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *mbr = NULL; uint num_instrs; bool bb_in_app; #ifdef VERBOSE dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag); # ifdef VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first(bb), num_instrs = 0; instr != NULL; instr = instr_get_next(instr)) { /* only care about app instr */ if (!instr_ok_to_mangle(instr)) continue; num_instrs++; /* Assuming most of the transfers between app and lib are paired, we * instrument indirect branches but not returns for better performance. */ if (instr_is_mbr(instr) && !instr_is_return(instr)) mbr = instr; } if (dr_fragment_app_pc(tag) >= app_base && dr_fragment_app_pc(tag) < app_end) bb_in_app = true; else bb_in_app = false; dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)(bb_in_app ? app_update : lib_update), false /* save fpstate */, 1, OPND_CREATE_INT32(num_instrs)); if (mbr != NULL) { dr_insert_mbr_instrumentation(drcontext, bb, mbr, (void *)(bb_in_app ? app_mbr : lib_mbr), SPILL_SLOT_1); } #if defined(VERBOSE) && defined(VERBOSE_VERBOSE) dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, bb, STDOUT); #endif return DR_EMIT_DEFAULT; }
static dr_emit_flags_t bb_event(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { static int64 bb_count; if (++bb_count % 10 == 0) { for (instr_t *inst = instrlist_first(bb); inst != NULL; inst = instr_get_next(inst)) { if (instr_is_exclusive_store(inst)) return DR_EMIT_DEFAULT; } dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)cleancallee, false, 1, OPND_CREATE_INTPTR(tag)); } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { app_pc pc = dr_fragment_app_pc(tag); if (pc == start_pc) { dr_fprintf(STDERR, "starting syscall monitoring\n"); monitoring = true; } else if (pc == stop_pc) { dr_fprintf(STDERR, "stopping syscall monitoring\n"); monitoring = false; } else { instr_t* instr; instr_t* next_instr; for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) { next_instr = instr_get_next(instr); /* Insert a callback to at_syscall before every system call */ if (instr_is_syscall(instr)) { dr_insert_clean_call(drcontext, bb, instr, at_syscall, false, 0); } } } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { int i; instr_t *instr, *first = instrlist_first(bb); for (instr = first; instr != NULL; instr = instr_get_next(instr)) { if (instr_reads_memory(instr)) { for (i = 0; i < instr_num_srcs(instr); i++) { if (opnd_is_memory_reference(instr_get_src(instr, i))) { instrument_mem(drcontext, bb, instr, i, false); } } } if (instr_writes_memory(instr)) { for (i = 0; i < instr_num_dsts(instr); i++) { if (opnd_is_memory_reference(instr_get_dst(instr, i))) { instrument_mem(drcontext, bb, instr, i, true); } } } } // dr_printf("count %d\n",count); return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_bb ( void* drcontext, void* tag, instrlist_t* bb, bool for_trace, bool translating ) { /* refer to dr_ir_instr.h */ instr_t* insn = instrlist_first(bb); for (; insn != NULL; insn = instr_get_next(insn)) { ++insn_count; if (instr_reads_memory(insn)) { ++read_count; read_size += instr_memory_reference_size(insn); dr_printf("read_size:%u\n", instr_memory_reference_size(insn)); } if (instr_writes_memory(insn)) { ++writ_count; writ_size += instr_memory_reference_size(insn); } } return DR_EMIT_DEFAULT; }
/* replaces all inc with add 1, dec with sub 1 * if cannot replace (eflags constraints), leaves original instruction alone */ static dr_emit_flags_t event_trace(void *drcontext, void *tag, instrlist_t *trace, bool translating) { instr_t *instr, *next_instr; int opcode; if (!enable) return DR_EMIT_DEFAULT; #ifdef VERBOSE dr_printf("in dynamorio_trace(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, trace, STDOUT); #endif for (instr = instrlist_first(trace); instr != NULL; instr = next_instr) { /* grab next now so we don't go over instructions we insert */ next_instr = instr_get_next(instr); opcode = instr_get_opcode(instr); if (opcode == OP_inc || opcode == OP_dec) { if (!translating) ATOMIC_INC(num_examined); if (replace_inc_with_add(drcontext, instr, trace)) { if (!translating) ATOMIC_INC(num_converted); } } } #ifdef VERBOSE dr_printf("after dynamorio_trace(tag="PFX"):\n", tag); instrlist_disassemble(drcontext, tag, trace, STDOUT); #endif return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr; trace_head_entry_t *e = NULL; if (translating) return DR_EMIT_DEFAULT; for (instr = instrlist_first(bb); instr != NULL; instr = instr_get_next(instr)) { /* blocks containing calls are trace heads */ if (instr_is_call(instr)) { dr_mark_trace_head(drcontext, tag); dr_mutex_lock(htable_mutex); e = add_trace_head_entry(NULL, tag); e->is_trace_head = true; dr_mutex_unlock(htable_mutex); #ifdef VERBOSE dr_log(drcontext, LOG_ALL, 3, "inline: marking bb "PFX" as trace head\n", tag); #endif /* doesn't matter what's in rest of bb */ return DR_EMIT_DEFAULT; } else if (instr_is_return(instr)) { dr_mutex_lock(htable_mutex); e = add_trace_head_entry(NULL, tag); e->has_ret = true; dr_mutex_unlock(htable_mutex); } } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t* bb, bool for_trace, bool translating) { instr_t *instr; instr_t *next_instr; reg_t in_eax = -1; for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) { next_instr = instr_get_next(instr); if (instr_get_opcode(instr) == OP_mov_imm && opnd_get_reg(instr_get_dst(instr, 0)) == REG_EAX) in_eax = opnd_get_immed_int(instr_get_src(instr, 0)); if (instr_is_syscall(instr) && in_eax == SYS_getpid) { instr_t *myval = INSTR_CREATE_mov_imm (drcontext, opnd_create_reg(REG_EAX), OPND_CREATE_INT32(-7)); instr_set_translation(myval, instr_get_app_pc(instr)); instrlist_preinsert(bb, instr, myval); instrlist_remove(bb, instr); instr_destroy(drcontext, instr); } } return DR_EMIT_DEFAULT; }
/* 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; }
/** Selects registers that should be used for instrumenting given fragment. * Returns a place where instrumentation should be inserted. */ instr_t* configure_instr(struct instr_info_t* instr_info, instrlist_t* frag) { // TODO: find dead registers instr_info->tls_reg = DR_REG_XAX; instr_info->restore_tls_reg = true; instr_info->current_reg = DR_REG_XDX; instr_info->restore_current_reg = true; return instrlist_first(frag); }
static dr_emit_flags_t bb_event(void* drcontext, void* tag, instrlist_t* bb, bool for_trace, bool translating) { dr_fprintf(STDERR, "got BB event\n"); dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)unregister, false, 0); return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_bb_analysis(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating, OUT void **user_data) { /* point at first instr */ *user_data = (void *) instrlist_first(bb); return DR_EMIT_DEFAULT; }
/* frees the Instrs in the instrlist_t */ void instrlist_clear(dcontext_t *dcontext, instrlist_t *ilist) { instr_t *instr; while (NULL != (instr = instrlist_first(ilist))) { instrlist_remove(ilist, instr); instr_destroy(dcontext, instr); } }
static dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *next_instr; int opcode; for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) { next_instr = instr_get_next(instr); opcode = instr_get_opcode(instr); if(instr_is_floating(instr)){ // dr_fprintf(logF, "Has seen FPU instruction with opcode %d\n",opcode); } else if(is_SIMD_packed(opcode)){ // dr_fprintf(logF, "Has seen SIMD packed instruction with opcode %d\n",opcode); } //AVX?rcpps? else if(is_SIMD_arithm(opcode)){ int is_single = 0; // printf("opcode is %d\n", opcode); // printf("number of sources %d\n", instr_num_srcs(instr)); // printf("number of dests %d\n", instr_num_dsts(instr)); //assert(number of sources = 2); opnd_t source1 = instr_get_src(instr,0); opnd_t source2 = instr_get_src(instr,1); opnd_t dest = instr_get_dst(instr,0); if(opnd_is_memory_reference(source1)){ // dr_print_instr(drcontext, logF, instr, "INSTR: "); // dr_print_opnd(drcontext, logF, source1, "OPND1: "); // dr_print_opnd(drcontext, logF, source2, "OPND2: "); reg_id_t rd = opnd_get_reg(source2); reg_id_t rs = opnd_get_reg_used(source1, 0); dr_insert_clean_call(drcontext, bb, instr, (void*) callback, true, 5, OPND_CREATE_INTPTR(rs), OPND_CREATE_INTPTR(opnd_get_disp(source1)), OPND_CREATE_INTPTR(rd), OPND_CREATE_INTPTR(opcode), OPND_CREATE_INTPTR(instr_get_app_pc(instr))); } else if(opnd_is_reg(source1) && opnd_is_reg(source2)){ reg_id_t reg1 = opnd_get_reg(source1); reg_id_t reg2 = opnd_get_reg(source2); dr_insert_clean_call(drcontext,bb,instr, (void*)getRegReg, true, 4, OPND_CREATE_INTPTR(reg1), OPND_CREATE_INTPTR(reg2) ,OPND_CREATE_INTPTR(opcode), OPND_CREATE_INTPTR(instr_get_app_pc(instr)) ); } else{ //should not be the case, throw an exception } fp_count++; } } return DR_EMIT_DEFAULT; }
void instrlist_append_instrlist(dcontext_t *dcontext,instrlist_t *ilist, instrlist_t *appendee) { instr_t *first=instrlist_first(appendee); if (!first) return; instrlist_append(ilist,first); instrlist_init(appendee); instrlist_destroy(dcontext,appendee); }
dr_emit_flags_t funcwrap_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, bool for_trace, bool translating, void *user_data) { instr_t * first = instrlist_first(bb); app_pc pc = instr_get_app_pc(first); module_data_t * module_data; per_thread_t * data = drmgr_get_tls_field(dr_get_current_drcontext(), tls_index); module_t * md; app_pc offset; if (instr != first || data->nesting != 0){ return DR_EMIT_DEFAULT; } module_data = dr_lookup_module(pc); data = drmgr_get_tls_field(drcontext, tls_index); if (module_data != NULL){ md = md_lookup_module(head, module_data->full_path); if (md != NULL){ offset = pc - module_data->start; for (int i = 1; i <= md->bbs[0].start_addr; i++){ if (offset == md->bbs[i].start_addr){ DEBUG_PRINT("bb instrumenting function\n"); data->filter_func = true; dr_insert_clean_call(drcontext, bb, instr, clean_call, false, 1, OPND_CREATE_INTPTR(instr_get_app_pc(instr))); wrap_thread_id = dr_get_thread_id(drcontext); DEBUG_PRINT("done bb instrumenting function\n"); } } } } /*if (data->filter_func){ instrlist_disassemble(drcontext, instr_get_app_pc(instrlist_first(bb)), bb, logfile); }*/ dr_free_module_data(module_data); return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_bb(void *dc, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *where = instrlist_first(bb); instr_t *ret_label = INSTR_CREATE_label(dc); dr_save_reg(dc, bb, where, DR_REG_XAX, SPILL_SLOT_1); PRE(bb, where, INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX), opnd_create_instr(ret_label))); PRE(bb, where, INSTR_CREATE_jmp(dc, opnd_create_pc(slowpath))); PRE(bb, where, ret_label); dr_restore_reg(dc, bb, where, DR_REG_XAX, SPILL_SLOT_1); return DR_EMIT_DEFAULT; }
/* event_bb_insert calls instrument_mem to instrument every * application memory reference. */ dr_emit_flags_t memtrace_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, bool for_trace, bool translating, void *user_data) { int i; reg_id_t reg; file_t out_file; instr_t * first = NULL; instr_t * current; //DR_ASSERT(instr_ok_to_mangle(instr)); if (instr_ok_to_mangle(instr)){ /* FIXME - need to generalize the filtering library */ for (current = instrlist_first(bb); current != NULL; current = instr_get_next(current)){ if (instr_ok_to_mangle(current)){ first = current; break; } } if ((first != NULL) && filter_from_list(head, first, client_arg->filter_mode)){ if (instr_reads_memory(instr)) { for (i = 0; i < instr_num_srcs(instr); i++) { if (opnd_is_memory_reference(instr_get_src(instr, i))) { instrument_mem(drcontext, bb, instr, i, false); } } } if (instr_writes_memory(instr)) { for (i = 0; i < instr_num_dsts(instr); i++) { if (opnd_is_memory_reference(instr_get_dst(instr, i))) { instrument_mem(drcontext, bb, instr, i, true); } } } } } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t bb_event(void *drcontext, app_pc tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *next_instr; app_pc bb_addr, instr_addr; bool found_section; bb_addr = dr_fragment_app_pc(tag); /* vsyscall: some versions of windows jump to 0x7ffe0300 to * execute a syscall; this address is not contained in any module. */ if ((ptr_uint_t)bb_addr == 0x7ffe0300 || (ptr_uint_t)bb_addr == 0x7ffe0302) return DR_EMIT_DEFAULT; if (!is_in_known_module(bb_addr, &found_section, §ion)) { dr_fprintf(STDERR, "ERROR: BB addr "PFX" in unknown module\n", bb_addr); } if (!found_section) { dr_fprintf(STDERR, "ERROR: BB addr "PFX" isn't within a module section\n", bb_addr); } if ((section.Characteristics & IMAGE_SCN_CNT_CODE) == 0) { dr_fprintf(STDERR, "ERROR: BB addr "PFX" isn't within a code section\n", bb_addr); } for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) { next_instr = instr_get_next(instr); instr_addr = instr_get_app_pc(instr); if (!is_in_known_module(instr_addr, &found_section, §ion)) { dr_fprintf(STDERR, "ERROR: instr addr "PFX" in unknown module\n", instr_addr); } if (!found_section) { dr_fprintf(STDERR, "ERROR: instr addr "PFX" isn't within a module section\n", instr_addr); } if ((section.Characteristics & IMAGE_SCN_CNT_CODE) == 0) { dr_fprintf(STDERR, "ERROR: instr addr "PFX" isn't within a code section\n", instr_addr); } if (instr_addr == exit_proc_addr) { dr_fprintf(STDERR, "Hit kernel32!ExitProcess\n"); exit_proc_addr = NULL; } } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *first = instrlist_first(bb), *point = NULL; uint num_instrs; uint flags; uint need_restore; /* count instruction */ for (instr = first, num_instrs = 0; instr != NULL; instr = instr_get_next(instr)) { num_instrs++; } need_restore = 0; flags = instr_get_arith_flags(instr); /* eflags are not dead save eflags to register */ if (!(TESTALL(EFLAGS_WRITE_6, flags) && !TESTANY(EFLAGS_READ_6, flags))) { need_restore = 1; dr_save_reg(drcontext, bb, first, DR_REG_XAX, SPILL_SLOT_1); dr_save_arith_flags_to_xax(drcontext, bb, first); } /* add the instruction count */ instrlist_meta_preinsert (bb, first, INSTR_CREATE_add(drcontext, OPND_CREATE_ABSMEM ((byte *)&global_count, OPSZ_4), OPND_CREATE_INT32(num_instrs))); /* Need to carry since it is a 8 byte variable. */ instrlist_meta_preinsert (bb, first, INSTR_CREATE_adc(drcontext, OPND_CREATE_ABSMEM ((byte *)&global_count + 4, OPSZ_4), OPND_CREATE_INT32(0))); /* resotre eflags */ if (need_restore) { dr_restore_arith_flags_from_xax(drcontext, bb, first); dr_restore_reg(drcontext, bb, first, DR_REG_XAX, SPILL_SLOT_1); } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_bb(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { app_pc pc = instr_get_app_pc(instrlist_first(bb)); if (pc == (app_pc)&func_0) took_over_thread[0] = true; if (pc == (app_pc)&func_1) took_over_thread[1] = true; if (pc == (app_pc)&func_2) took_over_thread[2] = true; if (pc == (app_pc)&func_3) took_over_thread[3] = true; if (pc == (app_pc)&func_4) took_over_thread[4] = true; if (pc == (app_pc)&func_5) took_over_thread[5] = true; if (pc == (app_pc)&func_6) took_over_thread[6] = true; if (pc == (app_pc)&func_7) took_over_thread[7] = true; if (pc == (app_pc)&func_8) took_over_thread[8] = true; if (pc == (app_pc)&func_9) took_over_thread[9] = true; return DR_EMIT_DEFAULT; }
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; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { uint num_instructions = 0; instr_t *instr; /* Count the number of instructions in this block */ for(instr = instrlist_first(bb); instr != NULL; instr = instr_get_next(instr)) { num_instructions++; } /* Update the as-built counts */ dr_mutex_lock(as_built_lock); counts_as_built.blocks++; counts_as_built.total_size += num_instructions; dr_mutex_unlock(as_built_lock); return DR_EMIT_DEFAULT; }
static dr_emit_flags_t bb_event(void* drcontext, app_pc tag, instrlist_t* bb, bool for_trace, bool translating) { if (tag >= start && tag < end) { instr_t* instr = instrlist_first(bb); dr_prepare_for_call(drcontext, bb, instr); MINSERT(bb, instr, INSTR_CREATE_push_imm (drcontext, OPND_CREATE_INT32((ptr_uint_t)tag))); MINSERT(bb, instr, INSTR_CREATE_push_imm (drcontext, OPND_CREATE_INT32((ptr_uint_t)drcontext))); MINSERT(bb, instr, INSTR_CREATE_call (drcontext, opnd_create_pc((void*)delete_fragment))); dr_cleanup_after_call(drcontext, bb, instr, 8); } return DR_EMIT_DEFAULT; }
void cfi_cleanup_after_native_call(void *drcontext, instrlist_t *ilist, instr_t *where) { instr_t *in = (where == NULL) ? instrlist_last(ilist) : instr_get_prev(where); CFI_ASSERT(drcontext != NULL, "dr_cleanup_after_call: drcontext cannot be NULL"); /* PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RDI))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RSI))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBP)));*/ /* skip xsp by popping into dead rbx */ /* PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RDX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RCX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RAX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R8))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R9))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R10))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R11))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R12))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R13))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R14))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R15))); PRE(ilist, where, INSTR_CREATE_lea (drcontext, opnd_create_reg(REG_XSP), OPND_CREATE_MEM_lea(REG_XSP, REG_NULL, 0, XMM_SLOTS_SIZE))); */ PRE(ilist, where, INSTR_CREATE_popf(drcontext)); /* now go through and mark inserted instrs as meta */ if (in == NULL) in = instrlist_first(ilist); else in = instr_get_next(in); while (in != where) { instr_set_ok_to_mangle(in, false); in = instr_get_next(in); } }