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            setgid32,
201            setgroups32,
202            setitimer,
203            setregid32,
204            setresgid32,
205            setresuid32,
206            setreuid32,
207            setrlimit,
208            settimeofday,
209            shmat,
210            shmctl,
211            sigaction,
212            sigaltstack,
213            signalfd,
214            signalfd4,
215            sigpending,
216            sigprocmask,
217            sigreturn,
218            stat,
219            stat64,
220            statfs,
221            statfs64,
222            sync_file_range2,
223            sysinfo,
224            timer_create,
225            timer_gettime64,
226            times,
227            truncate,
228            truncate64,
229            ugetrlimit,
230            unlink,
231            ustat,
232            vfork,
233            wait4,
234            waitid,
235
236            // go/keep-sorted end
237        }
238    }
239}
240
241#[cfg(target_arch = "aarch64")]
242#[macro_export]
243macro_rules! for_each_arch_syscall {
244    {$callback:ident; $($context:ident;)* ; $($common_name:ident,)*} => {
245        $callback!{
246            $($context;)*
247            $($common_name,)*
248            renameat,  // renameat2
249        }
250    }
251}
252
253#[cfg(target_arch = "riscv64")]
254#[macro_export]
255macro_rules! for_each_arch_syscall {
256    {$callback:ident; $($context:ident;)* ; $($common_name:ident,)*} => {
257        $callback!{
258            $($context;)*
259            $($common_name,)*
260        }
261    }
262}
263
264/// Intended to be used with other macros to produce code that needs to handle
265/// each syscall.
266///
267/// This list contains all cross-architecture syscalls, and delegates through for_each_arch_syscall!
268/// to add in any architecture-specific ones.
269#[macro_export]
270macro_rules! for_each_syscall {
271    {$callback:ident $(,$context:ident)*} => {
272        $crate::for_each_arch_syscall!{
273            $callback;
274            $($context;)*
275            ;
276
277            // go/keep-sorted start
278
279            accept,
280            accept4,
281            acct,
282            add_key,
283            adjtimex,
284            bind,
285            bpf,
286            brk,
287            cachestat,
288            capget,
289            capset,
290            chdir,
291            chroot,
292            clock_adjtime,
293            clock_getres,
294            clock_gettime,
295            clock_nanosleep,
296            clock_settime,
297            clone,
298            clone3,
299            close,
300            close_range,
301            connect,
302            copy_file_range,
303            delete_module,
304            dup,
305            dup3,
306            epoll_create1,
307            epoll_ctl,
308            epoll_pwait,
309            epoll_pwait2,
310            eventfd2,
311            execve,
312            execveat,
313            exit,
314            exit_group,
315            faccessat,
316            faccessat2,
317            fadvise64,
318            fallocate,
319            fanotify_init,
320            fanotify_mark,
321            fchdir,
322            fchmod,
323            fchmodat,
324            fchown,
325            fchownat,
326            fcntl,
327            fdatasync,
328            fgetxattr,
329            finit_module,
330            flistxattr,
331            flock,
332            fremovexattr,
333            fsconfig,
334            fsetxattr,
335            fsmount,
336            fsopen,
337            fspick,
338            fstat,
339            fstatfs,
340            fsync,
341            ftruncate,
342            futex,
343            futex_waitv,
344            get_mempolicy,
345            get_robust_list,
346            getcpu,
347            getcwd,
348            getdents64,
349            getegid,
350            geteuid,
351            getgid,
352            getgroups,
353            getitimer,
354            getpeername,
355            getpgid,
356            getpid,
357            getppid,
358            getpriority,
359            getrandom,
360            getresgid,
361            getresuid,
362            getrlimit,
363            getrusage,
364            getsid,
365            getsockname,
366            getsockopt,
367            gettid,
368            gettimeofday,
369            getuid,
370            getxattr,
371            init_module,
372            inotify_add_watch,
373            inotify_init1,
374            inotify_rm_watch,
375            io_cancel,
376            io_destroy,
377            io_getevents,
378            io_pgetevents,
379            io_setup,
380            io_submit,
381            io_uring_enter,
382            io_uring_register,
383            io_uring_setup,
384            ioctl,
385            ioprio_get,
386            ioprio_set,
387            kcmp,
388            kexec_file_load,
389            kexec_load,
390            keyctl,
391            kill,
392            landlock_add_rule,
393            landlock_create_ruleset,
394            landlock_restrict_self,
395            lgetxattr,
396            linkat,
397            listen,
398            listxattr,
399            llistxattr,
400            lookup_dcookie,
401            lremovexattr,
402            lseek,
403            lsetxattr,
404            madvise,
405            mbind,
406            membarrier,
407            memfd_create,
408            memfd_secret,
409            migrate_pages,
410            mincore,
411            mkdirat,
412            mknodat,
413            mlock,
414            mlock2,
415            mlockall,
416            mmap,
417            mount,
418            mount_setattr,
419            move_mount,
420            move_pages,
421            mprotect,
422            mq_getsetattr,
423            mq_notify,
424            mq_open,
425            mq_timedreceive,
426            mq_timedsend,
427            mq_unlink,
428            mremap,
429            msgctl,
430            msgget,
431            msgrcv,
432            msgsnd,
433            msync,
434            munlock,
435            munlockall,
436            munmap,
437            name_to_handle_at,
438            nanosleep,
439            newfstatat,
440            nfsservctl,
441            open_by_handle_at,
442            open_tree,
443            openat,
444            openat2,
445            perf_event_open,
446            personality,
447            pidfd_getfd,
448            pidfd_open,
449            pidfd_send_signal,
450            pipe2,
451            pivot_root,
452            pkey_alloc,
453            pkey_free,
454            pkey_mprotect,
455            ppoll,
456            prctl,
457            pread64,
458            preadv,
459            preadv2,
460            prlimit64,
461            process_madvise,
462            process_mrelease,
463            process_vm_readv,
464            process_vm_writev,
465            pselect6,
466            ptrace,
467            pwrite64,
468            pwritev,
469            pwritev2,
470            quotactl,
471            quotactl_fd,
472            read,
473            readahead,
474            readlinkat,
475            readv,
476            reboot,
477            recvfrom,
478            recvmmsg,
479            recvmsg,
480            remap_file_pages,
481            removexattr,
482            renameat2,
483            request_key,
484            restart_syscall,
485            rseq,
486            rt_sigaction,
487            rt_sigpending,
488            rt_sigprocmask,
489            rt_sigqueueinfo,
490            rt_sigreturn,
491            rt_sigsuspend,
492            rt_sigtimedwait,
493            rt_tgsigqueueinfo,
494            sched_get_priority_max,
495            sched_get_priority_min,
496            sched_getaffinity,
497            sched_getattr,
498            sched_getparam,
499            sched_getscheduler,
500            sched_rr_get_interval,
501            sched_setaffinity,
502            sched_setattr,
503            sched_setparam,
504            sched_setscheduler,
505            sched_yield,
506            seccomp,
507            semctl,
508            semget,
509            semop,
510            semtimedop,
511            sendfile,
512            sendmmsg,
513            sendmsg,
514            sendto,
515            set_mempolicy,
516            set_mempolicy_home_node,
517            set_robust_list,
518            set_tid_address,
519            setdomainname,
520            setfsgid,
521            setfsuid,
522            setgid,
523            setgroups,
524            sethostname,
525            setitimer,
526            setns,
527            setpgid,
528            setpriority,
529            setregid,
530            setresgid,
531            setresuid,
532            setreuid,
533            setrlimit,
534            setsid,
535            setsockopt,
536            settimeofday,
537            setuid,
538            setxattr,
539            shmat,
540            shmctl,
541            shmdt,
542            shmget,
543            shutdown,
544            sigaltstack,
545            signalfd4,
546            socket,
547            socketpair,
548            splice,
549            statfs,
550            statx,
551            swapoff,
552            swapon,
553            symlinkat,
554            sync,
555            sync_file_range,
556            syncfs,
557            sysinfo,
558            syslog,
559            tee,
560            tgkill,
561            timer_create,
562            timer_delete,
563            timer_getoverrun,
564            timer_gettime,
565            timer_settime,
566            timerfd_create,
567            timerfd_gettime,
568            timerfd_settime,
569            times,
570            tkill,
571            truncate,
572            umask,
573            umount2,
574            uname,
575            unlinkat,
576            unshare,
577            userfaultfd,
578            utimensat,
579            vhangup,
580            vmsplice,
581            wait4,
582            waitid,
583            write,
584            writev,
585
586            // go/keep-sorted end
587        }
588    }
589}
590
591/// As above, but this calls through for the arch32 for arch support.
592/// It's worth noting that common syscalls above are not common across
593/// arches like x86 or arm.  The common list below reflects only
594/// those common across arch32 arches.
595///
596/// Additionally, common syscalls are excluded if they have a different
597/// implementation when compared to the main arch.
598#[cfg(target_arch = "aarch64")]
599#[macro_export]
600macro_rules! for_each_arch32_syscall {
601    {$callback:ident $(,$context:ident)*} => {
602        $crate::for_each_arch_arch32_syscall!{
603            $callback;
604            $($context;)*
605            ;
606
607            // go/keep-sorted start
608
609            // memfd_secret,  Not yet in our arm uapi
610            _sysctl,
611            accept,
612            accept4,
613            access,  // faccessat
614            acct,
615            add_key,
616            adjtimex,
617            bind,
618            bpf,
619            brk,
620            cachestat,
621            capget,
622            capset,
623            chdir,
624            chroot,
625            clock_adjtime,
626            clock_getres,
627            clock_gettime,
628            clock_nanosleep,
629            clock_settime,
630            clone,
631            clone3,
632            close,
633            close_range,
634            connect,
635            copy_file_range,
636            delete_module,
637            dup,
638            dup3,
639            epoll_create1,
640            epoll_ctl,
641            eventfd2,
642            exit,
643            exit_group,
644            faccessat,
645            faccessat2,
646            fanotify_init,
647            fchdir,
648            fchmod,
649            fchmodat,
650            fchown,
651            fchownat,
652            fdatasync,
653            fgetxattr,
654            finit_module,
655            flistxattr,
656            flock,
657            fremovexattr,
658            fsconfig,
659            fsetxattr,
660            fsmount,
661            fsopen,
662            fspick,
663            fsync,
664            futex,
665            futex_waitv,
666            get_mempolicy,
667            getcpu,
668            getcwd,
669            getdents64,
670            getegid,
671            geteuid,
672            getgid,
673            getgroups,
674            getpeername,
675            getpgid,
676            getpid,
677            getppid,
678            getpriority,
679            getrandom,
680            getresgid,
681            getresuid,
682            getsid,
683            getsockname,
684            getsockopt,
685            gettid,
686            getuid,
687            getuid32,
688            getxattr,
689            init_module,
690            inotify_add_watch,
691            inotify_init1,
692            inotify_rm_watch,
693            io_cancel,
694            io_destroy,
695            io_getevents,
696            io_uring_enter,
697            io_uring_register,
698            io_uring_setup,
699            ioprio_get,
700            ioprio_set,
701            kcmp,
702            kexec_file_load,
703            kill,
704            landlock_add_rule,
705            landlock_create_ruleset,
706            landlock_restrict_self,
707            lgetxattr,
708            linkat,
709            listen,
710            listxattr,
711            llistxattr,
712            lookup_dcookie,
713            lremovexattr,
714            lsetxattr,
715            madvise,
716            mbind,
717            membarrier,
718            memfd_create,
719            migrate_pages,
720            mincore,
721            mkdirat,
722            mknodat,
723            mlock,
724            mlock2,
725            mlockall,
726            mount,
727            mount_setattr,
728            move_mount,
729            move_pages,
730            mprotect,
731            mq_timedreceive,
732            mq_timedsend,
733            mq_unlink,
734            mremap,
735            msgget,
736            msync,
737            munlock,
738            munlockall,
739            munmap,
740            name_to_handle_at,
741            nanosleep,
742            nfsservctl,
743            open_tree,
744            openat2,
745            perf_event_open,
746            personality,
747            pidfd_getfd,
748            pidfd_open,
749            pidfd_send_signal,
750            pipe2,
751            pivot_root,
752            pkey_alloc,
753            pkey_free,
754            pkey_mprotect,
755            prctl,
756            prlimit64,
757            process_madvise,
758            process_mrelease,
759            process_vm_readv,
760            process_vm_writev,
761            quotactl,
762            quotactl_fd,
763            read,
764            readlinkat,
765            readv,
766            reboot,
767            remap_file_pages,
768            removexattr,
769            renameat2,
770            request_key,
771            restart_syscall,
772            rseq,
773            sched_get_priority_max,
774            sched_get_priority_min,
775            sched_getattr,
776            sched_getparam,
777            sched_getscheduler,
778            sched_rr_get_interval,
779            sched_setattr,
780            sched_setparam,
781            sched_setscheduler,
782            sched_yield,
783            seccomp,
784            semget,
785            semop,
786            semtimedop,
787            sendto,
788            set_mempolicy,
789            set_mempolicy_home_node,
790            set_tid_address,
791            setdomainname,
792            setfsgid,
793            setfsuid,
794            setgid,
795            setgroups,
796            sethostname,
797            setns,
798            setpgid,
799            setpriority,
800            setregid,
801            setresgid,
802            setresuid,
803            setreuid,
804            setsid,
805            setsockopt,
806            setuid,
807            setxattr,
808            shmdt,
809            shmget,
810            shutdown,
811            socket,
812            socketpair,
813            splice,
814            statx,
815            swapoff,
816            swapon,
817            symlinkat,
818            sync,
819            syncfs,
820            syslog,
821            tee,
822            tgkill,
823            timer_delete,
824            timer_getoverrun,
825            timer_gettime,
826            timer_settime,
827            timerfd_create,
828            timerfd_gettime,
829            timerfd_settime,
830            tkill,
831            umask,
832            umount2,
833            uname,
834            unlinkat,
835            unshare,
836            userfaultfd,
837            utimensat,
838            vhangup,
839            vmsplice,
840            write,
841            writev,
842
843            // go/keep-sorted end
844        }
845    }
846}
847
848/// A particular invocation of a system call.
849///
850/// Contains the declaration of the invoked system call, as well as which arguments it was invoked
851/// with.
852pub struct Syscall {
853    pub decl: SyscallDecl,
854    pub arg0: SyscallArg,
855    pub arg1: SyscallArg,
856    pub arg2: SyscallArg,
857    pub arg3: SyscallArg,
858    pub arg4: SyscallArg,
859    pub arg5: SyscallArg,
860}
861
862impl std::fmt::Debug for Syscall {
863    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
864        write!(
865            f,
866            "{:?}({:#x}, {:#x}, {:#x}, {:#x}, {:#x}, {:#x})",
867            self.decl, self.arg0, self.arg1, self.arg2, self.arg3, self.arg4, self.arg5
868        )
869    }
870}
871
872/// Evaluates to a string literal for the given syscall number when called back by for_each_syscall.
873#[macro_export]
874macro_rules! syscall_number_to_name_literal_callback {
875    {$number:ident; $($name:ident,)*} => {
876        $crate::__paste::paste! {
877            match $number as u32 {
878                $(starnix_uapi::[<__NR_ $name>] => stringify!($name),)*
879                _ => "<unknown syscall>",
880            }
881        }
882    }
883}
884
885// As above, but for the arch32 namespace.
886#[cfg(target_arch = "aarch64")]
887#[macro_export]
888macro_rules! syscall_arch32_number_to_name_literal_callback {
889    {$number:ident; $($name:ident,)*} => {
890        $crate::__paste::paste! {
891            match $number as u32 {
892                $(starnix_uapi::arch32::[<__NR_ $name>] => stringify!($name),)*
893                _ => "<unknown syscall>",
894            }
895        }
896    }
897}
898
899/// Evaluates to a str literal for the given syscall number when called back by for_each_syscall.
900#[macro_export]
901macro_rules! syscall_number_to_trace_name_callback {
902    {$number:ident; $($name:ident,)*} => {
903        $crate::__paste::paste! {
904            match $number as u32 {
905                $(starnix_uapi::[<__NR_ $name>] => concat!("sys_", stringify!($name)),)*
906                _ => "<unknown syscall>",
907            }
908        }
909    }
910}
911
912// As above, but for the arch32 namespace.
913#[cfg(target_arch = "aarch64")]
914#[macro_export]
915macro_rules! syscall_arch32_number_to_trace_name_callback {
916    {$number:ident; $($name:ident,)*} => {
917        $crate::__paste::paste! {
918            match $number as u32 {
919                $(starnix_uapi::arch32::[<__NR_ $name>] => concat!("sys_", stringify!($name)),)*
920                _ => "<unknown syscall>",
921            }
922        }
923    }
924}
925
926/// A system call declaration.
927///
928/// Describes the name of the syscall and its number.
929#[derive(Copy, Clone)]
930pub struct SyscallDecl {
931    pub number: u64,
932
933    #[cfg_attr(target_arch = "x86_64", allow(unused))]
934    pub arch_width: ArchWidth,
935}
936
937impl SyscallDecl {
938    /// The SyscallDecl for the given syscall number.
939    ///
940    /// Returns &DECL_UNKNOWN if the given syscall number is not known.
941    pub fn from_number(number: u64, arch_width: ArchWidth) -> SyscallDecl {
942        Self { arch_width, number }
943    }
944
945    pub fn name(&self) -> &'static str {
946        // Make a binding because the macro makes it difficult to pass a member variable.
947        let number = self.number;
948
949        #[cfg(target_arch = "aarch64")]
950        if self.arch_width.is_arch32() {
951            return for_each_arch32_syscall! { syscall_arch32_number_to_name_literal_callback, number };
952        }
953
954        for_each_syscall! { syscall_number_to_name_literal_callback, number }
955    }
956
957    pub fn trace_name(&self) -> &'static str {
958        // Make a binding because the macro makes it difficult to pass a member variable.
959        let number = self.number;
960
961        #[cfg(target_arch = "aarch64")]
962        if self.arch_width.is_arch32() {
963            return for_each_arch32_syscall! { syscall_arch32_number_to_trace_name_callback, number };
964        }
965
966        for_each_syscall! { syscall_number_to_trace_name_callback, number }
967    }
968}
969
970impl std::fmt::Debug for SyscallDecl {
971    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
972        write!(f, "{}:{}", self.name(), self.number)
973    }
974}