authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-17 01:18:54+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-17 01:20:33+02:00
logd5481e65365f78c9ca20c29882f28bf80129e579
treeb1fd89119dd2f17d69ae0b49505a135c9dec27ce
parent502eca7b0908cc8f0fa334fde4c3f7e4fc067027
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.os.linux: add incomplete x32 arch bits file

This is very likely full of wrong stuff. It's effectively just a copy of the x86_64 file - needed because the former stopped using usize/isize. To be clear, this is no more broken than the old situation was; this just makes the brokenness explicit.

2 files changed, 204 insertions(+), 9 deletions(-)

lib/std/os/linux.zig+12-9
...@@ -32,14 +32,9 @@ test {...@@ -32,14 +32,9 @@ test {
32}32}
3333
34const arch_bits = switch (native_arch) {34const arch_bits = switch (native_arch) {
35 .x86 => @import("linux/x86.zig"),
36 .x86_64 => @import("linux/x86_64.zig"),
37 .aarch64, .aarch64_be => @import("linux/aarch64.zig"),35 .aarch64, .aarch64_be => @import("linux/aarch64.zig"),
38 .arm, .armeb, .thumb, .thumbeb => @import("linux/arm.zig"),36 .arm, .armeb, .thumb, .thumbeb => @import("linux/arm.zig"),
39 .hexagon => @import("linux/hexagon.zig"),37 .hexagon => @import("linux/hexagon.zig"),
40 .riscv32 => @import("linux/riscv32.zig"),
41 .riscv64 => @import("linux/riscv64.zig"),
42 .sparc64 => @import("linux/sparc64.zig"),
43 .loongarch64 => @import("linux/loongarch64.zig"),38 .loongarch64 => @import("linux/loongarch64.zig"),
44 .m68k => @import("linux/m68k.zig"),39 .m68k => @import("linux/m68k.zig"),
45 .mips, .mipsel => @import("linux/mips.zig"),40 .mips, .mipsel => @import("linux/mips.zig"),
...@@ -49,7 +44,15 @@ const arch_bits = switch (native_arch) {...@@ -49,7 +44,15 @@ const arch_bits = switch (native_arch) {
49 },44 },
50 .powerpc, .powerpcle => @import("linux/powerpc.zig"),45 .powerpc, .powerpcle => @import("linux/powerpc.zig"),
51 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),46 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
47 .riscv32 => @import("linux/riscv32.zig"),
48 .riscv64 => @import("linux/riscv64.zig"),
52 .s390x => @import("linux/s390x.zig"),49 .s390x => @import("linux/s390x.zig"),
50 .sparc64 => @import("linux/sparc64.zig"),
51 .x86 => @import("linux/x86.zig"),
52 .x86_64 => switch (builtin.abi) {
53 .gnux32, .muslx32 => @import("linux/x32.zig"),
54 else => @import("linux/x86_64.zig"),
55 },
53 else => struct {},56 else => struct {},
54};57};
5558
...@@ -113,8 +116,8 @@ pub const SECCOMP = @import("linux/seccomp.zig");...@@ -113,8 +116,8 @@ pub const SECCOMP = @import("linux/seccomp.zig");
113pub const syscalls = @import("linux/syscalls.zig");116pub const syscalls = @import("linux/syscalls.zig");
114pub const SYS = switch (native_arch) {117pub const SYS = switch (native_arch) {
115 .arc => syscalls.Arc,118 .arc => syscalls.Arc,
116 .arm, .armeb, .thumb, .thumbeb => syscalls.Arm,
117 .aarch64, .aarch64_be => syscalls.Arm64,119 .aarch64, .aarch64_be => syscalls.Arm64,
120 .arm, .armeb, .thumb, .thumbeb => syscalls.Arm,
118 .csky => syscalls.CSky,121 .csky => syscalls.CSky,
119 .hexagon => syscalls.Hexagon,122 .hexagon => syscalls.Hexagon,
120 .loongarch64 => syscalls.LoongArch64,123 .loongarch64 => syscalls.LoongArch64,
...@@ -124,20 +127,20 @@ pub const SYS = switch (native_arch) {...@@ -124,20 +127,20 @@ pub const SYS = switch (native_arch) {
124 .gnuabin32, .muslabin32 => syscalls.MipsN32,127 .gnuabin32, .muslabin32 => syscalls.MipsN32,
125 else => syscalls.MipsN64,128 else => syscalls.MipsN64,
126 },129 },
130 .or1k => syscalls.OpenRisc,
131 .powerpc, .powerpcle => syscalls.PowerPC,
132 .powerpc64, .powerpc64le => syscalls.PowerPC64,
127 .riscv32 => syscalls.RiscV32,133 .riscv32 => syscalls.RiscV32,
128 .riscv64 => syscalls.RiscV64,134 .riscv64 => syscalls.RiscV64,
129 .s390x => syscalls.S390x,135 .s390x => syscalls.S390x,
130 .sparc => syscalls.Sparc,136 .sparc => syscalls.Sparc,
131 .sparc64 => syscalls.Sparc64,137 .sparc64 => syscalls.Sparc64,
132 .powerpc, .powerpcle => syscalls.PowerPC,
133 .powerpc64, .powerpc64le => syscalls.PowerPC64,
134 .x86 => syscalls.X86,138 .x86 => syscalls.X86,
135 .x86_64 => switch (builtin.abi) {139 .x86_64 => switch (builtin.abi) {
136 .gnux32, .muslx32 => syscalls.X32,140 .gnux32, .muslx32 => syscalls.X32,
137 else => syscalls.X64,141 else => syscalls.X64,
138 },142 },
139 .xtensa => syscalls.Xtensa,143 .xtensa => syscalls.Xtensa,
140 .or1k => syscalls.OpenRisc,
141 else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"),144 else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"),
142};145};
143146
lib/std/os/linux/x32.zig created+192
...@@ -0,0 +1,192 @@
1// TODO: A lot of this file is very likely wrong.
2
3const builtin = @import("builtin");
4const std = @import("../../std.zig");
5const SYS = std.os.linux.SYS;
6
7pub fn syscall0(number: SYS) u32 {
8 return asm volatile ("syscall"
9 : [ret] "={rax}" (-> u32),
10 : [number] "{rax}" (@intFromEnum(number)),
11 : .{ .rcx = true, .r11 = true, .memory = true });
12}
13
14pub fn syscall1(number: SYS, arg1: u32) u32 {
15 return asm volatile ("syscall"
16 : [ret] "={rax}" (-> u32),
17 : [number] "{rax}" (@intFromEnum(number)),
18 [arg1] "{rdi}" (arg1),
19 : .{ .rcx = true, .r11 = true, .memory = true });
20}
21
22pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
23 return asm volatile ("syscall"
24 : [ret] "={rax}" (-> u32),
25 : [number] "{rax}" (@intFromEnum(number)),
26 [arg1] "{rdi}" (arg1),
27 [arg2] "{rsi}" (arg2),
28 : .{ .rcx = true, .r11 = true, .memory = true });
29}
30
31pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
32 return asm volatile ("syscall"
33 : [ret] "={rax}" (-> u32),
34 : [number] "{rax}" (@intFromEnum(number)),
35 [arg1] "{rdi}" (arg1),
36 [arg2] "{rsi}" (arg2),
37 [arg3] "{rdx}" (arg3),
38 : .{ .rcx = true, .r11 = true, .memory = true });
39}
40
41pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
42 return asm volatile ("syscall"
43 : [ret] "={rax}" (-> u32),
44 : [number] "{rax}" (@intFromEnum(number)),
45 [arg1] "{rdi}" (arg1),
46 [arg2] "{rsi}" (arg2),
47 [arg3] "{rdx}" (arg3),
48 [arg4] "{r10}" (arg4),
49 : .{ .rcx = true, .r11 = true, .memory = true });
50}
51
52pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
53 return asm volatile ("syscall"
54 : [ret] "={rax}" (-> u32),
55 : [number] "{rax}" (@intFromEnum(number)),
56 [arg1] "{rdi}" (arg1),
57 [arg2] "{rsi}" (arg2),
58 [arg3] "{rdx}" (arg3),
59 [arg4] "{r10}" (arg4),
60 [arg5] "{r8}" (arg5),
61 : .{ .rcx = true, .r11 = true, .memory = true });
62}
63
64pub fn syscall6(
65 number: SYS,
66 arg1: u32,
67 arg2: u32,
68 arg3: u32,
69 arg4: u32,
70 arg5: u32,
71 arg6: u32,
72) u32 {
73 return asm volatile ("syscall"
74 : [ret] "={rax}" (-> u32),
75 : [number] "{rax}" (@intFromEnum(number)),
76 [arg1] "{rdi}" (arg1),
77 [arg2] "{rsi}" (arg2),
78 [arg3] "{rdx}" (arg3),
79 [arg4] "{r10}" (arg4),
80 [arg5] "{r8}" (arg5),
81 [arg6] "{r9}" (arg6),
82 : .{ .rcx = true, .r11 = true, .memory = true });
83}
84
85pub fn clone() callconv(.naked) u32 {
86 asm volatile (
87 \\ movl $56,%%eax // SYS_clone
88 \\ movq %%rdi,%%r11
89 \\ movq %%rdx,%%rdi
90 \\ movq %%r8,%%rdx
91 \\ movq %%r9,%%r8
92 \\ movq 8(%%rsp),%%r10
93 \\ movq %%r11,%%r9
94 \\ andq $-16,%%rsi
95 \\ subq $8,%%rsi
96 \\ movq %%rcx,(%%rsi)
97 \\ syscall
98 \\ testq %%rax,%%rax
99 \\ jz 1f
100 \\ retq
101 \\
102 \\1:
103 );
104 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
105 \\ .cfi_undefined %%rip
106 );
107 asm volatile (
108 \\ xorl %%ebp,%%ebp
109 \\
110 \\ popq %%rdi
111 \\ callq *%%r9
112 \\ movl %%eax,%%edi
113 \\ movl $60,%%eax // SYS_exit
114 \\ syscall
115 \\
116 );
117}
118
119pub const restore = restore_rt;
120
121pub fn restore_rt() callconv(.naked) noreturn {
122 switch (builtin.zig_backend) {
123 .stage2_c => asm volatile (
124 \\ movl %[number], %%eax
125 \\ syscall
126 :
127 : [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
128 ),
129 else => asm volatile (
130 \\ syscall
131 :
132 : [number] "{rax}" (@intFromEnum(SYS.rt_sigreturn)),
133 ),
134 }
135}
136
137pub const mode_t = u32;
138pub const time_t = i32;
139pub const nlink_t = u32;
140pub const blksize_t = i32;
141pub const blkcnt_t = i32;
142pub const off_t = i64;
143pub const ino_t = u64;
144pub const dev_t = u64;
145
146pub const VDSO = struct {
147 pub const CGT_SYM = "__vdso_clock_gettime";
148 pub const CGT_VER = "LINUX_2.6";
149
150 pub const GETCPU_SYM = "__vdso_getcpu";
151 pub const GETCPU_VER = "LINUX_2.6";
152};
153
154pub const ARCH = struct {
155 pub const SET_GS = 0x1001;
156 pub const SET_FS = 0x1002;
157 pub const GET_FS = 0x1003;
158 pub const GET_GS = 0x1004;
159};
160
161// The `stat` definition used by the Linux kernel.
162pub const Stat = extern struct {
163 dev: dev_t,
164 ino: ino_t,
165 nlink: nlink_t,
166
167 mode: mode_t,
168 uid: std.os.linux.uid_t,
169 gid: std.os.linux.gid_t,
170 __pad0: u32,
171 rdev: dev_t,
172 size: off_t,
173 blksize: blksize_t,
174 blocks: i64,
175
176 atim: std.os.linux.timespec,
177 mtim: std.os.linux.timespec,
178 ctim: std.os.linux.timespec,
179 __unused: [3]i32,
180
181 pub fn atime(self: @This()) std.os.linux.timespec {
182 return self.atim;
183 }
184
185 pub fn mtime(self: @This()) std.os.linux.timespec {
186 return self.mtim;
187 }
188
189 pub fn ctime(self: @This()) std.os.linux.timespec {
190 return self.ctim;
191 }
192};