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: 4d6d8a05a0 ("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>
This commit is contained in:
Richard Henderson 2024-04-08 14:33:35 -10:00
parent dcd092a063
commit 143bcc1d59

View File

@ -1173,6 +1173,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
CPUState *cpu = env_cpu(cpu_env); CPUState *cpu = env_cpu(cpu_env);
abi_ulong handler; abi_ulong handler;
sigset_t set; sigset_t set;
target_siginfo_t unswapped;
target_sigset_t target_old_set; target_sigset_t target_old_set;
struct target_sigaction *sa; struct target_sigaction *sa;
TaskState *ts = get_task_state(cpu); TaskState *ts = get_task_state(cpu);
@ -1182,9 +1183,14 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
k->pending = 0; k->pending = 0;
/* /*
* Writes out siginfo values byteswapped, accordingly to the target. It also * Writes out siginfo values byteswapped, accordingly to the target.
* cleans the si_type from si_code making it correct for 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); tswap_siginfo(&k->info, &k->info);
sig = gdb_handlesig(cpu, sig, NULL, &k->info, sizeof(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))) { if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
print_taken_signal(sig, &k->info); print_taken_signal(sig, &unswapped);
} }
if (handler == TARGET_SIG_DFL) { if (handler == TARGET_SIG_DFL) {