summary refs log tree commit diff stats
path: root/linux-user/signal.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-11-23 11:33:14 +0100
committerRichard Henderson <richard.henderson@linaro.org>2021-11-23 11:33:14 +0100
commit73e0f70e097b7c92a5ce16ee35b53afe119b20d7 (patch)
tree367c83eab788d75083b87ac1528de1eed5f72329 /linux-user/signal.c
parent3c2a46d5286b475ce9fc81cbf0ed47af5adeff6b (diff)
parent07637888687bfecf3c0cc8351c5c24f29a611691 (diff)
downloadfocaccia-qemu-73e0f70e097b7c92a5ce16ee35b53afe119b20d7.tar.gz
focaccia-qemu-73e0f70e097b7c92a5ce16ee35b53afe119b20d7.zip
Merge tag 'pull-lu-20211123' of https://gitlab.com/rth7680/qemu into staging
Create common rewind_if_in_safe_syscall function.
Resolves pointer type issues with uc_mcontext.pc
on aarch64 between glibc and musl.

# gpg: Signature made Tue 23 Nov 2021 09:47:07 AM CET
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate]

* tag 'pull-lu-20211123' of https://gitlab.com/rth7680/qemu:
  linux-user/signal.c: Create a common rewind_if_in_safe_syscall
  linux-user: Add host_signal_set_pc to set pc in mcontext

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/signal.c')
-rw-r--r--linux-user/signal.c15
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)
 {