cache_pc indirect_linkstub_target(dcontext_t *dcontext, fragment_t *f, linkstub_t *l) { // COMPLETEDD #495 indirect_linkstub_target printf("Starting indirect_linkstub_target\n"); ASSERT(LINKSTUB_INDIRECT(l->flags)); ASSERT(!TESTANY(LINK_NI_SYSCALL_ALL, l->flags)); #ifdef WINDOWS if (EXIT_TARGETS_SHARED_SYSCALL(l->flags)) { /* currently this is the only way to distinguish shared_syscall * exit from other indirect exits and from other exits in * a fragment containing ignorable or non-ignorable syscalls */ ASSERT(TEST(FRAG_HAS_SYSCALL, f->flags)); return shared_syscall_routine_ex(dcontext _IF_X64(MODE_OVERRIDE(FRAG_IS_32(f->flags)))); } #endif if (TEST(FRAG_COARSE_GRAIN, f->flags)) { /* Need to target the ibl prefix. Passing in cti works as well as stub, * and avoids a circular dependence where linkstub_unlink_entry_offset() * call this routine to get the target and then this routine asks for * the stub which calls linkstub_unlink_entry_offset()... */ return get_coarse_ibl_prefix(dcontext, EXIT_CTI_PC(f, l), extract_branchtype(l->flags)); } else { return get_ibl_routine_ex(dcontext, IF_X64(TEST(LINK_TRACE_CMP, l->flags) ? IBL_TRACE_CMP :) IBL_LINKED, get_source_fragment_type(dcontext, f->flags), extract_branchtype(l->flags) _IF_X64(MODE_OVERRIDE(FRAG_IS_32(f->flags)))); } }
/* case 4344 - verify we can recreate app pc in fragment, returns the pc of * the last instruction in the body of f */ static cache_pc get_last_fragment_body_instr_pc(dcontext_t *dcontext, fragment_t *f) { cache_pc body_last_inst_pc; linkstub_t *l; /* Assumption : the last exit stub exit cti is the last instruction in the * body. PR 215217 enforces this for CLIENT_INTERFACE as well. */ l = FRAGMENT_EXIT_STUBS(f); /* never called on future fragments, so a stub should exist */ while (!LINKSTUB_FINAL(l)) l = LINKSTUB_NEXT_EXIT(l); body_last_inst_pc = EXIT_CTI_PC(f, l); return body_last_inst_pc; }