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]

[Patch] MIPS: Simplify unwinding through signal frames.


This patch is similar to the fix for PR 26208. MIPS does not suffer from the bug, but this simplifies and cleans up the code in libgcj that converts signals into exceptions.

The basic idea is to move all knowledge of unwinding through signal frames into the same place (config/mips/linux-unwind.h). This allows libgcj's mips-signal.h greatly simplified.

Tested with a full bootstrap of c,c++, and java on mipsel-linux-gnu. No regressions.

OK to commit?

gcc:
2006-11-18  David Daney  <ddaney@avtrex.com>

	* config/mips/linux-unwind.h (mips_fallback_frame_state): Adjust
	PC to point to following instruction.

libjava:
2006-11-18  David Daney  <ddaney@avtrex.com>

	* include/mips-signal.h (sys/syscall.h): Do not include.
	(sig_ucontext_t): Removed.
	(MAKE_THROW_FRAME): Changed to be a nop.
	(_INIT_SIG_HANDLER): New macro.
	(INIT_SEGV): Rewrote to use _INIT_SIG_HANDLER.
	(INIT_FPE): Same.



Index: gcc/config/mips/linux-unwind.h
===================================================================
--- gcc/config/mips/linux-unwind.h	(revision 118191)
+++ gcc/config/mips/linux-unwind.h	(working copy)
@@ -1,5 +1,5 @@
 /* DWARF2 EH unwinding support for MIPS Linux.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -51,6 +51,7 @@
 			   _Unwind_FrameState *fs)
 {
   u_int32_t *pc = (u_int32_t *) context->ra;
+  u_int32_t t;
   struct sigcontext *sc;
   _Unwind_Ptr new_cfa;
   int i;
@@ -102,9 +103,13 @@
     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;
+  /* The PC points to the faulting instruction, but the unwind tables
+     expect it point to the following instruction.  We compensate by
+     reporting a return address at the next instruction. */
+  fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_VAL_OFFSET;
+  t = (*(u_int32_t *)(void *)&sc->sc_pc) + 4;
   fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset
-    = (_Unwind_Ptr)&(sc->sc_pc) - new_cfa;
+    = (_Unwind_Ptr)t - new_cfa;
   fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
 
   return _URC_NO_REASON;
Index: libjava/include/mips-signal.h
===================================================================
--- libjava/include/mips-signal.h	(revision 118191)
+++ libjava/include/mips-signal.h	(working copy)
@@ -18,65 +18,31 @@
 
 #include <signal.h>
 #include <unistd.h>
-#include <sys/syscall.h>
-/* #include <asm/ucontext.h> structures we use are here but clash with
-   sys/ucontext.h included by java-signal.h from prims.cc */
 
 #define HANDLE_SEGV 1
 #define HANDLE_FPE 1
 
-/* 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;
-
 #define SIGNAL_HANDLER(_name) \
 static void _name (int _dummy __attribute__ ((__unused__)), \
 		   siginfo_t *_info __attribute__ ((__unused__)), \
 		   void *_arg __attribute__ ((__unused__)))
 
-/*
- *  MIPS leaves pc pointing at the faulting instruction, but the
- *  unwinder expects it to point to the following instruction
- */
+#define MAKE_THROW_FRAME(_exception)
 
-#define MAKE_THROW_FRAME(_exception) \
-do                                   \
-{                                    \
-  ((sig_ucontext_t *)_arg)->uc_mcontext.sc_pc += 4;      \
-  (void)_dummy;                      \
-  (void)_info;                       \
-}                                    \
-while (0)
-
-#define INIT_SEGV                            \
+#define _INIT_SIG_HANDLER(_SIG, _ACTION)     \
 do                                           \
   {                                          \
     struct sigaction act;                    \
-    act.sa_sigaction = catch_segv;           \
+    act.sa_sigaction = _ACTION;              \
     act.sa_flags = SA_SIGINFO | SA_NODEFER;  \
     sigemptyset (&act.sa_mask);              \
-    sigaction(SIGSEGV, &act, NULL);          \
+    sigaction(_SIG, &act, NULL);             \
   }                                          \
 while (0)
 
-#define INIT_FPE                             \
-do                                           \
-  {                                          \
-    struct sigaction act;                    \
-    act.sa_sigaction = catch_fpe;            \
-    act.sa_flags = SA_SIGINFO | SA_NODEFER;  \
-    sigemptyset (&act.sa_mask);              \
-    sigaction(SIGFPE, &act, NULL);           \
-  }                                          \
-while (0)
+#define INIT_SEGV _INIT_SIG_HANDLER (SIGSEGV, catch_segv)
 
+#define INIT_FPE _INIT_SIG_HANDLER (SIGFPE, catch_fpe)
 #undef HANDLE_DIVIDE_OVERFLOW
 
 #endif /* JAVA_SIGNAL_H */

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