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]

Resend: RFC Patch: Fix bad eh_frame data for MIPS.


Why didn't this showup the first time I sent it?

David Daney wrote:

This patch is against gcc-3.3.1, I have not tried it against the cvs
mainline yet.

Gcc was generating bad eh_frame data for MIPS targets, but the problem
did not become evident until unwinding through leaf functions.  Which
can only be done if unwinding through a signal handler, which in turn
is not possible without the attached patch (or the superseded
http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00652.html).

The problem is that initial_return_save() was causing the emission of
the return save to be suppressed due to munging of the register numbers.

This patch attempts to rectify that.

David Daney

------------------------------------------------------------------------

20003-09-17 David Daney <ddaney@avtrex.com>

	* 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


diff -u --recursive --ignore-space-change --new-file --exclude=*~ --exclude=Makefile.in --exclude=configure --exclude=semantic.cache* gcc-3.3.1/gcc/config/mips/linux.h gcc-3.3.1.dave/gcc/config/mips/linux.h --- gcc-3.3.1/gcc/config/mips/linux.h Thu May 8 10:31:34 2003 +++ gcc-3.3.1.dave/gcc/config/mips/linux.h Wed Sep 17 13:47:35 2003 @@ -252,3 +252,78 @@ /* The current Linux binutils uses MIPS_STABS_ELF and doesn't support COFF. */ #undef SDB_DEBUGGING_INFO + +/* 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 { \ + unsigned char *pc_ = (CONTEXT)->ra; \ + struct sigcontext *sc_; \ + long new_cfa_; \ + int i_; \ + \ + /* 24021061 li v0, 0x1061 (rt_sigreturn)*/ \ + /* 0000000c syscall */ \ + /* or */ \ + /* 24021017 li v0, 0x1017 (sigreturn) */ \ + /* 0000000c syscall */ \ + if (*(unsigned int *) (pc_+4) != 0x0000000c) \ + break; \ + if (*(unsigned int *) (pc_+0) == 0x24021017) \ + { \ + struct sigframe { \ + unsigned int trampoline[2]; \ + struct sigcontext sigctx; \ + } *rt_ = (CONTEXT)->ra; \ + sc_ = &rt_->sigctx; \ + } \ + else if (*(unsigned int *) (pc_+0) == 0x24021061) \ + { \ + struct rt_sigframe { \ + unsigned int trampoline[2]; \ + struct siginfo info; \ + sig_ucontext_t uc; \ + } *rt_ = (CONTEXT)->ra; \ + sc_ = &rt_->uc.uc_mcontext; \ + } \ + else \ + break; \ + \ + new_cfa_ = sc_->sc_regs[STACK_POINTER_REGNUM]; \ + (FS)->cfa_how = CFA_REG_OFFSET; \ + (FS)->cfa_reg = STACK_POINTER_REGNUM; \ + (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ + \ + for (i_ = 0; i_ < 32; i_++) \ + if (i_ != STACK_POINTER_REGNUM) \ + { \ + (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \ + (FS)->regs.reg[i_].loc.offset \ + = (long)&(sc_->sc_regs[i_]) - new_cfa_; \ + } \ + /* Overload RAP_REG_NUM to be signal handler return address. */ \ + /* Is this correct? It seems to work. We don't have to define */ \ + /* more pseudo registers. RAP should be unused in a signal frame. */\ + (FS)->regs.reg[DWARF_FRAME_RETURN_COLUMN].how = REG_SAVED_OFFSET; \ + (FS)->regs.reg[DWARF_FRAME_RETURN_COLUMN].loc.offset \ + = (long)&(sc_->sc_pc) - new_cfa_; \ + (FS)->retaddr_column = DWARF_FRAME_RETURN_COLUMN; \ + \ + goto SUCCESS; \ + } while (0) diff -u --recursive --ignore-space-change --new-file --exclude=*~ --exclude=Makefile.in --exclude=configure --exclude=semantic.cache* gcc-3.3.1/gcc/config/mips/mips.h gcc-3.3.1.dave/gcc/config/mips/mips.h --- gcc-3.3.1/gcc/config/mips/mips.h Fri May 30 05:00:42 2003 +++ gcc-3.3.1.dave/gcc/config/mips/mips.h Wed Sep 17 13:44:38 2003 @@ -1289,6 +1289,12 @@ /* Before the prologue, RA lives in r31. */ #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)

+/* Don't use DWARF_FRAME_REGNUM in dwarf2out.c(initial_return_save).
+   Mapping r31 to DWARF_FRAME_RETURN_COLUMN breaks unwinding through
+   leaf functions which can happen when unwinding through a signal
+   handler.*/
+#define DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE(REG) (REG)
+
/* Describe how we implement __builtin_eh_return.  */
#define EH_RETURN_DATA_REGNO(N) ((N) < (TARGET_MIPS16 ? 2 : 4) ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
diff -u --recursive --ignore-space-change --new-file --exclude=*~ --exclude=Makefile.in --exclude=configure --exclude=semantic.cache* gcc-3.3.1/gcc/dwarf2out.c gcc-3.3.1.dave/gcc/dwarf2out.c
--- gcc-3.3.1/gcc/dwarf2out.c	Sun Jul 20 00:22:55 2003
+++ gcc-3.3.1.dave/gcc/dwarf2out.c	Wed Sep 17 13:44:35 2003
@@ -377,6 +377,11 @@
#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
#endif

+#ifndef DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE
+#define DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE(REG) \
+  DWARF_FRAME_REGNUM (REG)
+#endif
+
/* The offset from the incoming value of %sp to the top of the stack frame
   for the current function.  */
#ifndef INCOMING_FRAME_SP_OFFSET
@@ -885,7 +890,7 @@
    {
    case REG:
      /* RA is in a register.  */
-      reg = DWARF_FRAME_REGNUM (REGNO (rtl));
+      reg = DWARF_FRAME_REGNUM_FOR_INITIAL_RETURN_SAVE (REGNO (rtl));
      break;

case MEM:




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