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: Fix unwinding through signal frames for n32 and n64 ABIs.


Richard Sandiford wrote:
David Daney <ddaney@avtrex.com> writes:
As noted by Daniel Jacobowitz, this patch:

http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01337.html

broke unwinding through signal frames on n32 and n64 ABIs. It also causes 4.3 to emit aliasing warnings.

My new patch fixes both of these problems.

The root of the problem is that the original MD_FALLBACK_FRAME_STATE_FOR support for MIPS placed the return address in the register slot use by $hi. This register has the same width as the other general purpose registers. This was causing the unwinder to assert because the width of the return address (Pmode) differs from that of the registers in the n32 ABI (32 bits vs. 64).

The fix is to move the SIGNAL_UNWIND_RETURN_COLUMN into an unused column and give that column the with of Pmode.

I wonder if it would be better to define DWARF_ALT_FRAME_RETURN_COLUMN
to the new register? You then wouldn't need to bother with
HARD_REGNO_MODE_OK, etc., which I think is a good thing: this
register is a purely DWARF concept, it isn't a gcc register.
Yes, that is exactly what I should have used in the first place.
Either way, the change is going to extend the ABI -- DWARF register 66
should not be used for other purposes going forward -- and I think
defining DWARF_ALT_FRAME_RETURN_COLUMN makes that a little more
explicit.

(It's probably a good idea to keep SIGNAL_UNWIND_RETURN_COLUMN too,
#defined to DWARF_ALT_FRAME_RETURN_COLUMN.)

I see no reason to keep SIGNAL_UNWIND_RETURN_COLUMN around. Other ports (pa) use

DWARF_ALT_FRAME_RETURN_COLUMN in the same manner I do in MD_FALLBACK_FRAME_STATE_FOR. It seems that keeping it would just clutters things up. It was only used in the one place in MD_FALLBACK_FRAME_STATE_FOR, and only because I didn't know about DWARF_ALT_FRAME_RETURN_COLUMN at the time.

Here is the new patch. Tested as before (that is to say very lightly) with gcc.dg/cleanup-9.c on mips64-linux with both n32 and n64 ABIs. I will do a full test on mipsel-linux.

Comments?

OK to commit if testing reveals no problems?

2007-07-10 David Daney <ddaney@avtrex.com>

	* config/mips/linux-unwind.h (mips_fallback_frame_state): Rewrite
	return address calculation.  Substitute DWARF_ALT_FRAME_RETURN_COLUMN
	for SIGNAL_UNWIND_RETURN_COLUMN.
	* config/mips/mips.h (SIGNAL_UNWIND_RETURN_COLUMN): Remove.
	(DWARF_ALT_FRAME_RETURN_COLUMN) Define.


Index: config/mips/linux-unwind.h
===================================================================
--- config/mips/linux-unwind.h	(revision 126478)
+++ config/mips/linux-unwind.h	(working copy)
@@ -1,5 +1,5 @@
 /* DWARF2 EH unwinding support for MIPS Linux.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -51,7 +51,6 @@ mips_fallback_frame_state (struct _Unwin
 			   _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;
@@ -106,11 +105,10 @@ mips_fallback_frame_state (struct _Unwin
   /* 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)t - new_cfa;
-  fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
+  fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].how = REG_SAVED_VAL_OFFSET;
+  fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].loc.offset
+    = (_Unwind_Ptr)(sc->sc_pc) + 4 - new_cfa;
+  fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
 
   return _URC_NO_REASON;
 }
Index: config/mips/mips.h
===================================================================
--- config/mips/mips.h	(revision 126478)
+++ config/mips/mips.h	(working copy)
@@ -1,6 +1,7 @@
 /* Definitions of target machine for GNU compiler.  MIPS version.
    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+   Free Software Foundation, Inc.
    Contributed by A. Lichnewsky (lich@inria.inria.fr).
    Changed by Michael Meissner	(meissner@osf.org).
    64-bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
@@ -1008,10 +1009,6 @@ extern const struct mips_rtx_cost_data *
 /* The DWARF 2 CFA column which tracks the return address.  */
 #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)
 
@@ -1355,6 +1352,12 @@ extern const struct mips_rtx_cost_data *
 #define MD_REG_NUM   (MD_REG_LAST - MD_REG_FIRST + 1)
 #define MD_DBX_FIRST (FP_DBX_FIRST + FP_REG_NUM)
 
+/* The DWARF 2 CFA column which tracks the return address from a
+   signal handler context.  This means that to maintain backwards
+   compatibility, no hard register can be assigned this column if it
+   would need to be handled by the DWARF unwinder.  */
+#define DWARF_ALT_FRAME_RETURN_COLUMN 66
+
 #define ST_REG_FIRST 67
 #define ST_REG_LAST  74
 #define ST_REG_NUM   (ST_REG_LAST - ST_REG_FIRST + 1)

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