diff options
Diffstat (limited to 'linux-user/signal.c')
-rw-r--r-- | linux-user/signal.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c index 81c45bfce9..6d5e5b698c 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -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) { |