Commit 28027082 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Benjamin Herrenschmidt

powerpc: Wrong DWARF CFI in the kernel vdso for little-endian / ELFv2

I've finally tracked down why my CR signal-unwind test case still
fails on little-endian.  The problem turned to be that the kernel
installs a signal trampoline in the vDSO, and provides a DWARF CFI
record for that trampoline.  This CFI describes the save location
for CR:

  rsave (70, 38*RSIZE + (RSIZE - CRSIZE))

which is correct for big-endian, but points to the wrong word on
little-endian.   This is wrong no matter which ABI.

In addition, for the ELFv2 ABI, we should not only provide a CFI
record for register 70 (cr2), but for all CR fields separately.
Strictly speaking, I guess this would mean providing two separate
vDSO images, one for ELFv1 processes and one for ELFv2 processes (or
maybe playing some tricks with conditional DWARF expressions).
However, having CFI records for the other CR fields in ELFv1 is not
actually wrong, they just will be ignored.   So it seems the simplest
fix would be just to always provide CFI for all the fields.
Signed-off-by: default avatarUlrich Weigand <Ulrich.Weigand@de.ibm.com>
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent f53e462e
...@@ -142,6 +142,13 @@ V_FUNCTION_END(__kernel_sigtramp_rt64) ...@@ -142,6 +142,13 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
/* Size of CR reg in DWARF unwind info. */ /* Size of CR reg in DWARF unwind info. */
#define CRSIZE 4 #define CRSIZE 4
/* Offset of CR reg within a full word. */
#ifdef __LITTLE_ENDIAN__
#define CROFF 0
#else
#define CROFF (RSIZE - CRSIZE)
#endif
/* This is the offset of the VMX reg pointer. */ /* This is the offset of the VMX reg pointer. */
#define VREGS 48*RSIZE+33*8 #define VREGS 48*RSIZE+33*8
...@@ -181,7 +188,14 @@ V_FUNCTION_END(__kernel_sigtramp_rt64) ...@@ -181,7 +188,14 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
rsave (31, 31*RSIZE); \ rsave (31, 31*RSIZE); \
rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \ rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \
rsave (65, 36*RSIZE); /* lr */ \ rsave (65, 36*RSIZE); /* lr */ \
rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */ rsave (68, 38*RSIZE + CROFF); /* cr fields */ \
rsave (69, 38*RSIZE + CROFF); \
rsave (70, 38*RSIZE + CROFF); \
rsave (71, 38*RSIZE + CROFF); \
rsave (72, 38*RSIZE + CROFF); \
rsave (73, 38*RSIZE + CROFF); \
rsave (74, 38*RSIZE + CROFF); \
rsave (75, 38*RSIZE + CROFF)
/* Describe where the FP regs are saved. */ /* Describe where the FP regs are saved. */
#define EH_FRAME_FP \ #define EH_FRAME_FP \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment