[klibc] sparc: deal with SA_RESTORER; sparc64 requires a restorer function
Fake out SA_RESTORER on sparc; sparc64 requires a restorer function, so
make sure one is provided.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
diff --git a/usr/include/arch/sparc/klibc/archsignal.h b/usr/include/arch/sparc/klibc/archsignal.h
index 0ff7aab..6e845a8 100644
--- a/usr/include/arch/sparc/klibc/archsignal.h
+++ b/usr/include/arch/sparc/klibc/archsignal.h
@@ -18,4 +18,7 @@
sigset_t sa_mask;
};
+/* Not actually used by the kernel... */
+#define SA_RESTORER 0x80000000
+
#endif
diff --git a/usr/include/arch/sparc64/klibc/archconfig.h b/usr/include/arch/sparc64/klibc/archconfig.h
index 212f616..bb0c003 100644
--- a/usr/include/arch/sparc64/klibc/archconfig.h
+++ b/usr/include/arch/sparc64/klibc/archconfig.h
@@ -10,5 +10,6 @@
#define _KLIBC_ARCHCONFIG_H
#define _KLIBC_USE_RT_SIG 1 /* Use rt_* signals */
+#define _KLIBC_NEEDS_SA_RESTORER 1 /* Need a restorer function */
#endif /* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/sparc64/klibc/archsignal.h b/usr/include/arch/sparc64/klibc/archsignal.h
index 55f0550..bb0a5ce 100644
--- a/usr/include/arch/sparc64/klibc/archsignal.h
+++ b/usr/include/arch/sparc64/klibc/archsignal.h
@@ -11,4 +11,7 @@
#define __WANT_POSIX1B_SIGNALS__
#include <asm/signal.h>
+/* Not actually used by the kernel... */
+#define SA_RESTORER 0x80000000
+
#endif
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 9ab685d..435abd5 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -186,6 +186,7 @@
int rt_sigsuspend::__rt_sigsuspend(const sigset_t *, size_t)
int rt_sigpending::__rt_sigpending(sigset_t *, size_t)
int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+<sparc64> void rt_sigreturn::__sigreturn(void)
#else
int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *)
int sigsuspend(const sigset_t *)
diff --git a/usr/klibc/sigaction.c b/usr/klibc/sigaction.c
index f0dbe21..658c3ad 100644
--- a/usr/klibc/sigaction.c
+++ b/usr/klibc/sigaction.c
@@ -10,7 +10,7 @@
__extern int __sigaction(int, const struct sigaction *, struct sigaction *);
#ifdef __sparc__
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
- void *, size_t);
+ void (*)(void), size_t);
#else
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
size_t);
@@ -36,7 +36,13 @@
#if _KLIBC_USE_RT_SIG
# ifdef __sparc__
- rv = __rt_sigaction(sig, act, oact, NULL, sizeof(sigset_t));
+ {
+ void (*restorer)(void);
+ restorer = (act && act->sa_flags & SA_RESTORER)
+ ? (void (*)(void))((uintptr_t)act->sa_restorer - 8)
+ : NULL;
+ rv = __rt_sigaction(sig, act, oact, restorer, sizeof(sigset_t));
+ }
# else
rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t));
# endif