1#![no_std]
2
3use strat9_abi::{flag::posix_oflags_to_strat9, syscall::*};
4use strat9_syscall::{syscall0, syscall1, syscall2, syscall3, syscall4, syscall5, syscall6};
5
6#[inline(always)]
9fn raw0(nr: usize) -> i64 {
10 unsafe {
11 match syscall0(nr) {
12 Ok(v) => v as i64,
13 Err(e) => -(e.to_errno() as i64),
14 }
15 }
16}
17
18#[inline(always)]
19fn raw1(nr: usize, a1: usize) -> i64 {
20 unsafe {
21 match syscall1(nr, a1) {
22 Ok(v) => v as i64,
23 Err(e) => -(e.to_errno() as i64),
24 }
25 }
26}
27
28#[inline(always)]
29fn raw2(nr: usize, a1: usize, a2: usize) -> i64 {
30 unsafe {
31 match syscall2(nr, a1, a2) {
32 Ok(v) => v as i64,
33 Err(e) => -(e.to_errno() as i64),
34 }
35 }
36}
37
38#[inline(always)]
39fn raw3(nr: usize, a1: usize, a2: usize, a3: usize) -> i64 {
40 unsafe {
41 match syscall3(nr, a1, a2, a3) {
42 Ok(v) => v as i64,
43 Err(e) => -(e.to_errno() as i64),
44 }
45 }
46}
47
48#[inline(always)]
49fn raw4(nr: usize, a1: usize, a2: usize, a3: usize, a4: usize) -> i64 {
50 unsafe {
51 match syscall4(nr, a1, a2, a3, a4) {
52 Ok(v) => v as i64,
53 Err(e) => -(e.to_errno() as i64),
54 }
55 }
56}
57
58#[inline(always)]
59fn raw5(nr: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize) -> i64 {
60 unsafe {
61 match syscall5(nr, a1, a2, a3, a4, a5) {
62 Ok(v) => v as i64,
63 Err(e) => -(e.to_errno() as i64),
64 }
65 }
66}
67
68#[inline(always)]
69fn raw6(nr: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize) -> i64 {
70 unsafe {
71 match syscall6(nr, a1, a2, a3, a4, a5, a6) {
72 Ok(v) => v as i64,
73 Err(e) => -(e.to_errno() as i64),
74 }
75 }
76}
77
78const CLONE_VM: usize = 0x00000100; const CLONE_THREAD: usize = 0x00010000; const CLONE_SIGHAND: usize = 0x00000800; const CLONE_SETTLS: usize = 0x00080000; const CLONE_PARENT_SETTID: usize = 0x00100000; const CLONE_CHILD_CLEARTID: usize = 0x00200000; const CLONE_CHILD_SETTID: usize = 0x02000000; const CLONE_VFORK: usize = 0x00004000; const FUTEX_WAIT: usize = 0;
93const FUTEX_WAKE: usize = 1;
94const FUTEX_REQUEUE: usize = 3;
95const FUTEX_CMP_REQUEUE: usize = 4;
96const FUTEX_PRIVATE_FLAG: usize = 128;
97
98const ARCH_SET_FS: usize = 0x1002;
101const ARCH_GET_FS: usize = 0x1003;
102
103const LNR_read: i64 = 0;
110const LNR_write: i64 = 1;
111const LNR_open: i64 = 2;
112const LNR_close: i64 = 3;
113const LNR_stat: i64 = 4;
114const LNR_fstat: i64 = 5;
115const LNR_lstat: i64 = 6;
116const LNR_poll: i64 = 7;
117const LNR_lseek: i64 = 8;
118const LNR_mmap: i64 = 9;
119const LNR_mprotect: i64 = 10;
120const LNR_munmap: i64 = 11;
121const LNR_brk: i64 = 12;
122const LNR_rt_sigaction: i64 = 13;
123const LNR_rt_sigprocmask: i64 = 14;
124const LNR_rt_sigreturn: i64 = 15;
125const LNR_ioctl: i64 = 16;
126const LNR_pread64: i64 = 17;
127const LNR_pwrite64: i64 = 18;
128const LNR_access: i64 = 21;
129const LNR_pipe: i64 = 22;
130const LNR_sched_yield: i64 = 24;
131const LNR_mremap: i64 = 25;
132const LNR_dup: i64 = 32;
133const LNR_dup2: i64 = 33;
134const LNR_nanosleep: i64 = 35;
135const LNR_getitimer: i64 = 36;
136const LNR_setitimer: i64 = 38;
137const LNR_getpid: i64 = 39;
138const LNR_clone: i64 = 56;
139const LNR_fork: i64 = 57;
140const LNR_execve: i64 = 59;
141const LNR_exit: i64 = 60;
142const LNR_wait4: i64 = 61;
143const LNR_kill: i64 = 62;
144const LNR_uname: i64 = 63;
145const LNR_fcntl: i64 = 72;
146const LNR_truncate: i64 = 76;
147const LNR_ftruncate: i64 = 77;
148const LNR_getdents: i64 = 78;
149const LNR_getcwd: i64 = 79;
150const LNR_chdir: i64 = 80;
151const LNR_fchdir: i64 = 81;
152const LNR_rename: i64 = 82;
153const LNR_mkdir: i64 = 83;
154const LNR_rmdir: i64 = 84;
155const LNR_link: i64 = 86;
156const LNR_unlink: i64 = 87;
157const LNR_symlink: i64 = 88;
158const LNR_readlink: i64 = 89;
159const LNR_chmod: i64 = 90;
160const LNR_fchmod: i64 = 91;
161const LNR_umask: i64 = 95;
162const LNR_getuid: i64 = 102;
163const LNR_getgid: i64 = 104;
164const LNR_setuid: i64 = 105;
165const LNR_setgid: i64 = 106;
166const LNR_geteuid: i64 = 107;
167const LNR_getegid: i64 = 108;
168const LNR_setpgid: i64 = 109;
169const LNR_getppid: i64 = 110;
170const LNR_getpgrp: i64 = 111;
171const LNR_setsid: i64 = 112;
172const LNR_getpgid: i64 = 121;
173const LNR_getsid: i64 = 124;
174const LNR_rt_sigpending: i64 = 127;
175const LNR_rt_sigtimedwait: i64 = 128;
176const LNR_rt_sigsuspend: i64 = 130;
177const LNR_sigaltstack: i64 = 131;
178const LNR_pause: i64 = 34;
179const LNR_socket: i64 = 41;
180const LNR_connect: i64 = 42;
181const LNR_accept: i64 = 43;
182const LNR_sendto: i64 = 44;
183const LNR_recvfrom: i64 = 45;
184const LNR_sendmsg: i64 = 46;
185const LNR_recvmsg: i64 = 47;
186const LNR_shutdown: i64 = 48;
187const LNR_bind: i64 = 49;
188const LNR_listen: i64 = 50;
189const LNR_getsockname: i64 = 51;
190const LNR_getpeername: i64 = 52;
191const LNR_socketpair: i64 = 53;
192const LNR_setsockopt: i64 = 54;
193const LNR_getsockopt: i64 = 55;
194const LNR_gettid: i64 = 186;
195const LNR_tkill: i64 = 200;
196const LNR_futex: i64 = 202;
197const LNR_set_tid_address: i64 = 218;
198const LNR_clock_gettime: i64 = 228;
199const LNR_clock_getres: i64 = 229;
200const LNR_clock_nanosleep: i64 = 230;
201const LNR_exit_group: i64 = 231;
202const LNR_tgkill: i64 = 234;
203const LNR_openat: i64 = 257;
204const LNR_mkdirat: i64 = 258;
205const LNR_newfstatat: i64 = 262;
206const LNR_unlinkat: i64 = 263;
207const LNR_renameat: i64 = 264;
208const LNR_readlinkat: i64 = 267;
209const LNR_ppoll: i64 = 271;
210const LNR_set_robust_list: i64 = 273;
211const LNR_get_robust_list: i64 = 274;
212const LNR_arch_prctl: i64 = 158;
213const LNR_faccessat: i64 = 269;
214const LNR_getrandom: i64 = 318;
215const LNR_faccessat2: i64 = 439;
216
217#[no_mangle]
229pub unsafe extern "C" fn strat9_syscall_dispatcher(
230 n: i64,
231 a1: i64,
232 a2: i64,
233 a3: i64,
234 a4: i64,
235 a5: i64,
236 a6: i64,
237) -> i64 {
238 let a1u = a1 as usize;
239 let a2u = a2 as usize;
240 let a3u = a3 as usize;
241 let a4u = a4 as usize;
242 let a5u = a5 as usize;
243 let a6u = a6 as usize;
244
245 match n {
249 LNR_read => raw3(SYS_READ, a1u, a2u, a3u),
250 LNR_write => raw3(SYS_WRITE, a1u, a2u, a3u),
251 LNR_open => {
252 let sf = posix_oflags_to_strat9(a2 as u32);
255 raw3(SYS_OPEN, a1u, sf.bits() as usize, a3u)
256 }
257 LNR_close => raw1(SYS_CLOSE, a1u),
258 LNR_lseek => raw3(SYS_LSEEK, a1u, a2u, a3u),
259 LNR_pread64 => raw4(SYS_PREAD, a1u, a2u, a3u, a4u),
260 LNR_pwrite64 => raw4(SYS_PWRITE, a1u, a2u, a3u, a4u),
261 LNR_fstat => raw2(SYS_FSTAT, a1u, a2u),
262 LNR_stat => raw2(SYS_STAT, a1u, a2u),
263 LNR_lstat => raw2(SYS_STAT, a1u, a2u), LNR_access => raw3(SYS_ACCESS, a1u, a2u, a3u),
265 LNR_pipe => raw1(SYS_PIPE, a1u),
266 LNR_dup => raw1(SYS_DUP, a1u),
267 LNR_dup2 => raw2(SYS_DUP2, a1u, a2u),
268 LNR_ioctl => raw3(SYS_IOCTL, a1u, a2u, a3u),
269 LNR_fcntl => raw3(SYS_FCNTL, a1u, a2u, a3u),
270 LNR_truncate => raw2(SYS_TRUNCATE, a1u, a2u),
271 LNR_ftruncate => raw2(SYS_FTRUNCATE, a1u, a2u),
272 LNR_getdents => raw3(SYS_GETDENTS, a1u, a2u, a3u),
273 LNR_poll => raw3(SYS_POLL, a1u, a2u, a3u),
274 LNR_ppoll => raw5(SYS_PPOLL, a1u, a2u, a3u, a4u, a5u),
275
276 LNR_openat => {
278 let sf = posix_oflags_to_strat9(a3 as u32);
279 raw4(SYS_OPENAT, a1u, a2u, sf.bits() as usize, a4u)
280 }
281 LNR_mkdirat => raw3(SYS_MKDIRAT, a1u, a2u, a3u),
282 LNR_newfstatat => raw4(SYS_FSTATAT, a1u, a2u, a3u, a4u),
283 LNR_unlinkat => raw3(SYS_UNLINKAT, a1u, a2u, a3u),
284 LNR_renameat => raw4(SYS_RENAMEAT, a1u, a2u, a3u, a4u),
285 LNR_readlinkat => raw4(SYS_READLINKAT, a1u, a2u, a3u, a4u),
286 LNR_faccessat => raw5(SYS_FACCESSAT, a1u, a2u, a3u, a4u, 0),
287 LNR_faccessat2 => raw5(SYS_FACCESSAT, a1u, a2u, a3u, a4u, a5u),
288
289 LNR_getcwd => raw2(SYS_GETCWD, a1u, a2u),
291 LNR_chdir => raw1(SYS_CHDIR, a1u),
292 LNR_fchdir => raw1(SYS_FCHDIR, a1u),
293 LNR_rename => raw2(SYS_RENAME, a1u, a2u),
294 LNR_mkdir => raw2(SYS_MKDIR, a1u, a2u),
295 LNR_rmdir => raw1(SYS_RMDIR, a1u),
296 LNR_link => raw2(SYS_LINK, a1u, a2u),
297 LNR_unlink => raw1(SYS_UNLINK, a1u),
298 LNR_symlink => raw2(SYS_SYMLINK, a1u, a2u),
299 LNR_readlink => raw3(SYS_READLINK, a1u, a2u, a3u),
300 LNR_chmod => raw2(SYS_CHMOD, a1u, a2u),
301 LNR_fchmod => raw2(SYS_FCHMOD, a1u, a2u),
302 LNR_umask => raw1(SYS_UMASK, a1u),
303
304 LNR_mmap => raw6(
306 SYS_MMAP, a1u, a2u, a3u, a4u, a5u, a6u, ),
311 LNR_munmap => raw2(SYS_MUNMAP, a1u, a2u),
312 LNR_mprotect => raw3(SYS_MPROTECT, a1u, a2u, a3u),
313 LNR_brk => raw1(SYS_BRK, a1u),
314 LNR_mremap => raw4(SYS_MREMAP, a1u, a2u, a3u, a4u),
315
316 LNR_exit => {
318 raw1(SYS_PROC_EXIT, a1u);
319 loop {}
320 }
321 LNR_exit_group => {
322 raw1(SYS_EXIT_GROUP, a1u);
323 loop {}
324 }
325 LNR_sched_yield => raw0(SYS_PROC_YIELD),
326 LNR_getpid => raw0(SYS_GETPID),
327 LNR_getppid => raw0(SYS_GETPPID),
328 LNR_gettid => raw0(SYS_GETTID),
329 LNR_getuid => raw0(SYS_GETUID),
330 LNR_geteuid => raw0(SYS_GETEUID),
331 LNR_getgid => raw0(SYS_GETGID),
332 LNR_getegid => raw0(SYS_GETEGID),
333 LNR_setuid => raw1(SYS_SETUID, a1u),
334 LNR_setgid => raw1(SYS_SETGID, a1u),
335 LNR_setpgid => raw2(SYS_SETPGID, a1u, a2u),
336 LNR_getpgid => raw1(SYS_GETPGID, a1u),
337 LNR_getpgrp => raw0(SYS_GETPGRP),
338 LNR_setsid => raw0(SYS_SETSID),
339 LNR_getsid => raw1(SYS_GETSID, a1u),
340 LNR_fork => raw0(SYS_PROC_FORK),
341 LNR_execve => raw3(SYS_PROC_EXECVE, a1u, a2u, a3u),
342 LNR_wait4 => raw4(SYS_PROC_WAITPID, a1u, a2u, a3u, a4u),
343 LNR_uname => raw1(SYS_UNAME, a1u),
344 LNR_pause => raw1(SYS_SIGSUSPEND, 0), LNR_kill => raw2(SYS_KILL, a1u, a2u),
346
347 LNR_clone => {
349 let flags = a1u;
358 let result = if (flags & CLONE_THREAD) != 0 {
359 let child_stack = a2u;
361 let arg = unsafe { *(child_stack as *const usize) };
362 raw5(SYS_THREAD_CREATE, a6u, child_stack, arg, 0, a4u)
364 } else {
365 raw0(SYS_PROC_FORK)
367 };
368
369 if result > 0 {
371 let child_tid = result as u32;
372 if (flags & CLONE_PARENT_SETTID) != 0 && a3u != 0 {
374 unsafe {
375 *(a3u as *mut u32) = child_tid;
376 }
377 }
378 if (flags & CLONE_CHILD_SETTID) != 0 && a5u != 0 {
380 unsafe {
381 *(a5u as *mut u32) = child_tid;
382 }
383 }
384 }
385 result
386 }
387 LNR_tkill => raw2(SYS_TGKILL, a1u, a2u),
388 LNR_tgkill => raw3(SYS_TGKILL, a1u, a2u, a3u),
389
390 LNR_rt_sigaction => raw4(SYS_SIGACTION, a1u, a2u, a3u, a4u),
392 LNR_rt_sigprocmask => raw4(SYS_SIGPROCMASK, a1u, a2u, a3u, a4u),
393 LNR_rt_sigreturn => raw0(SYS_RT_SIGRETURN),
394 LNR_rt_sigpending => raw2(SYS_SIGPENDING, a1u, a2u),
395 LNR_rt_sigtimedwait => raw4(SYS_SIGTIMEDWAIT, a1u, a2u, a3u, a4u),
396 LNR_rt_sigsuspend => raw2(SYS_SIGSUSPEND, a1u, a2u),
397 LNR_sigaltstack => raw2(SYS_SIGALTSTACK, a1u, a2u),
398
399 LNR_nanosleep => raw2(SYS_NANOSLEEP, a1u, a2u),
401 LNR_clock_gettime => raw2(SYS_CLOCK_GETTIME, a1u, a2u),
402 LNR_clock_getres => {
403 0
405 }
406 LNR_clock_nanosleep => raw4(SYS_CLOCK_NANOSLEEP, a1u, a2u, a3u, a4u),
407 LNR_getitimer => raw2(SYS_GETITIMER, a1u, a2u),
408 LNR_setitimer => raw3(SYS_SETITIMER, a1u, a2u, a3u),
409
410 LNR_futex => {
412 let op = a2u & !FUTEX_PRIVATE_FLAG; match op {
415 FUTEX_WAIT => raw3(SYS_FUTEX_WAIT, a1u, a3u, a4u),
416 FUTEX_WAKE => raw2(SYS_FUTEX_WAKE, a1u, a3u),
417 FUTEX_REQUEUE => raw4(SYS_FUTEX_REQUEUE, a1u, a3u, a5u, a4u),
418 FUTEX_CMP_REQUEUE => raw5(SYS_FUTEX_CMP_REQUEUE, a1u, a3u, a5u, a6u, a4u),
419 _ => {
420 -38 }
423 }
424 }
425
426 LNR_socket | LNR_connect | LNR_accept | LNR_sendto | LNR_recvfrom | LNR_sendmsg
441 | LNR_recvmsg | LNR_shutdown | LNR_bind | LNR_listen | LNR_getsockname
442 | LNR_getpeername | LNR_socketpair | LNR_setsockopt | LNR_getsockopt => {
443 -38 }
445
446 LNR_set_tid_address => raw1(SYS_SET_TID_ADDRESS, a1u),
448 LNR_set_robust_list => raw2(SYS_SET_ROBUST_LIST, a1u, a2u),
449 LNR_get_robust_list => raw3(SYS_GET_ROBUST_LIST, a1u, a2u, a3u),
450 LNR_arch_prctl => {
451 match a1u {
452 ARCH_SET_FS => raw2(SYS_ARCH_PRCTL, a1u, a2u),
453 ARCH_GET_FS => raw2(SYS_ARCH_PRCTL, a1u, a2u),
454 _ => -22, }
456 }
457
458 LNR_getrandom => raw3(SYS_GETRANDOM, a1u, a2u, a3u),
460
461 _ => -38, }
464}
465
466