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]

RFA: Fix MIPS/Linux unwinding for big-endian


For mips-linux (o32 ABI), the signal frame layout is a little odd.  The
registers are all saved as eight-byte quantities even though they are 32-bit
values.  For little-endian, we don't need to do anything; but for big-endian
we need to bias all the CFA offsets by four bytes, or we can't unwind
through signal frames.

I'm having a little trouble with my test environment right now so I'm still
waiting for complete testsuite results; but I ran the libjava testsuite with
and without this patch and it fixes twenty failures, and introduces none. 
OK?

-- 
Daniel Jacobowitz

2005-02-03  Daniel Jacobowitz  <dan@codesourcery.com>

	* config/mips/linux-unwind.h (mips_fallback_frame_state): Adjust
	offsets for the big-endian 32-bit case.

Index: gcc/config/mips/linux-unwind.h
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/gcc/config/mips/linux-unwind.h,v
retrieving revision 1.1
diff -u -p -r1.1 linux-unwind.h
--- gcc/config/mips/linux-unwind.h	8 Sep 2004 00:17:15 -0000	1.1
+++ gcc/config/mips/linux-unwind.h	21 Jan 2005 21:08:52 -0000
@@ -1,5 +1,5 @@
 /* DWARF2 EH unwinding support for MIPS Linux.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -78,6 +78,13 @@ mips_fallback_frame_state (struct _Unwin
   fs->cfa_reg = STACK_POINTER_REGNUM;
   fs->cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
 
+#if defined _ABIO32 && _MIPS_SIM == _ABIO32 && defined __MIPSEB__
+  /* 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;
+#endif
+
   for (i = 0; i < 32; i++) {
     fs->regs.reg[i].how = REG_SAVED_OFFSET;
     fs->regs.reg[i].loc.offset


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