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 fallthrough case. */ elem_t *elem = lookup(table, src); ASSERT(elem != NULL); elem->state |= CBR_NOT_TAKEN; dr_fprintf(STDERR, "cbr not taken\n"); /* * Remove the bb from the cache so it will be re-built the next * time it is executed. Since the flush will remove the fragment * we're already in, redirect execution to the target. */ dr_flush_region(src, 1); dr_get_mcontext(drcontext, &mcontext); mcontext.pc = fall; dr_redirect_execution(&mcontext); }
static void callback(void *tag, app_pc next_pc) { callback_count++; /* Flush all fragments containing this tag twice every hundred calls alternating * between a sync_all and delay flush (if available) and an unlink and delay flush * (if available). */ if (callback_count % 100 == 0) { if (callback_count % 200 == 0) { /* For windows test dr_flush_region() half the time */ dr_mcontext_t mcontext = {sizeof(mcontext),DR_MC_ALL,}; dr_delay_flush_region((app_pc)tag - 20, 30, callback_count, flush_event); dr_get_mcontext(dr_get_current_drcontext(), &mcontext); mcontext.pc = next_pc; dr_flush_region(tag, 1); dr_redirect_execution(&mcontext); *(volatile uint *)NULL = 0; /* ASSERT_NOT_REACHED() */ } else if (use_unlink) { /* Test dr_unlink_flush_region() half the time (if available). * FIXME - extend once we add unlink callback. */ delay_flush_at_next_build = true; dr_unlink_flush_region(tag, 1); } } }
static void at_taken(app_pc src, app_pc targ) { int app_errno; dr_mcontext_t mcontext; void *drcontext = dr_get_current_drcontext(); /* * Record the fact that we've seen the taken case. */ elem_t *elem = lookup(table, src); ASSERT(elem != NULL); elem->state |= CBR_TAKEN; dr_fprintf(STDERR, "cbr taken\n"); /* * Remove the bb from the cache so it will be re-built the next * time it is executed. Since the flush will remove the fragment * we're already in, redirect execution to the target. */ dr_flush_region(src, 1); dr_get_mcontext(drcontext, &mcontext, &app_errno); mcontext.xip = targ; dr_redirect_execution(&mcontext, app_errno); }
static bool exception_event1(void *dcontext, dr_exception_t *excpt) { if (excpt->record->ExceptionCode == STATUS_ACCESS_VIOLATION) inc_count_first(EVENT_EXCEPTION_1, EVENT_EXCEPTION_2); if (!dr_unregister_exception_event(exception_event1)) dr_fprintf(STDERR, "unregister failed!\n"); /* ensure we get our deletion events */ dr_flush_region((app_pc)excpt->record->ExceptionAddress, 1); return true; }
static void check_prctl_whitelist(byte *prctl_arg1) { /* disable instrumentation on seeing prctl(PR_SET_NAME) that does not * match any of the specified ,-separated names (PR 574018) */ char nm[PRCTL_NAME_SZ+1]; ASSERT(options.prctl_whitelist[0] != '\0', "caller should check for empty op"); if (safe_read(prctl_arg1, PRCTL_NAME_SZ, nm)) { bool on_whitelist = false; char *s, *next; char *list_end = options.prctl_whitelist + strlen(options.prctl_whitelist); size_t white_sz; NULL_TERMINATE_BUFFER(nm); LOG(1, "prctl set name %s\n", nm); s = options.prctl_whitelist; while (s < list_end) { next = strchr(s, ','); if (next == NULL) white_sz = (list_end - s); else white_sz = (next - s); LOG(2, "comparing \"%s\" with whitelist entry \"%.*s\" sz=%d\n", nm, white_sz, s, white_sz); if (strncmp(nm, s, white_sz) == 0) { LOG(0, "prctl name %s matches whitelist\n", nm); on_whitelist = true; break; } s += white_sz + 1 /* skip , itself */; } if (!on_whitelist) { /* ideally: suspend world, then set options, then flush * w/o resuming. * FIXME: just setting options is unsafe if another thread * hits an event and fails to restore state or sthg. * Fortunately we expect most uses of PR_SET_NAME to be * immediately after forking. * Ideally we'd call dr_suspend_all_other_threads() * and nest dr_flush_region() inside it but both want * the same master lock: should check whether easy to support * via internal vars indicating whether lock held. */ ELOGF(0, f_global, "\n*********\nDISABLING MEMORY CHECKING for %s\n", nm); options.shadowing = false; options.track_allocs = false; options.count_leaks = false; dr_flush_region(0, ~((ptr_uint_t)0)); } } }
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"); }
/* Clean call for the 'taken' case */ static void at_taken(app_pc src, app_pc targ) { dr_mcontext_t mcontext = {sizeof(mcontext),DR_MC_ALL,}; void *drcontext = dr_get_current_drcontext(); /* * Record the fact that we've seen the taken case. */ elem_t *elem = lookup(table, src); ASSERT(elem != NULL); elem->state |= CBR_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 target address. */ dr_flush_region(src, 1); dr_get_mcontext(drcontext, &mcontext); mcontext.pc = targ; dr_redirect_execution(&mcontext); }