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