summaryrefslogtreecommitdiff
path: root/src/signal
diff options
context:
space:
mode:
Diffstat (limited to 'src/signal')
-rw-r--r--src/signal/block.c4
-rw-r--r--src/signal/loongarch64/restore.s (renamed from src/signal/mips/restore.s)15
-rw-r--r--src/signal/loongarch64/sigsetjmp.s25
-rw-r--r--src/signal/mips64/restore.s11
-rw-r--r--src/signal/mipsn32/restore.s11
-rw-r--r--src/signal/riscv32/restore.s8
-rw-r--r--src/signal/riscv32/sigsetjmp.s23
-rw-r--r--src/signal/sh/sigsetjmp.s2
-rw-r--r--src/signal/sigaction.c41
9 files changed, 84 insertions, 56 deletions
diff --git a/src/signal/block.c b/src/signal/block.c
index d7f61001..cc8698f0 100644
--- a/src/signal/block.c
+++ b/src/signal/block.c
@@ -3,9 +3,9 @@
#include <signal.h>
static const unsigned long all_mask[] = {
-#if ULONG_MAX == 0xffffffff && _NSIG == 129
+#if ULONG_MAX == 0xffffffff && _NSIG > 65
-1UL, -1UL, -1UL, -1UL
-#elif ULONG_MAX == 0xffffffff
+#elif ULONG_MAX == 0xffffffff || _NSIG > 65
-1UL, -1UL
#else
-1UL
diff --git a/src/signal/mips/restore.s b/src/signal/loongarch64/restore.s
index b6dadce0..d90a8ebb 100644
--- a/src/signal/mips/restore.s
+++ b/src/signal/loongarch64/restore.s
@@ -1,15 +1,10 @@
-.set noreorder
-
.global __restore_rt
-.hidden __restore_rt
-.type __restore_rt,@function
-__restore_rt:
- li $2, 4193
- syscall
-
.global __restore
+.hidden __restore_rt
.hidden __restore
+.type __restore_rt,@function
.type __restore,@function
+__restore_rt:
__restore:
- li $2, 4119
- syscall
+ li.w $a7, 139
+ syscall 0
diff --git a/src/signal/loongarch64/sigsetjmp.s b/src/signal/loongarch64/sigsetjmp.s
new file mode 100644
index 00000000..9c0e3ae2
--- /dev/null
+++ b/src/signal/loongarch64/sigsetjmp.s
@@ -0,0 +1,25 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+ beq $a1, $zero, 1f
+ st.d $ra, $a0, 184
+ st.d $s0, $a0, 200 #184+8+8
+ move $s0, $a0
+
+ la.global $t0, setjmp
+ jirl $ra, $t0, 0
+
+ move $a1, $a0 # Return from 'setjmp' or 'longjmp'
+ move $a0, $s0
+ ld.d $ra, $a0, 184
+ ld.d $s0, $a0, 200 #184+8+8
+
+.hidden __sigsetjmp_tail
+ la.global $t0, __sigsetjmp_tail
+ jr $t0
+1:
+ la.global $t0, setjmp
+ jr $t0
diff --git a/src/signal/mips64/restore.s b/src/signal/mips64/restore.s
deleted file mode 100644
index 401f8e73..00000000
--- a/src/signal/mips64/restore.s
+++ /dev/null
@@ -1,11 +0,0 @@
-.set noreorder
-.global __restore_rt
-.global __restore
-.hidden __restore_rt
-.hidden __restore
-.type __restore_rt,@function
-.type __restore,@function
-__restore_rt:
-__restore:
- li $2,5211
- syscall
diff --git a/src/signal/mipsn32/restore.s b/src/signal/mipsn32/restore.s
deleted file mode 100644
index 4cd4e1b4..00000000
--- a/src/signal/mipsn32/restore.s
+++ /dev/null
@@ -1,11 +0,0 @@
-.set noreorder
-.global __restore_rt
-.global __restore
-.hidden __restore_rt
-.hidden __restore
-.type __restore_rt,@function
-.type __restore,@function
-__restore_rt:
-__restore:
- li $2,6211
- syscall
diff --git a/src/signal/riscv32/restore.s b/src/signal/riscv32/restore.s
new file mode 100644
index 00000000..40012c75
--- /dev/null
+++ b/src/signal/riscv32/restore.s
@@ -0,0 +1,8 @@
+.global __restore
+.type __restore, %function
+__restore:
+.global __restore_rt
+.type __restore_rt, %function
+__restore_rt:
+ li a7, 139 # SYS_rt_sigreturn
+ ecall
diff --git a/src/signal/riscv32/sigsetjmp.s b/src/signal/riscv32/sigsetjmp.s
new file mode 100644
index 00000000..c1caeab1
--- /dev/null
+++ b/src/signal/riscv32/sigsetjmp.s
@@ -0,0 +1,23 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp, %function
+.type __sigsetjmp, %function
+sigsetjmp:
+__sigsetjmp:
+ bnez a1, 1f
+ tail setjmp
+1:
+
+ sw ra, 152(a0)
+ sw s0, 164(a0)
+ mv s0, a0
+
+ call setjmp
+
+ mv a1, a0
+ mv a0, s0
+ lw s0, 164(a0)
+ lw ra, 152(a0)
+
+.hidden __sigsetjmp_tail
+ tail __sigsetjmp_tail
diff --git a/src/signal/sh/sigsetjmp.s b/src/signal/sh/sigsetjmp.s
index 1e2270be..f0f604e2 100644
--- a/src/signal/sh/sigsetjmp.s
+++ b/src/signal/sh/sigsetjmp.s
@@ -27,7 +27,7 @@ __sigsetjmp:
mov.l 3f, r0
4: braf r0
- mov.l @(4+8,r4), r8
+ mov.l @(4+8,r6), r8
9: mov.l 5f, r0
6: braf r0
diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
index c109bea0..e45308fa 100644
--- a/src/signal/sigaction.c
+++ b/src/signal/sigaction.c
@@ -7,12 +7,6 @@
#include "lock.h"
#include "ksigaction.h"
-static volatile int dummy_lock[1] = { 0 };
-
-extern hidden volatile int __abort_lock[1];
-
-weak_alias(dummy_lock, __abort_lock);
-
static int unmask_done;
static unsigned long handler_set[_NSIG/(8*sizeof(long))];
@@ -26,7 +20,6 @@ volatile int __eintr_valid_flag;
int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
{
struct k_sigaction ksa, ksa_old;
- unsigned long set[_NSIG/(8*sizeof(long))];
if (sa) {
if ((uintptr_t)sa->sa_handler > 1UL) {
a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
@@ -50,24 +43,15 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
a_store(&__eintr_valid_flag, 1);
}
}
- /* Changing the disposition of SIGABRT to anything but
- * SIG_DFL requires a lock, so that it cannot be changed
- * while abort is terminating the process after simply
- * calling raise(SIGABRT) failed to do so. */
- if (sa->sa_handler != SIG_DFL && sig == SIGABRT) {
- __block_all_sigs(&set);
- LOCK(__abort_lock);
- }
ksa.handler = sa->sa_handler;
- ksa.flags = sa->sa_flags | SA_RESTORER;
+ ksa.flags = sa->sa_flags;
+#ifdef SA_RESTORER
+ ksa.flags |= SA_RESTORER;
ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
+#endif
memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
}
int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
- if (sig == SIGABRT && sa && sa->sa_handler != SIG_DFL) {
- UNLOCK(__abort_lock);
- __restore_sigs(&set);
- }
if (old && !r) {
old->sa_handler = ksa_old.handler;
old->sa_flags = ksa_old.flags;
@@ -78,11 +62,26 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
{
+ unsigned long set[_NSIG/(8*sizeof(long))];
+
if (sig-32U < 3 || sig-1U >= _NSIG-1) {
errno = EINVAL;
return -1;
}
- return __libc_sigaction(sig, sa, old);
+
+ /* Doing anything with the disposition of SIGABRT requires a lock,
+ * so that it cannot be changed while abort is terminating the
+ * process and so any change made by abort can't be observed. */
+ if (sig == SIGABRT) {
+ __block_all_sigs(&set);
+ LOCK(__abort_lock);
+ }
+ int r = __libc_sigaction(sig, sa, old);
+ if (sig == SIGABRT) {
+ UNLOCK(__abort_lock);
+ __restore_sigs(&set);
+ }
+ return r;
}
weak_alias(__sigaction, sigaction);