/* * The first few arguments are dummy, to force the other arguments to be passed on * the stack, this avoids overwriting the argument registers in the throw trampoline. */ void mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, guint64 dummy5, guint64 dummy6, MonoContext *mctx, MonoObject *exc, gboolean rethrow) { MonoContext ctx; /* mctx is on the caller's stack */ memcpy (&ctx, mctx, sizeof (MonoContext)); if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } } /* adjust eip so that it point into the call instruction */ ctx.gregs [AMD64_RIP] --; mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); g_assert_not_reached (); }
void mono_arm_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gulong *int_regs, gdouble *fp_regs) { static void (*restore_context) (MonoContext *); MonoContext ctx; gboolean rethrow = eip & 1; if (!restore_context) restore_context = mono_get_restore_context (); eip &= ~1; /* clear the optional rethrow bit */ /* adjust eip so that it point into the call instruction */ eip -= 4; /*printf ("stack in throw: %p\n", esp);*/ MONO_CONTEXT_SET_BP (&ctx, int_regs [ARMREG_FP - 4]); MONO_CONTEXT_SET_SP (&ctx, esp); MONO_CONTEXT_SET_IP (&ctx, eip); memcpy (((guint8*)&ctx.regs) + (4 * 4), int_regs, sizeof (gulong) * 8); /* memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_SAVED_FREGS); */ if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } mono_handle_exception (&ctx, exc, (gpointer)(eip + 4), FALSE); restore_context (&ctx); g_assert_not_reached (); }
/** * mono_arch_handle_exception: * * @ctx: saved processor state * @obj: the exception object */ gboolean mono_arch_handle_exception (void *sigctx, gpointer obj) { #if defined(MONO_ARCH_USE_SIGACTION) MonoContext mctx; /* * Handling the exception in the signal handler is problematic, since the original * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); /* Pass the ctx parameter in TLS */ mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); mctx = jit_tls->ex_ctx; mono_arch_setup_async_callback (&mctx, handle_signal_exception, obj); mono_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #else MonoContext mctx; mono_sigctx_to_monoctx (sigctx, &mctx); mono_handle_exception (&mctx, obj); mono_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #endif }
gboolean mono_arch_handle_exception (void *sigctx, gpointer obj) { MonoContext mctx; ucontext_t *ctx = (ucontext_t*)sigctx; gpointer *window; /* * Access to the machine state using the ucontext_t parameter is somewhat * under documented under solaris. The code below seems to work under * Solaris 9. */ g_assert (!ctx->uc_mcontext.gwins); mctx.ip = ctx->uc_mcontext.gregs [REG_PC]; mctx.sp = ctx->uc_mcontext.gregs [REG_SP]; window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS); mctx.fp = window [sparc_fp - 16]; mono_handle_exception (&mctx, obj); /* We can't use restore_context to return from a signal handler */ ctx->uc_mcontext.gregs [REG_PC] = mctx.ip; ctx->uc_mcontext.gregs [REG_nPC] = mctx.ip + 4; ctx->uc_mcontext.gregs [REG_SP] = mctx.sp; window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS); window [sparc_fp - 16] = mctx.fp; return TRUE; }
static void throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow) { MonoContext ctx; static void (*restore_context) (MonoContext *); gpointer *window; if (!restore_context) restore_context = mono_get_restore_context (); window = MONO_SPARC_WINDOW_ADDR (sp); ctx.sp = (gpointer*)sp; ctx.ip = ip; ctx.fp = (gpointer*)(MONO_SPARC_WINDOW_ADDR (sp) [sparc_i6 - 16]); if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } mono_handle_exception (&ctx, exc); restore_context (&ctx); g_assert_not_reached (); }
gboolean mono_arch_handle_exception (void *sigctx, gpointer obj) { MonoContext mctx; struct sigcontext *sc = sigctx; gpointer *window; #ifdef SPARCV9 mctx.ip = (gpointer) sc->sigc_regs.tpc; mctx.sp = (gpointer) sc->sigc_regs.u_regs[14]; #else mctx.ip = (gpointer) sc->si_regs.pc; mctx.sp = (gpointer) sc->si_regs.u_regs[14]; #endif window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS); mctx.fp = window [sparc_fp - 16]; mono_handle_exception (&mctx, obj); #ifdef SPARCV9 sc->sigc_regs.tpc = (unsigned long) mctx.ip; sc->sigc_regs.tnpc = (unsigned long) (mctx.ip + 4); sc->sigc_regs.u_regs[14] = (unsigned long) mctx.sp; #else sc->si_regs.pc = (unsigned long) mctx.ip; sc->si_regs.npc = (unsigned long) (mctx.ip + 4); sc->si_regs.u_regs[14] = (unsigned long) mctx.sp; #endif window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS); window [sparc_fp - 16] = mctx.fp; return TRUE; }
/* * The first few arguments are dummy, to force the other arguments to be passed on * the stack, this avoids overwriting the argument registers in the throw trampoline. */ void mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, guint64 dummy5, guint64 dummy6, mgreg_t *regs, mgreg_t rip, MonoObject *exc, gboolean rethrow) { MonoContext ctx; ctx.rsp = regs [AMD64_RSP]; ctx.rip = rip; ctx.rbx = regs [AMD64_RBX]; ctx.rbp = regs [AMD64_RBP]; ctx.r12 = regs [AMD64_R12]; ctx.r13 = regs [AMD64_R13]; ctx.r14 = regs [AMD64_R14]; ctx.r15 = regs [AMD64_R15]; ctx.rdi = regs [AMD64_RDI]; ctx.rsi = regs [AMD64_RSI]; ctx.rax = regs [AMD64_RAX]; ctx.rcx = regs [AMD64_RCX]; ctx.rdx = regs [AMD64_RDX]; if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } /* adjust eip so that it point into the call instruction */ ctx.rip -= 1; mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); g_assert_not_reached (); }
void mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs) { MonoContext ctx; gboolean rethrow = pc & 1; pc &= ~1; /* clear the optional rethrow bit */ /* adjust eip so that it point into the call instruction */ pc -= 4; /*printf ("stack in throw: %p\n", esp);*/ MONO_CONTEXT_SET_BP (&ctx, int_regs [ARMREG_FP - 4]); MONO_CONTEXT_SET_SP (&ctx, sp); MONO_CONTEXT_SET_IP (&ctx, pc); memcpy (((guint8*)&ctx.regs) + (ARMREG_R4 * sizeof (mgreg_t)), int_regs, 8 * sizeof (mgreg_t)); memcpy (&ctx.fregs, fp_regs, sizeof (double) * 16); if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); g_assert_not_reached (); }
void mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow) { MonoError error; MonoContext ctx; /* adjust eip so that it point into the call instruction */ eip -= 4; setup_context (&ctx); /*printf ("stack in throw: %p\n", esp);*/ MONO_CONTEXT_SET_BP (&ctx, esp); MONO_CONTEXT_SET_IP (&ctx, eip); memcpy (&ctx.regs, int_regs, sizeof (mgreg_t) * MONO_MAX_IREGS); memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_MAX_FREGS); if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } } mono_error_assert_ok (&error); mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); g_assert_not_reached (); }
static void throw_exception (MonoObject *exc, guint64 rethrow) { unw_context_t unw_ctx; MonoContext ctx; MonoJitInfo *ji; unw_word_t ip, sp; int res; if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } } res = unw_getcontext (&unw_ctx); g_assert (res == 0); res = unw_init_local (&ctx.cursor, &unw_ctx); g_assert (res == 0); /* * Unwind until the first managed frame. This is needed since * mono_handle_exception expects the variables in the original context to * correspond to the method returned by mono_find_jit_info. */ while (TRUE) { res = unw_get_reg (&ctx.cursor, UNW_IA64_IP, &ip); g_assert (res == 0); res = unw_get_reg (&ctx.cursor, UNW_IA64_SP, &sp); g_assert (res == 0); ji = mini_jit_info_table_find (mono_domain_get (), (gpointer)ip, NULL); //printf ("UN: %s %lx %lx\n", ji ? jinfo_get_method (ji)->name : "", ip, sp); if (ji) break; res = unw_step (&ctx.cursor); if (res == 0) { /* * This means an unhandled exception during the compilation of a * topmost method like Main */ break; } g_assert (res >= 0); } ctx.precise_ip = FALSE; mono_handle_exception (&ctx, exc); restore_context (&ctx); g_assert_not_reached (); }
/* * mono_x86_throw_exception: * * C function called from the throw trampolines. */ void mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, mgreg_t eip, gboolean rethrow) { static void (*restore_context) (MonoContext *); MonoContext ctx; if (!restore_context) restore_context = mono_get_restore_context (); ctx.esp = regs [X86_ESP]; ctx.eip = eip; ctx.ebp = regs [X86_EBP]; ctx.edi = regs [X86_EDI]; ctx.esi = regs [X86_ESI]; ctx.ebx = regs [X86_EBX]; ctx.edx = regs [X86_EDX]; ctx.ecx = regs [X86_ECX]; ctx.eax = regs [X86_EAX]; #ifdef __APPLE__ /* The OSX ABI specifies 16 byte alignment at call sites */ g_assert ((ctx.esp % MONO_ARCH_FRAME_ALIGNMENT) == 0); #endif if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } if (mono_debug_using_mono_debugger ()) { guint8 buf [16], *code; mono_breakpoint_clean_code (NULL, (gpointer)eip, 8, buf, sizeof (buf)); code = buf + 8; if (buf [3] == 0xe8) { MonoContext ctx_cp = ctx; ctx_cp.eip = eip - 5; if (mono_debugger_handle_exception (&ctx_cp, exc)) { restore_context (&ctx_cp); g_assert_not_reached (); } } } /* adjust eip so that it point into the call instruction */ ctx.eip -= 1; mono_handle_exception (&ctx, exc); restore_context (&ctx); g_assert_not_reached (); }
static void altstack_handle_and_restore (void *sigctx, gpointer obj) { MonoContext mctx; mono_sigctx_to_monoctx (sigctx, &mctx); mono_handle_exception (&mctx, obj); mono_restore_context (&mctx); }
/* * The first few arguments are dummy, to force the other arguments to be passed on * the stack, this avoids overwriting the argument registers in the throw trampoline. */ void mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, guint64 dummy5, guint64 dummy6, mgreg_t *regs, mgreg_t rip, MonoObject *exc, gboolean rethrow) { static void (*restore_context) (MonoContext *); MonoContext ctx; if (!restore_context) restore_context = mono_get_restore_context (); ctx.rsp = regs [AMD64_RSP]; ctx.rip = rip; ctx.rbx = regs [AMD64_RBX]; ctx.rbp = regs [AMD64_RBP]; ctx.r12 = regs [AMD64_R12]; ctx.r13 = regs [AMD64_R13]; ctx.r14 = regs [AMD64_R14]; ctx.r15 = regs [AMD64_R15]; ctx.rdi = regs [AMD64_RDI]; ctx.rsi = regs [AMD64_RSI]; ctx.rax = regs [AMD64_RAX]; ctx.rcx = regs [AMD64_RCX]; ctx.rdx = regs [AMD64_RDX]; if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } if (mono_debug_using_mono_debugger ()) { guint8 buf [16]; mono_breakpoint_clean_code (NULL, (gpointer)rip, 8, buf, sizeof (buf)); if (buf [3] == 0xe8) { MonoContext ctx_cp = ctx; ctx_cp.rip = rip - 5; if (mono_debugger_handle_exception (&ctx_cp, exc)) { restore_context (&ctx_cp); g_assert_not_reached (); } } } /* adjust eip so that it point into the call instruction */ ctx.rip -= 1; mono_handle_exception (&ctx, exc); restore_context (&ctx); g_assert_not_reached (); }
static void altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf) { MonoContext mctx; mctx = *ctx; mono_handle_exception (&mctx, obj); if (stack_ovf) prepare_for_guard_pages (&mctx); mono_restore_context (&mctx); }
/* * handle_exception: * * Called by resuming from a signal handler. */ static void handle_signal_exception (gpointer obj) { MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); MonoContext ctx; memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext)); mono_handle_exception (&ctx, obj); mono_restore_context (&ctx); }
gboolean mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) { #if defined(MONO_ARCH_USE_SIGACTION) MonoContext mctx; ucontext_t *ctx = (ucontext_t*)sigctx; /* * Handling the exception in the signal handler is problematic, since the original * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); /* Pass the ctx parameter in TLS */ mono_arch_sigctx_to_monoctx (ctx, &jit_tls->ex_ctx); g_assert (!test_only); mctx = jit_tls->ex_ctx; mono_setup_async_callback (&mctx, handle_signal_exception, obj); mono_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #elif defined (TARGET_WIN32) MonoContext mctx; MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); struct sigcontext *ctx = (struct sigcontext *)sigctx; mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); g_assert (!test_only); mctx = jit_tls->ex_ctx; mono_setup_async_callback (&mctx, handle_signal_exception, obj); mono_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #else MonoContext mctx; mono_arch_sigctx_to_monoctx (sigctx, &mctx); if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) return TRUE; mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only); mono_arch_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #endif }
/* * This is the function called from the signal handler */ gboolean mono_arch_handle_exception (void *ctx, gpointer obj) { #if defined(MONO_CROSS_COMPILE) || !defined(MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX) g_assert_not_reached (); #elif defined(MONO_ARCH_USE_SIGACTION) arm_ucontext *sigctx = ctx; /* * Handling the exception in the signal handler is problematic, since the original * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); guint64 sp = UCONTEXT_REG_SP (sigctx); /* Pass the ctx parameter in TLS */ mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); /* The others in registers */ UCONTEXT_REG_R0 (sigctx) = (gsize)obj; /* Allocate a stack frame */ sp -= 16; UCONTEXT_REG_SP (sigctx) = sp; UCONTEXT_REG_PC (sigctx) = (gsize)get_handle_signal_exception_addr (); #ifdef UCONTEXT_REG_CPSR if ((gsize)UCONTEXT_REG_PC (sigctx) & 1) /* Transition to thumb */ UCONTEXT_REG_CPSR (sigctx) |= (1 << 5); else /* Transition to ARM */ UCONTEXT_REG_CPSR (sigctx) &= ~(1 << 5); #endif return TRUE; #else MonoContext mctx; gboolean result; mono_arch_sigctx_to_monoctx (ctx, &mctx); result = mono_handle_exception (&mctx, obj); /* restore the context so that returning from the signal handler will invoke * the catch clause */ mono_arch_monoctx_to_sigctx (&mctx, ctx); return result; #endif }
static void altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf) { MonoContext mctx; mctx = *ctx; mono_handle_exception (&mctx, obj); if (stack_ovf) { MonoJitTlsData *jit_tls = (MonoJitTlsData *) mono_tls_get_jit_tls (); jit_tls->stack_ovf_pending = 1; prepare_for_guard_pages (&mctx); } mono_restore_context (&mctx); }
gboolean mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) { MonoContext mctx; mono_arch_sigctx_to_monoctx (sigctx, &mctx); if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) return TRUE; mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only); mono_arch_monoctx_to_sigctx (&mctx, sigctx); return TRUE; }
static void altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, gboolean stack_ovf) { MonoContext mctx; MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (ctx), NULL); if (!ji) mono_handle_native_sigsegv (SIGSEGV, NULL, NULL); mctx = *ctx; mono_handle_exception (&mctx, obj); if (stack_ovf) prepare_for_guard_pages (&mctx); mono_restore_context (&mctx); }
/* * handle_exception: * * Called by resuming from a signal handler. */ static void handle_signal_exception (gpointer obj, gboolean test_only) { MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); MonoContext ctx; static void (*restore_context) (MonoContext *); if (!restore_context) restore_context = mono_get_restore_context (); memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext)); mono_handle_exception (&ctx, obj, MONO_CONTEXT_GET_IP (&ctx), test_only); restore_context (&ctx); }
gboolean mono_arch_handle_exception (void *ctx, gpointer obj) { #if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_REG_Rn) /* * Handling the exception in the signal handler is problematic, since the original * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ MonoJitTlsData *jit_tls = mono_tls_get_jit_tls (); mgreg_t sp; void *sigctx = ctx; int frame_size; void *uc = sigctx; /* Pass the ctx parameter in TLS */ mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); /* The others in registers */ UCONTEXT_REG_Rn (sigctx, PPC_FIRST_ARG_REG) = (gsize)obj; /* Allocate a stack frame below the red zone */ /* Similar to mono_arch_handle_altstack_exception () */ frame_size = 224; frame_size += 15; frame_size &= ~15; sp = (mgreg_t)(UCONTEXT_REG_Rn(uc, 1) & ~15); sp = (mgreg_t)(sp - frame_size); UCONTEXT_REG_Rn(uc, 1) = (mgreg_t)sp; setup_ucontext_return (uc, handle_signal_exception); return TRUE; #else MonoContext mctx; gboolean result; mono_sigctx_to_monoctx (ctx, &mctx); result = mono_handle_exception (&mctx, obj); /* restore the context so that returning from the signal handler will invoke * the catch clause */ mono_monoctx_to_sigctx (&mctx, ctx); return result; #endif }
/* * handle_exception: * * Called by resuming from a signal handler. */ static void handle_signal_exception (gpointer obj) { MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); MonoContext ctx; static void (*restore_context) (MonoContext *); if (!restore_context) restore_context = mono_get_restore_context (); memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext)); if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj)) return; mono_handle_exception (&ctx, obj); restore_context (&ctx); }
static void throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; #ifdef DEBUG_EXCEPTIONS g_print ("throw_exception: exc=%p eip=%p esp=%p rethrow=%d\n", exc, (void *)eip, (void *) esp, rethrow); #endif /* adjust eip so that it point into the call instruction */ eip -= 8; memset (&ctx, 0, sizeof (MonoContext)); /*g_print ("stack in throw: %p\n", esp);*/ memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET), sizeof (gulong) * MONO_SAVED_GREGS); memset (&ctx.sc_fpregs, 0, sizeof (mips_freg) * MONO_SAVED_FREGS); MONO_CONTEXT_SET_IP (&ctx, eip); if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } if (preserve_ips) { mono_ex->caught_in_unmanaged = TRUE; } } mono_error_assert_ok (error); mono_handle_exception (&ctx, exc); #ifdef DEBUG_EXCEPTIONS g_print ("throw_exception: restore to pc=%p sp=%p fp=%p ctx=%p\n", (void *) ctx.sc_pc, (void *) ctx.sc_regs[mips_sp], (void *) ctx.sc_regs[mips_fp], &ctx); #endif mono_restore_context (&ctx); g_assert_not_reached (); }
/* * This is the function called from the signal handler */ gboolean mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only) { #if defined(MONO_CROSS_COMPILE) g_assert_not_reached (); #elif defined(MONO_ARCH_USE_SIGACTION) arm_ucontext *sigctx = ctx; /* * Handling the exception in the signal handler is problematic, since the original * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); guint64 sp = UCONTEXT_REG_SP (sigctx); /* Pass the ctx parameter in TLS */ mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); /* The others in registers */ UCONTEXT_REG_R0 (sigctx) = (gsize)obj; UCONTEXT_REG_R1 (sigctx) = test_only; /* Allocate a stack frame */ sp -= 16; UCONTEXT_REG_SP (sigctx) = sp; UCONTEXT_REG_PC (sigctx) = (gsize)handle_signal_exception; return TRUE; #else MonoContext mctx; gboolean result; mono_arch_sigctx_to_monoctx (ctx, &mctx); result = mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only); /* restore the context so that returning from the signal handler will invoke * the catch clause */ mono_arch_monoctx_to_sigctx (&mctx, ctx); return result; #endif }
static void altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf) { void (*restore_context) (MonoContext *); MonoContext mctx; restore_context = mono_get_restore_context (); mono_arch_sigctx_to_monoctx (sigctx, &mctx); if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) { if (stack_ovf) prepare_for_guard_pages (&mctx); restore_context (&mctx); } mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, FALSE); if (stack_ovf) prepare_for_guard_pages (&mctx); restore_context (&mctx); }
static void altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf) { void (*restore_context) (MonoContext *); MonoContext mctx; restore_context = mono_get_restore_context (); mctx = *ctx; if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) { if (stack_ovf) prepare_for_guard_pages (&mctx); restore_context (&mctx); } mono_handle_exception (&mctx, obj); if (stack_ovf) prepare_for_guard_pages (&mctx); restore_context (&mctx); }
static void throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean rethrow) { static void (*restore_context) (MonoContext *); MonoContext ctx; #ifdef DEBUG_EXCEPTIONS g_print ("throw_exception: exc=%p eip=%p esp=%p rethrow=%d\n", exc, (void *)eip, (void *) esp, rethrow); #endif if (!restore_context) restore_context = mono_get_restore_context (); /* adjust eip so that it point into the call instruction */ eip -= 8; setup_context (&ctx); /*g_print ("stack in throw: %p\n", esp);*/ memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET), sizeof (gulong) * MONO_SAVED_GREGS); memset (&ctx.sc_fpregs, 0, sizeof (mips_freg) * MONO_SAVED_FREGS); MONO_CONTEXT_SET_IP (&ctx, eip); if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) mono_ex->stack_trace = NULL; } mono_handle_exception (&ctx, exc, (void *)eip, FALSE); #ifdef DEBUG_EXCEPTIONS g_print ("throw_exception: restore to pc=%p sp=%p fp=%p ctx=%p\n", (void *) ctx.sc_pc, (void *) ctx.sc_regs[mips_sp], (void *) ctx.sc_regs[mips_fp], &ctx); #endif restore_context (&ctx); g_assert_not_reached (); }
/* * mono_x86_throw_exception: * * C function called from the throw trampolines. */ void mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, mgreg_t eip, gboolean rethrow) { MonoError error; MonoContext ctx; ctx.esp = regs [X86_ESP]; ctx.eip = eip; ctx.ebp = regs [X86_EBP]; ctx.edi = regs [X86_EDI]; ctx.esi = regs [X86_ESI]; ctx.ebx = regs [X86_EBX]; ctx.edx = regs [X86_EDX]; ctx.ecx = regs [X86_ECX]; ctx.eax = regs [X86_EAX]; #ifdef __APPLE__ /* The OSX ABI specifies 16 byte alignment at call sites */ g_assert ((ctx.esp % MONO_ARCH_FRAME_ALIGNMENT) == 0); #endif if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } } mono_error_assert_ok (&error); /* adjust eip so that it point into the call instruction */ ctx.eip -= 1; mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); g_assert_not_reached (); }
/* * mono_arm_throw_exception: * * This function is called by the exception trampolines. * FP_REGS points to the 8 callee saved fp regs. */ void mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow) { MonoError error; MonoContext ctx; MonoObject *exc = NULL; guint32 ex_token_index, ex_token; if (!corlib) exc = arg; else { ex_token_index = (guint64)arg; ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index; exc = (MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token); } /* Adjust pc so it points into the call instruction */ pc -= 4; /* Initialize a ctx based on the arguments */ memset (&ctx, 0, sizeof (MonoContext)); memcpy (&(ctx.regs [0]), int_regs, sizeof (mgreg_t) * 32); memcpy (&(ctx.fregs [ARMREG_D8]), fp_regs, sizeof (double) * 8); ctx.has_fregs = 1; ctx.pc = pc; if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } } mono_error_assert_ok (&error); mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); }