Subject: Storing DAR (and maybe DSISR and ES) in uc_mcontext
To: None <port-powerpc@netbsd.org>
From: Richard M Kreuter <kreuter@progn.net>
List: port-powerpc
Date: 12/15/2005 10:53:56
Hello,

I'm trying to port an application from Darwin and Linux whose segfault
handler wants to examine the contents of the DAR, but the DAR doesn't
get stored in the native ucontext on NetBSD (it looks as though it does
get stored in the Darwin ucontext for emulation, though).  I thought the
patch below would do this, but it doesn't seem to work (or perhaps my
test programs are incorrect).  In any case this patch doesn't seem to
destabilize anything: I've been running with a kernel and userland built
with these patches for a couple weeks.  Can anybody help me get this
working?

Thank you,
Richard M Kreuter

--- ./sys/arch/powerpc/include/mcontext.h.~1.7~	2005-12-12 21:55:35.000000000 -0500
+++ ./sys/arch/powerpc/include/mcontext.h	2005-12-12 21:54:49.000000000 -0500
@@ -47,7 +47,7 @@
  * an ucontext_t is different from System V.
  */
 
-#define	_NGREG	39		/* GR0-31, CR, LR, SRR0, SRR1, CTR, XER, MQ */
+#define	_NGREG	42		/* GR0-31, CR, LR, SRR0, SRR1, CTR, XER, MQ, DAR, DSISR, EXC */
 
 typedef	long		__greg_t;
 typedef	__greg_t	__gregset_t[_NGREG];
@@ -91,6 +91,9 @@ typedef	__greg_t	__gregset_t[_NGREG];
 #define	_REG_CTR	36		/* Count Register */
 #define	_REG_XER	37		/* Integet Exception Reigster */
 #define	_REG_MQ		38		/* MQ Register (POWER only) */
+#define	_REG_DAR	39		/* Data Address register */
+#define	_REG_DSISR	40		/* DSISR */
+#define	_REG_EXC	41		/* EXC */
 
 typedef struct {
 	double		__fpu_regs[32];	/* FP0-31 */
--- ./sys/arch/powerpc/powerpc/sig_machdep.c.~1.24~	2005-12-12 21:56:18.000000000 -0500
+++ ./sys/arch/powerpc/powerpc/sig_machdep.c	2005-12-12 21:54:51.000000000 -0500
@@ -175,6 +175,9 @@ cpu_getmcontext(struct lwp *l, mcontext_
 #else
 	gr[_REG_MQ]  = 0;
 #endif
+	gr[_REG_DAR] = tf->dar;
+	gr[_REG_DSISR] = tf->dsisr;
+	gr[_REG_EXC] = tf->exc;
 	*flagp |= _UC_CPU;
 
 #ifdef PPC_HAVE_FPU
@@ -244,6 +247,9 @@ cpu_setmcontext(struct lwp *l, const mco
 #ifdef PPC_OEA
 		tf->tf_xtra[TF_MQ] = gr[_REG_MQ];
 #endif
+		tf->dar = gr[_REG_DAR]; 
+		tf->dsisr = gr[_REG_DSISR];
+		tf->exc = gr[_REG_EXC];
 	}
 
 #ifdef PPC_HAVE_FPU /* Restore FPR context, if any. */