1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub const syscall_arg_t = u64;
6
7pub fn syscall0(
8 number: SYS,
9) u64 {
10 return asm volatile (
11 \\ syscall 0
12 : [ret] "={$r4}" (-> u64),
13 : [number] "{$r11}" (@backingInt(number)),
14 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
15}
16
17pub fn syscall1(
18 number: SYS,
19 arg1: syscall_arg_t,
20) u64 {
21 return asm volatile (
22 \\ syscall 0
23 : [ret] "={$r4}" (-> u64),
24 : [number] "{$r11}" (@backingInt(number)),
25 [arg1] "{$r4}" (arg1),
26 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
27}
28
29pub fn syscall2(
30 number: SYS,
31 arg1: syscall_arg_t,
32 arg2: syscall_arg_t,
33) u64 {
34 return asm volatile (
35 \\ syscall 0
36 : [ret] "={$r4}" (-> u64),
37 : [number] "{$r11}" (@backingInt(number)),
38 [arg1] "{$r4}" (arg1),
39 [arg2] "{$r5}" (arg2),
40 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
41}
42
43pub fn syscall3(
44 number: SYS,
45 arg1: syscall_arg_t,
46 arg2: syscall_arg_t,
47 arg3: syscall_arg_t,
48) u64 {
49 return asm volatile (
50 \\ syscall 0
51 : [ret] "={$r4}" (-> u64),
52 : [number] "{$r11}" (@backingInt(number)),
53 [arg1] "{$r4}" (arg1),
54 [arg2] "{$r5}" (arg2),
55 [arg3] "{$r6}" (arg3),
56 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
57}
58
59pub fn syscall4(
60 number: SYS,
61 arg1: syscall_arg_t,
62 arg2: syscall_arg_t,
63 arg3: syscall_arg_t,
64 arg4: syscall_arg_t,
65) u64 {
66 return asm volatile (
67 \\ syscall 0
68 : [ret] "={$r4}" (-> u64),
69 : [number] "{$r11}" (@backingInt(number)),
70 [arg1] "{$r4}" (arg1),
71 [arg2] "{$r5}" (arg2),
72 [arg3] "{$r6}" (arg3),
73 [arg4] "{$r7}" (arg4),
74 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
75}
76
77pub fn syscall5(
78 number: SYS,
79 arg1: syscall_arg_t,
80 arg2: syscall_arg_t,
81 arg3: syscall_arg_t,
82 arg4: syscall_arg_t,
83 arg5: syscall_arg_t,
84) u64 {
85 return asm volatile (
86 \\ syscall 0
87 : [ret] "={$r4}" (-> u64),
88 : [number] "{$r11}" (@backingInt(number)),
89 [arg1] "{$r4}" (arg1),
90 [arg2] "{$r5}" (arg2),
91 [arg3] "{$r6}" (arg3),
92 [arg4] "{$r7}" (arg4),
93 [arg5] "{$r8}" (arg5),
94 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
95}
96
97pub fn syscall6(
98 number: SYS,
99 arg1: syscall_arg_t,
100 arg2: syscall_arg_t,
101 arg3: syscall_arg_t,
102 arg4: syscall_arg_t,
103 arg5: syscall_arg_t,
104 arg6: syscall_arg_t,
105) u64 {
106 return asm volatile (
107 \\ syscall 0
108 : [ret] "={$r4}" (-> u64),
109 : [number] "{$r11}" (@backingInt(number)),
110 [arg1] "{$r4}" (arg1),
111 [arg2] "{$r5}" (arg2),
112 [arg3] "{$r6}" (arg3),
113 [arg4] "{$r7}" (arg4),
114 [arg5] "{$r8}" (arg5),
115 [arg6] "{$r9}" (arg6),
116 : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
117}
118
119pub fn clone() callconv(.naked) u64 {
120 // __clone(func, stack, flags, arg, ptid, tls, ctid)
121 // a0, a1, a2, a3, a4, a5, a6
122 // sys_clone(flags, stack, ptid, ctid, tls)
123 // a0, a1, a2, a3, a4
124 asm volatile (
125 \\ bstrins.d $a1, $zero, 3, 0 # stack to 16 align
126 \\
127 \\ # Save function pointer and argument pointer on new thread stack
128 \\ addi.d $a1, $a1, -16
129 \\ st.d $a0, $a1, 0 # save function pointer
130 \\ st.d $a3, $a1, 8 # save argument pointer
131 \\ or $a0, $a2, $zero
132 \\ or $a2, $a4, $zero
133 \\ or $a3, $a6, $zero
134 \\ or $a4, $a5, $zero
135 \\ ori $a7, $zero, 220 # SYS_clone
136 \\ syscall 0 # call clone
137 \\
138 \\ beqz $a0, 1f # whether child process
139 \\ jirl $zero, $ra, 0 # parent process return
140 \\1:
141 );
142 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
143 \\ .cfi_undefined 1
144 );
145 asm volatile (
146 \\ move $fp, $zero
147 \\ move $ra, $zero
148 \\
149 \\ ld.d $t8, $sp, 0 # function pointer
150 \\ ld.d $a0, $sp, 8 # argument pointer
151 \\ jirl $ra, $t8, 0 # call the user's function
152 \\ ori $a7, $zero, 93 # SYS_exit
153 \\ syscall 0 # child process exit
154 );
155}
156
157pub const time_t = i64;
158
159pub const VDSO = struct {
160 pub const CGT_SYM = "__vdso_clock_gettime";
161 pub const CGT_VER = "LINUX_5.10";
162};