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) u32 {
10 return asm volatile ("syscall"
11 : [ret] "={rax}" (-> u32),
12 : [number] "{rax}" (@backingInt(number)),
13 : .{ .rcx = true, .r11 = true, .memory = true });
14}
15
16pub fn syscall1(
17 number: SYS,
18 arg1: syscall_arg_t,
19) u32 {
20 return asm volatile ("syscall"
21 : [ret] "={rax}" (-> u32),
22 : [number] "{rax}" (@backingInt(number)),
23 [arg1] "{rdi}" (arg1),
24 : .{ .rcx = true, .r11 = true, .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 ("syscall"
33 : [ret] "={rax}" (-> u32),
34 : [number] "{rax}" (@backingInt(number)),
35 [arg1] "{rdi}" (arg1),
36 [arg2] "{rsi}" (arg2),
37 : .{ .rcx = true, .r11 = true, .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 ("syscall"
47 : [ret] "={rax}" (-> u32),
48 : [number] "{rax}" (@backingInt(number)),
49 [arg1] "{rdi}" (arg1),
50 [arg2] "{rsi}" (arg2),
51 [arg3] "{rdx}" (arg3),
52 : .{ .rcx = true, .r11 = true, .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 ("syscall"
63 : [ret] "={rax}" (-> u32),
64 : [number] "{rax}" (@backingInt(number)),
65 [arg1] "{rdi}" (arg1),
66 [arg2] "{rsi}" (arg2),
67 [arg3] "{rdx}" (arg3),
68 [arg4] "{r10}" (arg4),
69 : .{ .rcx = true, .r11 = true, .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 ("syscall"
81 : [ret] "={rax}" (-> u32),
82 : [number] "{rax}" (@backingInt(number)),
83 [arg1] "{rdi}" (arg1),
84 [arg2] "{rsi}" (arg2),
85 [arg3] "{rdx}" (arg3),
86 [arg4] "{r10}" (arg4),
87 [arg5] "{r8}" (arg5),
88 : .{ .rcx = true, .r11 = true, .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 ("syscall"
101 : [ret] "={rax}" (-> u32),
102 : [number] "{rax}" (@backingInt(number)),
103 [arg1] "{rdi}" (arg1),
104 [arg2] "{rsi}" (arg2),
105 [arg3] "{rdx}" (arg3),
106 [arg4] "{r10}" (arg4),
107 [arg5] "{r8}" (arg5),
108 [arg6] "{r9}" (arg6),
109 : .{ .rcx = true, .r11 = true, .memory = true });
110}
111
112pub fn syscall_lseek(
113 fd: std.os.linux.fd_t,
114 offset: std.os.linux.off_t,
115 whence: u32,
116) u64 {
117 return asm volatile ("syscall"
118 : [ret] "={rax}" (-> u64),
119 : [number] "{rax}" (@backingInt(SYS.lseek)),
120 [fd] "{rdi}" (@as(u32, @bitCast(fd))),
121 [offset] "{rsi}" (@as(u64, @bitCast(offset))),
122 [whence] "{rdx}" (whence),
123 : .{ .rcx = true, .r11 = true, .memory = true });
124}
125
126pub fn clone() callconv(.naked) u32 {
127 asm volatile (
128 \\ movl $0x40000038,%%eax // SYS_clone
129 \\ mov %%rdi,%%r11
130 \\ mov %%rdx,%%rdi
131 \\ mov %%r8,%%rdx
132 \\ mov %%r9,%%r8
133 \\ mov 8(%%rsp),%%r10d
134 \\ mov %%r11,%%r9
135 \\ and $-16,%%rsi
136 \\ sub $8,%%rsi
137 \\ mov %%rcx,(%%rsi)
138 \\ syscall
139 \\ test %%eax,%%eax
140 \\ jz 1f
141 \\ ret
142 \\
143 \\1:
144 );
145 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
146 \\ .cfi_undefined %%rip
147 );
148 asm volatile (
149 \\ xor %%ebp,%%ebp
150 \\
151 \\ pop %%rdi
152 \\ call *%%r9
153 \\ mov %%eax,%%edi
154 \\ movl $0x4000003c,%%eax // SYS_exit
155 \\ syscall
156 );
157}
158
159pub const restore = restore_rt;
160
161pub fn restore_rt() callconv(.naked) noreturn {
162 asm volatile (
163 \\ movl %[number], %%eax
164 \\ syscall
165 :
166 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
167 );
168}
169
170pub const time_t = i64;
171
172pub const VDSO = struct {
173 pub const CGT_SYM = "__vdso_clock_gettime";
174 pub const CGT_VER = "LINUX_2.6";
175
176 pub const GETCPU_SYM = "__vdso_getcpu";
177 pub const GETCPU_VER = "LINUX_2.6";
178};
179
180pub const ARCH = struct {
181 pub const SET_GS = 0x1001;
182 pub const SET_FS = 0x1002;
183 pub const GET_FS = 0x1003;
184 pub const GET_GS = 0x1004;
185};