static bool drsys_iter_arg_cb(drsys_arg_t *arg, void *user_data) { ptr_uint_t val; uint64 val64; ASSERT(arg->valid, "no args should be invalid in this app"); ASSERT(arg->mc != NULL, "mc check"); ASSERT(arg->drcontext == dr_get_current_drcontext(), "dc check"); if (arg->reg == DR_REG_NULL && !TEST(DRSYS_PARAM_RETVAL, arg->mode)) { ASSERT((byte *)arg->start_addr >= (byte *)arg->mc->xsp && (byte *)arg->start_addr < (byte *)arg->mc->xsp + PAGE_SIZE, "mem args should be on stack"); } if (TEST(DRSYS_PARAM_RETVAL, arg->mode)) { ASSERT(arg->pre || arg->value == dr_syscall_get_result(dr_get_current_drcontext()), "return val wrong"); } else { if (drsys_pre_syscall_arg(arg->drcontext, arg->ordinal, &val) != DRMF_SUCCESS) ASSERT(false, "drsys_pre_syscall_arg failed"); if (drsys_pre_syscall_arg64(arg->drcontext, arg->ordinal, &val64) != DRMF_SUCCESS) ASSERT(false, "drsys_pre_syscall_arg64 failed"); if (arg->size < sizeof(val)) { val = truncate_int_to_size(val, arg->size); val64 = truncate_int_to_size(val64, arg->size); } ASSERT(val == arg->value, "values do not match"); ASSERT(val64 == arg->value64, "values do not match"); } /* We could test drsys_handle_is_current_process() but we'd have to * locate syscalls operating on processes. Currently drsyscall.c * already tests this call. */ return true; /* keep going */ }
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 void post_func_cb(void * wrapcxt, void ** user_data){ DEBUG_PRINT("funcwrap - post_func_cb\n"); per_thread_t * data = drmgr_get_tls_field(dr_get_current_drcontext(), tls_index); data->nesting--; //dr_unlink_flush_region(0, ~((ptr_uint_t)0)); DR_ASSERT(data->nesting >= 0); if (data->nesting == 0){ data->filter_func = false; } DEBUG_PRINT("funcwrap - post_func_cb done \n"); }
static void test_instr_as_immed(void) { void *drcontext = dr_get_current_drcontext(); instrlist_t *ilist = instrlist_create(drcontext); byte *pc; instr_t *ins0, *ins1, *ins2; opnd_t opnd; byte *highmem = PREFERRED_ADDR; pc = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC, highmem); ASSERT(pc == highmem); /* Test push_imm of instr */ ins0 = INSTR_CREATE_nop(drcontext); instrlist_append(ilist, ins0); instrlist_insert_push_instr_addr(drcontext, ins0, highmem, ilist, NULL, &ins1, &ins2); ASSERT(ins2 != NULL); instrlist_append(ilist, INSTR_CREATE_pop (drcontext, opnd_create_reg(DR_REG_RAX))); instrlist_append(ilist, INSTR_CREATE_ret(drcontext)); pc = instrlist_encode(drcontext, ilist, highmem, true); instrlist_clear(drcontext, ilist); ASSERT(pc < highmem + PAGE_SIZE); pc = ((byte* (*)(void))highmem)(); ASSERT(pc == highmem); /* Test mov_imm of instr */ ins0 = INSTR_CREATE_nop(drcontext); instrlist_append(ilist, ins0); /* Beyond TOS, but a convenient mem dest */ opnd = opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0, -8, OPSZ_8); instrlist_insert_mov_instr_addr(drcontext, ins0, highmem, opnd, ilist, NULL, &ins1, &ins2); ASSERT(ins2 != NULL); instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_RAX), opnd)); instrlist_append(ilist, INSTR_CREATE_ret(drcontext)); pc = instrlist_encode(drcontext, ilist, highmem, true); instrlist_clear(drcontext, ilist); ASSERT(pc < highmem + PAGE_SIZE); pc = ((byte* (*)(void))highmem)(); ASSERT(pc == highmem); instrlist_clear_and_destroy(drcontext, ilist); dr_raw_mem_free(highmem, PAGE_SIZE); }
DR_EXPORT void dr_init(client_id_t id) { /* Generate the "slowpath" which just returns to eax. */ void *dc = dr_get_current_drcontext(); instrlist_t *ilist = instrlist_create(dc); PRE(ilist, NULL, INSTR_CREATE_jmp_ind(dc, opnd_create_reg(DR_REG_XAX))); slowpath = dr_nonheap_alloc(SLOWPATH_SIZE, (DR_MEMPROT_READ| DR_MEMPROT_WRITE| DR_MEMPROT_EXEC)); instrlist_encode(dc, ilist, slowpath, false /*no relative jumps*/); instrlist_clear_and_destroy(dc, ilist); dr_register_bb_event(event_bb); dr_register_exit_event(event_exit); }
static void wrap_unwindtest_post(void *wrapcxt, void *user_data) { void *drcontext = dr_get_current_drcontext(); ptr_uint_t val = (ptr_uint_t) drmgr_get_tls_field(drcontext, tls_idx); if (drwrap_get_func(wrapcxt) == addr_longdone) { /* ensure our post-calls were all called and we got back to 0 */ CHECK(val == 0, "post-calls were bypassed"); } else { /* decrement on way down */ val--; dr_fprintf(STDERR, " <post-long%d%s>\n", val, wrapcxt == NULL ? " abnormal" : ""); drmgr_set_tls_field(drcontext, tls_idx, (void *)val); } }
void tb_flush(struct trace_buffer_t* tb) { size_t size; int64 pos; size_t written; void* aligned_current; tb_tlv_complete(tb); // Align current position to block boundary. aligned_current = aligned_block(tb->current); memset(tb->current, 'X', aligned_current - tb->current); tb->current = aligned_current; size = tb->current - (void*)&tb->block; if(size == sizeof(struct block_t)) { // Nothing to do. return; } tb->block.length = (uint32_t)size; tb->block.crc32 = 0; tb->block.crc32 = crc32((char*)&tb->block, size); // Write data. dr_mutex_lock(tb->mutex); pos = dr_file_tell(tb->file); if(pos == -1) { dr_fprintf(STDERR, "fatal: dr_file_tell() failed\n"); dr_exit_process(1); } dr_fprintf(STDERR, "info: flushing tb=%p file-offset=%" PRId64 " size=%u" " tb-thread=0x%" PRIx64 " current-thread=0x%" PRIx64 "\n", tb, pos, (unsigned int)size, tb->block.thread_id, (uint64_t)dr_get_thread_id(dr_get_current_drcontext())); written = dr_write_file(tb->file, &tb->block, size); dr_mutex_unlock(tb->mutex); if(written != size) { dr_fprintf(STDERR, "fatal: dr_write_file() failed\n"); dr_exit_process(1); } // Reset position. tb->current = tb + 1; }
static void clean_call_print_regvalues(){ uint regvalue; dr_mcontext_t mc = { sizeof(mc), DR_MC_ALL }; void * drcontext = dr_get_current_drcontext(); dr_get_mcontext(drcontext, &mc); dr_printf("---------\n"); regvalue = reg_get_value(DR_REG_XAX, &mc); dr_printf("xax - %x\n", regvalue); regvalue = reg_get_value(DR_REG_XBX, &mc); dr_printf("xbx - %x\n", regvalue); regvalue = reg_get_value(DR_REG_XCX, &mc); dr_printf("xcx - %x\n", regvalue); regvalue = reg_get_value(DR_REG_XDX, &mc); dr_printf("xdx - %x\n", regvalue); }
static bool drsys_iter_memarg_cb(drsys_arg_t *arg, void *user_data) { ASSERT(arg->valid, "no args should be invalid in this app"); ASSERT(arg->mc != NULL, "mc check"); ASSERT(arg->drcontext == dr_get_current_drcontext(), "dc check"); #ifdef UNIX /* the app deliberately trips i#1119 w/ a too-small sockaddr */ if (arg->type == DRSYS_TYPE_SOCKADDR && !arg->pre) { static bool first = true; ASSERT(!first || arg->size == sizeof(struct sockaddr)/2, "i#1119 test"); first = false; } #endif return true; /* keep going */ }
static app_pc get_function_entry(app_pc C_var) { void *drcontext = dr_get_current_drcontext(); byte *pc; instr_t inst; instr_init(drcontext, &inst); pc = decode(drcontext, C_var, &inst); ASSERT(pc != NULL, "invalid instr at function entry"); if (instr_get_opcode(&inst) == OP_jmp) { /* skip jmp in ILT */ ASSERT(opnd_is_pc(instr_get_target(&inst)), "decoded jmp should have pc tgt"); pc = opnd_get_pc(instr_get_target(&inst)); } else pc = C_var; instr_free(drcontext, &inst); return pc; }
static void clean_call(uint pc){ //DEBUG_PRINT("funcwrap - entered the pre-call clean call\n"); dr_mcontext_t mc = { sizeof(mc), DR_MC_ALL }; dr_get_mcontext(dr_get_current_drcontext(), &mc); mc.pc = pc; if (dumped == 0){ dumped = 1; dr_flush_region(0, ~((ptr_uint_t)0)); dr_redirect_execution(&mc); } //DEBUG_PRINT("funcwrap - entered the pre-call done\n"); }
DR_EXPORT drmf_status_t drfuzz_get_target_per_thread_user_data(IN void *fuzzcxt, IN generic_func_t target_pc, OUT void **user_data) { fuzz_pass_context_t *fp = (fuzz_pass_context_t *) fuzzcxt; pass_target_t *target; if (fp == NULL) { void *dcontext = dr_get_current_drcontext(); fp = (fuzz_pass_context_t *) drmgr_get_tls_field(dcontext, tls_idx_fuzzer); } target = lookup_live_target(fp, (app_pc) target_pc); if (target == NULL) return DRMF_ERROR_INVALID_PARAMETER; *user_data = target->user_data; return DRMF_SUCCESS; }
static void at_not_taken(app_pc src, app_pc fall, void *tag) { instrlist_t *bb; void *drcontext = dr_get_current_drcontext(); /* * Record the fact that we've seen the fallthrough case. */ elem_t *elem = lookup(table, src); ASSERT(elem != NULL); elem->state |= CBR_NOT_TAKEN; dr_fprintf(STDERR, "cbr not taken\n"); /* * Re-instrument and replace the fragment. */ ASSERT(dr_bb_exists_at(drcontext, tag)); bb = decode_as_bb(drcontext, tag); instrument_bb(drcontext, tag, bb, false, false); dr_replace_fragment(drcontext, tag, bb); }
/* Clean call for the 'not taken' case */ static void at_not_taken(app_pc src, app_pc fall) { dr_mcontext_t mcontext = {sizeof(mcontext),DR_MC_ALL,}; void *drcontext = dr_get_current_drcontext(); /* * Record the fact that we've seen the not_taken case. */ elem_t *elem = lookup(table, src); ASSERT(elem != NULL); elem->state |= CBR_NOT_TAKEN; /* Remove the bb from the cache so it will be re-built the next * time it executes. */ /* Since the flush will remove the fragment we're already in, * redirect execution to the fallthrough address. */ dr_flush_region(src, 1); dr_get_mcontext(drcontext, &mcontext); mcontext.pc = fall; dr_redirect_execution(&mcontext); }
void memdump_exit_event(void) { int i = 0; md_delete_list(filter_head, false); md_delete_list(done_head, false); md_delete_list(app_pc_head, false); dr_global_free(client_arg, sizeof(client_arg_t)); drmgr_unregister_tls_field(tls_index); if (log_mode){ dr_close_file(logfile); } for (i = 0; i < instr_clone_amount; i++){ instr_destroy(dr_get_current_drcontext(), instr_clones[i]); } dr_mutex_destroy(mutex); drutil_exit(); drmgr_exit(); drwrap_exit(); }
/* clean_call dumps the memory reference info to the log file */ static void clean_call_ins_trace(void) { void *drcontext = dr_get_current_drcontext(); ins_trace(drcontext); }
static void custom_test(void) { void *drcontext = dr_get_current_drcontext(); void *array, *preferred; size_t size; uint prot; dr_fprintf(STDERR, " testing custom memory alloc...."); /* test global */ array = dr_custom_alloc(NULL, 0, SIZE, 0, NULL); write_array(array); dr_custom_free(NULL, 0, array, SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test thread-local */ array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE, SIZE, 0, NULL); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE, array, SIZE); array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test non-heap */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); /* Find a free region of memory without inadvertently "preloading" it. * First probe by allocating 2x the platform allocation alignment unit. */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, HINT_ALLOC_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); /* Then select the second half as the preferred address for the allocation test. */ preferred = (void *)((ptr_uint_t)array + HINT_OFFSET); /* Free the probe allocation. */ dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, array, HINT_ALLOC_SIZE); /* Now `preferred` is guaranteed to be available. */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, preferred); ASSERT(array == preferred); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); #ifdef X64 ASSERT((ptr_uint_t)array < 0x80000000); #endif write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC, NULL); ASSERT(dr_query_memory((byte *)array, NULL, &size, &prot) && size == PAGE_SIZE && prot == (DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); dr_fprintf(STDERR, "success\n"); }
static void custom_test(void) { void *drcontext = dr_get_current_drcontext(); void *array; size_t size; uint prot; dr_fprintf(STDERR, " testing custom memory alloc...."); /* test global */ array = dr_custom_alloc(NULL, 0, SIZE, 0, NULL); write_array(array); dr_custom_free(NULL, 0, array, SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test thread-local */ array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE, SIZE, 0, NULL); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE, array, SIZE); array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test non-heap */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, PREFERRED_ADDR); ASSERT(array == (void *)PREFERRED_ADDR); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); #ifdef X64 ASSERT((ptr_uint_t)array < 0x80000000); #endif write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC, NULL); ASSERT(dr_query_memory((byte *)array, NULL, &size, &prot) && size == PAGE_SIZE && prot == (DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); dr_fprintf(STDERR, "success\n"); }
static void getRegReg(reg_id_t r1, reg_id_t r2, int opcode, app_pc addr){ const char * r1Name = get_register_name(r1); const char * r2Name = get_register_name(r2); int s1 = atoi(r1Name + 3 * sizeof(char)); int s2 = atoi(r2Name + 3 * sizeof(char)); dr_mcontext_t mcontext; memset(&mcontext, 0, sizeof(dr_mcontext_t)); mcontext.flags = DR_MC_MULTIMEDIA; mcontext.size = sizeof(dr_mcontext_t); bool result = dr_get_mcontext(dr_get_current_drcontext(), &mcontext); int r, s; int bits = 0; double loss = 0; double lossD = 0; if(is_single_precision_instr(opcode)){ float op1, op2; // for(r=0; r<16; ++r) // for(s=0; s<4; ++s) // printf("reg %i.%i: %f\n", r, s, // *((float*) &mcontext.ymm[r].u32[s])); op1 = *((float*) &mcontext.ymm[s1].u32[0]); op2 = *((float*) &mcontext.ymm[s2].u32[0]); // dr_fprintf(logF, "%d: %f %f\n",opcode, op1, op2); int exp1, exp2; float mant1, mant2; mant1 = frexpf(op1, &exp1); mant2 = frexpf(op2, &exp2); bits = abs(exp1-exp2); double dop1 = op1; double dop2 = op2; if(opcode == OP_addss){ double dadd = dop1 + dop2; float fadd = op1 + op2; lossD = dadd - fadd; // printf("double %.13lf float %.13f\n", dadd, fadd); } else{ double dsub = dop1 - dop2; float fsub = op1 - op2; lossD = dsub - fsub; } // printf("diff of double and float is %.13lf\n", lossD); } else{ double op1, op2; // for(r=0; r<16; ++r) // for(s=0; s<2; ++s) // printf("reg %i.%i: %f\n", r, s, // *((double*) &mcontext.ymm[r].u64[s])); op1 = *((double*) &mcontext.ymm[s1].u64[0]); op2 = *((double*) &mcontext.ymm[s2].u64[0]); // dr_fprintf(logF, "%d: %.13lf %.13lf\n",opcode, op1, op2); int exp1, exp2; double mant1, mant2; mant1 = frexp(op1, &exp1); mant2 = frexp(op2, &exp2); bits = abs(exp1-exp2); printf("op1 %.13lf mantissa %.13lf exp %d\n", op1, mant1, exp1); printf("op2 %.13lf mantissa %.13lf exp %d\n", op2, mant2, exp2); } print_address(addr, bits, loss, lossD); }
static void reachability_test(void) { void *drcontext = dr_get_current_drcontext(); instrlist_t *ilist = instrlist_create(drcontext); byte *gencode = (byte *) dr_nonheap_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC); byte *pc; int res; byte *highmem = PREFERRED_ADDR; pc = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC, highmem); ASSERT(pc == highmem); dr_fprintf(STDERR, " reachability test..."); /* Test auto-magically turning rip-rel that won't reach but targets xax * into absmem. */ instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_EAX), opnd_create_rel_addr(highmem, OPSZ_4))); instrlist_append(ilist, INSTR_CREATE_ret(drcontext)); pc = instrlist_encode(drcontext, ilist, gencode, false); instrlist_clear(drcontext, ilist); ASSERT(pc < gencode + PAGE_SIZE); *(int*)highmem = 0x12345678; res = ((int (*)(void))gencode)(); ASSERT(res == 0x12345678); /* Test auto-magically turning a reachable absmem into a rip-rel. */ instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_ECX), opnd_create_abs_addr(highmem + 0x800, OPSZ_4))); instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_EAX), opnd_create_reg(DR_REG_ECX))); instrlist_append(ilist, INSTR_CREATE_ret(drcontext)); pc = instrlist_encode(drcontext, ilist, highmem, false); instrlist_clear(drcontext, ilist); ASSERT(pc < highmem + PAGE_SIZE); *(int*)(highmem + 0x800) = 0x12345678; res = ((int (*)(void))highmem)(); ASSERT(res == 0x12345678); dr_raw_mem_free(highmem, PAGE_SIZE); /* Test targeting upper 2GB of low 4GB */ highmem = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC, (byte *)0xabcd0000); instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_ECX), opnd_create_abs_addr(highmem, OPSZ_4))); instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_EAX), opnd_create_reg(DR_REG_ECX))); instrlist_append(ilist, INSTR_CREATE_ret(drcontext)); pc = instrlist_encode(drcontext, ilist, gencode, false); instrlist_clear(drcontext, ilist); ASSERT(pc < gencode + PAGE_SIZE); *(int*)highmem = 0x12345678; res = ((int (*)(void))gencode)(); ASSERT(res == 0x12345678); dr_raw_mem_free(highmem, PAGE_SIZE); /* Test targeting lower 2GB of low 4GB */ highmem = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC, (byte *)0x143d0000); instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_ECX), opnd_create_abs_addr(highmem, OPSZ_4))); instrlist_append(ilist, INSTR_CREATE_mov_ld (drcontext, opnd_create_reg(DR_REG_EAX), opnd_create_reg(DR_REG_ECX))); instrlist_append(ilist, INSTR_CREATE_ret(drcontext)); pc = instrlist_encode(drcontext, ilist, gencode, false); instrlist_clear(drcontext, ilist); ASSERT(pc < gencode + PAGE_SIZE); *(int*)highmem = 0x12345678; res = ((int (*)(void))gencode)(); ASSERT(res == 0x12345678); dr_raw_mem_free(highmem, PAGE_SIZE); instrlist_clear_and_destroy(drcontext, ilist); dr_nonheap_free(gencode, PAGE_SIZE); test_instr_as_immed(); dr_fprintf(STDERR, "success\n"); }
/* clean_call dumps the memory reference info to the log file */ static void clean_call(void) { void *drcontext = dr_get_current_drcontext(); memtrace(drcontext); }
static void callback(reg_id_t reg, int displacement, reg_id_t destReg, int opcode, app_pc addr){ int r, s; const char * destRegName = get_register_name(destReg); int regId = atoi(destRegName + 3 * sizeof(char)); dr_mcontext_t mcontext; memset(&mcontext, 0, sizeof(dr_mcontext_t)); mcontext.flags = DR_MC_ALL; mcontext.size = sizeof(dr_mcontext_t); bool result = dr_get_mcontext(dr_get_current_drcontext(), &mcontext); reg_t mem_reg; if(reg == DR_REG_RAX) mem_reg = mcontext.rax; else if(reg == DR_REG_RBP) mem_reg = mcontext.rbp; else if(reg == DR_REG_RBX) mem_reg = mcontext.rbx; else if(reg == DR_REG_RCX) mem_reg = mcontext.rcx; else if(reg == DR_REG_RDI) mem_reg = mcontext.rdi; else if(reg == DR_REG_RDX) mem_reg = mcontext.rdx; else if(reg == DR_REG_RSI) mem_reg = mcontext.rsi; else if(reg == DR_REG_RSP) mem_reg = mcontext.rsp; else mem_reg = NULL; //deal with a null case, rip enum doesn't exist int bits = 0; double loss = 0; double lossD = 0; if(is_single_precision_instr(opcode)){ float op1, op2; // printf("Mem reg contents: %f\n", *(float*)(mem_reg + displacement)); op2 = *(float*)(mem_reg + displacement); // for(r=0; r<16; ++r) // for(s=0; s<4; ++s) // printf("reg %i.%i: %f\n", r, s, // *((float*) &mcontext.ymm[r].u32[s])); op1 = *((float*) &mcontext.ymm[regId].u32[0]); // dr_fprintf(logF, "%d: %f %f\n",opcode, op1, op2); int exp1, exp2; float mant1, mant2; mant1 = frexpf(op1, &exp1); mant2 = frexpf(op2, &exp2); bits = abs(exp1-exp2); double dop1 = op1; double dop2 = op2; if(opcode == OP_addss){ double dadd = dop1 + dop2; float fadd = op1 + op2; lossD = dadd - fadd; //printf("double %.13lf float %.13f\n", dadd, fadd); } else{ double dsub = dop1 - dop2; float fsub = op1 - op2; lossD = dsub - fsub; } // printf("diff of double and float is %.13lf\n", lossD); } else{ double op1, op2; printf("Mem reg contents: %.13lf\n", *(double*)(mem_reg + displacement)); op2 = *(double*)(mem_reg + displacement); // for(r=0; r<16; ++r) // for(s=0; s<2; ++s) // printf("reg %i.%i: %lf\n", r, s, // *((double*) &mcontext.ymm[r].u64[s])); op1 = *((double*) &mcontext.ymm[regId].u64[0]); // dr_fprintf(logF, "%d: %.13lf %.13lf\n",opcode, op1, op2); int exp1, exp2; double mant1, mant2; mant1 = frexp(op1, &exp1); mant2 = frexp(op2, &exp2); bits = abs(exp1-exp2); printf("op1 %.13lf mantissa %.13lf exp %d\n", op1, mant1, exp1); printf("op2 %.13lf mantissa %.13lf exp %d\n", op2, mant2, exp2); } print_address(addr, bits, loss, lossD); }
DR_EXPORT drmf_status_t drsymcache_init(client_id_t client_id, const char *symcache_dir_in, size_t modsize_cache_threshold) { #ifdef WINDOWS module_data_t *mod; #endif drmf_status_t res; drmgr_priority_t pri_mod_load_cache = {sizeof(pri_mod_load_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL, DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_READ}; drmgr_priority_t pri_mod_unload_cache = {sizeof(pri_mod_unload_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL, DRMGR_PRIORITY_MODUNLOAD_DRSYMCACHE}; drmgr_priority_t pri_mod_save_cache = {sizeof(pri_mod_save_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE_SAVE, NULL, NULL, DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_SAVE}; /* handle multiple sets of init/exit calls */ int count = dr_atomic_add32_return_sum(&symcache_init_count, 1); if (count > 1) return DRMF_WARNING_ALREADY_INITIALIZED; res = drmf_check_version(client_id); if (res != DRMF_SUCCESS) return res; drmgr_init(); drmgr_register_module_load_event_ex(symcache_module_load, &pri_mod_load_cache); drmgr_register_module_unload_event_ex(symcache_module_unload, &pri_mod_unload_cache); drmgr_register_module_load_event_ex(symcache_module_load_save, &pri_mod_save_cache); initialized = true; op_modsize_cache_threshold = modsize_cache_threshold; hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS, IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING), true/*strdup*/, false/*!synch*/, symcache_free_entry, NULL, NULL); symcache_lock = dr_mutex_create(); dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir), "%s", symcache_dir_in); NULL_TERMINATE_BUFFER(symcache_dir); if (!dr_directory_exists(symcache_dir)) { if (!dr_create_dir(symcache_dir)) { /* check again in case of a race (i#616) */ if (!dr_directory_exists(symcache_dir)) { NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir); ASSERT(false, "unable to create symcache dir"); dr_abort(); } } } #ifdef WINDOWS /* It's common for tools to query ntdll in their init routines so we add it * early here */ mod = dr_lookup_module_by_name("ntdll.dll"); if (mod != NULL) { symcache_module_load(dr_get_current_drcontext(), mod, true); dr_free_module_data(mod); } #endif return DRMF_SUCCESS; }
static void pre_func_cb(void * wrapcxt, OUT void ** user_data){ DEBUG_PRINT("funcwrap - pre_func_cb\n"); per_thread_t * data = drmgr_get_tls_field(dr_get_current_drcontext(), tls_index); data->filter_func = true; data->nesting++; }