[Mono-dev] [PATCH]: Implement Sparc exceptions correctly under Linux

David S. Miller davem at davemloft.net
Fri Mar 24 18:27:43 EST 2006


Linux does not pass a ucontext_t to signal handlers, instead
it passes in a "struct sigcontext".  The layout is different
for 64-bit vs 32-bit chips.

This patch implements the necessary support.

With this and the libgc configure.in patch I just posted the
testsuite seems to be running quite well.

Thanks.

2006-03-24  David S. Miller  <davem at sunset.davemloft.net>

	* exceptions-sparc.c (mono_arch_handle_exception,
	mono_arch_ip_from_context): Implement correctly for Linux.

--- mono/mini/exceptions-sparc.c.~1~	2005-01-28 06:54:11.000000000 -0800
+++ mono/mini/exceptions-sparc.c	2006-03-24 15:01:22.000000000 -0800
@@ -425,6 +425,58 @@
 	return FALSE;
 }
 
+#ifdef __linux__
+gboolean
+mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+{
+	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, mctx.ip, test_only);
+	
+#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;
+}
+
+gpointer
+mono_arch_ip_from_context (void *sigctx)
+{
+	struct sigcontext *sc = sigctx;
+	gpointer *ret;
+
+#ifdef SPARCV9
+	ret = (gpointer) sc->sigc_regs.tpc;
+#else
+	ret = (gpointer) sc->si_regs.pc;
+#endif
+
+	return ret;
+}
+#else
 gboolean
 mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
 {
@@ -437,12 +489,7 @@
 	 * under documented under solaris. The code below seems to work under
 	 * Solaris 9.
 	 */
-#ifndef __linux__
 	g_assert (!ctx->uc_mcontext.gwins);
-#else
-	/* better, but doesn't work all the time.  need to rethink! */
-	g_assert (!ctx->uc_mcontext.gregs);
-#endif
 
 	mctx.ip = ctx->uc_mcontext.gregs [REG_PC];
 	mctx.sp = ctx->uc_mcontext.gregs [REG_SP];
@@ -467,4 +514,4 @@
 	ucontext_t *ctx = (ucontext_t*)sigctx;
 	return (gpointer)ctx->uc_mcontext.gregs [REG_PC];
 }
-
+#endif



More information about the Mono-devel-list mailing list