PPC / Unwinding non-call exceptions

Andrew Haley aph@cambridge.redhat.com
Thu May 17 09:18:00 GMT 2001


Richard Henderson writes:
 > 
 > See the definition of MD_FALLBACK_FRAME_STATE_FOR in
 > config/alpha/linux.h and config/i386/linux.h.  We need
 > more of these written.

Okay for trunk and branch?

Andrew.

2001-05-17  Andrew Haley  <aph@redhat.com>

	* config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.

Index: linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux.h,v
retrieving revision 1.23
diff -u -r1.23 linux.h
--- linux.h	2000/12/12 21:38:18	1.23
+++ linux.h	2001/05/17 15:53:43
@@ -66,3 +66,56 @@
 #ifndef USE_GNULIBC_1
 #define DEFAULT_VTABLE_THUNKS 1
 #endif
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#ifdef IN_LIBGCC2
+#include <signal.h>
+#include <sys/ucontext.h>
+#endif
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
+  do {									\
+    unsigned char *pc_ = (CONTEXT)->ra;				\
+    struct sigcontext *sc_;						\
+    long new_cfa_;							\
+    int i_;								\
+									\
+    /* li r0, 0x7777; sc  (rt_sigreturn)  */				\
+    /* li r0, 0x6666; sc  (sigreturn)  */				\
+    if (((*(unsigned int *) (pc_+0) == 0x38007777)			\
+	 || (*(unsigned int *) (pc_+0) == 0x38006666))			\
+	&& (*(unsigned int *) (pc_+4)  == 0x44000002))			\
+	sc_ = (CONTEXT)->cfa + __SIGNAL_FRAMESIZE;			\
+    else								\
+      break;								\
+    									\
+    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
+    (FS)->cfa_how = CFA_REG_OFFSET;					\
+    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
+    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+    									\
+    for (i_ = 0; i_ < 32; i_++)					\
+      if (i_ != STACK_POINTER_REGNUM)					\
+	{	    							\
+	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
+	  (FS)->regs.reg[i_].loc.offset 				\
+	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
+	}								\
+									\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
+      = (long)&(sc_->regs->link) - new_cfa_;				\
+									\
+    /* The unwinder expects the IP to point to the following insn,	\
+       whereas the kernel returns the address of the actual		\
+       faulting insn.  */						\
+    sc_->regs->nip += 4;  						\
+    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
+    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
+      = (long)&(sc_->regs->nip) - new_cfa_;				\
+    (FS)->retaddr_column = CR0_REGNO;					\
+    goto SUCCESS;							\
+  } while (0)
+



More information about the Gcc-patches mailing list