From af88310caf86b1b1e84d9f0764af522b402241b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 19 Jun 2026 05:58:47 +0200 Subject: [PATCH 1/6] std.os.linux: fix kernel_timespec.nsec to be isize Only kernel_timespec.sec should be unconditionally i64. --- lib/std/os/linux.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 8892c15ae9082aa5f5f014d49d9665401032dbcc..f39d48d7996d51ade1fb5df3b9d40fa267fb5fe7 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -9438,7 +9438,7 @@ pub const timezone = extern struct { /// The timespec struct used by the kernel. pub const kernel_timespec = extern struct { sec: i64, - nsec: i64, + nsec: isize, /// For use with `utimensat` and `futimens`. pub const NOW: timespec = .{ -- 2.54.0 From fe9f2c7d1a4ed2eb637ea1900a84a9ef85dc14d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 19 Jun 2026 06:02:11 +0200 Subject: [PATCH 2/6] std.os.linux: use kernel_timespec on x32 --- lib/std/os/linux.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index f39d48d7996d51ade1fb5df3b9d40fa267fb5fe7..aeecb8c1b499313efc00b40711359f4e85f87d18 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -9460,7 +9460,11 @@ pub const UTIME = struct { }; // https://github.com/ziglang/zig/issues/4726#issuecomment-2190337877 -pub const timespec = if (native_arch == .hexagon or native_arch == .riscv32) kernel_timespec else extern struct { +const use_kernel_timespec = native_arch == .hexagon or native_arch == .riscv32 or switch (native_abi) { + .gnux32, .muslx32, .x32 => true, + else => false, +}; +pub const timespec = if (use_kernel_timespec) kernel_timespec else extern struct { sec: isize, nsec: isize, }; -- 2.54.0 From eed6464426046a3c9697fa24be4ae2f6274133e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 19 Jun 2026 04:51:30 +0200 Subject: [PATCH 3/6] std.os.linux.x32: use 64-bit time_t --- lib/std/os/linux/x32.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/linux/x32.zig b/lib/std/os/linux/x32.zig index 9cfe2f7899d9535aed61019997b94d99a5527668..6cf18045b35a6501f11bd009c0c7d17d25cc6447 100644 --- a/lib/std/os/linux/x32.zig +++ b/lib/std/os/linux/x32.zig @@ -175,7 +175,7 @@ pub fn restore_rt() callconv(.naked) noreturn { } } -pub const time_t = i32; +pub const time_t = i64; pub const VDSO = struct { pub const CGT_SYM = "__vdso_clock_gettime"; -- 2.54.0 From ae3ab88153db9e83b3eb981121727be7c6bc3346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 19 Jun 2026 08:25:25 +0200 Subject: [PATCH 4/6] std.os.linux.x32: fix read of stack slot containing ctid in clone() It's a 32-bit pointer and passed on the stack; the upper 32 bits of the stack slot are garbage. This means that we ask the kernel to write to some random 64-bit location, which it will just silently fail to do (the process is in x32 mode; nothing can be mapped up there), and consequently, the thread's child_tid field will never be populated, causing a later join() to hang. --- lib/std/os/linux/x32.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/linux/x32.zig b/lib/std/os/linux/x32.zig index 6cf18045b35a6501f11bd009c0c7d17d25cc6447..3b10612786a6d256775c3f3dbe068b1ced5e352b 100644 --- a/lib/std/os/linux/x32.zig +++ b/lib/std/os/linux/x32.zig @@ -130,7 +130,7 @@ pub fn clone() callconv(.naked) u32 { \\ mov %%rdx,%%rdi \\ mov %%r8,%%rdx \\ mov %%r9,%%r8 - \\ mov 8(%%rsp),%%r10 + \\ mov 8(%%rsp),%%r10d \\ mov %%r11,%%r9 \\ and $-16,%%rsi \\ sub $8,%%rsi -- 2.54.0 From f5e83388288f827a17a4dfaa6c58b2f9063c1f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 19 Jun 2026 07:47:38 +0200 Subject: [PATCH 5/6] musl: fix read of stack slot containing ctid in x32 clone() https://www.openwall.com/lists/musl/2026/06/19/4 --- lib/libc/musl/src/thread/x32/clone.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/musl/src/thread/x32/clone.s b/lib/libc/musl/src/thread/x32/clone.s index d713452676333d3e34ef9f004fcec4eebf2bcd6d..31e2ccabe61d5b9443cc08b9606ae26ca664bc5c 100644 --- a/lib/libc/musl/src/thread/x32/clone.s +++ b/lib/libc/musl/src/thread/x32/clone.s @@ -8,7 +8,7 @@ __clone: mov %rdx,%rdi mov %r8,%rdx mov %r9,%r8 - mov 8(%rsp),%r10 + mov 8(%rsp),%r10d mov %r11,%r9 and $-16,%rsi sub $8,%rsi -- 2.54.0 From 6e001367a436ddae0c5d7e5861200a7966940073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 18 Jun 2026 13:35:15 +0200 Subject: [PATCH 6/6] test: promote most x32/n32 module test targets to non-extra status These ILP32 ABIs are now about as well supported as their LP64 counterparts. mips64(el)-linux-muslabin32 with dynamic linking is still marked as extra, in line with other dynamically-linked musl targets. --- test/tests.zig | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/tests.zig b/test/tests.zig index a3883223728b7141c6a7f90a76a57e5914a75af5..fe0c7622e6608fe5979004e05730ae1d5bdc347f 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -627,7 +627,6 @@ const module_test_targets = blk: { .os_tag = .linux, .abi = .abin32, }, - .extra_target = true, }, .{ .target = .{ @@ -654,7 +653,6 @@ const module_test_targets = blk: { .abi = .muslabin32, }, .link_libc = true, - .extra_target = true, }, .{ .target = .{ @@ -681,7 +679,6 @@ const module_test_targets = blk: { .abi = .gnuabin32, }, .link_libc = true, - .extra_target = true, }, .{ @@ -1167,7 +1164,6 @@ const module_test_targets = blk: { .os_tag = .linux, .abi = .x32, }, - .extra_target = true, }, .{ .target = .{ @@ -1204,7 +1200,6 @@ const module_test_targets = blk: { .abi = .muslx32, }, .link_libc = true, - .extra_target = true, }, .{ .target = .{ @@ -1231,7 +1226,6 @@ const module_test_targets = blk: { .abi = .gnux32, }, .link_libc = true, - .extra_target = true, }, // Darwin Targets -- 2.54.0