1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub const syscall_arg_t = u32;
6
7pub fn syscall0(
8 number: SYS,
9) u32 {
10 return asm volatile ("trap #0"
11 : [ret] "={d0}" (-> u32),
12 : [number] "{d0}" (@backingInt(number)),
13 : .{ .memory = true });
14}
15
16pub fn syscall1(
17 number: SYS,
18 arg1: syscall_arg_t,
19) u32 {
20 return asm volatile ("trap #0"
21 : [ret] "={d0}" (-> u32),
22 : [number] "{d0}" (@backingInt(number)),
23 [arg1] "{d1}" (arg1),
24 : .{ .memory = true });
25}
26
27pub fn syscall2(
28 number: SYS,
29 arg1: syscall_arg_t,
30 arg2: syscall_arg_t,
31) u32 {
32 return asm volatile ("trap #0"
33 : [ret] "={d0}" (-> u32),
34 : [number] "{d0}" (@backingInt(number)),
35 [arg1] "{d1}" (arg1),
36 [arg2] "{d2}" (arg2),
37 : .{ .memory = true });
38}
39
40pub fn syscall3(
41 number: SYS,
42 arg1: syscall_arg_t,
43 arg2: syscall_arg_t,
44 arg3: syscall_arg_t,
45) u32 {
46 return asm volatile ("trap #0"
47 : [ret] "={d0}" (-> u32),
48 : [number] "{d0}" (@backingInt(number)),
49 [arg1] "{d1}" (arg1),
50 [arg2] "{d2}" (arg2),
51 [arg3] "{d3}" (arg3),
52 : .{ .memory = true });
53}
54
55pub fn syscall4(
56 number: SYS,
57 arg1: syscall_arg_t,
58 arg2: syscall_arg_t,
59 arg3: syscall_arg_t,
60 arg4: syscall_arg_t,
61) u32 {
62 return asm volatile ("trap #0"
63 : [ret] "={d0}" (-> u32),
64 : [number] "{d0}" (@backingInt(number)),
65 [arg1] "{d1}" (arg1),
66 [arg2] "{d2}" (arg2),
67 [arg3] "{d3}" (arg3),
68 [arg4] "{d4}" (arg4),
69 : .{ .memory = true });
70}
71
72pub fn syscall5(
73 number: SYS,
74 arg1: syscall_arg_t,
75 arg2: syscall_arg_t,
76 arg3: syscall_arg_t,
77 arg4: syscall_arg_t,
78 arg5: syscall_arg_t,
79) u32 {
80 return asm volatile ("trap #0"
81 : [ret] "={d0}" (-> u32),
82 : [number] "{d0}" (@backingInt(number)),
83 [arg1] "{d1}" (arg1),
84 [arg2] "{d2}" (arg2),
85 [arg3] "{d3}" (arg3),
86 [arg4] "{d4}" (arg4),
87 [arg5] "{d5}" (arg5),
88 : .{ .memory = true });
89}
90
91pub fn syscall6(
92 number: SYS,
93 arg1: syscall_arg_t,
94 arg2: syscall_arg_t,
95 arg3: syscall_arg_t,
96 arg4: syscall_arg_t,
97 arg5: syscall_arg_t,
98 arg6: syscall_arg_t,
99) u32 {
100 return asm volatile ("trap #0"
101 : [ret] "={d0}" (-> u32),
102 : [number] "{d0}" (@backingInt(number)),
103 [arg1] "{d1}" (arg1),
104 [arg2] "{d2}" (arg2),
105 [arg3] "{d3}" (arg3),
106 [arg4] "{d4}" (arg4),
107 [arg5] "{d5}" (arg5),
108 [arg6] "{a0}" (arg6),
109 : .{ .memory = true });
110}
111
112pub fn clone() callconv(.naked) u32 {
113 // __clone(func, stack, flags, arg, ptid, tls, ctid)
114 // +4, +8, +12, +16, +20, +24, +28
115 //
116 // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
117 // d0, d1, d2, d3, d4, d5
118 asm volatile (
119 \\ // Save callee-saved registers.
120 \\ movem.l %%d2-%%d5, -(%%sp) // sp -= 16
121 \\
122 \\ // Save func and arg.
123 \\ move.l 16+4(%%sp), %%a0
124 \\ move.l 16+16(%%sp), %%a1
125 \\
126 \\ // d0 = syscall(d0, d1, d2, d3, d4, d5)
127 \\ move.l #120, %%d0 // SYS_clone
128 \\ move.l 16+12(%%sp), %%d1
129 \\ move.l 16+8(%%sp), %%d2
130 \\ move.l 16+20(%%sp), %%d3
131 \\ move.l 16+28(%%sp), %%d4
132 \\ move.l 16+24(%%sp), %%d5
133 \\ and.l #-4, %%d2 // Align the child stack pointer.
134 \\ trap #0
135 \\
136 \\ // Are we in the parent or child?
137 \\ tst.l %%d0
138 \\ beq 1f
139 \\ // Parent:
140 \\
141 \\ // Restore callee-saved registers and return.
142 \\ movem.l (%%sp)+, %%d2-%%d5 // sp += 16
143 \\ rts
144 \\
145 \\ // Child:
146 \\1:
147 );
148 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
149 \\ .cfi_undefined %%pc
150 );
151 asm volatile (
152 \\ suba.l %%fp, %%fp
153 \\
154 \\ // d0 = func(a1)
155 \\ move.l %%a1, -(%%sp)
156 \\ jsr (%%a0)
157 \\
158 \\ // syscall(d0, d1)
159 \\ move.l %%d0, %%d1
160 \\ move.l #1, %%d0 // SYS_exit
161 \\ trap #0
162 );
163}
164
165pub const restore = restore_rt;
166
167pub fn restore_rt() callconv(.naked) noreturn {
168 asm volatile ("trap #0"
169 :
170 : [number] "{d0}" (@backingInt(SYS.rt_sigreturn)),
171 );
172}
173
174pub const time_t = i32;
175
176pub const VDSO = void;