qemu/linux-user
Matt Turner a78df9ab50 linux-user/sh4: Fix setup_sigtramp to match Linux kernel trampoline pattern
QEMU used MOVW(2) (0x9300), which loads the syscall number from PC+4,
instead of the kernel's MOVW(7) (0x9305), which loads from PC+14.  The
kernel uses five "or r0,r0" nop pads between TRAP_NOARG and the syscall
number word to reach that offset.  libunwind's unw_is_signal_frame checks
for the exact kernel byte pattern 0xc3109305 at the frame PC, so QEMU's
compact layout was not detected, breaking unwinding through signal frames.

Expand each trampoline from 6 to 16 bytes matching the kernel layout
defined in arch/sh/kernel/signal_32.c:

  #define MOVW(n)    (0x9300|((n)-2))  /* Move mem word at PC+n to R3 */
  #define TRAP_NOARG 0xc310            /* Syscall w/no args (NR in R3) */
  #define OR_R0_R0   0x200b            /* or r0,r0 (insert to avoid hardware bug) */

  __put_user(MOVW(7),          &frame->retcode[0]);  /* 0x9305 */
  __put_user(TRAP_NOARG,       &frame->retcode[1]);  /* 0xc310 */
  __put_user(OR_R0_R0,         &frame->retcode[2]);  /* 0x200b */
  __put_user(OR_R0_R0,         &frame->retcode[3]);  /* 0x200b */
  __put_user(OR_R0_R0,         &frame->retcode[4]);  /* 0x200b */
  __put_user(OR_R0_R0,         &frame->retcode[5]);  /* 0x200b */
  __put_user(OR_R0_R0,         &frame->retcode[6]);  /* 0x200b */
  __put_user((__NR_sigreturn), &frame->retcode[7]);

The first two halfwords (MOVW(7) || TRAP_NOARG = 0xc3109305) form the
32-bit value libunwind checks at the frame PC, followed by two
OR_R0_R0 halfwords (0x200b200b) at PC+4.  The same layout applies to
the rt_sigreturn trampoline (lines 366-373 of signal_32.c).

Neither this fix nor the companion tuc_link fix is independently
sufficient: this fix makes signal frames detectable but register reads
remain garbage without the correct ucontext layout; that fix corrects the
ucontext layout but libunwind still cannot detect the frame without the
correct trampoline pattern.  Together they fix the following libunwind
tests on a 64-bit host:
  Gtest-sig-context, Gtest-trace, Ltest-init-local-signal,
  Ltest-sig-context, Ltest-trace

