This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: MIPS unwind through signal handlers (revised)


I fixed my build problems (a dumb mistake on my part).

testsuite/gcc.dg/cleanup-9 succeeds for me (--target=mipsisa32el-linux) with this patch applied to cvs mainline.

Get ready for the libgcj patch.

David Daney.

David Daney wrote:

Thanks to those who made me understand, here is a revised patch.

This is agains the cvs mainline, but was only tested against 3.3.1 because the mainline build is broken for me right now.

This should superseed earlier versions sent to the list (but not committed):
http://gcc.gnu.org/ml/gcc-patches/2003-09/msg01135.html and
http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00652.html



David Daney.


------------------------------------------------------------------------

2003-09-18 David Daney <ddaney@avtrex.com>

	* gcc/gcc/config/mips/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
	* gcc/gcc/config/mips/mips.h (DWARF_FRAME_REGNUM): Fixed to
	allow unwind from leaf functions.
	* gcc/gcc/config/mips/mips.h (DWARF_FRAME_RETURN_COLUMN): Ditto.
	* gcc/gcc/config/mips/mips.h (SIGNAL_UNWIND_RETURN_COLUMN): New,
	used by MD_FALLBACK_FRAME_STATE_FOR.
	* gcc/gcc/testsuite/gcc.dg/cleanup-9.c: Added mips*-*-linux* target.

Index: gcc/gcc/config/mips/linux.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/linux.h,v
retrieving revision 1.66
diff -u -3 -p -r1.66 linux.h
--- gcc/gcc/config/mips/linux.h	14 Jul 2003 20:29:34 -0000	1.66
+++ gcc/gcc/config/mips/linux.h	18 Sep 2003 23:35:15 -0000
@@ -190,3 +190,73 @@ Boston, MA 02111-1307, USA.  */
%{!static:-rpath-link %R/lib:%R/usr/lib} \
%{!shared: %{pthread:-lpthread} \
  %{profile:-lc_p} %{!profile: -lc}}"
+
+/* 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>
+
+/* The third parameter to the signal handler points to something with
+ * this structure defined in asm/ucontext.h, but the name clashes with
+ * struct ucontext from sys/ucontext.h so this private copy is used. */
+typedef struct _sig_ucontext {
+    unsigned long         uc_flags;
+    struct _sig_ucontext  *uc_link;
+    stack_t               uc_stack;
+    struct sigcontext uc_mcontext;
+    sigset_t      uc_sigmask;
+} sig_ucontext_t;
+
+#endif /* IN_LIBGCC2  */
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)            \
+  do {                                                               \
+    unsigned char *pc_ = (CONTEXT)->ra;                              \
+    struct sigcontext *sc_;                                          \
+    char *new_cfa_;                                                  \
+    int i_;                                                          \
+                                                                     \
+    /* 24021061 li v0, 0x1061 (rt_sigreturn)*/                       \
+    /* 0000000c syscall    */                                        \
+    /*    or */                                                      \
+    /* 24021017 li v0, 0x1017 (sigreturn) */                         \
+    /* 0000000c syscall  */                                          \
+    if (*(unsigned int *) (pc_+4) != 0x0000000c)                     \
+      break;                                                         \
+    if (*(unsigned int *) (pc_+0) == 0x24021017)                     \
+      {                                                              \
+        struct sigframe {                                            \
+          unsigned int trampoline[2];                                \
+          struct sigcontext sigctx;                                  \
+        } *rt_ = (CONTEXT)->ra;                                      \
+        sc_ = &rt_->sigctx;                                          \
+      }                                                              \
+    else if (*(unsigned int *) (pc_+0) == 0x24021061)                \
+      {                                                              \
+        struct rt_sigframe {                                         \
+          unsigned int trampoline[2];                                \
+          struct siginfo info;                                       \
+          sig_ucontext_t uc;                                         \
+        } *rt_ = (CONTEXT)->ra;                                      \
+        sc_ = &rt_->uc.uc_mcontext;                                  \
+      }                                                              \
+    else                                                             \
+      break;                                                         \
+                                                                     \
+    new_cfa_ = (char *)sc_;                                          \
+    (FS)->cfa_how = CFA_REG_OFFSET;                                  \
+    (FS)->cfa_reg = STACK_POINTER_REGNUM;                            \
+    (FS)->cfa_offset = new_cfa_ - (char *) (CONTEXT)->cfa;           \
+                                                                     \
+    for (i_ = 0; i_ < 32; i_++) {                                    \
+      (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;                     \
+      (FS)->regs.reg[i_].loc.offset                                  \
+        = (char *)&(sc_->sc_regs[i_]) - new_cfa_;                    \
+    }                                                                \
+    (FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET; \
+    (FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset           \
+        = (char *)&(sc_->sc_pc) - new_cfa_;                          \
+    (FS)->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;              \
+                                                                     \
+    goto SUCCESS;                                                    \
+  } while (0)
Index: gcc/gcc/config/mips/mips.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.289
diff -u -3 -p -r1.289 mips.h
--- gcc/gcc/config/mips/mips.h	4 Sep 2003 09:55:33 -0000	1.289
+++ gcc/gcc/config/mips/mips.h	18 Sep 2003 23:35:23 -0000
@@ -1211,11 +1211,14 @@ extern const struct mips_cpu_info *mips_
#define DBX_REGISTER_NUMBER(REGNO) mips_dbx_regno[ (REGNO) ]

/* The mapping from gcc register number to DWARF 2 CFA column number.  */
-#define DWARF_FRAME_REGNUM(REG)				\
-  (REG == GP_REG_FIRST + 31 ? DWARF_FRAME_RETURN_COLUMN : REG)
+#define DWARF_FRAME_REGNUM(REG)	(REG)

/* The DWARF 2 CFA column which tracks the return address.  */
-#define DWARF_FRAME_RETURN_COLUMN (FP_REG_LAST + 1)
+#define DWARF_FRAME_RETURN_COLUMN (GP_REG_FIRST + 31)
+
+/* The DWARF 2 CFA column which tracks the return address from a
+   signal handler context.  */
+#define SIGNAL_UNWIND_RETURN_COLUMN (FP_REG_LAST + 1)

/* Before the prologue, RA lives in r31. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)
Index: gcc/gcc/testsuite/gcc.dg/cleanup-9.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/cleanup-9.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 cleanup-9.c
--- gcc/gcc/testsuite/gcc.dg/cleanup-9.c 16 Jul 2003 11:52:55 -0000 1.2
+++ gcc/gcc/testsuite/gcc.dg/cleanup-9.c 18 Sep 2003 23:35:49 -0000
@@ -1,4 +1,4 @@
-/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* alpha*-*-linux* powerpc*-*-linux* s390*-*-linux* sparc*-*-linux* } } */
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* alpha*-*-linux* powerpc*-*-linux* s390*-*-linux* sparc*-*-linux* mips*-*-linux* } } */
/* { dg-options "-fasynchronous-unwind-tables -fexceptions -O2" } */
/* Verify that cleanups work with exception handling through realtime
signal frames. */




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]