linux-user/ppc: Fix ppc64 rt_sigframe stack offset
The kernel's 64-bit signal delivery (signal_64.c) uses: newsp = frame - __SIGNAL_FRAMESIZE while the 32-bit path (signal_32.c) uses: newsp = frame - (__SIGNAL_FRAMESIZE + 16) The extra 16 bytes in the 32-bit case is to place siginfo and ucontext at the same offsets as older kernels (see the comment in signal_32.c). The 64-bit rt_sigframe starts with ucontext directly and does not need this adjustment. QEMU's setup_rt_frame() unconditionally used (SIGNAL_FRAMESIZE + 16) for both 32-bit and 64-bit, placing the handler's SP 16 bytes too low on ppc64. Signal delivery and return still worked because do_rt_sigreturn had the matching wrong offset, but the vDSO DWARF unwind info encodes the correct kernel offset. This caused any DWARF unwinder (libunwind, libgcc, etc.) to compute a CFA that is 16 bytes off, reading garbage register values from the signal frame. Define RT_SIGFRAME_ADJUST (0 on ppc64, 16 on ppc32) and use it in both setup_rt_frame and do_rt_sigreturn to match the kernel. This was verified by A/B testing with libunwind's test suite: ppc64le: Gtest-bt, Ltest-bt, Gtest-concurrent, Ltest-concurrent, and Ltest-sig-context all change from FAIL to PASS. ppc64be: Gtest-bt, Ltest-bt, and Ltest-sig-context all change from FAIL to PASS. Signed-off-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Helge Deller <deller@gmx.de> Cc: qemu-stable@nongnu.org