/* * 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 }
/* * 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 (); #else MonoJitTlsData *jit_tls; void *sigctx = ctx; /* * Resume into the normal stack and handle the exception there. */ jit_tls = mono_tls_get_jit_tls (); /* Pass the ctx parameter in TLS */ mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); /* The others in registers */ UCONTEXT_REG_R0 (sigctx) = (gsize)obj; UCONTEXT_REG_PC (sigctx) = (gsize)handle_signal_exception; UCONTEXT_REG_SP (sigctx) = UCONTEXT_REG_SP (sigctx) - MONO_ARCH_REDZONE_SIZE; #endif return TRUE; }
gpointer mono_arch_ip_from_context (void *sigctx) { #if BROKEN_LINUX g_assert_not_reached (); #else arm_ucontext *my_uc = sigctx; return (void*) UCONTEXT_REG_PC (my_uc); #endif }
gpointer mono_arch_ip_from_context (void *sigctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else arm_ucontext *my_uc = sigctx; return (void*) UCONTEXT_REG_PC (my_uc); #endif }
gpointer mono_arch_ip_from_context (void *sigctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); return NULL; #else return (gpointer)UCONTEXT_REG_PC (sigctx); #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_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { #if BROKEN_LINUX g_assert_not_reached (); #else arm_ucontext *my_uc = sigctx; mctx->eip = UCONTEXT_REG_PC (my_uc); mctx->esp = UCONTEXT_REG_SP (my_uc); memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (gulong) * 16); #endif }
void mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx) { #if BROKEN_LINUX g_assert_not_reached (); #else arm_ucontext *my_uc = ctx; UCONTEXT_REG_PC (my_uc) = mctx->eip; UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_FP]; /* The upper registers are not guaranteed to be valid */ memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (gulong) * 12); #endif }
void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else arm_ucontext *my_uc = sigctx; mctx->pc = UCONTEXT_REG_PC (my_uc); mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc); mctx->cpsr = UCONTEXT_REG_CPSR (my_uc); memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16); #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_monoctx_to_sigctx (MonoContext *mctx, void *ctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else arm_ucontext *my_uc = ctx; UCONTEXT_REG_PC (my_uc) = mctx->pc; UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_FP]; UCONTEXT_REG_CPSR (my_uc) = mctx->cpsr; /* The upper registers are not guaranteed to be valid */ memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (mgreg_t) * 12); #endif }
void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #elif defined(__native_client__) g_assert_not_reached (); #else arm_ucontext *my_uc = sigctx; mctx->pc = UCONTEXT_REG_PC (my_uc); mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc); mctx->cpsr = UCONTEXT_REG_CPSR (my_uc); memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16); #ifdef UCONTEXT_REG_VFPREGS memcpy (&mctx->fregs, UCONTEXT_REG_VFPREGS (my_uc), sizeof (double) * 16); #endif #endif }
/* * 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 }
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 }
gpointer mono_arch_ip_from_context (void *sigctx) { return (gpointer)(gsize)UCONTEXT_REG_PC (sigctx); }