This is the mail archive of the
mailing list for the GCC project.
Re: [Patch] MIPS: Fix unwinding through signal frames for n32 and n64 ABIs.
- From: David Daney <ddaney at avtrex dot com>
- To: gcc-patches at gcc dot gnu dot org, Daniel Jacobowitz <drow at false dot org>, rsandifo at nildram dot co dot uk
- Date: Tue, 10 Jul 2007 00:08:06 -0700
- Subject: Re: [Patch] MIPS: Fix unwinding through signal frames for n32 and n64 ABIs.
- References: <4691DBF0.firstname.lastname@example.org> <email@example.com>
Richard Sandiford wrote:
David Daney <firstname.lastname@example.org> writes:Yes, that is exactly what I should have used in the first place.
As noted by Daniel Jacobowitz, this patch:
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.
I see no reason to keep SIGNAL_UNWIND_RETURN_COLUMN around. Other ports
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
(It's probably a good idea to keep SIGNAL_UNWIND_RETURN_COLUMN too,
#defined to DWARF_ALT_FRAME_RETURN_COLUMN.)
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.
OK to commit if testing reveals no problems?
2007-07-10 David Daney <email@example.com>
* config/mips/linux-unwind.h (mips_fallback_frame_state): Rewrite
return address calculation. Substitute DWARF_ALT_FRAME_RETURN_COLUMN
* config/mips/mips.h (SIGNAL_UNWIND_RETURN_COLUMN): Remove.
--- 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
u_int32_t *pc = (u_int32_t *) context->ra;
- u_int32_t t;
struct sigcontext *sc;
@@ -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;
- = (_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;
+ = (_Unwind_Ptr)(sc->sc_pc) + 4 - new_cfa;
+ fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
--- 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 (firstname.lastname@example.org).
Changed by Michael Meissner (email@example.com).
64-bit r4000 support by Ian Lance Taylor (firstname.lastname@example.org) 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)