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: Fix unwinding through signal frames on -EB o32.


When I previously changed the mips_fallback_frame_state to return an adjusted $pc value, I overlooked the big-endian o32 case. For this case (and only this case), we were adding 4 to $pc and also adding 4 to the cfa resulting in a total adjustment of 8. This was causing the libjava Array_3 test to fail as the reported $pc had been moved outside of the catch block resulting in the exception being caught at the wrong place.

The fix is to base the $pc calculation on the unadjusted cfa value and use a new (possibly adjusted) variable 'reg_base' as the base for the rest of the registers.

Tested with --enable-languages=c,c++,java on both mips-linux and mipsel-linux with no regressions.

OK to commit?

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

   * config/mips/linux-unwind.h (mips_fallback_frame_state): Use new
   reg_base variable to calculate register locations.

Index: config/mips/linux-unwind.h
===================================================================
--- config/mips/linux-unwind.h	(revision 129223)
+++ config/mips/linux-unwind.h	(working copy)
@@ -52,7 +52,7 @@ mips_fallback_frame_state (struct _Unwin
 {
   u_int32_t *pc = (u_int32_t *) context->ra;
   struct sigcontext *sc;
-  _Unwind_Ptr new_cfa;
+  _Unwind_Ptr new_cfa, reg_base;
   int i;
 
   /* 24021061 li v0, 0x1061 (rt_sigreturn)*/
@@ -94,13 +94,15 @@ mips_fallback_frame_state (struct _Unwin
   /* On o32 Linux, the register save slots in the sigcontext are
      eight bytes.  We need the lower half of each register slot,
      so slide our view of the structure back four bytes.  */
-  new_cfa -= 4;
+  reg_base = new_cfa - 4;
+#else
+  reg_base = new_cfa;
 #endif
 
   for (i = 0; i < 32; i++) {
     fs->regs.reg[i].how = REG_SAVED_OFFSET;
     fs->regs.reg[i].loc.offset
-      = (_Unwind_Ptr)&(sc->sc_regs[i]) - new_cfa;
+      = (_Unwind_Ptr)&(sc->sc_regs[i]) - reg_base;
   }
   /* The PC points to the faulting instruction, but the unwind tables
      expect it point to the following instruction.  We compensate by

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