Skip to main content

starnix_syscalls/
decls.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#![allow(non_upper_case_globals)]
6
7use crate::SyscallArg;
8use starnix_types::arch::ArchWidth;
9#[allow(unused_imports)]
10use starnix_uapi::user_address::ArchSpecific;
11
12/// Helper for for_each_syscall! that adds any architecture-specific syscalls.
13///
14/// X86_64 has many unique syscalls for legacy reasons. Newer architectures funnel some of these
15/// through some newer and more general variants. The variants used by other platforms are listed in
16/// the comments below.
17#[cfg(target_arch = "x86_64")]
18#[macro_export]
19macro_rules! for_each_arch_syscall {
20    {$callback:ident; $($context:ident;)* ; $($common_name:ident,)*} => {
21        $callback!{
22            $($context;)*
23            $($common_name,)*
24
25            // go/keep-sorted start
26
27            _sysctl,  // (deprecated)
28            access,  // faccessat
29            afs_syscall, // (deprecated)
30            alarm,  // setitimer
31            arch_prctl,  // (unused)
32            chmod,  // fchmodat
33            chown,  // fchownat
34            creat,  // openat
35            create_module, // (deprecated)
36            dup2,  // dup3
37            epoll_create,  // epoll_create1
38            epoll_ctl_old,  // (unused)
39            epoll_wait,  // epoll_pwait
40            epoll_wait_old,  // (unused)
41            eventfd,  // eventfd2
42            fork,  // clone
43            futimesat,  // (deprecated)
44            get_kernel_syms, // (deprecated)
45            get_thread_area,  // (unused)
46            getdents,  // getdents64
47            getpgrp,  // getpgid
48            getpmsg, // (unused)
49            inotify_init,  // inotify_init1
50            ioperm,  // (unused)
51            iopl,  // (deprevated)
52            lchown,  // fchownat
53            link,  // linkat
54            lstat,  // fstatat
55            mkdir,  // mkdirat
56            mknod,  // mknodat
57            modify_ldt,  // (unused)
58            open,  // openat
59            pause,  // sigsuspend
60            pipe,  // pipe2
61            poll,  // ppoll
62            putpmsg, // (unused)
63            query_module, // (deprecated)
64            readlink,  // readlinkat
65            rename,  // renameat2
66            renameat,  // renameat2
67            rmdir,  // unlinkat
68            security,  // (unused)
69            select,  // pselect
70            set_thread_area, // (unused)
71            signalfd,  // signalfd4
72            stat,  // fstatat
73            symlink,  // symlinkat
74            sysfs,  // (deprecated)
75            time,  // gettimeofday
76            tuxcall,  // (unused)
77            unlink,  // unlinkat
78            uselib,  // (deprecated)
79            ustat,  // (deprecated)
80            utime,  // utimesat
81            utimes,  // utimesat
82            vfork,  // clone
83            vserver,  // (unused)
84
85            // go/keep-sorted end
86        }
87    }
88}
89
90// This macro ensures there is a unique way to identify syscalls that have a
91// distinct implementation from the primary architecture.
92#[cfg(all(target_arch = "aarch64"))]
93#[macro_export]
94macro_rules! for_each_arch_arch32_syscall {
95    {$callback:ident; $($context:ident;)* ; $($common_name:ident,)*} => {
96        $callback!{
97            $($context;)*
98            $($common_name,)*
99
100            // go/keep-sorted start
101
102            ARM_breakpoint,
103            ARM_cacheflush,
104            ARM_set_tls,
105            ARM_usr26,
106            ARM_usr32,
107            _llseek,
108            _newselect,
109            arm_fadvise64_64,
110            chown,
111            chown32,
112            clock_gettime64,
113            dup2,
114            epoll_create,
115            epoll_pwait,
116            epoll_pwait2,
117            epoll_wait,
118            execve,
119            execveat,
120            fallocate,
121            fanotify_mark,
122            fchown32,
123            fcntl,
124            fcntl64,
125            fstat,
126            fstat64,
127            fstatat64,
128            fstatfs,
129            fstatfs64,
130            ftruncate,
131            ftruncate64,
132            get_robust_list,
133            getdents,
134            getegid32,
135            geteuid32,
136            getgid32,
137            getgroups32,
138            getitimer,
139            getresgid32,
140            getresuid32,
141            getrusage,
142            gettimeofday,
143            io_pgetevents,
144            io_pgetevents_time64,
145            io_setup,
146            io_submit,
147            ioctl,
148            kexec_load,
149            keyctl,
150            lseek,
151            lstat,
152            mkdir,
153            mmap2,
154            mq_getsetattr,
155            mq_notify,
156            mq_open,
157            msgctl,
158            msgrcv,
159            msgsnd,
160            open,
161            open_by_handle_at,
162            openat,
163            poll,
164            ppoll,
165            ppoll_time64,
166            pread64,
167            preadv,
168            preadv2,
169            pselect6,
170            pselect6_time64,
171            ptrace,
172            pwrite64,
173            pwritev,
174            pwritev2,
175            readahead,
176            recv,
177            recvfrom,
178            recvmmsg,
179            recvmmsg_time64,
180            recvmsg,
181            renameat,  // renameat2
182            rt_sigaction,
183            rt_sigpending,
184            rt_sigprocmask,
185            rt_sigqueueinfo,
186            rt_sigreturn,
187            rt_sigsuspend,
188            rt_sigtimedwait,
189            rt_sigtimedwait_time64,
190            rt_tgsigqueueinfo,
191            sched_getaffinity,
192            sched_setaffinity,
193            semctl,
194            send,
195            sendfile,
196            sendfile64,
197            sendmmsg,
198            sendmsg,
199            set_robust_list,
200            setfsgid32,
201            setfsuid32,
202            setgid32,
203            setgroups32,
204            setitimer,
205            setregid32,
206            setresgid32,
207            setresuid32,
208            setreuid32,
209            setrlimit,
210            settimeofday,
211            setuid32,
212            shmat,
213            shmctl,
214            sigaction,
215            sigaltstack,
216            signalfd,
217            signalfd4,
218            sigpending,
219            sigprocmask,
220            sigreturn,
221            stat,
222            stat64,
223            statfs,
224            statfs64,
225            sync_file_range2,
226            sysinfo,
227            timer_create,
228            timer_gettime64,
229            times,
230            truncate,
231            truncate64,
232            ugetrlimit,
233            unlink,
234            ustat,
235            vfork,
236            wait4,
237            waitid,
238
239            // go/keep-sorted end
240        }
241    }
242}
243
244#[cfg(target_arch = "aarch64")]
245#[macro_export]
246macro_rules! for_each_arch_syscall {
247    {$callback:ident; $($context:ident;)* ; $($common_name:ident,)*} => {
248        $callback!{
249            $($context;)*
250            $($common_name,)*
251            renameat,  // renameat2
252        }
253    }
254}
255
256#[cfg(target_arch = "riscv64")]
257#[macro_export]
258macro_rules! for_each_arch_syscall {
259    {$callback:ident; $($context:ident;)* ; $($common_name:ident,)*} => {
260        $callback!{
261            $($context;)*
262            $($common_name,)*
263        }
264    }
265}
266
267/// Intended to be used with other macros to produce code that needs to handle
268/// each syscall.
269///
270/// This list contains all cross-architecture syscalls, and delegates through for_each_arch_syscall!
271/// to add in any architecture-specific ones.
272#[macro_export]
273macro_rules! for_each_syscall {
274    {$callback:ident $(,$context:ident)*} => {
275        $crate::for_each_arch_syscall!{
276            $callback;
277            $($context;)*
278            ;
279
280            // go/keep-sorted start
281
282            accept,
283            accept4,
284            acct,
285            add_key,
286            adjtimex,
287            bind,
288            bpf,
289            brk,
290            cachestat,
291            capget,
292            capset,
293            chdir,
294            chroot,
295            clock_adjtime,
296            clock_getres,
297            clock_gettime,
298            clock_nanosleep,
299            clock_settime,
300            clone,
301            clone3,
302            close,
303            close_range,
304            connect,
305            copy_file_range,
306            delete_module,
307            dup,
308            dup3,
309            epoll_create1,
310            epoll_ctl,
311            epoll_pwait,
312            epoll_pwait2,
313            eventfd2,
314            execve,
315            execveat,
316            exit,
317            exit_group,
318            faccessat,
319            faccessat2,
320            fadvise64,
321            fallocate,
322            fanotify_init,
323            fanotify_mark,
324            fchdir,
325            fchmod,
326            fchmodat,
327            fchown,
328            fchownat,
329            fcntl,
330            fdatasync,
331            fgetxattr,
332            finit_module,
333            flistxattr,
334            flock,
335            fremovexattr,
336            fsconfig,
337            fsetxattr,
338            fsmount,
339            fsopen,
340            fspick,
341            fstat,
342            fstatfs,
343            fsync,
344            ftruncate,
345            futex,
346            futex_waitv,
347            get_mempolicy,
348            get_robust_list,
349            getcpu,
350            getcwd,
351            getdents64,
352            getegid,
353            geteuid,
354            getgid,
355            getgroups,
356            getitimer,
357            getpeername,
358            getpgid,
359            getpid,
360            getppid,
361            getpriority,
362            getrandom,
363            getresgid,
364            getresuid,
365            getrlimit,
366            getrusage,
367            getsid,
368            getsockname,
369            getsockopt,
370            gettid,
371            gettimeofday,
372            getuid,
373            getxattr,
374            init_module,
375            inotify_add_watch,
376            inotify_init1,
377            inotify_rm_watch,
378            io_cancel,
379            io_destroy,
380            io_getevents,
381            io_pgetevents,
382            io_setup,
383            io_submit,
384            io_uring_enter,
385            io_uring_register,
386            io_uring_setup,
387            ioctl,
388            ioprio_get,
389            ioprio_set,
390            kcmp,
391            kexec_file_load,
392            kexec_load,
393            keyctl,
394            kill,
395            landlock_add_rule,
396            landlock_create_ruleset,
397            landlock_restrict_self,
398            lgetxattr,
399            linkat,
400            listen,
401            listxattr,
402            llistxattr,
403            lookup_dcookie,
404            lremovexattr,
405            lseek,
406            lsetxattr,
407            madvise,
408            mbind,
409            membarrier,
410            memfd_create,
411            memfd_secret,
412            migrate_pages,
413            mincore,
414            mkdirat,
415            mknodat,
416            mlock,
417            mlock2,
418            mlockall,
419            mmap,
420            mount,
421            mount_setattr,
422            move_mount,
423            move_pages,
424            mprotect,
425            mq_getsetattr,
426            mq_notify,
427            mq_open,
428            mq_timedreceive,
429            mq_timedsend,
430            mq_unlink,
431            mremap,
432            msgctl,
433            msgget,
434            msgrcv,
435            msgsnd,
436            msync,
437            munlock,
438            munlockall,
439            munmap,
440            name_to_handle_at,
441            nanosleep,
442            newfstatat,
443            nfsservctl,
444            open_by_handle_at,
445            open_tree,
446            openat,
447            openat2,
448            perf_event_open,
449            personality,
450            pidfd_getfd,
451            pidfd_open,
452            pidfd_send_signal,
453            pipe2,
454            pivot_root,
455            pkey_alloc,
456            pkey_free,
457            pkey_mprotect,
458            ppoll,
459            prctl,
460            pread64,
461            preadv,
462            preadv2,
463            prlimit64,
464            process_madvise,
465            process_mrelease,
466            process_vm_readv,
467            process_vm_writev,
468            pselect6,
469            ptrace,
470            pwrite64,
471            pwritev,
472            pwritev2,
473            quotactl,
474            quotactl_fd,
475            read,
476            readahead,
477            readlinkat,
478            readv,
479            reboot,
480            recvfrom,
481            recvmmsg,
482            recvmsg,
483            remap_file_pages,
484            removexattr,
485            renameat2,
486            request_key,
487            restart_syscall,
488            rseq,
489            rt_sigaction,
490            rt_sigpending,
491            rt_sigprocmask,
492            rt_sigqueueinfo,
493            rt_sigreturn,
494            rt_sigsuspend,
495            rt_sigtimedwait,
496            rt_tgsigqueueinfo,
497            sched_get_priority_max,
498            sched_get_priority_min,
499            sched_getaffinity,
500            sched_getattr,
501            sched_getparam,
502            sched_getscheduler,
503            sched_rr_get_interval,
504            sched_setaffinity,
505            sched_setattr,
506            sched_setparam,
507            sched_setscheduler,
508            sched_yield,
509            seccomp,
510            semctl,
511            semget,
512            semop,
513            semtimedop,
514            sendfile,
515            sendmmsg,
516            sendmsg,
517            sendto,
518            set_mempolicy,
519            set_mempolicy_home_node,
520            set_robust_list,
521            set_tid_address,
522            setdomainname,
523            setfsgid,
524            setfsuid,
525            setgid,
526            setgroups,
527            sethostname,
528            setitimer,
529            setns,
530            setpgid,
531            setpriority,
532            setregid,
533            setresgid,
534            setresuid,
535            setreuid,
536            setrlimit,
537            setsid,
538            setsockopt,
539            settimeofday,
540            setuid,
541            setxattr,
542            shmat,
543            shmctl,
544            shmdt,
545            shmget,
546            shutdown,
547            sigaltstack,
548            signalfd4,
549            socket,
550            socketpair,
551            splice,
552            statfs,
553            statx,
554            swapoff,
555            swapon,
556            symlinkat,
557            sync,
558            sync_file_range,
559            syncfs,
560            sysinfo,
561            syslog,
562            tee,
563            tgkill,
564            timer_create,
565            timer_delete,
566            timer_getoverrun,
567            timer_gettime,
568            timer_settime,
569            timerfd_create,
570            timerfd_gettime,
571            timerfd_settime,
572            times,
573            tkill,
574            truncate,
575            umask,
576            umount2,
577            uname,
578            unlinkat,
579            unshare,
580            userfaultfd,
581            utimensat,
582            vhangup,
583            vmsplice,
584            wait4,
585            waitid,
586            write,
587            writev,
588
589            // go/keep-sorted end
590        }
591    }
592}
593
594/// As above, but this calls through for the arch32 for arch support.
595/// It's worth noting that common syscalls above are not common across
596/// arches like x86 or arm.  The common list below reflects only
597/// those common across arch32 arches.
598///
599/// Additionally, common syscalls are excluded if they have a different
600/// implementation when compared to the main arch.
601#[cfg(target_arch = "aarch64")]
602#[macro_export]
603macro_rules! for_each_arch32_syscall {
604    {$callback:ident $(,$context:ident)*} => {
605        $crate::for_each_arch_arch32_syscall!{
606            $callback;
607            $($context;)*
608            ;
609
610            // go/keep-sorted start
611
612            // memfd_secret,  Not yet in our arm uapi
613            _sysctl,
614            accept,
615            accept4,
616            access,  // faccessat
617            acct,
618            add_key,
619            adjtimex,
620            bind,
621            bpf,
622            brk,
623            cachestat,
624            capget,
625            capset,
626            chdir,
627            chroot,
628            clock_adjtime,
629            clock_getres,
630            clock_gettime,
631            clock_nanosleep,
632            clock_settime,
633            clone,
634            clone3,
635            close,
636            close_range,
637            connect,
638            copy_file_range,
639            delete_module,
640            dup,
641            dup3,
642            epoll_create1,
643            epoll_ctl,
644            eventfd2,
645            exit,
646            exit_group,
647            faccessat,
648            faccessat2,
649            fanotify_init,
650            fchdir,
651            fchmod,
652            fchmodat,
653            fchown,
654            fchownat,
655            fdatasync,
656            fgetxattr,
657            finit_module,
658            flistxattr,
659            flock,
660            fremovexattr,
661            fsconfig,
662            fsetxattr,
663            fsmount,
664            fsopen,
665            fspick,
666            fsync,
667            futex,
668            futex_waitv,
669            get_mempolicy,
670            getcpu,
671            getcwd,
672            getdents64,
673            getegid,
674            geteuid,
675            getgid,
676            getgroups,
677            getpeername,
678            getpgid,
679            getpid,
680            getppid,
681            getpriority,
682            getrandom,
683            getresgid,
684            getresuid,
685            getsid,
686            getsockname,
687            getsockopt,
688            gettid,
689            getuid,
690            getuid32,
691            getxattr,
692            init_module,
693            inotify_add_watch,
694            inotify_init1,
695            inotify_rm_watch,
696            io_cancel,
697            io_destroy,
698            io_getevents,
699            io_uring_enter,
700            io_uring_register,
701            io_uring_setup,
702            ioprio_get,
703            ioprio_set,
704            kcmp,
705            kexec_file_load,
706            kill,
707            landlock_add_rule,
708            landlock_create_ruleset,
709            landlock_restrict_self,
710            lgetxattr,
711            linkat,
712            listen,
713            listxattr,
714            llistxattr,
715            lookup_dcookie,
716            lremovexattr,
717            lsetxattr,
718            madvise,
719            mbind,
720            membarrier,
721            memfd_create,
722            migrate_pages,
723            mincore,
724            mkdirat,
725            mknodat,
726            mlock,
727            mlock2,
728            mlockall,
729            mount,
730            mount_setattr,
731            move_mount,
732            move_pages,
733            mprotect,
734            mq_timedreceive,
735            mq_timedsend,
736            mq_unlink,
737            mremap,
738            msgget,
739            msync,
740            munlock,
741            munlockall,
742            munmap,
743            name_to_handle_at,
744            nanosleep,
745            nfsservctl,
746            open_tree,
747            openat2,
748            perf_event_open,
749            personality,
750            pidfd_getfd,
751            pidfd_open,
752            pidfd_send_signal,
753            pipe2,
754            pivot_root,
755            pkey_alloc,
756            pkey_free,
757            pkey_mprotect,
758            prctl,
759            prlimit64,
760            process_madvise,
761            process_mrelease,
762            process_vm_readv,
763            process_vm_writev,
764            quotactl,
765            quotactl_fd,
766            read,
767            readlinkat,
768            readv,
769            reboot,
770            remap_file_pages,
771            removexattr,
772            renameat2,
773            request_key,
774            restart_syscall,
775            rseq,
776            sched_get_priority_max,
777            sched_get_priority_min,
778            sched_getattr,
779            sched_getparam,
780            sched_getscheduler,
781            sched_rr_get_interval,
782            sched_setattr,
783            sched_setparam,
784            sched_setscheduler,
785            sched_yield,
786            seccomp,
787            semget,
788            semop,
789            semtimedop,
790            sendto,
791            set_mempolicy,
792            set_mempolicy_home_node,
793            set_tid_address,
794            setdomainname,
795            setfsgid,
796            setfsuid,
797            setgid,
798            setgroups,
799            sethostname,
800            setns,
801            setpgid,
802            setpriority,
803            setregid,
804            setresgid,
805            setresuid,
806            setreuid,
807            setsid,
808            setsockopt,
809            setuid,
810            setxattr,
811            shmdt,
812            shmget,
813            shutdown,
814            socket,
815            socketpair,
816            splice,
817            statx,
818            swapoff,
819            swapon,
820            symlinkat,
821            sync,
822            syncfs,
823            syslog,
824            tee,
825            tgkill,
826            timer_delete,
827            timer_getoverrun,
828            timer_gettime,
829            timer_settime,
830            timerfd_create,
831            timerfd_gettime,
832            timerfd_settime,
833            tkill,
834            umask,
835            umount2,
836            uname,
837            unlinkat,
838            unshare,
839            userfaultfd,
840            utimensat,
841            vhangup,
842            vmsplice,
843            write,
844            writev,
845
846            // go/keep-sorted end
847        }
848    }
849}
850
851/// A particular invocation of a system call.
852///
853/// Contains the declaration of the invoked system call, as well as which arguments it was invoked
854/// with.
855pub struct Syscall {
856    pub decl: SyscallDecl,
857    pub arg0: SyscallArg,
858    pub arg1: SyscallArg,
859    pub arg2: SyscallArg,
860    pub arg3: SyscallArg,
861    pub arg4: SyscallArg,
862    pub arg5: SyscallArg,
863}
864
865impl std::fmt::Debug for Syscall {
866    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
867        write!(
868            f,
869            "{:?}({:#x}, {:#x}, {:#x}, {:#x}, {:#x}, {:#x})",
870            self.decl, self.arg0, self.arg1, self.arg2, self.arg3, self.arg4, self.arg5
871        )
872    }
873}
874
875/// Evaluates to a string literal for the given syscall number when called back by for_each_syscall.
876#[macro_export]
877macro_rules! syscall_number_to_name_literal_callback {
878    {$number:ident; $($name:ident,)*} => {
879        $crate::__paste::paste! {
880            match $number as u32 {
881                $(starnix_uapi::[<__NR_ $name>] => stringify!($name),)*
882                _ => "<unknown syscall>",
883            }
884        }
885    }
886}
887
888// As above, but for the arch32 namespace.
889#[cfg(target_arch = "aarch64")]
890#[macro_export]
891macro_rules! syscall_arch32_number_to_name_literal_callback {
892    {$number:ident; $($name:ident,)*} => {
893        $crate::__paste::paste! {
894            match $number as u32 {
895                $(starnix_uapi::arch32::[<__NR_ $name>] => stringify!($name),)*
896                _ => "<unknown syscall>",
897            }
898        }
899    }
900}
901
902/// Evaluates to a str literal for the given syscall number when called back by for_each_syscall.
903#[macro_export]
904macro_rules! syscall_number_to_trace_name_callback {
905    {$number:ident; $($name:ident,)*} => {
906        $crate::__paste::paste! {
907            match $number as u32 {
908                $(starnix_uapi::[<__NR_ $name>] => concat!("sys_", stringify!($name)),)*
909                _ => "<unknown syscall>",
910            }
911        }
912    }
913}
914
915// As above, but for the arch32 namespace.
916#[cfg(target_arch = "aarch64")]
917#[macro_export]
918macro_rules! syscall_arch32_number_to_trace_name_callback {
919    {$number:ident; $($name:ident,)*} => {
920        $crate::__paste::paste! {
921            match $number as u32 {
922                $(starnix_uapi::arch32::[<__NR_ $name>] => concat!("sys_", stringify!($name)),)*
923                _ => "<unknown syscall>",
924            }
925        }
926    }
927}
928
929/// A system call declaration.
930///
931/// Describes the name of the syscall and its number.
932#[derive(Copy, Clone)]
933pub struct SyscallDecl {
934    pub number: u64,
935
936    #[cfg_attr(target_arch = "x86_64", allow(unused))]
937    pub arch_width: ArchWidth,
938}
939
940impl SyscallDecl {
941    /// The SyscallDecl for the given syscall number.
942    ///
943    /// Returns &DECL_UNKNOWN if the given syscall number is not known.
944    pub fn from_number(number: u64, arch_width: ArchWidth) -> SyscallDecl {
945        Self { arch_width, number }
946    }
947
948    pub fn name(&self) -> &'static str {
949        // Make a binding because the macro makes it difficult to pass a member variable.
950        let number = self.number;
951
952        #[cfg(target_arch = "aarch64")]
953        if self.arch_width.is_arch32() {
954            return for_each_arch32_syscall! { syscall_arch32_number_to_name_literal_callback, number };
955        }
956
957        for_each_syscall! { syscall_number_to_name_literal_callback, number }
958    }
959
960    pub fn trace_name(&self) -> &'static str {
961        // Make a binding because the macro makes it difficult to pass a member variable.
962        let number = self.number;
963
964        #[cfg(target_arch = "aarch64")]
965        if self.arch_width.is_arch32() {
966            return for_each_arch32_syscall! { syscall_arch32_number_to_trace_name_callback, number };
967        }
968
969        for_each_syscall! { syscall_number_to_trace_name_callback, number }
970    }
971}
972
973impl std::fmt::Debug for SyscallDecl {
974    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
975        write!(f, "{}:{}", self.name(), self.number)
976    }
977}