Signed-off-by: Matt Turner <mattst88@gmail.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 9ac5aa7227)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-05-19 23:56:02 +03:00
..
aarch64 linux-user/aarch64/target_fcntl.h: add missing TARGET_O_LARGEFILE definition 2026-01-21 10:23:05 +03:00
alpha linux-user: Define SO_TIMESTAMP*_NEW and SO_RCVTIMEIO_NEW 2026-05-14 22:28:26 +03:00
arm linux-user/arm/nwfpe: Use thread-local storage for qemufpa 2026-05-14 22:28:26 +03:00
generic linux-user: Define SO_TIMESTAMP*_NEW and SO_RCVTIMEIO_NEW 2026-05-14 22:28:26 +03:00
hexagon linux-user/hexagon: Use an array for GPRs 2025-10-17 13:45:46 -07:00
hppa linux-user: Define SO_TIMESTAMP*_NEW and SO_RCVTIMEIO_NEW 2026-05-14 22:28:26 +03:00
i386 linux-user/i386/signal.c: Correct definition of target_fpstate_32 2026-03-31 20:10:04 +03:00
include linux-user: cleanup unused linux-user/include/host directories 2023-08-08 20:44:08 +02:00
loongarch64 linux-user: Populate sigreturn_region_{start,end} in all vdso.S 2025-09-23 16:17:59 -07:00
m68k bsd-user, linux-user: introduce qemu_process_cpu_events 2025-09-17 19:00:56 +02:00
microblaze linux-user/microblaze: Fix little-endianness binary 2025-10-16 17:07:52 +02:00
mips linux-user: Define SO_TIMESTAMP*_NEW and SO_RCVTIMEIO_NEW 2026-05-14 22:28:26 +03:00
mips64 linux-user: Standardize on ELF_MACHINE not ELF_ARCH 2025-08-30 07:04:04 +10:00
openrisc bsd-user, linux-user: introduce qemu_process_cpu_events 2025-09-17 19:00:56 +02:00
ppc linux-user/ppc: Fix ppc64 rt_sigframe stack offset 2026-05-14 22:28:26 +03:00
riscv linux-user: Populate sigreturn_region_{start,end} in all vdso.S 2025-09-23 16:17:59 -07:00
s390x linux-user: Populate sigreturn_region_{start,end} in all vdso.S 2025-09-23 16:17:59 -07:00
sh4 linux-user/sh4: Fix setup_sigtramp to match Linux kernel trampoline pattern 2026-05-19 23:56:02 +03:00
sparc linux-user: Define SO_TIMESTAMP*_NEW and SO_RCVTIMEIO_NEW 2026-05-14 22:28:26 +03:00
x86_64 accel/tcg: Add clear_flags argument to page_set_flags 2025-10-14 07:30:39 -07:00
xtensa bsd-user, linux-user: introduce qemu_process_cpu_events 2025-09-17 19:00:56 +02:00
elfload.c linux-user/mips: sync k0 TLS for EF_MIPS_MACH_OCTEON userlands 2026-05-14 22:28:26 +03:00
errnos.c.inc linux-user: Simplify host <-> target errno conversion using macros 2021-07-12 21:53:35 +02:00
exit.c accel/tcg: Move perf and debuginfo support to tcg/ 2024-01-29 21:04:10 +10:00
fd-trans.c linux-user: fix off-by-one in host_to_target_for_each_rtattr() 2026-05-14 22:28:26 +03:00
fd-trans.h linux-user: Hold the fd-trans lock across fork 2025-07-10 13:49:03 -06:00
flat.h linux-user/flatload.c: Remove unused bFLT shared-library and ZFLAT code 2024-04-25 10:21:06 +01:00
flatload.c include/exec: Split out mmap-lock.h 2025-04-23 14:08:17 -07:00
gen-vdso-elfn.c.inc linux-user: Create vdso_sigreturn_region_{start,end} 2025-09-23 16:17:59 -07:00
gen-vdso.c linux-user: Create vdso_sigreturn_region_{start,end} 2025-09-23 16:17:59 -07:00
ioctls.h linux-user: Add missing CDROM ioctls 2026-05-14 22:28:26 +03:00
linux_loop.h linux-user: implement more loop ioctls 2021-11-29 14:54:17 +01:00
linuxload.c linux-user: Create do_init_main_thread 2025-08-28 06:39:25 +10:00
loader.h linux-user: Create vdso_sigreturn_region_{start,end} 2025-09-23 16:17:59 -07:00
main.c linux-user: Fix AT_EXECFN in AUXV for symlinked programs 2026-05-19 23:53:28 +03:00
meson.build plugins: fix inclusion of user-mode APIs 2025-07-14 11:42:49 +01:00
mmap.c linux-user: fix mremap with old_size=0 for shared mappings 2026-03-18 08:05:36 +03:00
plugin-api.c plugins: fix inclusion of user-mode APIs 2025-07-14 11:42:49 +01:00
qemu.h linux-user/mips: sync k0 TLS for EF_MIPS_MACH_OCTEON userlands 2026-05-14 22:28:26 +03:00
semihost.c semihosting: Remove qemu_semihosting_console_outs 2022-06-28 04:41:20 +05:30
signal-common.h linux-user: Add syscall dispatch support 2025-09-23 16:17:59 -07:00
signal.c bsd-user, linux-user: signal: recursive signal delivery fix 2026-05-14 22:28:26 +03:00
socket.h Supply missing header guards 2019-06-12 13:20:21 +02:00
strace.c linux-user: Add termios2 support 2026-01-24 23:47:45 +03:00
strace.h linux-user: Have do_syscall() use CPUArchState* instead of void* 2022-05-23 22:47:19 +02:00
strace.list linux-user/strace: Use pointer type for read and write values 2026-05-14 22:28:26 +03:00
syscall.c linux-user: Fix AT_EXECFN in AUXV for symlinked programs 2026-05-19 23:53:28 +03:00
syscall_defs.h linux-user: Use abi_int for imr_ifindex in ip_mreqn struct 2026-05-14 22:28:26 +03:00
syscall_types.h linux-user: Add termios2 support 2026-01-24 23:47:45 +03:00
thunk.c user: Move 'thunk.h' from 'exec/user' to 'user' 2024-05-03 17:21:20 +02:00
trace-events linux-user: Rename user_force_sig tracepoint to match function name 2022-01-18 12:41:42 +01:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
uaccess.c meson: Make DEBUG_REMAP a meson option 2024-04-24 15:46:00 -07:00
uname.c linux-user: Remove pointless CPU{ARCH}State casts 2022-05-23 22:47:20 +02:00
uname.h linux-user: Have do_syscall() use CPUArchState* instead of void* 2022-05-23 22:47:19 +02:00
user-internals.h linux-user: Fix AT_EXECFN in AUXV for symlinked programs 2026-05-19 23:53:28 +03:00
user-mmap.h user: Extract common MMAP API to 'user/mmap.h' 2025-03-09 14:54:32 +01:00
vm86.c linux-user/vm86: Fix compilation with Clang 2024-10-13 10:34:00 -07:00