/* Initializes a dcontext with the supplied state and calls dispatch */ void dynamo_start(priv_mcontext_t *mc) { priv_mcontext_t *mcontext; dcontext_t *dcontext = get_thread_private_dcontext(); ASSERT(dcontext != NULL); thread_starting(dcontext); /* Signal other threads for take over. */ dynamorio_take_over_threads(dcontext); /* Set return address */ mc->pc = canonicalize_pc_target(dcontext, mc->pc); dcontext->next_tag = mc->pc; ASSERT(dcontext->next_tag != NULL); /* transfer exec state to mcontext */ mcontext = get_mcontext(dcontext); *mcontext = *mc; /* clear pc */ mcontext->pc = 0; DOLOG(2, LOG_TOP, { byte *cur_esp; GET_STACK_PTR(cur_esp); LOG(THREAD, LOG_TOP, 2, "%s: next_tag="PFX", cur xsp="PFX", mc->xsp="PFX"\n", __FUNCTION__, dcontext->next_tag, cur_esp, mc->xsp); });
/* Initializes a dcontext with the supplied state and calls dispatch */ void dynamo_start(priv_mcontext_t *mc) { priv_mcontext_t *mcontext; dcontext_t *dcontext = get_thread_private_dcontext(); ASSERT(dcontext != NULL); thread_starting(dcontext); /* Signal other threads for take over. */ dynamorio_take_over_threads(dcontext); /* Set return address */ dcontext->next_tag = mc->pc; ASSERT(dcontext->next_tag != NULL); /* transfer exec state to mcontext */ mcontext = get_mcontext(dcontext); *mcontext = *mc; /* clear pc */ mcontext->pc = 0; /* Swap stacks so dispatch is invoked outside the application. * We begin interpretation at the application return point, * and thus we need to look like DR returned -- adjust the app * stack to account for the return address. */ mcontext->xsp += XSP_SZ; call_switch_stack(dcontext, dcontext->dstack, dispatch, false/*not on initstack*/, true/*return on error*/); /* In release builds, this will simply return and continue native * execution. That's better than calling unexpected_return() which * goes into an infinite loop. */ ASSERT_NOT_REACHED(); }