/* * This is the function called from the signal handler */ gboolean mono_arch_handle_exception (void *ctx, gpointer obj) { #if defined(MONO_CROSS_COMPILE) g_assert_not_reached (); #elif defined(MONO_ARCH_USE_SIGACTION) void *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_GREGS (sigctx) [mips_sp]; /* Pass the ctx parameter in TLS */ mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); /* The others in registers */ UCONTEXT_GREGS (sigctx)[mips_a0] = (gsize)obj; /* Allocate a stack frame */ sp -= 256; UCONTEXT_GREGS (sigctx)[mips_sp] = 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); /* 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 }
void mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) { int i; UCONTEXT_REG_PC (sigctx) = mctx->sc_pc; for (i = 0; i < 32; ++i) { UCONTEXT_GREGS (sigctx) [i] = mctx->sc_regs[i]; UCONTEXT_FPREGS (sigctx) [i] = mctx->sc_fpregs[i]; } }
void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { int i; mctx->sc_pc = UCONTEXT_REG_PC (sigctx); for (i = 0; i < 32; ++i) { mctx->sc_regs[i] = UCONTEXT_GREGS (sigctx) [i]; mctx->sc_fpregs[i] = UCONTEXT_FPREGS (sigctx) [i]; } }
void mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31); UCONTEXT_REG_PC (sigctx) = mctx->pc; UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP]; #endif }
void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31); mctx->pc = UCONTEXT_REG_PC (sigctx); mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx); /* * We don't handle fp regs, this is not currrently a * problem, since we don't allocate them globally. */ #endif }
void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31); mctx->pc = UCONTEXT_REG_PC (sigctx); mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx); #ifdef __linux__ struct fpsimd_context *fpctx = (struct fpsimd_context*)&((ucontext_t*)sigctx)->uc_mcontext.__reserved; int i; g_assert (fpctx->head.magic == FPSIMD_MAGIC); for (i = 0; i < 32; ++i) /* Only store the bottom 8 bytes for now */ *(guint64*)&(mctx->fregs [i]) = fpctx->vregs [i]; #endif /* FIXME: apple */ #endif }