aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2020-08-23 15:18:19 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-08-27 15:00:33 +0100
commit570ed1e207cbe38ed487c722f8ac7db68e664a94 (patch)
treedf1040680ad4524bddf8b3e66961779dd47c7668
parentc341c978e3024b9c575fac94012fc5b6f5679334 (diff)
downloadklibc-570ed1e207cbe38ed487c722f8ac7db68e664a94.tar.gz
[klibc] alpha: Pass restorer to rt_sigaction() and disable executable stack
alpha does not support the SA_RESTORER flag, but allows specifiying a restorer callback as an additional parameter to rt_sigaction(). We should do this to avoid needing an executable stack. * Force the SA_SIGINFO flag on for all signal handlers, so that we can always return from them with rt_sigreturn * Define a __sigreturn() routine that calls rt_sigreturn * Pass that routine as the last argument to rt_sigaction() * Set KLIBCEXECSTACK=n Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/include/arch/alpha/klibc/archconfig.h2
-rw-r--r--usr/klibc/arch/alpha/Kbuild2
-rw-r--r--usr/klibc/arch/alpha/MCONFIG5
-rw-r--r--usr/klibc/arch/alpha/sigreturn.S18
-rw-r--r--usr/klibc/sigaction.c4
5 files changed, 25 insertions, 6 deletions
diff --git a/usr/include/arch/alpha/klibc/archconfig.h b/usr/include/arch/alpha/klibc/archconfig.h
index 272fee0ad3560..9d28db12f0add 100644
--- a/usr/include/arch/alpha/klibc/archconfig.h
+++ b/usr/include/arch/alpha/klibc/archconfig.h
@@ -10,6 +10,8 @@
#define _KLIBC_ARCHCONFIG_H
#define _KLIBC_USE_RT_SIG 1
+/* We provide our own restorer that call rt_sigreturn() */
+#define _KLIBC_NEEDS_SA_SIGINFO 1
#define _KLIBC_STATFS_F_TYPE_64 0
#endif /* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/klibc/arch/alpha/Kbuild b/usr/klibc/arch/alpha/Kbuild
index 2e566eb6fbc1d..89386aeaddc9d 100644
--- a/usr/klibc/arch/alpha/Kbuild
+++ b/usr/klibc/arch/alpha/Kbuild
@@ -9,7 +9,7 @@
always := crt0.o
targets := crt0.o
-klib-y := pipe.o setjmp.o syscall.o sysdual.o
+klib-y := pipe.o setjmp.o sigreturn.o syscall.o sysdual.o
# Special CFLAGS for the divide code
DIVCFLAGS = $(KLIBCREQFLAGS) $(KLIBCARCHREQFLAGS) \
diff --git a/usr/klibc/arch/alpha/MCONFIG b/usr/klibc/arch/alpha/MCONFIG
index 072adb8574f7b..e71db264253f3 100644
--- a/usr/klibc/arch/alpha/MCONFIG
+++ b/usr/klibc/arch/alpha/MCONFIG
@@ -15,6 +15,5 @@ KLIBCBITSIZE = 64
# the binary.
KLIBCSHAREDFLAGS = -Ttext-segment 0x1c0000000
-# Kernel uses stack trampoline for signal return unless we set
-# sa_restorer
-KLIBCEXECSTACK := y
+# Kernel uses our sa_restorer for signal return
+KLIBCEXECSTACK := n
diff --git a/usr/klibc/arch/alpha/sigreturn.S b/usr/klibc/arch/alpha/sigreturn.S
new file mode 100644
index 0000000000000..a979b7a347e5c
--- /dev/null
+++ b/usr/klibc/arch/alpha/sigreturn.S
@@ -0,0 +1,18 @@
+/*
+ * arch/alpha/sigreturn.S
+ */
+
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ .text
+ .align 3
+ .type __sigreturn,@function
+ .ent __sigreturn,0
+ .globl __sigreturn
+__sigreturn:
+ mov sp,a0 # struct sigcontext on stack
+ lda v0,__NR_rt_sigreturn(zero)
+ callsys
+ .size __sigreturn,.-__sigreturn
+ .end __sigreturn
diff --git a/usr/klibc/sigaction.c b/usr/klibc/sigaction.c
index 0d7c5c9dac35f..789494dbb97db 100644
--- a/usr/klibc/sigaction.c
+++ b/usr/klibc/sigaction.c
@@ -14,7 +14,7 @@ __extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
void (*)(void), size_t);
#elif defined(__alpha__)
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
- size_t, void *);
+ size_t, void (*)(void));
#else
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
size_t);
@@ -60,7 +60,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
rv = __rt_sigaction(sig, act, oact, restorer, sizeof(sigset_t));
}
# elif defined(__alpha__)
- rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t), NULL);
+ rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t), &__sigreturn);
# else
rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t));
# endif