diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-04-08 14:33:35 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-04-09 07:47:11 -1000 |
commit | 143bcc1d59f174b6c6743bd4ca8f99415ed1aba2 (patch) | |
tree | 880680186cf7c312ef25b2d181de089c541d69b7 /linux-user/signal.c | |
parent | dcd092a0636ec36e69e42a3dbbe447d97cb0d113 (diff) |
linux-user: Preserve unswapped siginfo_t for strace
Passing the tswapped structure to strace means that
our internal si_type is also gone, which then aborts
in print_siginfo.
Fixes: 4d6d8a05a0a ("linux-user: Move tswap_siginfo out of target code")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/signal.c')
-rw-r--r-- | linux-user/signal.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c index a93148a4cb..05dc4afb52 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1173,6 +1173,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig, CPUState *cpu = env_cpu(cpu_env); abi_ulong handler; sigset_t set; + target_siginfo_t unswapped; target_sigset_t target_old_set; struct target_sigaction *sa; TaskState *ts = get_task_state(cpu); @@ -1182,9 +1183,14 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig, k->pending = 0; /* - * Writes out siginfo values byteswapped, accordingly to the target. It also - * cleans the si_type from si_code making it correct for the target. + * Writes out siginfo values byteswapped, accordingly to the target. + * It also cleans the si_type from si_code making it correct for + * the target. We must hold on to the original unswapped copy for + * strace below, because si_type is still required there. */ + if (unlikely(qemu_loglevel_mask(LOG_STRACE))) { + unswapped = k->info; + } tswap_siginfo(&k->info, &k->info); sig = gdb_handlesig(cpu, sig, NULL, &k->info, sizeof(k->info)); @@ -1197,7 +1203,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig, } if (unlikely(qemu_loglevel_mask(LOG_STRACE))) { - print_taken_signal(sig, &k->info); + print_taken_signal(sig, &unswapped); } if (handler == TARGET_SIG_DFL) { |