commit f624191f9a759c0d310f3615c10dbfbbc6ae511e (tree)
parent f90510b081e06449ab0bd97a1254c78f5be6a8d4
Author: Alex Rønne Petersen <alex@alexrp.com>
Date: Mon, 29 Sep 2025 14:48:24 +0200
Merge pull request #25388 from alexrp/ksigaction
`std.os.linux`: Fix `k_sigaction` ABI issue on platforms w/o `SA_RESTORER`
Diffstat:
14 files changed, 34 insertions(+), 132 deletions(-)
diff --git a/lib/libc/musl/arch/hexagon/bits/signal.h b/lib/libc/musl/arch/hexagon/bits/signal.h
@@ -61,7 +61,6 @@ typedef struct __ucontext {
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
-#define SA_RESTORER 0x04000000
#endif
diff --git a/lib/libc/musl/arch/riscv32/bits/signal.h b/lib/libc/musl/arch/riscv32/bits/signal.h
@@ -78,7 +78,6 @@ typedef struct __ucontext
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
-#define SA_RESTORER 0x04000000
#endif
diff --git a/lib/libc/musl/src/signal/hexagon/restore.s b/lib/libc/musl/src/signal/hexagon/restore.s
@@ -1,11 +0,0 @@
-// TODO - Test this if sa_restorer is ever supported in our kernel
-.global __restore
-.type __restore,%function
-.global __restore_rt
-.type __restore_rt,%function
-__restore:
-__restore_rt:
- r6 = #139 // SYS_rt_sigreturn
- trap0(#0)
-.size __restore, .-__restore
-.size __restore_rt, .-__restore_rt
diff --git a/lib/libc/musl/src/signal/loongarch64/restore.s b/lib/libc/musl/src/signal/loongarch64/restore.s
@@ -1,10 +0,0 @@
-.global __restore_rt
-.global __restore
-.hidden __restore_rt
-.hidden __restore
-.type __restore_rt,@function
-.type __restore,@function
-__restore_rt:
-__restore:
- li.w $a7, 139
- syscall 0
diff --git a/lib/libc/musl/src/signal/riscv32/restore.s b/lib/libc/musl/src/signal/riscv32/restore.s
@@ -1,10 +0,0 @@
-.global __restore
-.hidden __restore
-.type __restore, %function
-__restore:
-.global __restore_rt
-.hidden __restore_rt
-.type __restore_rt, %function
-__restore_rt:
- li a7, 139 # SYS_rt_sigreturn
- ecall
diff --git a/lib/libc/musl/src/signal/riscv64/restore.s b/lib/libc/musl/src/signal/riscv64/restore.s
@@ -1,10 +0,0 @@
-.global __restore
-.hidden __restore
-.type __restore, %function
-__restore:
-.global __restore_rt
-.hidden __restore_rt
-.type __restore_rt, %function
-__restore_rt:
- li a7, 139 # SYS_rt_sigreturn
- ecall
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
@@ -15,8 +15,10 @@ const dl = @import("../dynamic_library.zig");
const native_arch = builtin.cpu.arch;
const native_abi = builtin.abi;
const native_endian = native_arch.endian();
+const is_loongarch = native_arch.isLoongArch();
const is_mips = native_arch.isMIPS();
const is_ppc = native_arch.isPowerPC();
+const is_riscv = native_arch.isRISCV();
const is_sparc = native_arch.isSPARC();
const iovec = std.posix.iovec;
const iovec_const = std.posix.iovec_const;
@@ -1868,15 +1870,23 @@ pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
const mask_size = @sizeOf(@TypeOf(ksa.mask));
if (act) |new| {
- // Zig needs to install our arch restorer function with any signal handler, so
- // must copy the Sigaction struct
- const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) &restore_rt else &restore;
- ksa = k_sigaction{
- .handler = new.handler.handler,
- .flags = new.flags | SA.RESTORER,
- .mask = new.mask,
- .restorer = @ptrCast(restorer_fn),
- };
+ if (native_arch == .hexagon or is_loongarch or is_mips or is_riscv) {
+ ksa = .{
+ .handler = new.handler.handler,
+ .flags = new.flags,
+ .mask = new.mask,
+ };
+ } else {
+ // Zig needs to install our arch restorer function with any signal handler, so
+ // must copy the Sigaction struct
+ const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) &restore_rt else &restore;
+ ksa = .{
+ .handler = new.handler.handler,
+ .flags = new.flags | SA.RESTORER,
+ .mask = new.mask,
+ .restorer = @ptrCast(restorer_fn),
+ };
+ }
}
const ksa_arg = if (act != null) @intFromPtr(&ksa) else 0;
@@ -3668,7 +3678,6 @@ pub const SA = if (is_mips) struct {
pub const RESETHAND = 0x80000000;
pub const ONSTACK = 0x08000000;
pub const NODEFER = 0x40000000;
- pub const RESTORER = 0x04000000;
} else if (is_sparc) struct {
pub const NOCLDSTOP = 0x8;
pub const NOCLDWAIT = 0x100;
@@ -3678,6 +3687,14 @@ pub const SA = if (is_mips) struct {
pub const ONSTACK = 0x1;
pub const NODEFER = 0x20;
pub const RESTORER = 0x04000000;
+} else if (native_arch == .hexagon or is_loongarch or is_riscv) struct {
+ pub const NOCLDSTOP = 1;
+ pub const NOCLDWAIT = 2;
+ pub const SIGINFO = 4;
+ pub const RESTART = 0x10000000;
+ pub const RESETHAND = 0x80000000;
+ pub const ONSTACK = 0x08000000;
+ pub const NODEFER = 0x40000000;
} else struct {
pub const NOCLDSTOP = 1;
pub const NOCLDWAIT = 2;
@@ -5743,13 +5760,18 @@ const k_sigaction_funcs = struct {
const restorer = *const fn () callconv(.c) void;
};
-/// Kernel sigaction struct, as expected by the `rt_sigaction` syscall. Includes restorer.
+/// Kernel sigaction struct, as expected by the `rt_sigaction` syscall. Includes `restorer` on
+/// targets where userspace is responsible for hooking up `rt_sigreturn`.
pub const k_sigaction = switch (native_arch) {
.mips, .mipsel, .mips64, .mips64el => extern struct {
flags: c_uint,
handler: k_sigaction_funcs.handler,
mask: sigset_t,
- restorer: k_sigaction_funcs.restorer,
+ },
+ .hexagon, .loongarch32, .loongarch64, .riscv32, .riscv64 => extern struct {
+ handler: k_sigaction_funcs.handler,
+ flags: c_ulong,
+ mask: sigset_t,
},
else => extern struct {
handler: k_sigaction_funcs.handler,
diff --git a/lib/std/os/linux/hexagon.zig b/lib/std/os/linux/hexagon.zig
@@ -128,16 +128,6 @@ pub fn clone() callconv(.naked) usize {
);
}
-pub const restore = restore_rt;
-
-pub fn restore_rt() callconv(.naked) noreturn {
- asm volatile (
- \\ trap0(#0)
- :
- : [number] "{r6}" (@intFromEnum(SYS.rt_sigreturn)),
- );
-}
-
pub const F = struct {
pub const DUPFD = 0;
pub const GETFD = 1;
diff --git a/lib/std/os/linux/loongarch64.zig b/lib/std/os/linux/loongarch64.zig
@@ -135,17 +135,6 @@ pub fn clone() callconv(.naked) usize {
);
}
-pub const restore = restore_rt;
-
-pub fn restore_rt() callconv(.naked) noreturn {
- asm volatile (
- \\ or $a7, $zero, %[number]
- \\ syscall 0
- :
- : [number] "r" (@intFromEnum(SYS.rt_sigreturn)),
- );
-}
-
pub const msghdr = extern struct {
name: ?*sockaddr,
namelen: socklen_t,
diff --git a/lib/std/os/linux/mips.zig b/lib/std/os/linux/mips.zig
@@ -241,22 +241,6 @@ pub fn clone() callconv(.naked) usize {
);
}
-pub fn restore() callconv(.naked) noreturn {
- asm volatile (
- \\ syscall
- :
- : [number] "{$2}" (@intFromEnum(SYS.sigreturn)),
- : .{ .r1 = true, .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
-}
-
-pub fn restore_rt() callconv(.naked) noreturn {
- asm volatile (
- \\ syscall
- :
- : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)),
- );
-}
-
pub const F = struct {
pub const DUPFD = 0;
pub const GETFD = 1;
diff --git a/lib/std/os/linux/mips64.zig b/lib/std/os/linux/mips64.zig
@@ -220,22 +220,6 @@ pub fn clone() callconv(.naked) usize {
);
}
-pub fn restore() callconv(.naked) noreturn {
- asm volatile (
- \\ syscall
- :
- : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)),
- : .{ .r1 = true, .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
-}
-
-pub fn restore_rt() callconv(.naked) noreturn {
- asm volatile (
- \\ syscall
- :
- : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)),
- );
-}
-
pub const F = struct {
pub const DUPFD = 0;
pub const GETFD = 1;
diff --git a/lib/std/os/linux/riscv32.zig b/lib/std/os/linux/riscv32.zig
@@ -135,16 +135,6 @@ pub fn clone() callconv(.naked) usize {
);
}
-pub const restore = restore_rt;
-
-pub fn restore_rt() callconv(.naked) noreturn {
- asm volatile (
- \\ ecall
- :
- : [number] "{x17}" (@intFromEnum(SYS.rt_sigreturn)),
- );
-}
-
pub const F = struct {
pub const DUPFD = 0;
pub const GETFD = 1;
diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig
@@ -135,16 +135,6 @@ pub fn clone() callconv(.naked) usize {
);
}
-pub const restore = restore_rt;
-
-pub fn restore_rt() callconv(.naked) noreturn {
- asm volatile (
- \\ ecall
- :
- : [number] "{x17}" (@intFromEnum(SYS.rt_sigreturn)),
- );
-}
-
pub const F = struct {
pub const DUPFD = 0;
pub const GETFD = 1;
diff --git a/src/libs/musl.zig b/src/libs/musl.zig
@@ -1538,13 +1538,11 @@ const src_files = [_][]const u8{
"musl/src/signal/arm/sigsetjmp.s",
"musl/src/signal/block.c",
"musl/src/signal/getitimer.c",
- "musl/src/signal/hexagon/restore.s",
"musl/src/signal/hexagon/sigsetjmp.s",
"musl/src/signal/i386/restore.s",
"musl/src/signal/i386/sigsetjmp.s",
"musl/src/signal/kill.c",
"musl/src/signal/killpg.c",
- "musl/src/signal/loongarch64/restore.s",
"musl/src/signal/loongarch64/sigsetjmp.s",
"musl/src/signal/m68k/sigsetjmp.s",
"musl/src/signal/mips64/sigsetjmp.s",
@@ -1558,9 +1556,7 @@ const src_files = [_][]const u8{
"musl/src/signal/psignal.c",
"musl/src/signal/raise.c",
"musl/src/signal/restore.c",
- "musl/src/signal/riscv32/restore.s",
"musl/src/signal/riscv32/sigsetjmp.s",
- "musl/src/signal/riscv64/restore.s",
"musl/src/signal/riscv64/sigsetjmp.s",
"musl/src/signal/s390x/restore.s",
"musl/src/signal/s390x/sigsetjmp.s",