1#[cfg(not(feature = "rustc-dep-of-std"))]
4extern crate alloc;
5use core::arch::asm;
6pub use safa_abi::syscalls::SyscallTable as SyscallNum;
7
8macro_rules! err_from_u16 {
9 ($result:expr) => {
10 $result.into_result()
11 };
12 ($result:expr, $ok:expr) => {
13 err_from_u16!($result).map(|()| $ok)
14 };
15}
16
17pub(crate) use err_from_u16;
18
19#[doc(hidden)]
20#[inline(always)]
21pub fn syscall0<const NUM: u16>() -> SyscallResult {
22 let result: u16;
23 unsafe {
24 #[cfg(target_arch = "x86_64")]
25 asm!(
26 "int 0x80",
27 in("rax") NUM as usize,
28 lateout("rax") result,
29 );
30 #[cfg(target_arch = "aarch64")]
31 asm!(
32 "svc #{num}",
33 num = const NUM,
34 lateout("x0") result
35 );
36 core::mem::transmute(result)
37 }
38}
39
40#[doc(hidden)]
41#[inline(always)]
42pub fn syscall1<const NUM: u16>(arg1: usize) -> SyscallResult {
43 let result: u16;
44 unsafe {
45 #[cfg(target_arch = "x86_64")]
46 asm!(
47 "int 0x80",
48 in("rax") NUM as usize,
49 in("rdi") arg1,
50 lateout("rax") result,
51 );
52 #[cfg(target_arch = "aarch64")]
53 asm!(
54 "svc #{num}",
55 num = const NUM,
56 in("x0") arg1,
57 lateout("x0") result
58 );
59 core::mem::transmute(result)
60 }
61}
62
63#[doc(hidden)]
64#[inline(always)]
65pub fn syscall2<const NUM: u16>(arg1: usize, arg2: usize) -> SyscallResult {
66 let result: u16;
67 unsafe {
68 #[cfg(target_arch = "x86_64")]
69 asm!(
70 "int 0x80",
71 in("rax") NUM as usize,
72 in("rdi") arg1,
73 in("rsi") arg2,
74 lateout("rax") result,
75 );
76 #[cfg(target_arch = "aarch64")]
77 asm!(
78 "svc #{num}",
79 num = const NUM,
80 in("x0") arg1,
81 in("x1") arg2,
82 lateout("x0") result
83 );
84 core::mem::transmute(result)
85 }
86}
87
88#[doc(hidden)]
89#[inline(always)]
90pub fn syscall3<const NUM: u16>(arg1: usize, arg2: usize, arg3: usize) -> SyscallResult {
91 let result: u16;
92 unsafe {
93 #[cfg(target_arch = "x86_64")]
94 asm!(
95 "int 0x80",
96 in("rax") NUM as usize,
97 in("rdi") arg1,
98 in("rsi") arg2,
99 in("rdx") arg3,
100 lateout("rax") result,
101 );
102 #[cfg(target_arch = "aarch64")]
103 asm!(
104 "svc #{num}",
105 num = const NUM,
106 in("x0") arg1,
107 in("x1") arg2,
108 in("x2") arg3,
109 lateout("x0") result
110 );
111 core::mem::transmute(result)
112 }
113}
114
115#[doc(hidden)]
116#[inline(always)]
117pub fn syscall4<const NUM: u16>(
118 arg1: usize,
119 arg2: usize,
120 arg3: usize,
121 arg4: usize,
122) -> SyscallResult {
123 let result: u16;
124 unsafe {
125 #[cfg(target_arch = "x86_64")]
126 asm!(
127 "int 0x80",
128 in("rax") NUM as usize,
129 in("rdi") arg1,
130 in("rsi") arg2,
131 in("rdx") arg3,
132 in("rcx") arg4,
133 lateout("rax") result,
134 );
135
136 #[cfg(target_arch = "aarch64")]
137 asm!(
138 "svc #{num}",
139 num = const NUM,
140 in("x0") arg1,
141 in("x1") arg2,
142 in("x2") arg3,
143 in("x3") arg4,
144 lateout("x0") result
145 );
146 core::mem::transmute(result)
147 }
148}
149
150#[doc(hidden)]
151#[inline(always)]
152pub fn syscall5<const NUM: u16>(
153 arg1: usize,
154 arg2: usize,
155 arg3: usize,
156 arg4: usize,
157 arg5: usize,
158) -> SyscallResult {
159 let result: u16;
160 unsafe {
161 #[cfg(target_arch = "x86_64")]
162 asm!(
163 "int 0x80",
164 in("rax") NUM as usize,
165 in("rdi") arg1,
166 in("rsi") arg2,
167 in("rdx") arg3,
168 in("rcx") arg4,
169 in("r8") arg5,
170 lateout("rax") result,
171 );
172 #[cfg(target_arch = "aarch64")]
173 asm!(
174 "svc #{num}",
175 num = const NUM,
176 in("x0") arg1,
177 in("x1") arg2,
178 in("x2") arg3,
179 in("x3") arg4,
180 in("x4") arg5,
181 lateout("x0") result
182 );
183 core::mem::transmute(result)
184 }
185}
186
187macro_rules! syscall {
192 ($num: path $(,)?) => {
193 $crate::syscalls::syscall0::<{ $num as u16 }>()
194 };
195 ($num: path, $arg1: expr $(,)?) => {
196 $crate::syscalls::syscall1::<{ $num as u16 }>($arg1)
197 };
198 ($num: path, $arg1: expr, $arg2: expr $(,)?) => {
199 $crate::syscalls::syscall2::<{ $num as u16 }>($arg1, $arg2)
200 };
201 ($num: path, $arg1: expr, $arg2: expr, $arg3: expr $(,)?) => {
202 $crate::syscalls::syscall3::<{ $num as u16 }>($arg1, $arg2, $arg3)
203 };
204 ($num: path, $arg1: expr, $arg2: expr, $arg3: expr, $arg4: expr $(,)?) => {
205 $crate::syscalls::syscall4::<{ $num as u16 }>($arg1, $arg2, $arg3, $arg4)
206 };
207 ($num: path, $arg1: expr, $arg2: expr, $arg3: expr, $arg4: expr, $arg5: expr $(,)?) => {
208 $crate::syscalls::syscall5::<{ $num as u16 }>($arg1, $arg2, $arg3, $arg4, $arg5)
209 };
210}
211
212pub(crate) use syscall;
213
214macro_rules! define_syscall {
215 ($num:path => { $(#[$attrss:meta])* $name:ident ($($arg:ident : $ty:ty),*) unreachable }) => {
216 $(#[$attrss])*
217 #[cfg_attr(
218 not(any(feature = "std", feature = "rustc-dep-of-std")),
219 unsafe(no_mangle)
220 )]
221 #[inline(always)]
222 pub extern "C" fn $name($($arg: $ty),*) -> ! {
223 #[allow(unused_imports)]
224 use $crate::syscalls::types::IntoSyscallArg;
225 _ = $crate::syscalls::syscall!($num, $( $arg.into_syscall_arg() ),*);
226 unreachable!()
227 }
228 };
229 ($num:path => { $(#[$attrss:meta])* $name:ident ($($arg:ident : $ty:ty),*) }) => {
230 $(#[$attrss])*
231 #[cfg_attr(
232 not(any(feature = "std", feature = "rustc-dep-of-std")),
233 unsafe(no_mangle)
234 )]
235 #[inline(always)]
236 pub extern "C" fn $name($($arg: $ty),*) -> $crate::syscalls::types::SyscallResult {
237 #[allow(unused_imports)]
238 use $crate::syscalls::types::IntoSyscallArg;
239 let result = $crate::syscalls::syscall!($num, $( $arg.into_syscall_arg() ),*);
240 result
241 }
242 };
243 {$($num:path => { $(#[$attrss:meta])* $name:ident ($($arg:ident: $ty:ty),*) $($modifier:tt)* }),* $(,)?} => {
244 $(define_syscall!($num => { $(#[$attrss])* $name($($arg: $ty),*) $($modifier)* });)*
245 };
246}
247
248pub(crate) use define_syscall;
249
250pub mod fs;
252pub mod io;
254pub mod misc;
256pub mod process;
258pub mod process_misc;
260pub mod resources;
262pub mod thread;
264
265use types::SyscallResult;
266pub mod types;