* config/mips/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New
authordaney <daney@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Oct 2003 22:24:56 +0000 (22:24 +0000)
committerdaney <daney@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Oct 2003 22:24:56 +0000 (22:24 +0000)
* config/mips/mips.h (DWARF_FRAME_REGNUM): Fixed to allow unwind
from leaf functions.
(DWARF_FRAME_RETURN_COLUMN): Ditto.
(SIGNAL_UNWIND_RETURN_COLUMN): New, used
by MD_FALLBACK_FRAME_STATE_FOR.
* testsuite/gcc.dg/cleanup-9.c: Added mips*-*-linux* target.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72536 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/mips/linux.h
gcc/config/mips/mips.h
gcc/testsuite/gcc.dg/cleanup-9.c

index 851f048..8712242 100644 (file)
@@ -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 {                                                               \
+    u_int32_t *pc_ = (u_int32_t *) (CONTEXT)->ra;                \
+    struct sigcontext *sc_;                                          \
+    _Unwind_Ptr new_cfa_;                                            \
+    int i_;                                                          \
+                                                                     \
+    /* 24021061 li v0, 0x1061 (rt_sigreturn)*/                       \
+    /* 0000000c syscall    */                                        \
+    /*    or */                                                      \
+    /* 24021017 li v0, 0x1017 (sigreturn) */                         \
+    /* 0000000c syscall  */                                          \
+    if (*(pc_ + 1) != 0x0000000c)                                    \
+      break;                                                         \
+    if (*(pc_ + 0) == 0x24021017)                                    \
+      {                                                              \
+        struct sigframe {                                            \
+          u_int32_t  trampoline[2];                                \
+          struct sigcontext sigctx;                                  \
+        } *rt_ = (CONTEXT)->ra;                                      \
+        sc_ = &rt_->sigctx;                                          \
+      }                                                              \
+    else if (*(pc_ + 0) == 0x24021061)                               \
+      {                                                              \
+        struct rt_sigframe {                                         \
+          u_int32_t  trampoline[2];                                \
+          struct siginfo info;                                       \
+          _sig_ucontext_t uc;                                        \
+        } *rt_ = (CONTEXT)->ra;                                      \
+        sc_ = &rt_->uc.uc_mcontext;                                  \
+      }                                                              \
+    else                                                             \
+      break;                                                         \
+                                                                     \
+    new_cfa_ = (_Unwind_Ptr)sc_;                                     \
+    (FS)->cfa_how = CFA_REG_OFFSET;                                  \
+    (FS)->cfa_reg = STACK_POINTER_REGNUM;                            \
+    (FS)->cfa_offset = new_cfa_ - (_Unwind_Ptr) (CONTEXT)->cfa;      \
+                                                                     \
+    for (i_ = 0; i_ < 32; i_++) {                                    \
+      (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;                     \
+      (FS)->regs.reg[i_].loc.offset                                  \
+        = (_Unwind_Ptr)&(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           \
+        = (_Unwind_Ptr)&(sc_->sc_pc) - new_cfa_;                     \
+    (FS)->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;              \
+                                                                     \
+    goto SUCCESS;                                                    \
+  } while (0)
index 2e5fb7a..23fe285 100644 (file)
@@ -1216,11 +1216,14 @@ extern const struct mips_cpu_info *mips_tune_info;
 #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 0c17f25..29048d2 100644 (file)
@@ -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.  */