1use core::arch::asm;
4use core::ffi::c_long;
5use core::marker::PhantomData;
6
7#[cfg(target_pointer_width = "32")]
8compile_error!("x32 is not supported");
9
10#[repr(transparent)]
11#[derive(Copy, Clone)]
12pub struct SyscallArg<'a>(usize, PhantomData<&'a ()>);
13
14impl From<i32> for SyscallArg<'_> {
15 #[inline]
16 fn from(value: i32) -> Self {
17 SyscallArg(value as isize as usize, PhantomData)
18 }
19}
20
21impl From<i64> for SyscallArg<'_> {
22 #[inline]
23 fn from(value: i64) -> Self {
24 SyscallArg(value as isize as usize, PhantomData)
25 }
26}
27
28impl From<isize> for SyscallArg<'_> {
29 #[inline]
30 fn from(value: isize) -> Self {
31 SyscallArg(value as usize, PhantomData)
32 }
33}
34
35impl From<u32> for SyscallArg<'_> {
36 #[inline]
37 fn from(value: u32) -> Self {
38 SyscallArg(value as usize, PhantomData)
39 }
40}
41
42impl From<u64> for SyscallArg<'_> {
43 #[inline]
44 fn from(value: u64) -> Self {
45 SyscallArg(value as usize, PhantomData)
46 }
47}
48
49impl From<usize> for SyscallArg<'_> {
50 #[inline]
51 fn from(value: usize) -> Self {
52 SyscallArg(value, PhantomData)
53 }
54}
55
56impl<T> From<*const T> for SyscallArg<'_> {
57 #[inline]
58 fn from(value: *const T) -> Self {
59 SyscallArg(value as usize, PhantomData)
60 }
61}
62
63impl<T> From<*mut T> for SyscallArg<'_> {
64 #[inline]
65 fn from(value: *mut T) -> Self {
66 SyscallArg(value as usize, PhantomData)
67 }
68}
69
70impl<'a, T> From<&'a [T]> for SyscallArg<'a> {
71 #[inline]
72 fn from(value: &'a [T]) -> Self {
73 SyscallArg::from(value.as_ptr())
74 }
75}
76
77impl<'a, T, const N: usize> From<&'a [T; N]> for SyscallArg<'a> {
78 #[inline]
79 fn from(value: &'a [T; N]) -> Self {
80 SyscallArg::from(value.as_ptr())
81 }
82}
83
84impl<'a, T> From<&'a mut [T]> for SyscallArg<'a> {
85 #[inline]
86 fn from(value: &'a mut [T]) -> Self {
87 SyscallArg::from(value.as_mut_ptr())
88 }
89}
90
91impl<'a> From<crate::FdRef<'a>> for SyscallArg<'a> {
92 #[inline]
93 fn from(value: crate::FdRef<'a>) -> Self {
94 SyscallArg(value.raw() as isize as usize, PhantomData)
95 }
96}
97
98impl<'a> From<Option<crate::FdRef<'a>>> for SyscallArg<'a> {
99 #[inline]
100 fn from(value: Option<crate::FdRef<'a>>) -> Self {
101 SyscallArg(value.map_or(-1, |fd| fd.raw()) as isize as usize, PhantomData)
102 }
103}
104
105impl<'a> From<&'a crate::Fd> for SyscallArg<'a> {
106 #[inline]
107 fn from(value: &'a crate::Fd) -> Self {
108 SyscallArg(value.raw() as isize as usize, PhantomData)
109 }
110}
111
112impl<'a> From<&'a core::ffi::CStr> for SyscallArg<'a> {
113 #[inline]
114 fn from(value: &'a core::ffi::CStr) -> Self {
115 SyscallArg(value.as_ptr() as usize, PhantomData)
116 }
117}
118
119#[inline]
120pub unsafe fn syscall0_readonly(nr: c_long) -> c_long {
121 let r0;
122 asm!(
123 "syscall",
124 inlateout("rax") nr => r0,
125 lateout("rcx") _,
126 lateout("r11") _,
127 options(nostack, preserves_flags, readonly)
128 );
129 r0
130}
131
132#[inline]
133pub unsafe fn syscall1(nr: c_long, a0: SyscallArg) -> c_long {
134 let r0;
135 asm!(
136 "syscall",
137 inlateout("rax") nr => r0,
138 in("rdi") a0.0,
139 lateout("rcx") _,
140 lateout("r11") _,
141 options(nostack, preserves_flags)
142 );
143 r0
144}
145
146#[inline]
147pub unsafe fn syscall1_readonly(nr: c_long, a0: SyscallArg) -> c_long {
148 let r0;
149 asm!(
150 "syscall",
151 inlateout("rax") nr => r0,
152 in("rdi") a0.0,
153 lateout("rcx") _,
154 lateout("r11") _,
155 options(nostack, preserves_flags, readonly)
156 );
157 r0
158}
159
160#[inline]
161pub unsafe fn syscall1_noreturn(nr: c_long, a0: SyscallArg) -> ! {
162 asm!(
163 "syscall",
164 in("rax") nr,
165 in("rdi") a0.0,
166 options(noreturn)
167 )
168}
169
170#[inline]
171pub unsafe fn syscall2(nr: c_long, a0: SyscallArg, a1: SyscallArg) -> c_long {
172 let r0;
173 asm!(
174 "syscall",
175 inlateout("rax") nr => r0,
176 in("rdi") a0.0,
177 in("rsi") a1.0,
178 lateout("rcx") _,
179 lateout("r11") _,
180 options(nostack, preserves_flags)
181 );
182 r0
183}
184
185#[inline]
186pub unsafe fn syscall2_readonly(nr: c_long, a0: SyscallArg, a1: SyscallArg) -> c_long {
187 let r0;
188 asm!(
189 "syscall",
190 inlateout("rax") nr => r0,
191 in("rdi") a0.0,
192 in("rsi") a1.0,
193 lateout("rcx") _,
194 lateout("r11") _,
195 options(nostack, preserves_flags, readonly)
196 );
197 r0
198}
199
200#[inline]
201pub unsafe fn syscall3(nr: c_long, a0: SyscallArg, a1: SyscallArg, a2: SyscallArg) -> c_long {
202 let r0;
203 asm!(
204 "syscall",
205 inlateout("rax") nr => r0,
206 in("rdi") a0.0,
207 in("rsi") a1.0,
208 in("rdx") a2.0,
209 lateout("rcx") _,
210 lateout("r11") _,
211 options(nostack, preserves_flags)
212 );
213 r0
214}
215
216#[inline]
217pub unsafe fn syscall3_readonly(nr: u64, a0: SyscallArg, a1: SyscallArg, a2: SyscallArg) -> c_long {
218 let r0;
219 asm!(
220 "syscall",
221 inlateout("rax") nr => r0,
222 in("rdi") a0.0,
223 in("rsi") a1.0,
224 in("rdx") a2.0,
225 lateout("rcx") _,
226 lateout("r11") _,
227 options(nostack, preserves_flags, readonly)
228 );
229 r0
230}
231
232#[inline]
233pub unsafe fn syscall4(nr: c_long, a0: SyscallArg, a1: SyscallArg, a2: SyscallArg, a3: SyscallArg) -> c_long {
234 let r0;
235 asm!(
236 "syscall",
237 inlateout("rax") nr => r0,
238 in("rdi") a0.0,
239 in("rsi") a1.0,
240 in("rdx") a2.0,
241 in("r10") a3.0,
242 lateout("rcx") _,
243 lateout("r11") _,
244 options(nostack, preserves_flags)
245 );
246 r0
247}
248
249#[inline]
250pub unsafe fn syscall4_readonly(nr: c_long, a0: SyscallArg, a1: SyscallArg, a2: SyscallArg, a3: SyscallArg) -> c_long {
251 let r0;
252 asm!(
253 "syscall",
254 inlateout("rax") nr => r0,
255 in("rdi") a0.0,
256 in("rsi") a1.0,
257 in("rdx") a2.0,
258 in("r10") a3.0,
259 lateout("rcx") _,
260 lateout("r11") _,
261 options(nostack, preserves_flags, readonly)
262 );
263 r0
264}
265
266#[inline]
267pub unsafe fn syscall5(nr: c_long, a0: SyscallArg, a1: SyscallArg, a2: SyscallArg, a3: SyscallArg, a4: SyscallArg) -> c_long {
268 let r0;
269 asm!(
270 "syscall",
271 inlateout("rax") nr => r0,
272 in("rdi") a0.0,
273 in("rsi") a1.0,
274 in("rdx") a2.0,
275 in("r10") a3.0,
276 in("r8") a4.0,
277 lateout("rcx") _,
278 lateout("r11") _,
279 options(nostack, preserves_flags)
280 );
281 r0
282}
283
284#[inline]
285pub unsafe fn syscall5_readonly(nr: c_long, a0: SyscallArg, a1: SyscallArg, a2: SyscallArg, a3: SyscallArg, a4: SyscallArg) -> c_long {
286 let r0;
287 asm!(
288 "syscall",
289 inlateout("rax") nr => r0,
290 in("rdi") a0.0,
291 in("rsi") a1.0,
292 in("rdx") a2.0,
293 in("r10") a3.0,
294 in("r8") a4.0,
295 lateout("rcx") _,
296 lateout("r11") _,
297 options(nostack, preserves_flags, readonly)
298 );
299 r0
300}
301
302#[inline]
303pub unsafe fn syscall6(
304 nr: c_long,
305 a0: SyscallArg,
306 a1: SyscallArg,
307 a2: SyscallArg,
308 a3: SyscallArg,
309 a4: SyscallArg,
310 a5: SyscallArg,
311) -> c_long {
312 let r0;
313 asm!(
314 "syscall",
315 inlateout("rax") nr => r0,
316 in("rdi") a0.0,
317 in("rsi") a1.0,
318 in("rdx") a2.0,
319 in("r10") a3.0,
320 in("r8") a4.0,
321 in("r9") a5.0,
322 lateout("rcx") _,
323 lateout("r11") _,
324 options(nostack, preserves_flags)
325 );
326 r0
327}
328
329#[inline]
330pub unsafe fn syscall6_readonly(
331 nr: c_long,
332 a0: SyscallArg,
333 a1: SyscallArg,
334 a2: SyscallArg,
335 a3: SyscallArg,
336 a4: SyscallArg,
337 a5: SyscallArg,
338) -> c_long {
339 let r0;
340 asm!(
341 "syscall",
342 inlateout("rax") nr => r0,
343 in("rdi") a0.0,
344 in("rsi") a1.0,
345 in("rdx") a2.0,
346 in("r10") a3.0,
347 in("r8") a4.0,
348 in("r9") a5.0,
349 lateout("rcx") _,
350 lateout("r11") _,
351 options(nostack, preserves_flags, readonly)
352 );
353 r0
354}