diff mbox

[rs6000] Fix little-endian bug in linux-unwind.h

Message ID 201311111434.rABEYoNE021217@d06av02.portsmouth.uk.ibm.com
State New
Headers show

Commit Message

Ulrich Weigand Nov. 11, 2013, 2:34 p.m. UTC
Hello,

this fixes another issue related to CR unwinding, this time only on
64-bit little-endian systems.

The problem is linux-unwind.h:ppc_fallback_frame_state, which notes
that the kernel places the CR value in the low bits of a 64-bit
field in the signal handler frame; but the offset of that field
is different in little-endian.

Tested on powerpc64-linux and powerpc64le-linux.

OK for mainline?

Bye,
Ulrich


libgcc/ChangeLog:

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
	    Alan Modra  <amodra@gmail.com>

	* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Correct
	location of CR save area for 64-bit little-endian systems.
diff mbox

Patch

Index: gcc/libgcc/config/rs6000/linux-unwind.h
===================================================================
--- gcc.orig/libgcc/config/rs6000/linux-unwind.h
+++ gcc/libgcc/config/rs6000/linux-unwind.h
@@ -185,6 +185,7 @@  ppc_fallback_frame_state (struct _Unwind
 {
   struct gcc_regs *regs = get_regs (context);
   struct gcc_vregs *vregs;
+  long cr_offset;
   long new_cfa;
   int i;
 
@@ -206,11 +207,13 @@  ppc_fallback_frame_state (struct _Unwind
       fs->regs.reg[i].loc.offset = (long) &regs->gpr[i] - new_cfa;
     }
 
+  /* The CR is saved in the low 32 bits of regs->ccr.  */
+  cr_offset = (long) &regs->ccr - new_cfa;
+#ifndef __LITTLE_ENDIAN__
+  cr_offset += sizeof (long) - 4;
+#endif
   fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET;
-  /* CR? regs are always 32-bit and PPC is big-endian, so in 64-bit
-     libgcc loc.offset needs to point to the low 32 bits of regs->ccr.  */
-  fs->regs.reg[R_CR2].loc.offset = (long) &regs->ccr - new_cfa
-				   + sizeof (long) - 4;
+  fs->regs.reg[R_CR2].loc.offset = cr_offset;
 
   fs->regs.reg[R_LR].how = REG_SAVED_OFFSET;
   fs->regs.reg[R_LR].loc.offset = (long) &regs->link - new_cfa;