*/
+/*
+ * So, it turns out that the ucontext struct defined by libc is incorrect.
+ * We define our own version here and use it instead.
+ */
+
+typedef struct my_ucontext {
+ unsigned long uc_flags;
+ struct my_ucontext *uc_link;
+ struct {
+ void *p;
+ int flags;
+ size_t size;
+ } sstack_data;
+ struct sigcontext sig_ctx;
+ /* some 2.6.x kernel has fp data here after a few other fields
+ * we don't use them for now...
+ */
+} my_ucontext;
#define restore_regs_from_context(ctx_reg,ip_reg,tmp_reg) do { \
int reg; \
restore_regs_from_context (ARMREG_R0, ARMREG_R1, ARMREG_R2);
/* restore also the stack pointer, FIXME: handle sp != fp */
ARM_LDR_IMM (code, ARMREG_SP, ARMREG_R0, G_STRUCT_OFFSET (MonoContext, ebp));
+ ARM_LDR_IMM (code, ARMREG_FP, ARMREG_R0, G_STRUCT_OFFSET (MonoContext, esp));
+
/* jump to the saved IP */
ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1);
/* never reached */
/*printf ("stack in throw: %p\n", esp);*/
MONO_CONTEXT_SET_BP (&ctx, esp);
+ MONO_CONTEXT_SET_SP (&ctx, esp);
MONO_CONTEXT_SET_IP (&ctx, eip);
memcpy (&ctx.regs, int_regs, sizeof (gulong) * 8);
/* memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_SAVED_FREGS); */
return start;
}
-static MonoArray *
-glist_to_array (GList *list, MonoClass *eclass)
-{
- MonoDomain *domain = mono_domain_get ();
- MonoArray *res;
- int len, i;
-
- if (!list)
- return NULL;
-
- len = g_list_length (list);
- res = mono_array_new (domain, eclass, len);
-
- for (i = 0; list; list = list->next, i++)
- mono_array_set (res, gpointer, i, list->data);
-
- return res;
-}
-
/* mono_arch_find_jit_info:
*
* This function is used to gather information from @ctx. It return the
return NULL;
}
+void
+mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
+{
+#if BROKEN_LINUX
+ struct ucontext *uc = sigctx;
+
+ mctx->eip = uc->uc_mcontext.gregs [ARMREG_PC];
+ mctx->ebp = uc->uc_mcontext.gregs [ARMREG_SP];
+ memcpy (&mctx->regs, &uc->uc_mcontext.gregs [ARMREG_R4], sizeof (gulong) * 8);
+ /* memcpy (&mctx->fregs, &uc->uc_mcontext.uc_regs->fpregs.fpregs [14], sizeof (double) * MONO_SAVED_FREGS);*/
+#else
+ my_ucontext *my_uc = sigctx;
+
+ mctx->eip = my_uc->sig_ctx.arm_pc;
+ mctx->ebp = my_uc->sig_ctx.arm_sp;
+ memcpy (&mctx->regs, &my_uc->sig_ctx.arm_r4, sizeof (gulong) * 8);
+#endif
+}
+
+void
+mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
+{
+#if BROKEN_LINUX
+ struct ucontext *uc = ctx;
+
+ uc->uc_mcontext.gregs [ARMREG_PC] = mctx->eip;
+ uc->uc_mcontext.gregs [ARMREG_SP] = mctx->ebp;
+ memcpy (&uc->uc_mcontext.gregs [ARMREG_R4], &mctx->regs, sizeof (gulong) * 8);
+ /* memcpy (&uc->uc_mcontext.uc_regs->fpregs.fpregs [14], &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);*/
+#else
+ my_ucontext *my_uc = ctx;
+
+ my_uc->sig_ctx.arm_pc = mctx->eip;
+ my_uc->sig_ctx.arm_sp = mctx->ebp;
+ memcpy (&my_uc->sig_ctx.arm_r4, &mctx->regs, sizeof (gulong) * 8);
+#endif
+}
+
/*
* This is the function called from the signal handler
*/
gboolean
mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only)
{
- struct ucontext *uc = ctx;
MonoContext mctx;
gboolean result;
- mctx.eip = uc->uc_mcontext.gregs [ARMREG_PC];
- mctx.ebp = uc->uc_mcontext.gregs [ARMREG_SP];
- memcpy (&mctx.regs, &uc->uc_mcontext.gregs [ARMREG_R4], sizeof (gulong) * 8);
- /* memcpy (&mctx.fregs, &uc->uc_mcontext.uc_regs->fpregs.fpregs [14], sizeof (double) * MONO_SAVED_FREGS);*/
+ 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
*/
- uc->uc_mcontext.gregs [ARMREG_PC] = mctx.eip;
- uc->uc_mcontext.gregs [ARMREG_SP] = mctx.ebp;
- memcpy (&uc->uc_mcontext.gregs [ARMREG_R4], &mctx.regs, sizeof (gulong) * 8);
- /* memcpy (&uc->uc_mcontext.uc_regs->fpregs.fpregs [14], &mctx.fregs, sizeof (double) * MONO_SAVED_FREGS);*/
+ mono_arch_monoctx_to_sigctx (&mctx, ctx);
return result;
}
gpointer
mono_arch_ip_from_context (void *sigctx)
{
+#if BROKEN_LINUX
struct ucontext *uc = sigctx;
return (gpointer)uc->uc_mcontext.gregs [ARMREG_PC];
+#else
+ my_ucontext *my_uc = sigctx;
+ return (void*)my_uc->sig_ctx.arm_pc;
+#endif
}
gboolean