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 ("trap0(#1)"
7 : [ret] "={r0}" (-> u32),
8 : [number] "{r6}" (@intFromEnum(number)),
9 : .{ .memory = true });
10}
11
12pub fn syscall1(number: SYS, arg1: u32) u32 {
13 return asm volatile ("trap0(#1)"
14 : [ret] "={r0}" (-> u32),
15 : [number] "{r6}" (@intFromEnum(number)),
16 [arg1] "{r0}" (arg1),
17 : .{ .memory = true });
18}
19
20pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
21 return asm volatile ("trap0(#1)"
22 : [ret] "={r0}" (-> u32),
23 : [number] "{r6}" (@intFromEnum(number)),
24 [arg1] "{r0}" (arg1),
25 [arg2] "{r1}" (arg2),
26 : .{ .memory = true });
27}
28
29pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
30 return asm volatile ("trap0(#1)"
31 : [ret] "={r0}" (-> u32),
32 : [number] "{r6}" (@intFromEnum(number)),
33 [arg1] "{r0}" (arg1),
34 [arg2] "{r1}" (arg2),
35 [arg3] "{r2}" (arg3),
36 : .{ .memory = true });
37}
38
39pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
40 return asm volatile ("trap0(#1)"
41 : [ret] "={r0}" (-> u32),
42 : [number] "{r6}" (@intFromEnum(number)),
43 [arg1] "{r0}" (arg1),
44 [arg2] "{r1}" (arg2),
45 [arg3] "{r2}" (arg3),
46 [arg4] "{r3}" (arg4),
47 : .{ .memory = true });
48}
49
50pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
51 return asm volatile ("trap0(#1)"
52 : [ret] "={r0}" (-> u32),
53 : [number] "{r6}" (@intFromEnum(number)),
54 [arg1] "{r0}" (arg1),
55 [arg2] "{r1}" (arg2),
56 [arg3] "{r2}" (arg3),
57 [arg4] "{r3}" (arg4),
58 [arg5] "{r4}" (arg5),
59 : .{ .memory = true });
60}
61
62pub fn syscall6(
63 number: SYS,
64 arg1: u32,
65 arg2: u32,
66 arg3: u32,
67 arg4: u32,
68 arg5: u32,
69 arg6: u32,
70) u32 {
71 return asm volatile ("trap0(#1)"
72 : [ret] "={r0}" (-> u32),
73 : [number] "{r6}" (@intFromEnum(number)),
74 [arg1] "{r0}" (arg1),
75 [arg2] "{r1}" (arg2),
76 [arg3] "{r2}" (arg3),
77 [arg4] "{r3}" (arg4),
78 [arg5] "{r4}" (arg5),
79 [arg6] "{r5}" (arg6),
80 : .{ .memory = true });
81}
82
83pub fn clone() callconv(.naked) u32 {
84 // __clone(func, stack, flags, arg, ptid, tls, ctid)
85 // r0, r1, r2, r3, r4, r5, +0
86 //
87 // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
88 // r6 r0, r1, r2, r3, r4
89 asm volatile (
90 \\ allocframe(#8)
91 \\
92 \\ r11 = r0
93 \\ r10 = r3
94 \\
95 \\ r6 = #220 // SYS_clone
96 \\ r0 = r2
97 \\ r1 = and(r1, #-8)
98 \\ r2 = r4
99 \\ r3 = memw(r30 + #8)
100 \\ r4 = r5
101 \\ trap0(#1)
102 \\
103 \\ p0 = cmp.eq(r0, #0)
104 \\ if (!p0) dealloc_return
105 );
106 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
107 \\ .cfi_undefined r31
108 );
109 asm volatile (
110 \\ r30 = #0
111 \\ r31 = #0
112 \\
113 \\ r0 = r10
114 \\ callr r11
115 \\
116 \\ r6 = #93 // SYS_exit
117 \\ r0 = #0
118 \\ trap0(#1)
119 );
120}
121
122pub const blksize_t = i32;
123pub const nlink_t = u32;
124pub const time_t = i64;
125pub const mode_t = u32;
126pub const off_t = i64;
127pub const ino_t = u64;
128pub const dev_t = u64;
129pub const blkcnt_t = i64;
130
131// The `stat` definition used by the Linux kernel.
132pub const Stat = extern struct {
133 dev: dev_t,
134 ino: ino_t,
135 mode: mode_t,
136 nlink: nlink_t,
137 uid: std.os.linux.uid_t,
138 gid: std.os.linux.gid_t,
139 rdev: dev_t,
140 __pad: u32,
141 size: off_t,
142 blksize: blksize_t,
143 __pad2: i32,
144 blocks: blkcnt_t,
145 atim: std.os.linux.timespec,
146 mtim: std.os.linux.timespec,
147 ctim: std.os.linux.timespec,
148 __unused: [2]u32,
149
150 pub fn atime(self: @This()) std.os.linux.timespec {
151 return self.atim;
152 }
153
154 pub fn mtime(self: @This()) std.os.linux.timespec {
155 return self.mtim;
156 }
157
158 pub fn ctime(self: @This()) std.os.linux.timespec {
159 return self.ctim;
160 }
161};
162
163pub const VDSO = void;