master
1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub fn syscall0(number: SYS) u32 {
6 return asm volatile (
7 \\ l.sys 1
8 : [ret] "={r11}" (-> u32),
9 : [number] "{r11}" (@intFromEnum(number)),
10 : .{ .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
11}
12
13pub fn syscall1(number: SYS, arg1: u32) u32 {
14 return asm volatile (
15 \\ l.sys 1
16 : [ret] "={r11}" (-> u32),
17 : [number] "{r11}" (@intFromEnum(number)),
18 [arg1] "{r3}" (arg1),
19 : .{ .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
20}
21
22pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
23 return asm volatile (
24 \\ l.sys 1
25 : [ret] "={r11}" (-> u32),
26 : [number] "{r11}" (@intFromEnum(number)),
27 [arg1] "{r3}" (arg1),
28 [arg2] "{r4}" (arg2),
29 : .{ .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
30}
31
32pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
33 return asm volatile (
34 \\ l.sys 1
35 : [ret] "={r11}" (-> u32),
36 : [number] "{r11}" (@intFromEnum(number)),
37 [arg1] "{r3}" (arg1),
38 [arg2] "{r4}" (arg2),
39 [arg3] "{r5}" (arg3),
40 : .{ .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
41}
42
43pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
44 return asm volatile (
45 \\ l.sys 1
46 : [ret] "={r11}" (-> u32),
47 : [number] "{r11}" (@intFromEnum(number)),
48 [arg1] "{r3}" (arg1),
49 [arg2] "{r4}" (arg2),
50 [arg3] "{r5}" (arg3),
51 [arg4] "{r6}" (arg4),
52 : .{ .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
53}
54
55pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
56 return asm volatile (
57 \\ l.sys 1
58 : [ret] "={r11}" (-> u32),
59 : [number] "{r11}" (@intFromEnum(number)),
60 [arg1] "{r3}" (arg1),
61 [arg2] "{r4}" (arg2),
62 [arg3] "{r5}" (arg3),
63 [arg4] "{r6}" (arg4),
64 [arg5] "{r7}" (arg5),
65 : .{ .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
66}
67
68pub fn syscall6(
69 number: SYS,
70 arg1: u32,
71 arg2: u32,
72 arg3: u32,
73 arg4: u32,
74 arg5: u32,
75 arg6: u32,
76) u32 {
77 return asm volatile (
78 \\ l.sys 1
79 : [ret] "={r11}" (-> u32),
80 : [number] "{r11}" (@intFromEnum(number)),
81 [arg1] "{r3}" (arg1),
82 [arg2] "{r4}" (arg2),
83 [arg3] "{r5}" (arg3),
84 [arg4] "{r6}" (arg4),
85 [arg5] "{r7}" (arg5),
86 [arg6] "{r8}" (arg6),
87 : .{ .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
88}
89
90pub fn clone() callconv(.naked) u32 {
91 // __clone(func, stack, flags, arg, ptid, tls, ctid)
92 // r3, r4, r5, r6, r7, r8, +0
93 //
94 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
95 // r11 r3, r4, r5, r6, r7
96 asm volatile (
97 \\ # Save function pointer and argument pointer on new thread stack
98 \\ l.andi r4, r4, -4
99 \\ l.addi r4, r4, -8
100 \\ l.sw 0(r4), r3
101 \\ l.sw 4(r4), r6
102 \\
103 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
104 \\ l.ori r11, r0, 220 # SYS_clone
105 \\ l.ori r3, r5, 0
106 \\ l.ori r5, r7, 0
107 \\ l.ori r6, r8, 0
108 \\ l.lwz r7, 0(r1)
109 \\ l.sys 1
110 \\ l.sfeqi r11, 0
111 \\ l.bf 1f
112 \\ l.jr r9
113 \\1:
114 );
115 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
116 \\ .cfi_undefined r9
117 );
118 asm volatile (
119 \\ l.ori r2, r0, 0
120 \\ l.ori r9, r0, 0
121 \\
122 \\ l.lwz r11, 0(r1)
123 \\ l.lwz r3, 4(r1)
124 \\ l.jalr r11
125 \\
126 \\ l.ori r3, r11, 0
127 \\ l.ori r11, r0, 93 # SYS_exit
128 \\ l.sys 1
129 );
130}
131
132pub const VDSO = void;
133
134pub const blksize_t = u32;
135pub const nlink_t = u32;
136pub const time_t = i32;
137pub const mode_t = u32;
138pub const off_t = i64;
139pub const ino_t = u64;
140pub const dev_t = u64;
141pub const blkcnt_t = i64;
142
143// The `stat64` definition used by the Linux kernel.
144pub const Stat = extern struct {
145 dev: dev_t,
146 ino: ino_t,
147 mode: mode_t,
148 nlink: nlink_t,
149 uid: std.os.linux.uid_t,
150 gid: std.os.linux.gid_t,
151 rdev: dev_t,
152 _pad0: [2]u32,
153 size: off_t,
154 blksize: blksize_t,
155 _pad1: u32,
156 blocks: blkcnt_t,
157 atim: std.os.linux.timespec,
158 mtim: std.os.linux.timespec,
159 ctim: std.os.linux.timespec,
160 _pad2: [2]u32,
161
162 pub fn atime(self: @This()) std.os.linux.timespec {
163 return self.atim;
164 }
165
166 pub fn mtime(self: @This()) std.os.linux.timespec {
167 return self.mtim;
168 }
169
170 pub fn ctime(self: @This()) std.os.linux.timespec {
171 return self.ctim;
172 }
173};