This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Bad unwinder data for __kernel_sigtramp_rt64 in PPC 64 vDSO corrupts Condition Register
On Wed, 2007-10-17 at 12:58 +0930, Alan Modra wrote:
> On Tue, Oct 16, 2007 at 08:21:55PM +0200, Jakub Jelinek wrote:
> > On Tue, Oct 16, 2007 at 06:02:13PM +0100, Andrew Haley wrote:
> > > The reason is that the unwinder data for CR in the vDSO is wrong. The
> > > line that affects the CR is here in
>
> My fault.
>
> > According to __builtin_init_dwarf_reg_size_table on ppc64-linux
> > r0..r31, fp0..fp31, mq, lr, ctr, ap, vrsave, vscr, spe_acc, spefcsr, sfp
> > are 64-bit, v0..v31 128-bit and cr0..cr7, xer 32-bit.
> > So both kernel and gcc/config/rs6000/linux-unwind.h are wrong.
> >
> > > arch/powerpc/kernel/vdso64/sigtramp.S:
> > >
> > > rsave (70, 38*RSIZE) /* cr */
> >
> > This should just be changed to
> > /* Size of CR regs in DWARF unwind info. */
> > #define CRSIZE 4
> > ...
> > rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */
> >
> > and similarly linux-unwind.h should do:
> >
> > fs->regs.reg[R_CR2].loc.offset = (long) ®s->ccr - new_cfa;
> > /* CR? regs are just 32-bit and PPC is big-endian. */
> > fs->regs.reg[R_CR2].loc.offset += sizeof (long) - 4;
>
> This looks good to me. I don't think we can change the unwinder to
> use a different size for cr as that would break unwinding through
> normal stack frames that save cr.
So the kernel fix would look like that right ? If you are ok, I'll
submit it tomorrow.
Index: linux-work/arch/powerpc/kernel/vdso64/sigtramp.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/sigtramp.S 2007-10-17 13:32:49.000000000 +1000
+++ linux-work/arch/powerpc/kernel/vdso64/sigtramp.S 2007-10-17 13:34:18.000000000 +1000
@@ -134,13 +134,16 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
9:
/* This is where the pt_regs pointer can be found on the stack. */
-#define PTREGS 128+168+56
+#define PTREGS 128+168+56
/* Size of regs. */
-#define RSIZE 8
+#define RSIZE 8
+
+/* Size of CR reg in DWARF unwind info. */
+#define CRSIZE 4
/* This is the offset of the VMX reg pointer. */
-#define VREGS 48*RSIZE+33*8
+#define VREGS 48*RSIZE+33*8
/* Describe where general purpose regs are saved. */
#define EH_FRAME_GEN \
@@ -178,7 +181,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
rsave (31, 31*RSIZE); \
rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \
rsave (65, 36*RSIZE); /* lr */ \
- rsave (70, 38*RSIZE) /* cr */
+ rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */
/* Describe where the FP regs are saved. */
#define EH_FRAME_FP \