linux-user/signal.c: Create a common rewind_if_in_safe_syscall

All instances of rewind_if_in_safe_syscall are the same, differing only
in how the instruction point is fetched from the ucontext and the size
of the registers. Use host_signal_pc and new host_signal_set_pc
interfaces to fetch the pointer to the PC and adjust if needed. Delete
all the old copies of rewind_if_in_safe_syscall.

Acked-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20211113045603.60391-3-imp@bsdimp.com>
[rth: include safe-syscall.h, simplify ifdefs]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Warner Losh
2021-11-12 21:56:00 -07:00
committed by Richard Henderson
parent c6cda6a44a
commit 0763788868
9 changed files with 15 additions and 143 deletions

View File

@@ -31,6 +31,7 @@
#include "trace.h"
#include "signal-common.h"
#include "host-signal.h"
#include "safe-syscall.h"
static struct target_sigaction sigact_table[TARGET_NSIG];
@@ -793,12 +794,20 @@ int queue_signal(CPUArchState *env, int sig, int si_type,
return 1; /* indicates that the signal was queued */
}
#ifndef HAVE_SAFE_SYSCALL
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
/* Default version: never rewind */
}
#ifdef HAVE_SAFE_SYSCALL
ucontext_t *uc = (ucontext_t *)puc;
uintptr_t pcreg = host_signal_pc(uc);
if (pcreg > (uintptr_t)safe_syscall_start
&& pcreg < (uintptr_t)safe_syscall_end) {
host_signal_set_pc(uc, (uintptr_t)safe_syscall_start);
}
#endif
}
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
{