This is the mail archive of the 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] Fix ppc64 MD_FALLBACK_FRAME_STATE_FOR cr2 handling


cr[0..7] and xer are just 32-bit registers according to
__builtin_init_dwarf_reg_size_table.  But Linux kernel saves it into a
64-bit field in sigcontext for 64-bit programs and as PPC is big-endian,
this means cr2 is restored from the wrong half of the ccr field.

Fixed thusly, tested with aph's testcase and hacked up which ignores the vdso (didn't want to reboot that box remotely with
elf/ --library-path .:math:/usr/src/gcc/obj/powerpc64-unknown-linux-gnu/64/libgcc.vanilla/64/ /tmp/z
cr = 0x2000
cr = 0x0
elf/ --library-path .:math:/usr/src/gcc/obj/powerpc64-unknown-linux-gnu/64/libgcc.patched/64/ /tmp/z
cr = 0x2000
cr = 0x2000

Ok for trunk?  What about 4.2/4.1?

2007-10-18  Jakub Jelinek  <>

	* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Point
	saved CR2 offset to low 32 bits of regs->ccr rather than the whole
	64-bit register in 64-bit libgcc.

--- gcc/config/rs6000/linux-unwind.h.jj	2007-09-04 22:24:32.000000000 +0200
+++ gcc/config/rs6000/linux-unwind.h	2007-10-18 14:42:25.000000000 +0200
@@ -250,7 +250,10 @@ ppc_fallback_frame_state (struct _Unwind
   fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET;
-  fs->regs.reg[R_CR2].loc.offset = (long) &regs->ccr - new_cfa;
+  /* 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_LR].how = REG_SAVED_OFFSET;
   fs->regs.reg[R_LR].loc.offset = (long) &regs->link - new_cfa;


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