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: RFC Patch: Fix bad eh_frame data for MIPS.


Richard Henderson wrote:

On Wed, Sep 17, 2003 at 02:31:30PM -0700, David Daney wrote:


* gcc/config/mips/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New,
needed for mips/libgcj signal handling.
* gcc/config/mips/mips.h (DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE): New.
* gcc/dwarf2out.c (DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE): New.
* gcc/dwarf2out.c (initial_return_save): Use
DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE instead of DWARF_FRAME_REGNUM



This is wrong.


After much though on the matter, I am starting to disagree. It may not be exactly correct, but it is close.


The existing DWARF_FRAME_REGNUM is completely wrong for mips.


??

After deleting that, you have a choice of:

(1) Leaving DWARF_FRAME_RETURN_COLUMN alone, and adding a REG_FRAME_RELATED_EXPR to the insn that saves r31 on the stack.
The expression would mention (reg DWARF_FRAME_RETURN_COLUMN).


I beleve that this is already being done.

However it is not getting written to the CIE because initial_return_save() uses DWARF_FRAME_REGNUM () to map the real register back to the "dwarf frame regnum", which in the case of mips is DWARF_FRAME_RETURN_COLUMN. It then calls reg_save() which suppresses the output because the registers are the same.


(2) Set


#define DWARF_FRAME_RETURN_COLUMN GP_REG_FIRST+31

    This will produce smaller CFI output.  I don't know if SGI's
    debugger can handle overlapping r31 with the return address.
    Gcc and gdb can.

Doing this will fail in the case of a leaf function where r31 is not saved on the stack.

When unwinding through a signal handler we must restore all the registers (including r31) however if we use r31 as the DWARF_FRAME_RETURN_COLUMN then it must have the value of the return address from the signal handler (i.e. the address of the faulting instruction). Unwinding then fails in the leaf function because r31 has the wrong value.

Now what to do? Here are my thoughts (and a psuedo-diff of initial_return_save for context):

static void
initial_return_save (rtl)
    rtx rtl;
{
 unsigned int reg = (unsigned int) -1;
 HOST_WIDE_INT offset = 0;

 switch (GET_CODE (rtl))
   {
   case REG:
     /* RA is in a register.  */
-      reg = DWARF_FRAME_REGNUM (REGNO (rtl));
+      reg = REGNO (rtl);
    break;

.
.
.
This is what my original patch did (but only for MIPS).

It seems that initial_return_save in the REG case is writing a mapping of the "real return address register"-> DWARF_FRAME_RETURN_COLUMN into the CIE. If this is true, then reg must be the real register number, not the DWARF_FRAME_REGNUM.

After looking at all the targets (other than MIPS) that use the REG case I seems that DWARF_FRAME_REGNUM was doing an identity mapping so that this change would not break them (actually for pa and mmix I could not really tell what they were doing).

Does any of this make sense?

David Daney.


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