ptrace_syscalls/
syscalls.rs

1#![allow(non_upper_case_globals)]
2#![allow(unused)]
3
4use std::path::PathBuf;
5use std::{
6  ffi::{c_int, CString},
7  os::fd::RawFd,
8};
9
10use crate::{
11  arch::{syscall_arg, syscall_no_from_regs, syscall_res_from_regs, PtraceRegisters},
12  types::*,
13  InspectCountedFromPid, InspectDynSizedFromPid, InspectError, InspectFromPid, InspectResult, SyscallNumber,
14  SyscallStopInspect,
15};
16use crate::{ptrace_getregs, SyscallGroups, SyscallGroupsGetter};
17use enumflags2::BitFlags;
18use nix::errno::Errno;
19use nix::libc::{
20  c_char, c_long, c_uchar, c_uint, c_ulong, c_void, clock_t, clockid_t, clone_args, dev_t, epoll_event, fd_set, gid_t,
21  id_t, idtype_t, iocb, iovec, itimerspec, itimerval, key_t, loff_t, mmsghdr, mode_t, mq_attr, mqd_t, msghdr, msqid_ds,
22  nfds_t, off_t, open_how, pid_t, pollfd, rlimit, rlimit64, rusage, sched_attr, sched_param, sembuf, shmid_ds,
23  sigaction, sigevent, siginfo_t, sigset_t, size_t, sockaddr, socklen_t, ssize_t, stack_t, stat, statfs, statx,
24  sysinfo, time_t, timer_t, timespec, timeval, timex, tms, uid_t, utimbuf, utsname,
25};
26use nix::sys::ptrace::AddressType;
27use nix::unistd::Pid;
28use ptrace_syscalls_macros::gen_syscalls;
29use std::mem::size_of;
30use std::sync::Arc;
31
32#[derive(Debug, Clone, Copy, PartialEq)]
33pub struct UnknownArgs {
34  pub number: isize,
35  pub args: [usize; 6],
36}
37
38impl UnknownArgs {
39  fn from_regs(regs: &PtraceRegisters) -> Self {
40    let number = syscall_no_from_regs!(regs) as isize;
41    let args = [
42      syscall_arg!(regs, 0) as usize,
43      syscall_arg!(regs, 1) as usize,
44      syscall_arg!(regs, 2) as usize,
45      syscall_arg!(regs, 3) as usize,
46      syscall_arg!(regs, 4) as usize,
47      syscall_arg!(regs, 5) as usize,
48    ];
49    UnknownArgs { number, args }
50  }
51}
52
53impl SyscallNumber for UnknownArgs {
54  fn syscall_number(&self) -> isize {
55    self.number
56  }
57}
58
59impl SyscallGroupsGetter for UnknownArgs {
60  fn syscall_groups(&self) -> BitFlags<SyscallGroups> {
61    BitFlags::empty()
62  }
63}
64
65pub type Unit = ();
66
67gen_syscalls! {
68  // _llseek (32bit)
69  // _newselect
70  accept(socketfd: c_int, addr: *mut sockaddr, addrlen: *mut socklen_t) /
71    { socketfd: RawFd, addr: sockaddr, addrlen: InspectResult<socklen_t> } -> c_int + { addr: sockaddr, addrlen: InspectResult<socklen_t> }
72    ~ [Network] for [x86_64: 43, aarch64: 202, riscv64: 202],
73  accept4(socketfd: RawFd, addr: *mut sockaddr, addrlen: *mut socklen_t, flags: c_int) /
74    { socketfd: RawFd, addr: sockaddr, addrlen: InspectResult<socklen_t>, flags: c_int } -> c_int + { addr: sockaddr, addrlen: InspectResult<socklen_t> }
75    ~ [Network] for [x86_64: 288, aarch64: 242, riscv64: 242],
76  access(pathname: *const c_char, mode: c_int) / { pathname: PathBuf, mode: c_int } -> c_int ~ [File] for [x86_64: 21],
77  acct(filename: *const c_char) / { filename: Option<PathBuf> } -> c_int ~ [File] for [x86_64: 163, aarch64: 89, riscv64: 89],
78  add_key(r#type: *const c_char, description: *const c_char, payload: *const c_void, plen: size_t, keyring: key_serial_t ) /
79    { r#type: CString, description: CString, payload: Vec<u8> @ counted_by(raw_args.plen), keyring: key_serial_t }
80    -> key_serial_t ~ [] for [x86_64: 248, aarch64: 217, riscv64: 217],
81  adjtimex(buf: *mut timex) / { buf: timex } -> c_int ~ [Clock] for [x86_64: 159, aarch64: 171, riscv64: 171],
82  alarm(seconds: c_uint) / { seconds: c_uint } -> c_uint ~ [] for [x86_64: 37],
83  // arc_gettls, arc_settls, arc_usr_cmpxchg
84  arch_prctl(code: c_int, addr: c_ulong) / {} -> c_int ~ [] for [x86_64: 158], // TODO: addr can be a ptr
85  // arm_fadvise64_64, atomic_barrier, atomic_barrier
86  bind(socketfd: RawFd, addr: *const sockaddr, addrlen: socklen_t) /
87    { socketfd: RawFd, addr: sockaddr, addrlen: socklen_t } -> c_int ~ [Network] for [x86_64: 49, aarch64: 200, riscv64: 200],
88  // TODO: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/bpf.h#L1454 and https://www.man7.org/linux/man-pages/man2/bpf.2.html
89  bpf(cmd: c_int, attr: *mut c_void, size: c_uint) /
90    { cmd: c_int, attr: Vec<u8> @ counted_by(raw_args.size) } -> c_int ~ [Desc] for [x86_64: 321, aarch64: 280, riscv64: 280],
91  brk(addr: *mut c_void) / { addr: AddressType } -> c_int ~ [Memory] for [x86_64: 12, aarch64: 214, riscv64: 214],
92  // cachectl, cacheflush
93  // cachestat: TODO: https://github.com/golang/go/issues/61917
94  cachestat(fd: RawFd, cstat_range: *mut cachestat_range, cstat: *mut cachestat, flags: c_uint) /
95    { fd: RawFd, cstat_range: cachestat_range, cstat: cachestat, flags: c_uint } -> c_int
96    ~ [Desc] for [x86_64: 451, aarch64: 451, riscv64: 451],
97  capget(hdrp: *mut cap_user_header, datap: *mut cap_user_data) / { } -> c_int +
98    { hdrp: cap_user_header, datap: cap_user_data } ~ [Creds] for [x86_64: 125, aarch64: 90, riscv64: 90],
99  capset(hdrp: *mut cap_user_header, datap: *const cap_user_data) /
100    { hdrp: cap_user_header, datap: cap_user_data } -> c_int ~ [Creds] for [x86_64: 126, aarch64: 91, riscv64: 91],
101  chdir(path: *const c_char) / { path: PathBuf } -> c_int ~ [File] for [x86_64: 80, aarch64: 49, riscv64: 49],
102  chmod(pathname: *const c_char, mode: mode_t) / { pathname: PathBuf, mode: mode_t } -> c_int ~ [File] for [x86_64: 90],
103  chown(pathname: *const c_char, owner: uid_t, group: gid_t)
104    / { pathname: PathBuf, owner: uid_t, group: gid_t } -> c_int ~ [File] for [x86_64: 92],
105  // chown32
106  chroot(path: *const c_char) / { path: PathBuf } -> c_int ~ [File] for [x86_64: 161, aarch64: 51, riscv64: 51],
107  clock_adjtime(clk_id: clockid_t, buf: *mut timex) / { clk_id: clockid_t, buf: timex } -> c_int ~ [Clock] for [x86_64: 305, aarch64: 266, riscv64: 266],
108  // clock_adjtime64
109  clock_getres(clk_id: clockid_t, res: *mut timespec) / { clk_id: clockid_t }
110    -> c_int + { res: Option<timespec> } ~ [Clock] for [x86_64: 229, aarch64: 114, riscv64: 114],
111  // clock_getres_time64
112  clock_gettime(clk_id: clockid_t, tp: *mut timespec) / { clk_id: clockid_t }
113    -> c_int + { tp: timespec } ~ [Clock] for [x86_64: 228, aarch64: 113, riscv64: 113],
114  // clock_gettime64
115  clock_nanosleep(clockid: clockid_t, flags: c_int, request: *const timespec, remain: *mut timespec) /
116  { clockid: clockid_t, flags: c_int, request: timespec } -> c_int + { remain: Option<timespec> }
117    ~ [] for [x86_64: 230, aarch64: 115, riscv64: 115],
118  // clock_nanosleep_time64
119  clock_settime(clk_id: clockid_t, tp: *const timespec) / { clk_id: clockid_t, tp: timespec } -> c_int
120    ~ [Clock] for [x86_64: 227, aarch64: 112, riscv64: 112],
121  // clock_settime64
122  // clone, the arguments vary for different architectures.
123  clone(flags: c_ulong, stack: AddressType, parent_tid: *mut pid_t, child_tid: *mut pid_t, tls: c_ulong) /
124   { flags: c_ulong, stack: AddressType, tls: c_ulong } -> c_long +
125   { parent_tid: InspectResult<pid_t>, child_tid: InspectResult<pid_t> } ~ [Process] for [x86_64: 56],
126  clone(flags: c_ulong, stack: AddressType, parent_tid: *mut pid_t, tls: c_ulong, child_tid: *mut pid_t) /
127   { flags: c_ulong, stack: AddressType, tls: c_ulong } -> c_long +
128   { parent_tid: InspectResult<pid_t>, child_tid: InspectResult<pid_t> } ~ [Process] for [aarch64: 220, riscv64: 220],
129  clone3(cl_args: *mut clone_args, size: size_t) / { cl_args: clone_args, size: size_t } -> c_int ~ [Process] for [x86_64: 435, aarch64: 435, riscv64: 435],
130  close(fd: RawFd) / { fd: RawFd } -> c_int ~ [Desc] for [x86_64: 3, aarch64: 57, riscv64: 57],
131  close_range(first: c_uint, last: c_uint, flags: c_uint) / { first: c_uint, last: c_uint, flags: c_uint }
132    -> c_int ~ [] for [x86_64: 436, aarch64: 436, riscv64: 436],
133  connect(sockfd: RawFd, addr: *const sockaddr, addrlen: socklen_t) /
134    { sockfd: RawFd, addr: sockaddr, addrlen: socklen_t } -> c_int ~ [Network] for [x86_64: 42, aarch64: 203, riscv64: 203],
135  copy_file_range(fd_in: RawFd, off_in: *mut off_t, fd_out: RawFd, off_out: *mut off_t, len: size_t, flags: c_uint) /
136    { fd_in: RawFd, off_in: InspectResult<off_t>, fd_out: RawFd, off_out: InspectResult<off_t>, len: size_t, flags: c_uint }
137    -> ssize_t + { off_in: InspectResult<off_t>, off_out: InspectResult<off_t> } ~ [Desc] for [x86_64: 326, aarch64: 285, riscv64: 285],
138  creat(pathname: *const c_char, mode: mode_t) / { pathname: PathBuf, mode: mode_t } -> RawFd ~ [Desc, File] for [x86_64: 85],
139  delete_module(name: *const c_char, flags: c_uint) / { name: CString, flags: c_uint } -> c_int ~ [] for [x86_64: 176, aarch64: 106, riscv64: 106],
140  // dipc
141  dup(oldfd: RawFd) / { oldfd: RawFd } -> c_int ~ [Desc] for [x86_64: 32, aarch64: 23, riscv64: 23],
142  dup2(oldfd: RawFd, newfd: RawFd) / { oldfd: RawFd, newfd: RawFd } -> c_int ~ [Desc] for [x86_64: 33, aarch64: 24, riscv64: 24],
143  dup3(oldfd: RawFd, newfd: RawFd, flags: c_int) / { oldfd: RawFd, newfd: RawFd, flags: c_int } -> c_int ~ [Desc] for [x86_64: 292, aarch64: 24, riscv64: 24],
144  epoll_create(size: c_int) / { size: c_int } -> c_int ~ [Desc] for [x86_64: 213],
145  epoll_create1(flags: c_int) / { flags: c_int } -> c_int ~ [Desc] for [x86_64: 291, aarch64: 20, riscv64: 20],
146  epoll_ctl(epfd: RawFd, op: c_int, fd: RawFd, event: *mut epoll_event) /
147    { epfd: RawFd, op: c_int, fd: RawFd, event: epoll_event } -> c_int ~ [Desc] for [x86_64: 233, aarch64: 21, riscv64: 21],
148  // TODO: epoll_ctl_old
149  // epoll_ctl_old(epfd: RawFd, op: c_int, fd: RawFd, event: *mut epoll_event) /
150  //   { epfd: RawFd, op: c_int, fd: RawFd, event: epoll_event } -> c_int for [x86_64: 214],
151  epoll_pwait(epfd: RawFd, events: *mut epoll_event, maxevents: c_int, timeout: c_int, sigmask: *const sigset_t) /
152    { epfd: RawFd, maxevents: c_int, timeout: c_int, sigmask: sigset_t }
153    -> c_int + { events: Vec<epoll_event> @ counted_by(syscall_result) } ~ [Desc] for [x86_64: 281, aarch64: 22, riscv64: 22],
154  epoll_pwait2(epfd: RawFd, events: *mut epoll_event, maxevents: c_int, timeout: *const timespec, sigmask: *const sigset_t) /
155    { epfd: RawFd, maxevents: c_int, timeout: Option<timespec>, sigmask: sigset_t }
156    -> c_int + { events: Vec<epoll_event> @ counted_by(syscall_result) } ~ [Desc] for [x86_64: 441, aarch64: 441, riscv64: 441],
157  epoll_wait(epfd: RawFd, events: *mut epoll_event, maxevents: c_int, timeout: c_int) /
158    { epfd: RawFd, maxevents: c_int, timeout: c_int }
159    -> c_int + { events: Vec<epoll_event> @ counted_by(syscall_result) } ~ [Desc] for [x86_64: 232],
160  // TODO: epoll_wait_old
161  // epoll_wait_old(epfd: RawFd, events: *mut epoll_event, maxevents: c_int, timeout: c_int) /
162  //   { epfd: RawFd, maxevents: c_int, timeout: c_int }
163  //   -> c_int + { events: Vec<epoll_event> } for [x86_64: 215],
164  eventfd(initval: c_uint) / { initval: c_uint } -> RawFd ~ [Desc] for [x86_64: 284],
165  eventfd2(initval: c_uint, flags: c_int) / { initval: c_uint, flags: c_int } -> RawFd ~ [Desc] for [x86_64: 290, aarch64: 19, riscv64: 19],
166  // exec_with_loader, execv
167  execve(filename: *const c_char, argv: *const *const c_char, envp: *const *const c_char) /
168    { filename: PathBuf, argv: Option<Vec<CString>>, envp: Option<Vec<CString>> } -> c_int
169    ~ [File, Process] for [x86_64: 59, aarch64: 221, riscv64: 221],
170  execveat(dirfd: RawFd, pathname: *const c_char, argv: *const *const c_char, envp: *const *const c_char, flags: c_int) /
171    { dirfd: RawFd, pathname: PathBuf, argv: Option<Vec<CString>>, envp: Option<Vec<CString>>, flags: c_int }
172    -> c_int ~ [Desc, File, Process] for [x86_64: 322, aarch64: 281, riscv64: 281],
173  exit(status: c_int) / { status: c_int } -> Unit ~ [Process] for [x86_64: 60, aarch64: 93, riscv64: 93],
174  exit_group(status: c_int) / { status: c_int } -> Unit ~ [Process] for [x86_64: 231, aarch64: 94, riscv64: 94],
175  faccessat(dirfd: RawFd, pathname: *const c_char, mode: c_int) /
176    { dirfd: RawFd, pathname: PathBuf, mode: c_int } -> c_int ~ [Desc, File] for [x86_64: 269, aarch64: 48, riscv64: 48],
177  faccessat2(dirfd: RawFd, pathname: *const c_char, mode: c_int, flags: c_int) /
178    { dirfd: RawFd, pathname: PathBuf, mode: c_int, flags: c_int } -> c_int ~ [Desc, File] for [x86_64: 439, aarch64: 439, riscv64: 439],
179  fadvise64(fd: RawFd, offset: off_t, len: size_t, advice: c_int) /
180    { fd: RawFd, offset: off_t, len: size_t, advice: c_int } -> c_int ~ [Desc] for [x86_64: 221, aarch64: 223, riscv64: 223],
181  // fadvise64_64(fd: RawFd, offset: off_t, len: off_t, advice: c_int) /
182  //   { fd: RawFd, offset: off_t, len: off_t, advice: c_int } -> c_int ~ [Desc] for [],
183  fallocate(fd: RawFd, mode: c_int, offset: off_t, len: off_t) /
184    { fd: RawFd, mode: c_int, offset: off_t, len: off_t } -> c_int ~ [Desc] for [x86_64: 285, aarch64: 47, riscv64: 47],
185  fanotify_init(flags: c_uint, event_f_flags: c_uint) /
186    { flags: c_uint, event_f_flags: c_uint } -> RawFd ~ [Desc] for [x86_64: 300, aarch64: 262, riscv64: 262],
187  fanotify_mark(fanotify_fd: RawFd, flags: c_uint, mask: u64, dirfd: RawFd, pathname: *const c_char) /
188    { fanotify_fd: RawFd, flags: c_uint, mask: u64, dirfd: RawFd, pathname: Option<PathBuf> } -> c_int ~ [Desc, File] for [x86_64: 301, aarch64: 263, riscv64: 263],
189  fchdir(fd: RawFd) / { fd: RawFd } -> c_int ~ [Desc] for [x86_64: 81, aarch64: 50, riscv64: 50],
190  fchmod(fd: RawFd, mode: mode_t) / { fd: RawFd, mode: mode_t } -> c_int ~ [Desc] for [x86_64: 91, aarch64: 52, riscv64: 52],
191  fchmodat(dirfd: RawFd, pathname: *const c_char, mode: mode_t) /
192    { dirfd: RawFd, pathname: PathBuf, mode: mode_t } -> c_int ~ [Desc, File] for [x86_64: 268, aarch64: 53, riscv64: 53],
193  fchmodat2(dirfd: RawFd, pathname: *const c_char, mode: mode_t, flags: c_int) /
194    { dirfd: RawFd, pathname: PathBuf, mode: mode_t, flags: c_int } -> c_int ~ [Desc, File] for [x86_64: 452, aarch64: 452, riscv64: 452],
195  fchown(fd: RawFd, owner: uid_t, group: gid_t) / { fd: RawFd, owner: uid_t, group: gid_t } -> c_int ~ [Desc] for [x86_64: 93, aarch64: 55, riscv64: 55],
196  // fchown32
197  fchownat(dirfd: RawFd, pathname: *const c_char, owner: uid_t, group: gid_t, flags: c_int) /
198    { dirfd: RawFd, pathname: PathBuf, owner: uid_t, group: gid_t, flags: c_int } -> c_int ~ [Desc, File] for [x86_64: 260, aarch64: 54, riscv64: 54],
199  fcntl(fd: RawFd, cmd: c_int, arg: usize) / { fd: RawFd, cmd: c_int, arg: usize } -> c_int ~ [Desc] for [x86_64: 72, aarch64: 25, riscv64: 25],
200  // fcntl64
201  fdatasync(fd: RawFd) / { fd: RawFd } -> c_int ~ [Desc] for [x86_64: 75, aarch64: 83, riscv64: 83],
202  fgetxattr(fd: RawFd, name: *const c_char, value: *mut c_void, size: size_t) /
203    { fd: RawFd, name: CString, value: CString, size: size_t } -> ssize_t ~ [Desc] for [x86_64: 193, aarch64: 10, riscv64: 10],
204  finit_module(fd: RawFd, param_values: *const c_char, flags: c_int) /
205    { fd: RawFd, param_values: CString, flags: c_int } -> c_int ~ [Desc] for [x86_64: 313, aarch64: 273, riscv64: 273],
206  flistxattr(fd: RawFd, list: *mut c_char, size: size_t) /
207    { fd: RawFd, list: Option<CString>, size: size_t } -> ssize_t ~ [Desc] for [x86_64: 196, aarch64: 13, riscv64: 13],
208  flock(fd: RawFd, operation: c_int) / { fd: RawFd, operation: c_int } -> c_int ~ [Desc] for [x86_64: 73, aarch64: 32, riscv64: 32],
209  fork() / {} -> pid_t ~ [Process] for [x86_64: 57],
210  fremovexattr(fd: RawFd, name: *const c_char) / { fd: RawFd, name: CString } -> c_int ~ [Desc] for [x86_64: 199, aarch64: 16, riscv64: 16],
211  // fsconfig: https://go-review.googlesource.com/c/sys/+/484995 and https://lwn.net/Articles/766155/
212  fsconfig(fd: RawFd, cmd: c_uint, key: *const c_char, value: *const c_char, aux: c_int) /
213    { fd: RawFd, cmd: c_uint, key: CString, value: CString, aux: c_int } -> c_int ~ [Desc, File] for [x86_64: 431, aarch64: 431, riscv64: 431],
214  fsetxattr(fd: RawFd, name: *const c_char, value: *const c_void, size: size_t, flags: c_int) /
215    { fd: RawFd, name: CString, value: CString, size: size_t, flags: c_int } -> c_int ~ [Desc] for [x86_64: 190, aarch64: 7, riscv64: 7],
216  // https://lwn.net/Articles/759499/
217  fsmount(fd: RawFd, flags: c_uint, ms_flags: c_uint) /
218    { fd: RawFd, flags: c_uint, ms_flags: c_uint } -> c_int ~ [Desc] for [x86_64: 432, aarch64: 432, riscv64: 432],
219  fsopen(fsname: *const c_char, flags: c_uint) / { fsname: CString, flags: c_uint } -> c_int ~ [Desc] for [x86_64: 430, aarch64: 430, riscv64: 430],
220  fspick(dirfd: RawFd, pathname: *const c_char, flags: c_uint) / { dirfd: RawFd, pathname: CString, flags: c_uint } -> c_int
221    ~ [Desc, File] for [x86_64: 433, aarch64: 433, riscv64: 433],
222  fstat(fd: RawFd, statbuf: *mut stat) / { fd: RawFd } -> c_int + { statbuf: stat } ~ [Desc, FStat, StatLike] for [x86_64: 5, aarch64: 80, riscv64: 80],
223  // fstat64, fstatat64
224  fstatfs(fd: RawFd, buf: *mut statfs) / { fd: RawFd } -> c_int + { buf: statfs } ~ [Desc, FStatFs, StatFsLike] for [x86_64: 138, aarch64: 44, riscv64: 44],
225  // fstatfs64
226  fsync(fd: RawFd) / { fd: RawFd } -> c_int ~ [Desc] for [x86_64: 74, aarch64: 82, riscv64: 82],
227  ftruncate(fd: RawFd, length: off_t) / { fd: RawFd, length: off_t } -> c_int ~ [Desc] for [x86_64: 77, aarch64: 46, riscv64: 46],
228  // ftruncate64
229  // futex: val2 can be a pointer to timespec or a u32 value. val2, uaddr2 and val3 is optional for some ops. TODO: design a better rust interface
230  futex(uaddr: *mut u32, futex_op: c_int, val: u32, val2: usize, uaddr2: *mut u32, val3: u32) /
231    { uaddr: InspectResult<u32>, futex_op: c_int, val: u32, val2: usize, uaddr2: InspectResult<u32>, val3: u32 }
232    -> c_long + { uaddr: InspectResult<u32>, uaddr2: InspectResult<u32> } ~ [] for [x86_64: 202, aarch64: 98, riscv64: 98],
233  // https://elixir.bootlin.com/linux/v6.9.3/source/include/linux/syscalls.h#L568
234  // futex_requeue: waiters is always a two-element array of futex_waitv. TODO: design a better rust interface
235  futex_requeue(waiters: *mut futex_waitv, flags: c_uint, nr_wake: c_int, nr_requeue: c_int) /
236    { waiters: [futex_waitv; 2], flags: c_uint, nr_wake: c_int, nr_requeue: c_int }
237    -> c_long + { waiters: [futex_waitv; 2] } ~ [] for [x86_64: 456, aarch64: 456, riscv64: 456],
238  // futex_time64
239  futex_wait(uaddr: *mut u32, val: c_ulong, mask: c_ulong, flags: c_uint, timespec: *mut timespec, clockid: clockid_t) /
240    { uaddr: InspectResult<u32>, val: c_ulong, mask: c_ulong, flags: c_uint, timespec: timespec, clockid: clockid_t }
241    -> c_long + { uaddr: InspectResult<u32> } ~ [] for [x86_64: 455, aarch64: 455, riscv64: 455],
242  futex_waitv(waiters: *mut futex_waitv, nr_futexes: c_uint, flags: c_uint, timeout: *mut timespec, clockid: clockid_t) /
243    { waiters: Vec<futex_waitv> @ counted_by(raw_args.nr_futexes), flags: c_uint, timeout: timespec, clockid: clockid_t }
244    -> c_long + { waiters: Vec<futex_waitv> @ counted_by(raw_args.nr_futexes) } ~ [] for [x86_64: 449, aarch64: 449, riscv64: 449],
245  futex_wake(uaddr: *mut u32, mask: c_ulong, nr: c_int, flags: c_uint) /
246    { uaddr: InspectResult<u32>, mask: c_ulong, nr: c_int, flags: c_uint }
247    -> c_long + { uaddr: InspectResult<u32> } ~ [] for [x86_64: 454, aarch64: 454, riscv64: 454],
248  futimesat(dirfd: RawFd, pathname: *const c_char, times: *const timeval) /
249    { dirfd: RawFd, pathname: PathBuf, times: [timeval;2] } -> c_int ~ [Desc, File] for [x86_64: 261],
250  // get_mempolicy: nodemask: [c_ulong; (maxnode + ULONG_WIDTH - 1) / ULONG_WIDTH]
251  get_mempolicy(mode: *mut c_int, nodemask: *mut c_ulong, maxnode: c_ulong, addr: AddressType, flags: c_ulong) /
252    { maxnode: c_ulong, addr: AddressType, flags: c_ulong }
253    -> c_long + { mode: InspectResult<Option<c_int>>,
254      nodemask: Option<Vec<c_ulong>> @ counted_by((raw_args.maxnode as usize + (8 * std::mem::size_of::<c_ulong>() - 1)) / (8 * std::mem::size_of::<c_ulong>())) }
255    ~ [Memory] for [x86_64: 239, aarch64: 236, riscv64: 236],
256  get_robust_list(pid: pid_t, head_ptr: *mut *mut robust_list_head, len_ptr: *mut size_t) /
257    { pid: pid_t, head_ptr: InspectResult<AddressType>, len_ptr: size_t } -> c_long ~ [] for [x86_64: 274, aarch64: 100, riscv64: 100],
258  get_thread_area(u_info: *mut user_desc) / { u_info: user_desc } -> c_int + { u_info: user_desc } ~ [] for [x86_64: 211],
259  getcpu(cpu: *mut c_uint, node: *mut c_uint) /
260    { cpu: InspectResult<Option<c_uint>>, node: InspectResult<Option<c_uint>> } -> c_int ~ [] for [x86_64: 309, aarch64: 168, riscv64: 168],
261  getcwd(buf: *mut c_char, size: size_t) / { size: size_t } -> c_long + { buf: CString } ~ [File] for [x86_64: 79, aarch64: 17, riscv64: 17],
262  // getdents: count is size of buffer! This syscall returns the number of bytes read.
263  getdents(fd: RawFd, dirp: *mut linux_dirent, count: c_uint) / { fd: RawFd, count: c_uint }
264    -> c_int + { dirp: Vec<linux_dirent> @ counted_by((syscall_result as usize) / size_of::<linux_dirent>()) }
265    ~ [Desc] for [x86_64: 78],
266  getdents64(fd: RawFd, dirp: *mut linux_dirent64, count: c_uint) / { fd: RawFd, count: c_uint }
267    -> c_int + { dirp: Vec<linux_dirent64> @ counted_by((syscall_result as usize) / size_of::<linux_dirent>()) }
268    ~ [Desc] for [x86_64: 217, aarch64: 61, riscv64: 61],
269  // getdomainname
270  // getdtablesize
271  getegid() / {} -> gid_t ~ [Creds, Pure] for [x86_64: 108, aarch64: 177, riscv64: 177],
272  // getegid32
273  geteuid() / {} -> uid_t ~ [Creds, Pure] for [x86_64: 107, aarch64: 175, riscv64: 175],
274  // geteuid32
275  getgid() / {} -> gid_t ~ [Creds, Pure] for [x86_64: 104, aarch64: 176, riscv64: 176],
276  // getgid32
277  getgroups(gidsetsize: c_int, grouplist: *mut gid_t) / { } -> c_int
278    + { grouplist: Vec<gid_t> @ counted_by(if raw_args.gidsetsize == 0 { 0 } else { syscall_result }) }
279    ~ [Creds] for [x86_64: 115, aarch64: 158, riscv64: 158],
280  // getgroups32
281  // gethostname
282  getitimer(which: c_int, value: *mut itimerval) / { which: c_int } -> c_int + { value: itimerval } ~ [] for [x86_64: 36, aarch64: 102, riscv64: 102],
283  // getpagesize
284  getpeername(sockfd: RawFd, addr: *mut sockaddr, addrlen: *mut socklen_t) /
285    { sockfd: RawFd, addr: sockaddr, addrlen: InspectResult<socklen_t> } -> c_int + { addr: sockaddr, addrlen: InspectResult<socklen_t> }
286    ~ [Network] for [x86_64: 52, aarch64: 205, riscv64: 205],
287  getpgid(pid: pid_t) / { pid: pid_t } -> pid_t ~ [] for [x86_64: 121, aarch64: 155, riscv64: 155],
288  getpgrp() / {} -> pid_t ~ [Pure] for [x86_64: 111],
289  getpid() / {} -> pid_t ~ [Pure] for [x86_64: 39, aarch64: 172, riscv64: 172],
290  getppid() / {} -> pid_t ~ [Pure] for [x86_64: 110, aarch64: 173, riscv64: 173],
291  getpriority(which: c_int, who: id_t) / { which: c_int, who: id_t } -> c_int ~ [] for [x86_64: 140, aarch64: 141, riscv64: 141],
292  getrandom(buf: *mut c_void, buflen: size_t, flags: c_uint) / { buflen: size_t, flags: c_uint } -> ssize_t + { buf: Vec<u8> @ counted_by(raw_args.buflen) }
293    ~ [] for [x86_64: 318, aarch64: 278, riscv64: 278],
294  getresgid(rgid: *mut gid_t, egid: *mut gid_t, sgid: *mut gid_t) / {}
295    -> c_int + { rgid: InspectResult<gid_t>, egid: InspectResult<gid_t>, sgid: InspectResult<gid_t> }
296    ~ [Creds] for [x86_64: 120, aarch64: 150, riscv64: 150],
297  // getresgid32
298  getresuid(ruid: *mut uid_t, euid: *mut uid_t, suid: *mut uid_t) / {}
299    -> c_int + { ruid: InspectResult<uid_t>, euid: InspectResult<uid_t>, suid: InspectResult<uid_t> }
300    ~ [Creds] for [x86_64: 118, aarch64: 148, riscv64: 148],
301  // getresuid32
302  getrlimit(resource: c_int, rlim: *mut rlimit) / { resource: c_int } -> c_int + { rlim: rlimit } ~ [] for [x86_64: 97, aarch64: 163, riscv64: 163],
303  getrusage(who: c_int, usage: *mut rusage) / { who: c_int } -> c_int + { usage: rusage } ~ [] for [x86_64: 98, aarch64: 165, riscv64: 165],
304  getsid(pid: pid_t) / { pid: pid_t } -> pid_t ~ [] for [x86_64: 124, aarch64: 156, riscv64: 156],
305  getsockname(sockfd: RawFd, addr: *mut sockaddr, addrlen: *mut socklen_t) /
306    { sockfd: RawFd, addrlen: InspectResult<socklen_t> } -> c_int + { addr: sockaddr, addrlen: InspectResult<socklen_t> }
307    ~ [Network] for [x86_64: 51, aarch64: 204, riscv64: 204],
308  getsockopt(sockfd: RawFd, level: c_int, optname: c_int, optval: *mut c_void, optlen: *mut socklen_t) /
309    { sockfd: RawFd, level: c_int, optname: c_int, optlen: InspectResult<socklen_t> }
310    -> c_int + { optlen: InspectResult<socklen_t>, optval: Vec<u8> @ counted_by_result(optlen) }
311    ~ [Network] for [x86_64: 55, aarch64: 209, riscv64: 209],
312  gettid() / {} -> pid_t ~ [Pure] for [x86_64: 186, aarch64: 178, riscv64: 178],
313  gettimeofday(tv: *mut timeval, tz: *mut timezone) / {} -> c_int + { tv: timeval, tz: Option<timezone> } ~ [Clock] for [x86_64: 96, aarch64: 169, riscv64: 169],
314  getuid() / {} -> uid_t ~ [Creds, Pure] for [x86_64: 102, aarch64: 174, riscv64: 174],
315  // getuid32
316  getxattr(pathname: *const c_char, name: *const c_char, value: *mut c_void, size: size_t) /
317    { pathname: PathBuf, name: CString, size: size_t } -> ssize_t + { value: Vec<u8> @ counted_by(syscall_result) } ~ [File] for [x86_64: 191, aarch64: 8, riscv64: 8],
318  // TODO: support result inspection (need to inspect args inside xattr_args)
319  getxattrat(dfd: RawFd, pathname: *const c_char, at_flags: c_uint, name: *const c_char, uargs: *mut c_void, r#usize: size_t) /
320    { dfd: RawFd, pathname: PathBuf, at_flags: c_uint, name: CString, uargs: Arc<xattr_args> @ sized_by(raw_args.r#usize) } -> ssize_t ~ [File, Desc] for [x86_64: 464, aarch64: 464, riscv64: 464],
321  // getxgid
322  // getxpid
323  // getxuid
324  init_module(module_image: *mut c_void, len: c_ulong, param_values: *const c_char) /
325    { module_image: Vec<u8> @ counted_by(raw_args.len), param_values: CString } -> c_int ~ [] for [x86_64: 175, aarch64: 105, riscv64: 105],
326  inotify_add_watch(fd: RawFd, pathname: *const c_char, mask: u32) /
327    { fd: RawFd, pathname: PathBuf, mask: u32 } -> c_int ~ [Desc, File] for [x86_64: 254, aarch64: 27, riscv64: 27],
328  inotify_init() / {} -> RawFd ~ [Desc] for [x86_64: 253],
329  inotify_init1(flags: c_int) / { flags: c_int } -> RawFd ~ [Desc] for [x86_64: 294, aarch64: 26, riscv64: 26],
330  inotify_rm_watch(fd: RawFd, wd: c_int) / { fd: RawFd, wd: c_int } -> c_int ~ [Desc] for [x86_64: 255, aarch64: 28, riscv64: 28],
331  io_cancel(ctx_id: aio_context_t, iocb: *mut iocb, result: *mut io_event) /
332    { ctx_id: aio_context_t, iocb: iocb } -> c_int + { result: io_event } ~ [] for [x86_64: 210, aarch64: 3, riscv64: 3],
333  // TODO: strace doesn't have io_destory?
334  io_destroy(ctx_id: aio_context_t) / { ctx_id: aio_context_t } -> c_int ~ [] for [x86_64: 207, aarch64: 1, riscv64: 1],
335
336  io_getevents(ctx_id: aio_context_t, min_nr: c_long, nr: c_long, events: *mut io_event, timeout: *mut timespec) /
337    { ctx_id: aio_context_t, min_nr: c_long, nr: c_long, timeout: Option<timespec> }
338    -> c_int + { events: Vec<io_event> @ counted_by(syscall_result) } ~ [] for [x86_64: 208, aarch64: 4, riscv64: 4],
339  io_pgetevents(ctx_id: aio_context_t, min_nr: c_long, nr: c_long, events: *mut io_event, timeout: *mut timespec, sig: *const __aio_sigset) /
340    { ctx_id: aio_context_t, min_nr: c_long, nr: c_long, timeout: Option<timespec>, sig: __aio_sigset }
341    -> c_int + { events: Vec<io_event> @ counted_by(syscall_result) } ~ [] for [x86_64: 333, aarch64: 292, riscv64: 292],
342  // io_pgetevents_time64
343  io_setup(nr_events: c_ulong, ctx_idp: *mut aio_context_t) / { nr_events: c_ulong }
344    -> c_int + { ctx_idp: InspectResult<aio_context_t> } ~ [Memory] for [x86_64: 206, aarch64: 0, riscv64: 0],
345  // io_submit: iocbpp is an array of iocb pointers. TODO: how to handle it?
346  io_submit(ctx: aio_context_t, nr: c_long, iocbs: *mut *mut iocb) /
347    { ctx: aio_context_t, iocbs: Vec<AddressType> @ counted_by(raw_args.nr) } -> c_int ~ [] for [x86_64: 209, aarch64: 2, riscv64: 2],
348  // io_uring_enter: arg can be a sigset_t ptr or io_uring_getevents_arg ptr depending on the flags
349  io_uring_enter(fd: c_uint, to_submit: c_uint, min_complete: c_uint, flags: c_uint, arg: AddressType, argsz: size_t) /
350    { fd: c_uint, to_submit: c_uint, min_complete: c_uint, flags: c_uint, arg: Vec<u8> @ counted_by(raw_args.argsz) }
351    -> c_int ~ [Desc, File] for [x86_64: 426, aarch64: 426, riscv64: 426],
352  // arg can point to a lot of different struct (array) depending on the op
353  io_uring_register(fd: c_uint, op: c_uint, arg: AddressType, nr_args: c_uint) /
354    { fd: c_uint, op: c_uint, arg: AddressType, nr_args: c_uint } -> c_int ~ [Desc, Memory] for [x86_64: 427, aarch64: 427, riscv64: 427],
355  io_uring_setup(entries: u32, p: *mut io_uring_params) /
356    { entries: c_uint, p: io_uring_params } -> c_int + { p: io_uring_params } ~ [Desc] for [x86_64: 425, aarch64: 425, riscv64: 425],
357  ioctl(fd: RawFd, request: c_ulong, argp: AddressType) / { fd: RawFd, request: c_ulong, argp: AddressType }
358    -> c_int ~ [Desc] for [x86_64: 16, aarch64: 29, riscv64: 29],
359  ioperm(from: c_ulong, num: c_ulong, turn_on: c_int) / { from: c_ulong, num: c_ulong, turn_on: c_int } -> c_int ~ [] for [x86_64: 173],
360  iopl(level: c_int) / { level: c_int } -> c_int ~ [] for [x86_64: 172],
361  ioprio_get(which: c_int, who: c_int) / { which: c_int, who: c_int } -> c_int ~ [] for [x86_64: 252, aarch64: 31, riscv64: 31],
362  ioprio_set(which: c_int, who: c_int, ioprio: c_int) / { which: c_int, who: c_int, ioprio: c_int } -> c_int ~ [] for [x86_64: 251, aarch64: 30, riscv64: 30],
363  // ipc
364  kcmp(pid1: pid_t, pid2: pid_t, r#type: c_int, idx1: c_ulong, idx2: c_ulong) /
365    { pid1: pid_t, pid2: pid_t, r#type: c_int, idx1: c_ulong, idx2: c_ulong } -> c_int ~ [] for [x86_64: 312, aarch64: 272, riscv64: 272],
366  // kern_features
367  kexec_file_load(kernel_fd: RawFd, initrd_fd: RawFd, cmdline_len: c_ulong, cmdline: *const c_char, flags: c_ulong) /
368    { kernel_fd: RawFd, initrd_fd: RawFd, cmdline_len: c_ulong, cmdline: CString, flags: c_ulong } -> c_long
369    ~ [Desc] for [x86_64: 320, aarch64: 294, riscv64: 294],
370  kexec_load(entry: c_ulong, nr_segments: c_ulong, segments: *mut kexec_segment, flags: c_ulong) /
371    { entry: c_ulong, segments: Vec<kexec_segment> @ counted_by(raw_args.nr_segments), flags: c_ulong } -> c_long
372    ~ [] for [x86_64: 246, aarch64: 104, riscv64: 104],
373  keyctl(option: c_int, arg2: c_ulong, arg3: c_ulong, arg4: c_ulong, arg5: c_ulong) /
374    { option: c_int, arg2: c_ulong, arg3: c_ulong, arg4: c_ulong, arg5: c_ulong } -> c_long ~ [] for [x86_64: 250, aarch64: 219, riscv64: 219],
375  kill(pid: pid_t, sig: c_int) / { pid: pid_t, sig: c_int } -> c_int ~ [Signal, Process] for [x86_64: 62, aarch64: 129, riscv64: 129],
376  // TODO: rule_type and rule_attr forms a sum type.
377  landlock_add_rule(ruleset_fd: RawFd, rule_type: c_long, rule_attr: *const c_void, flags: u32) /
378    { ruleset_fd: RawFd, rule_type: c_long, rule_attr: Vec<u8>, flags: u32 } -> c_int ~ [Desc] for [x86_64: 445, aarch64: 445, riscv64: 445],
379  landlock_create_ruleset(ruleset_attr: *const landlock_ruleset_attr, size: size_t, flags: u32) /
380    { ruleset_attr: landlock_ruleset_attr, size: size_t, flags: u32 } -> c_int ~ [Desc] for [x86_64: 444, aarch64: 444, riscv64: 444],
381  landlock_restrict_self(ruleset_fd: RawFd, flags: u32) / { ruleset_fd: RawFd, flags: u32 } -> c_int ~ [Desc] for [x86_64: 446, aarch64: 446, riscv64: 446],
382  lchown(pathname: *const c_char, owner: uid_t, group: gid_t) / { pathname: PathBuf, owner: uid_t, group: gid_t } -> c_int ~ [File] for [x86_64: 94],
383  // lchown32
384  lgetxattr(pathname: *const c_char, name: *const c_char, value: *mut c_void, size: size_t) /
385  { pathname: PathBuf, name: CString, size: size_t } -> ssize_t + { value: Vec<u8> @ counted_by(syscall_result) } ~ [File] for [x86_64: 192, aarch64: 9, riscv64: 9],
386  link(oldpath: *const c_char, newpath: *const c_char) / { oldpath: PathBuf, newpath: PathBuf } -> c_int ~ [File] for [x86_64: 86],
387  linkat(olddirfd: RawFd, oldpath: *const c_char, newdirfd: RawFd, newpath: *const c_char, flags: c_int) /
388    { olddirfd: RawFd, oldpath: PathBuf, newdirfd: RawFd, newpath: PathBuf, flags: c_int } -> c_int
389    ~ [Desc, File] for [x86_64: 265, aarch64: 37, riscv64: 37],
390  listen(sockfd: RawFd, backlog: c_int) / { sockfd: RawFd, backlog: c_int } -> c_int ~ [Network] for [x86_64: 50, aarch64: 201, riscv64: 201],
391  // listmount: https://lwn.net/Articles/950569/
392  listmount(req: *const __mount_arg, buf: *mut u64, bufsize: size_t, flags: c_uint) /
393    { req: __mount_arg, bufsize: size_t, flags: c_uint } -> c_int + { buf: Vec<u64> @ counted_by(raw_args.bufsize) }
394     ~ [] for [x86_64: 458, aarch64: 458, riscv64: 458],
395  listxattr(path: *const c_char, list: *mut c_char, size: size_t) /
396    { path: PathBuf, size: size_t } -> ssize_t + { list: Option<Vec<CString>> } ~ [File] for [x86_64: 194, aarch64: 11, riscv64: 11],
397  llistxattr(path: *const c_char, list: *mut c_char, size: size_t) /
398    { path: PathBuf, size: size_t } -> ssize_t + { list: Option<Vec<CString>> } ~ [File] for [x86_64: 195, aarch64: 12, riscv64: 12],
399  listxattrat(dfd: RawFd, pathname: *const c_char, at_flags: c_uint, list: *mut c_char, size: size_t) /
400    { dfd: RawFd, pathname: PathBuf, at_flags: c_uint, size: size_t } -> ssize_t + { list: Option<Vec<CString>> }
401    ~ [File, Desc] for [x86_64: 465, aarch64: 465, riscv64: 465],
402  lookup_dcookie(cookie: u64, buffer: *mut c_char, len: size_t) /
403    { cookie: u64, len: size_t } -> c_long + { buffer: PathBuf } ~ [] for [x86_64: 212, aarch64: 18, riscv64: 18],
404  lremovexattr(path: *const c_char, name: *const c_char) / { path: PathBuf, name: CString } -> c_int ~ [File] for [x86_64: 198, aarch64: 15, riscv64: 15],
405  lseek(fd: RawFd, offset: off_t, whence: c_int) / { fd: RawFd, offset: off_t, whence: c_int } -> off_t ~ [Desc] for [x86_64: 8, aarch64: 62, riscv64: 62],
406  lsetxattr(path: *const c_char, name: *const c_char, value: *const c_void, size: size_t, flags: c_int) /
407    { path: PathBuf, name: CString, value: CString, size: size_t, flags: c_int } -> c_int ~ [File] for [x86_64: 189, aarch64: 6, riscv64: 6],
408  // lsm: https://lwn.net/Articles/919545/
409  // TODO: how to deal with DST arrays?
410  lsm_get_self_attr(attr: c_uint, ctx: *mut c_void, size: *mut u32, flags: u32) / { attr: c_uint, size: InspectResult<u32>, flags: u32 }
411    -> c_int + { ctx: Vec<u8> } ~ [] for [x86_64: 459, aarch64: 459, riscv64: 459],
412  lsm_list_modules(ids: *mut u64, size: *mut u32, flags: u32) / { size: InspectResult<u32>, flags: u32 }
413    -> c_int + { size: InspectResult<u32>, ids: Vec<u64> @ counted_by_result(size) } ~ [] for [x86_64: 461, aarch64: 461, riscv64: 461],
414  lsm_set_self_attr(attr: c_uint, ctx: *const c_void, size: u32, flags: u32) /
415    { attr: c_uint, ctx: Vec<u8> @ counted_by(raw_args.size), flags: u32 } -> c_int ~ [] for [x86_64: 460, aarch64: 460, riscv64: 460],
416  lstat(pathname: *const c_char, statbuf: *mut stat) / { pathname: PathBuf } -> c_int + { statbuf: stat } ~ [File, LStat, StatLike] for [x86_64: 6],
417  // lstat64
418  madvise(addr: *mut c_void, length: size_t, advice: c_int) / { addr: AddressType, length: size_t, advice: c_int } -> c_int
419    ~ [Memory] for [x86_64: 28, aarch64: 233, riscv64: 233],
420  map_shadow_stack(addr: *mut c_void, len: c_ulong, flags: c_int) / { addr: AddressType, len: c_ulong, flags: c_int } -> c_int
421    ~ [Memory] for [x86_64: 453, aarch64: 453, riscv64: 453],
422  mbind(addr: *mut c_void, len: c_ulong, mode: c_int, nodemask: *const c_ulong, maxnode: c_ulong, flags: c_uint) /
423    { len: c_ulong, mode: c_int,
424       nodemask: Vec<c_ulong> @ counted_by((raw_args.maxnode as usize + (8 * std::mem::size_of::<c_ulong>() - 1)) / (8 * std::mem::size_of::<c_ulong>())),
425       maxnode: c_ulong, flags: c_uint } -> c_long
426    ~ [Memory] for [x86_64: 237, aarch64: 235, riscv64: 235],
427  membarrier(cmd: c_int, flags: c_uint, cpu_id: c_int) / { cmd: c_int, flags: c_int, cpu_id: c_int } -> c_int
428    ~ [Memory] for [x86_64: 324, aarch64: 283, riscv64: 283],
429  memfd_create(name: *const c_char, flags: c_uint) / { name: CString, flags: c_uint } -> RawFd
430    ~ [Desc] for [x86_64: 319, aarch64: 279, riscv64: 279],
431  memfd_secret(flags: c_uint) / { flags: c_uint } -> RawFd ~ [Desc] for [x86_64: 447, aarch64: 447, riscv64: 447],
432  // memory_ordering
433  migrate_pages(pid: pid_t, maxnode: c_ulong, old_nodes: *const c_ulong, new_nodes: *const c_ulong) /
434    { pid: pid_t, maxnode: c_ulong,
435      old_nodes: Vec<c_ulong> @ counted_by((raw_args.maxnode as usize + (8 * std::mem::size_of::<c_ulong>() - 1)) / (8 * std::mem::size_of::<c_ulong>())),
436      new_nodes: Vec<c_ulong> @ counted_by((raw_args.maxnode as usize + (8 * std::mem::size_of::<c_ulong>() - 1)) / (8 * std::mem::size_of::<c_ulong>())) }
437    -> c_long ~ [Memory] for [x86_64: 256, aarch64: 238, riscv64: 238],
438  // mincore: vec is at least of len (length+PAGE_SIZE-1) / PAGE_SIZE, where PAGE_SIZE is sysconf(_SC_PAGESIZE)
439  mincore(addr: *mut c_void, length: size_t, vec: *mut c_uchar) / { addr: AddressType, length: size_t } -> c_int + { vec: Vec<c_uchar> }
440    ~ [Memory] for [x86_64: 27, aarch64: 232, riscv64: 232],
441  mkdir(pathname: *const c_char, mode: mode_t) / { pathname: PathBuf, mode: mode_t } -> c_int ~ [File] for [x86_64: 83],
442  mkdirat(dirfd: RawFd, pathname: *const c_char, mode: mode_t) / { dirfd: RawFd, pathname: PathBuf, mode: mode_t } -> c_int
443    ~ [Desc, File] for [x86_64: 258, aarch64: 34, riscv64: 34],
444  mknod(pathname: *const c_char, mode: mode_t, dev: dev_t) / { pathname: PathBuf, mode: mode_t, dev: dev_t } -> c_int ~ [File] for [x86_64: 133],
445  mknodat(dirfd: RawFd, pathname: *const c_char, mode: mode_t, dev: dev_t) /
446    { dirfd: RawFd, pathname: PathBuf, mode: mode_t, dev: dev_t } -> c_int ~ [Desc, File] for [x86_64: 259, aarch64: 33, riscv64: 33],
447  mlock(addr: *const c_void, len: size_t) / { addr: AddressType, len: size_t } -> c_int ~ [Memory] for [x86_64: 149, aarch64: 228, riscv64: 228],
448  mlock2(start: *const c_void, len: size_t, flags: c_int) / { start: AddressType, len: size_t, flags: c_int } -> c_int
449    ~ [Memory] for [x86_64: 325, aarch64: 284, riscv64: 284],
450  mlockall(flags: c_int) / { flags: c_int } -> c_int ~ [Memory] for [x86_64: 151, aarch64: 230, riscv64: 230],
451  mmap(addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fd: RawFd, offset: off_t) /
452    { addr: AddressType, length: size_t, prot: c_int, flags: c_int, fd: RawFd, offset: off_t } -> AddressType
453    ~ [Memory] for [x86_64: 9, aarch64: 222, riscv64: 222],
454  // mmap2
455  modify_ldt(func: c_int, ptr: *mut c_void, bytecount: c_ulong) / { func: c_int, ptr: AddressType, bytecount: c_ulong } -> c_int
456    ~ [] for [x86_64: 154],
457  mount(source: *const c_char, target: *const c_char, filesystemtype: *const c_char, mountflags: c_ulong, data: *const c_void) /
458    { source: CString, target: PathBuf, filesystemtype: CString, mountflags: c_ulong, data: Option<CString> } -> c_int
459    ~ [File] for [x86_64: 165, aarch64: 40, riscv64: 40],
460  mount_setattr(dirfd: RawFd, pathname: *const c_char, flags: c_uint, uattr: *mut c_void, r#usize: size_t) /
461    { dirfd: RawFd, pathname: PathBuf, flags: c_uint, uattr: Arc<mount_attr> @ sized_by(raw_args.r#usize) } -> c_int
462    ~ [Desc, File] for [x86_64: 442, aarch64: 442, riscv64: 442],
463  move_mount(from_dfd: RawFd, from_path: *const c_char, to_dfd: RawFd, to_path: *const c_char, ms_flags: c_uint) /
464    { from_dfd: RawFd, from_path: PathBuf, to_dfd: RawFd, to_path: PathBuf, ms_flags: c_uint } -> c_int
465    ~ [Desc, File] for [x86_64: 429, aarch64: 429, riscv64: 429],
466  // move_pages: pages, nodes and status are arrays of size count
467  move_pages(pid: pid_t, count: c_ulong, pages: *mut *mut c_void, nodes: *const c_int, status: *mut c_int, flags: c_int) /
468    { pid: pid_t,
469      pages: Vec<AddressType> @ counted_by(raw_args.count),
470      nodes: Vec<c_int> @ counted_by(raw_args.count),
471      flags: c_int } -> c_long + { status: Vec<c_int> @ counted_by(raw_args.count) }
472    ~ [Memory] for [x86_64: 279, aarch64: 239, riscv64: 239],
473  mprotect(addr: *mut c_void, len: size_t, prot: c_int) / { addr: AddressType, len: size_t, prot: c_int } -> c_int
474    ~ [Memory] for [x86_64: 10, aarch64: 226, riscv64: 226],
475  mq_getsetattr(mqdes: mqd_t, newattr: *const mq_attr, oldattr: *mut mq_attr) /
476    { mqdes: mqd_t, newattr: mq_attr, oldattr: mq_attr } -> c_int + { oldattr: mq_attr }
477    ~ [Desc] for [x86_64: 245, aarch64: 185, riscv64: 185],
478  mq_notify(mqdes: mqd_t, sevp: *const sigevent) / { mqdes: mqd_t, sevp: sigevent } -> c_int ~ [Desc] for [x86_64: 244, aarch64: 184, riscv64: 184],
479  mq_open(name: *const c_char, oflag: c_int, mode: mode_t, attr: *mut mq_attr) /
480    { name: CString, oflag: c_int, mode: mode_t, attr: Option<mq_attr> } -> mqd_t
481    ~ [Desc] for [x86_64: 240, aarch64: 180, riscv64: 180],
482  mq_timedreceive(mqdes: mqd_t, msg_ptr: *mut *mut c_char, msg_len: size_t, msg_prio: *mut c_uint, abs_timeout: *const timespec) /
483    { mqdes: mqd_t, msg_len: size_t, abs_timeout: timespec } -> ssize_t
484    + { msg_ptr: Vec<CString> @ counted_by(raw_args.msg_len), msg_prio: Option<Vec<c_uint>> @ counted_by(raw_args.msg_len) }
485    ~ [Desc] for [x86_64: 243, aarch64: 183, riscv64: 183],
486  // mq_timedreceive_time64
487  mq_timedsend(mqdes: mqd_t, msg_ptr: *const c_char, msg_len: size_t, msg_prio: c_uint, abs_timeout: *const timespec) /
488    { mqdes: mqd_t, msg_ptr: CString, msg_len: size_t, msg_prio: c_uint, abs_timeout: timespec } -> c_int
489    ~ [Desc] for [x86_64: 242, aarch64: 182, riscv64: 182],
490  // mq_timedsend_time64
491  mq_unlink(name: *const c_char) / { name: CString } -> c_int ~ [] for [x86_64: 241, aarch64: 181, riscv64: 181],
492  mremap(old_address: *mut c_void, old_size: size_t, new_size: size_t, flags: c_int, new_address: *mut c_void) /
493    { old_address: AddressType, old_size: size_t, new_size: size_t, flags: c_int, new_address: AddressType } -> AddressType
494    ~ [Memory] for [x86_64: 25, aarch64: 216, riscv64: 216],
495  // mseal: 6.10 https://lwn.net/Articles/954936/
496  mseal(start: AddressType, len: size_t, types: c_ulong, flags: c_ulong) / { start: AddressType, len: size_t, types: c_ulong, flags: c_ulong } -> c_int
497    ~ [Memory] for [x86_64: 462, aarch64: 462, riscv64: 462],
498  msgctl(msqid: c_int, cmd: c_int, buf: *mut msqid_ds) / { msqid: c_int, cmd: c_int } -> c_int + { buf: msqid_ds }
499    ~ [] for [x86_64: 71, aarch64: 187, riscv64: 187],
500  msgget(key: key_t, msgflg: c_int) / { key: key_t, msgflg: c_int } -> c_int ~ [] for [x86_64: 68, aarch64: 186, riscv64: 186],
501  msgrcv(msqid: c_int, msgp: *mut c_void, msgsz: size_t, msgtyp: c_long, msgflg: c_int) /
502    { msqid: c_int, msgsz: size_t, msgtyp: c_long, msgflg: c_int } -> ssize_t + { msgp: Arc<msgbuf> @ sized_by(size_of::<c_long>() + syscall_result as usize) }
503    ~ [] for [x86_64: 70, aarch64: 188, riscv64: 188],
504  msgsnd(msqid: c_int, msgp: *const c_void, msgsz: size_t, msgflg: c_int) /
505    { msqid: c_int, msgp: Arc<msgbuf> @ sized_by(size_of::<c_long>() + raw_args.msgsz as usize), msgflg: c_int } -> c_int ~ [] for [x86_64: 69, aarch64: 189, riscv64: 189],
506  msync(addr: *mut c_void, length: size_t, flags: c_int) / { addr: AddressType, length: size_t, flags: c_int } -> c_int
507    ~ [Memory] for [x86_64: 26, aarch64: 227, riscv64: 227],
508  // multiplexer
509  munlock(addr: *const c_void, len: size_t) / { addr: AddressType, len: size_t } -> c_int ~ [Memory] for [x86_64: 150, aarch64: 229, riscv64: 229],
510  munlockall() / {} -> c_int ~ [Memory] for [x86_64: 152, aarch64: 231, riscv64: 231],
511  munmap(addr: *mut c_void, length: size_t) / { addr: AddressType, length: size_t } -> c_int ~ [Memory] for [x86_64: 11, aarch64: 215, riscv64: 215],
512  name_to_handle_at(dirfd: RawFd, pathname: *const c_char, handle: *mut c_void, mount_id: *mut c_int, flags: c_int) /
513    { dirfd: RawFd, pathname: PathBuf, flags: c_int } -> c_int +
514    { handle: Arc<file_handle> @ sized_by_result(<InspectResult<c_uint> as InspectFromPid>::inspect_from(inspectee_pid, raw_args.handle as AddressType)),
515      mount_id: InspectResult<c_int> }
516    ~ [Desc, File] for [x86_64: 303, aarch64: 264, riscv64: 264],
517  nanosleep(req: *const timespec, rem: *mut timespec) / { req: timespec } -> c_int + { rem: Option<timespec> }
518    ~ [Clock] for [x86_64: 35, aarch64: 101, riscv64: 101],
519  newfstatat(dirfd: RawFd, pathname: *const c_char, statbuf: *mut stat, flags: c_int) /
520    { dirfd: RawFd, pathname: PathBuf, flags: c_int } -> c_int + { statbuf: stat }
521    ~ [Desc, File, FStat, StatLike] for [x86_64: 262, aarch64: 79, riscv64: 79],
522  // nice
523  // old_adjtimex
524  // oldfstat
525  // oldlstat
526  // oldolduname
527  // oldstat
528  // oldumount
529  // olduname
530  open(pathname: *const c_char, flags: c_int, mode: mode_t) / { pathname: PathBuf, flags: c_int, mode: mode_t } -> RawFd
531    ~ [Desc, File] for [x86_64: 2, aarch64: 56, riscv64: 56],
532  open_by_handle_at(mount_fd: RawFd, handle: *mut c_void, flags: c_int) /
533    { mount_fd: RawFd,
534      handle: Arc<file_handle> @ sized_by_result(<InspectResult<c_uint> as InspectFromPid>::inspect_from(inspectee_pid, raw_args.handle as AddressType)),
535      flags: c_int }
536    -> RawFd ~ [Desc] for [x86_64: 304, aarch64: 265, riscv64: 265],
537  open_tree(dirfd: RawFd, path: *const c_char, flags: c_uint) / { dirfd: RawFd, path: PathBuf, flags: c_uint } -> c_int
538    ~ [Desc, File] for [x86_64: 428, aarch64: 428, riscv64: 428],
539  open_tree_attr(dfd: RawFd, filename: *const c_char, flags: c_uint, uattr: *mut c_void, r#usize: size_t) /
540    { dfd: RawFd, filename: PathBuf, flags: c_uint, uattr: Arc<mount_attr> @ sized_by(raw_args.r#usize) } -> c_int
541    ~ [Desc, File] for [x86_64: 467, aarch64: 467, riscv64: 467],
542  openat(dirfd: RawFd, pathname: *const c_char, flags: c_int, mode: mode_t) /
543    { dirfd: RawFd, pathname: PathBuf, flags: c_int, mode: mode_t } -> RawFd ~ [Desc, File] for [x86_64: 257, aarch64: 56, riscv64: 56],
544  openat2(dirfd: RawFd, pathname: *const c_char, how: *mut open_how, size: size_t) /
545    { dirfd: RawFd, pathname: PathBuf, how: open_how, size: size_t } -> c_int ~ [Desc, File] for [x86_64: 437, aarch64: 437, riscv64: 437],
546  // or1k_atomic
547  // osf_*
548  pause() / {} -> c_int ~ [Signal] for [x86_64: 34],
549  // pciconfig_iobase
550  // pciconfig_read
551  // pciconfig_write
552  // perf_event_open: TODO: attr is perf_event_attr struct
553  perf_event_open(attr: *mut c_void, pid: pid_t, cpu: c_int, group_fd: RawFd, flags: c_ulong) /
554    { attr: AddressType, pid: pid_t, cpu: c_int, group_fd: RawFd, flags: c_ulong } -> RawFd
555    ~ [Desc] for [x86_64: 298, aarch64: 241, riscv64: 241],
556  // perfctr
557  personality(persona: c_ulong) / { persona: c_ulong } -> c_int ~ [] for [x86_64: 135, aarch64: 92, riscv64: 92],
558  pidfd_getfd(pidfd: RawFd, targetfd: RawFd, flags: c_uint) / { pidfd: RawFd, targetfd: RawFd, flags: c_uint } -> RawFd
559    ~ [Desc] for [x86_64: 438, aarch64: 438, riscv64: 438],
560  pidfd_open(pid: pid_t, flags: c_uint) / { pid: pid_t, flags: c_uint } -> RawFd ~ [Desc] for [x86_64: 434, aarch64: 434, riscv64: 434],
561  pidfd_send_signal(pidfd: RawFd, sig: c_int, info: *mut siginfo_t, flags: c_uint) /
562    { pidfd: RawFd, sig: c_int, info: Option<siginfo_t>, flags: c_uint } -> c_int
563    ~ [Desc, Signal, Process] for [x86_64: 424, aarch64: 424, riscv64: 424],
564  pipe(pipefd: *mut c_int) / {} -> c_int + { pipefd: [RawFd; 2] } ~ [Desc] for [x86_64: 22],
565  pipe2(pipefd: *mut c_int, flags: c_int) / { flags: c_int } -> c_int + { pipefd: [RawFd; 2] } ~ [Desc] for [x86_64: 293, aarch64: 59, riscv64: 59],
566  pivot_root(new_root: *const c_char, put_old: *const c_char) / { new_root: PathBuf, put_old: PathBuf } -> c_int
567    ~ [File] for [x86_64: 155, aarch64: 41, riscv64: 41],
568  pkey_alloc(flags: c_uint, access_rights: c_uint) / { flags: c_uint, access_rights: c_uint } -> c_int ~ [] for [x86_64: 330, aarch64: 289, riscv64: 289],
569  pkey_free(pkey: c_int) / { pkey: c_int } -> c_int ~ [] for [x86_64: 331, aarch64: 290, riscv64: 290],
570  pkey_mprotect(addr: *mut c_void, len: size_t, prot: c_int, pkey: c_int) /
571    { addr: AddressType, len: size_t, prot: c_int, pkey: c_int } -> c_int ~ [Memory] for [x86_64: 329, aarch64: 288, riscv64: 288],
572  poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) / { fds: Vec<pollfd> @ counted_by(raw_args.nfds), timeout: c_int }
573    -> c_int + { fds: Vec<pollfd> @ counted_by(raw_args.nfds) } ~ [Desc] for [x86_64: 7],
574  ppoll(fds: *mut pollfd, nfds: nfds_t, tmo_p: *const timespec, sigmask: *const sigset_t) /
575    { fds: Vec<pollfd> @ counted_by(raw_args.nfds), tmo_p: Option<timespec>, sigmask: Option<sigset_t> }
576    -> c_int + { fds: Vec<pollfd> @ counted_by(raw_args.nfds) }
577    ~ [Desc] for [x86_64: 271, aarch64: 73, riscv64: 73],
578  // ppoll_time64
579  prctl(option: c_int, arg2: c_ulong, arg3: c_ulong, arg4: c_ulong, arg5: c_ulong) /
580    { option: c_int, arg2: c_ulong, arg3: c_ulong, arg4: c_ulong, arg5: c_ulong } -> c_int
581    ~ [Clock] for [x86_64: 157, aarch64: 167, riscv64: 167],
582  pread64(fd: RawFd, buf: *mut c_void, count: size_t, offset: loff_t) /
583    { fd: RawFd, count: size_t, offset: loff_t } -> ssize_t + { buf: Vec<u8> @ counted_by(syscall_result) }
584    ~ [Desc] for [x86_64: 17, aarch64: 67, riscv64: 67],
585  preadv(fd: RawFd, iov: *const iovec, iovcnt: c_int, offset: off_t) /
586    { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.iovcnt), offset: off_t } -> ssize_t ~ [Desc] for [x86_64: 295, aarch64: 69, riscv64: 69],
587  preadv2(fd: RawFd, iov: *const iovec, iovcnt: c_int, offset: off_t, flags: c_int) /
588    { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.iovcnt), offset: off_t, flags: c_int } -> ssize_t ~ [Desc] for [x86_64: 327, aarch64: 286, riscv64: 286],
589  prlimit64(pid: pid_t, resource: c_int, new_limit: *const rlimit64, old_limit: *mut rlimit64) /
590    { pid: pid_t, resource: c_int, new_limit: Option<rlimit64>, old_limit: Option<rlimit64> } -> c_int + { old_limit: Option<rlimit64> }
591    ~ [] for [x86_64: 302, aarch64: 261, riscv64: 261],
592  process_madvise(pidfd: RawFd, iovec: *const iovec, vlen: size_t, advice: c_int, flags: c_uint) /
593    { pidfd: RawFd, iovec: Vec<iovec> @ counted_by(raw_args.vlen), advice: c_int, flags: c_uint } -> c_int
594    ~ [Desc] for [x86_64: 440, aarch64: 440, riscv64: 440],
595  process_mrelease(pidfd: RawFd, flags: c_uint) / { pidfd: RawFd, flags: c_uint } -> c_int ~ [Desc] for [x86_64: 448, aarch64: 448, riscv64: 448],
596  process_vm_readv(pid: pid_t, local_iov: *const iovec, liovcnt: c_ulong, remote_iov: *const iovec, riovcnt: c_ulong, flags: c_ulong) /
597    { pid: pid_t, local_iov: Vec<iovec> @ counted_by(raw_args.liovcnt), remote_iov: Vec<iovec> @ counted_by(raw_args.riovcnt), flags: c_ulong }
598    -> ssize_t ~ [] for [x86_64: 310, aarch64: 270, riscv64: 270],
599  process_vm_writev(pid: pid_t, local_iov: *const iovec, liovcnt: c_ulong, remote_iov: *const iovec, riovcnt: c_ulong, flags: c_ulong) /
600    { pid: pid_t, local_iov: Vec<iovec> @ counted_by(raw_args.liovcnt), remote_iov: Vec<iovec> @ counted_by(raw_args.riovcnt), flags: c_ulong }
601    -> ssize_t ~ [] for [x86_64: 311, aarch64: 271, riscv64: 271],
602  // TODO: sigmask is { const kernel_sigset_t *ss;  size_t ss_len; /* Size (in bytes) of object pointed to by 'ss' */ }
603  pselect6(nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, exceptfds: *mut fd_set, timeout: *mut timespec, sigmask: *const c_void) /
604    { readfds: Option<fd_set>, writefds: Option<fd_set>, exceptfds: Option<fd_set>, timeout: Option<timespec>, sigmask: Option<sigset_t> }
605    -> c_int + { readfds: Option<fd_set>, writefds: Option<fd_set>, exceptfds: Option<fd_set> }
606    ~ [Desc] for [x86_64: 270, aarch64: 72, riscv64: 72],
607  // pselect6_time64
608  ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) / { } -> c_long
609    ~ [] for [x86_64: 101, aarch64: 117, riscv64: 117],
610  pwrite64(fd: RawFd, buf: *const c_void, count: size_t, offset: loff_t) /
611    { fd: RawFd, buf: Vec<u8> @ counted_by(raw_args.count), offset: loff_t } -> ssize_t ~ [Desc] for [x86_64: 18, aarch64: 68, riscv64: 68],
612  pwritev(fd: RawFd, iov: *const iovec, iovcnt: c_int, offset: off_t) /
613    { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.iovcnt), offset: off_t } -> ssize_t ~ [Desc] for [x86_64: 296, aarch64: 70, riscv64: 70],
614  pwritev2(fd: RawFd, iov: *const iovec, iovcnt: c_int, offset: off_t, flags: c_int) /
615    { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.iovcnt), offset: off_t, flags: c_int } -> ssize_t ~ [Desc] for [x86_64: 328, aarch64: 287, riscv64: 287],
616  quotactl(cmd: c_int, special: *const c_char, id: qid_t, addr: AddressType) /
617    { cmd: c_int, special: Option<CString>, id: qid_t } -> c_int ~ [File] for [x86_64: 179, aarch64: 60, riscv64: 60],
618  quotactl_fd(fd: RawFd, cmd: c_int, id: c_int, addr: AddressType) / { fd: RawFd, cmd: c_int, id: c_int } -> c_int
619    ~ [Desc] for [x86_64: 443, aarch64: 443, riscv64: 443],
620  read(fd: RawFd, buf: *mut c_void, count: size_t) / { fd: RawFd, count: size_t } -> ssize_t + { buf: Vec<u8> @ counted_by(syscall_result) }
621    ~ [Desc] for [x86_64: 0, aarch64: 63, riscv64: 63],
622  readahead(fd: RawFd, offset: off_t, count: size_t) / { fd: RawFd, offset: off_t, count: size_t } -> ssize_t
623    ~ [Desc] for [x86_64: 187, aarch64: 213, riscv64: 213],
624  // readdir(fd: RawFd, dirp: AddressType, count: c_uint) / { fd: RawFd, count: c_uint } -> c_int + { dirp: Vec<u8> } ~ [Desc] for [],
625  readlink(pathname: *const c_char, buf: *mut c_char, bufsiz: size_t) / { pathname: PathBuf, bufsiz: size_t } -> ssize_t
626    + { buf: Vec<u8> @ counted_by(syscall_result) } ~ [File] for [x86_64: 89],
627  readlinkat(dirfd: RawFd, pathname: *const c_char, buf: *mut c_char, bufsiz: size_t) /
628    { dirfd: RawFd, pathname: PathBuf, bufsiz: size_t } -> ssize_t + { buf: Vec<u8> @ counted_by(syscall_result) }
629    ~ [Desc, File] for [x86_64: 267, aarch64: 78, riscv64: 78],
630  readv(fd: RawFd, iov: *const iovec, iovcnt: c_int) / { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.iovcnt) } -> ssize_t
631    ~ [Desc] for [x86_64: 19, aarch64: 65, riscv64: 65],
632  reboot(magic: c_int, magic2: c_int, cmd: c_int, arg: *mut c_void) / { magic: c_int, magic2: c_int, cmd: c_int } -> c_int
633    ~ [] for [x86_64: 169, aarch64: 142, riscv64: 142],
634  //  recv
635  recvfrom(sockfd: RawFd, buf: *mut c_void, len: size_t, flags: c_int, src_addr: *mut sockaddr, addrlen: *mut socklen_t) /
636    { sockfd: RawFd, len: size_t, flags: c_int, src_addr: Option<sockaddr> } -> ssize_t + { buf: Vec<u8> @ counted_by(syscall_result) }
637    ~ [Network] for [x86_64: 45, aarch64: 207, riscv64: 207],
638  recvmmsg(sockfd: RawFd, msgvec: *mut mmsghdr, vlen: c_uint, flags: c_int, timeout: *mut timespec) /
639    { sockfd: RawFd, vlen: c_uint, flags: c_int, msgvec: Vec<mmsghdr> @ counted_by(vlen), timeout: Option<timespec> } -> c_int
640    ~ [Network] for [x86_64: 299, aarch64: 243, riscv64: 243],
641  // recvmmsg_time64
642  recvmsg(sockfd: RawFd, msg: *mut msghdr, flags: c_int) / { sockfd: RawFd, flags: c_int, msg: msghdr } -> ssize_t + { msg: msghdr }
643    ~ [Network] for [x86_64: 47, aarch64: 212, riscv64: 212],
644  remap_file_pages(addr: *mut c_void, size: size_t, prot: c_int, pgoff: size_t, flags: c_int) /
645    { addr: AddressType, size: size_t, prot: c_int, pgoff: size_t, flags: c_int } -> c_int
646    ~ [Memory] for [x86_64: 216, aarch64: 234, riscv64: 234],
647  removexattr(path: *const c_char, name: *const c_char) / { path: PathBuf, name: CString } -> c_int
648    ~ [File] for [x86_64: 197, aarch64: 14, riscv64: 14],
649  removexattrat(dfd: RawFd, pathname: *const c_char, at_flags: c_uint, name: *const c_char) /
650    { dfd: RawFd, pathname: PathBuf, at_flags: c_uint, name: CString } -> c_int
651    ~ [File, Desc] for [x86_64: 466, aarch64: 466, riscv64: 466],
652  rename(oldpath: *const c_char, newpath: *const c_char) / { oldpath: PathBuf, newpath: PathBuf } -> c_int
653    ~ [File] for [x86_64: 82],
654  renameat(olddirfd: RawFd, oldpath: *const c_char, newdirfd: RawFd, newpath: *const c_char) /
655    { olddirfd: RawFd, oldpath: PathBuf, newdirfd: RawFd, newpath: PathBuf } -> c_int
656    ~ [Desc, File] for [x86_64: 264, aarch64: 38],
657  renameat2(olddirfd: RawFd, oldpath: *const c_char, newdirfd: RawFd, newpath: *const c_char, flags: c_uint) /
658    { olddirfd: RawFd, oldpath: PathBuf, newdirfd: RawFd, newpath: PathBuf, flags: c_uint } -> c_int
659    ~ [Desc, File] for [x86_64: 316, aarch64: 276, riscv64: 276],
660  request_key(r#type: *const c_char, description: *const c_char, callout_info: *const c_char, dest_keyring: key_serial_t) /
661    { r#type: CString, description: CString, callout_info: Option<CString>, dest_keyring: key_serial_t } -> key_serial_t
662    ~ [] for [x86_64: 249, aarch64: 218, riscv64: 218],
663  restart_syscall() / {} -> c_long ~ [] for [x86_64: 219, aarch64: 128, riscv64: 128],
664  riscv_flush_icache(start: *mut c_void, end: *mut c_void, flags: c_ulong) / { start: AddressType, end: AddressType, flags: c_ulong } -> c_int
665    ~ [Memory] for [riscv64: 259],
666  // https://docs.kernel.org/6.5/riscv/hwprobe.html
667  riscv_hwprobe(pairs: *mut riscv_hwprobe, pair_count: size_t, cpu_count: size_t, cpus: *mut c_ulong, flags: c_uint) /
668    { pairs: Vec<riscv_hwprobe> @ counted_by(raw_args.pair_count), pair_count: size_t, cpu_count: size_t,
669      cpus: Vec<c_ulong> @ counted_by((raw_args.cpu_count as usize + (8 * std::mem::size_of::<c_ulong>() - 1)) / (8 * std::mem::size_of::<c_ulong>())),
670      flags: c_uint }
671    -> c_int + { pairs: Vec<riscv_hwprobe> @ counted_by(raw_args.pair_count) }
672    ~ [] for [riscv64: 258],
673  rmdir(pathname: *const c_char) / { pathname: PathBuf } -> c_int ~ [File] for [x86_64: 84],
674  rseq(rseq: *mut c_void, rseq_len: u32, flags: c_int, sig: u32) / { rseq: Arc<rseq> @ sized_by(raw_args.rseq_len), flags: c_int, sig: u32 } -> c_int
675    ~ [] for [x86_64: 334, aarch64: 293, riscv64: 293],
676  rt_sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction, sigsetsize: size_t) /
677    { sig: c_int, act: Option<sigaction>, oact: Option<sigaction>, sigsetsize: size_t } -> c_int + { oact: Option<sigaction> }
678    ~ [Signal] for [x86_64: 13, aarch64: 134, riscv64: 134],
679  rt_sigpending(set: *mut sigset_t, sigsetsize: size_t) / { set: sigset_t, sigsetsize: size_t } -> c_int
680    ~ [Signal] for [x86_64: 127, aarch64: 136, riscv64: 136],
681  rt_sigprocmask(how: c_int, set: *const sigset_t, oldset: *mut sigset_t, sigsetsize: size_t) /
682    { how: c_int, set: Option<sigset_t>, oldset: Option<sigset_t>, sigsetsize: size_t } -> c_int + { oldset: Option<sigset_t> }
683    ~ [Signal] for [x86_64: 14, aarch64: 135, riscv64: 135],
684  rt_sigqueueinfo(pid: pid_t, sig: c_int, info: *mut siginfo_t) / { pid: pid_t, sig: c_int, info: siginfo_t } -> c_int
685    ~ [Signal, Process] for [x86_64: 129, aarch64: 138, riscv64: 138],
686  // TODO: regs is pt_regs struct
687  rt_sigreturn(regs: *mut c_void) / {} -> c_int ~ [Signal] for [x86_64: 15, aarch64: 139, riscv64: 139],
688  rt_sigsuspend(newset: *mut sigset_t, sigsetsize: size_t) /
689    { newset: sigset_t, sigsetsize: size_t } -> c_int ~ [Signal] for [x86_64: 130, aarch64: 133, riscv64: 133],
690  rt_sigtimedwait(set: *const sigset_t, info: *mut siginfo_t, timeout: *const timespec, sigsetsize: size_t) /
691    { set: sigset_t, info: siginfo_t, timeout: timespec, sigsetsize: size_t } -> c_int + { info: Option<siginfo_t> }
692    ~ [Signal] for [x86_64: 128, aarch64: 137, riscv64: 137],
693  // rt_sigtimedwait_time64
694  rt_tgsigqueueinfo(tgid: pid_t, pid: pid_t, sig: c_int, info: *mut siginfo_t) /
695    { tgid: pid_t, pid: pid_t, sig: c_int, info: siginfo_t } -> c_int ~ [Signal, Process] for [x86_64: 297, aarch64: 240, riscv64: 240],
696  // rtas
697  // sched_get_affinity
698  sched_get_priority_max(policy: c_int) / { policy: c_int } -> c_int ~ [] for [x86_64: 146, aarch64: 125, riscv64: 125],
699  sched_get_priority_min(policy: c_int) / { policy: c_int } -> c_int ~ [] for [x86_64: 147, aarch64: 126, riscv64: 126],
700  // sched_getaffinity syscall returns (in bytes) the number of bytes placed copied into the mask buffer. arg cpusetsize is also in bytes
701  sched_getaffinity(pid: pid_t, cpusetsize: size_t, mask: *mut c_ulong) /
702    { pid: pid_t, cpusetsize: size_t } -> c_int + { mask: Vec<u8> @ counted_by(syscall_result) }
703    ~ [] for [x86_64: 204, aarch64: 123, riscv64: 123],
704  sched_getattr(pid: pid_t, attr: *mut sched_attr, size: c_uint, flags: c_uint) /
705    { pid: pid_t, size: c_uint, flags: c_uint } -> c_int + { attr: sched_attr }
706    ~ [] for [x86_64: 315, aarch64: 275, riscv64: 275],
707  sched_getparam(pid: pid_t, param: *mut sched_param) / { pid: pid_t } -> c_int + { param: sched_param }
708    ~ [] for [x86_64: 143, aarch64: 121, riscv64: 121],
709  sched_getscheduler(pid: pid_t) / { pid: pid_t } -> c_int ~ [] for [x86_64: 145, aarch64: 120, riscv64: 120],
710  sched_rr_get_interval(pid: pid_t, tp: *mut timespec) / { pid: pid_t } -> c_int + { tp: timespec }
711    ~ [] for [x86_64: 148, aarch64: 127, riscv64: 127],
712  // sched_rr_get_interval_time64
713  // sched_set_affinity
714  sched_setaffinity(pid: pid_t, cpusetsize: size_t, mask: *const c_ulong) /
715    { pid: pid_t, cpusetsize: size_t, mask: Vec<u8> @ counted_by(cpusetsize) } -> c_int
716    ~ [] for [x86_64: 203, aarch64: 122, riscv64: 122],
717  // sched_setattr size is the first field of sched_attr struct
718  sched_setattr(pid: pid_t, attr: *mut sched_attr, flags: c_uint) / { pid: pid_t, attr: sched_attr, flags: c_uint } -> c_int
719    ~ [] for [x86_64: 314, aarch64: 274, riscv64: 274],
720  sched_setparam(pid: pid_t, param: *const sched_param) / { pid: pid_t, param: sched_param } -> c_int
721    ~ [] for [x86_64: 142, aarch64: 118, riscv64: 118],
722  sched_setscheduler(pid: pid_t, policy: c_int, param: *const sched_param) /
723    { pid: pid_t, policy: c_int, param: sched_param } -> c_int
724    ~ [] for [x86_64: 144, aarch64: 119, riscv64: 119],
725  sched_yield() / {} -> c_int ~ [] for [x86_64: 24, aarch64: 124, riscv64: 124],
726  // seccomp: TODO: decode args
727  seccomp(operation: c_int, flags: c_uint, args: *mut c_void) / { operation: c_int, flags: c_uint } -> c_int
728    ~ [] for [x86_64: 317, aarch64: 277, riscv64: 277],
729  select(nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, exceptfds: *mut fd_set, timeout: *mut timeval) /
730    { nfds: c_int, readfds: Option<fd_set>, writefds: Option<fd_set>, exceptfds: Option<fd_set>, timeout: Option<timeval> }
731    -> c_int + { readfds: Option<fd_set>, writefds: Option<fd_set>, exceptfds: Option<fd_set> }
732    ~ [Desc] for [x86_64: 23],
733  // semctl: TODO: decode arg
734  semctl(semid: c_int, semnum: c_int, cmd: c_int, arg: *mut c_void) / { semid: c_int, semnum: c_int, cmd: c_int } -> c_int
735    ~ [IPC] for [x86_64: 66, aarch64: 191, riscv64: 191],
736  semget(key: key_t, nsems: c_int, semflg: c_int) / { key: key_t, nsems: c_int, semflg: c_int } -> c_int
737    ~ [IPC] for [x86_64: 64, aarch64: 190, riscv64: 190],
738  semop(semid: c_int, sops: *mut sembuf, nsops: size_t) / { sops: Vec<sembuf> @ counted_by(raw_args.nsops) } -> c_int
739    ~ [IPC] for [x86_64: 65, aarch64: 193, riscv64: 193],
740  semtimedop(semid: c_int, sops: *mut sembuf, nsops: size_t, timeout: *const timespec) /
741    { semid: c_int, nsops: c_uint, sops: Vec<sembuf> @ counted_by(nsops), timeout: Option<timespec> } -> c_int
742    ~ [IPC] for [x86_64: 220, aarch64: 192, riscv64: 192],
743  // semtimedop_time64
744  // send
745  sendfile(out_fd: RawFd, in_fd: RawFd, offset: *mut off_t, count: size_t) /
746    { out_fd: RawFd, in_fd: RawFd, offset: off_t, count: size_t } -> ssize_t ~ [Desc, Network] for [x86_64: 40, aarch64: 71, riscv64: 71],
747  // sendfile64
748  sendmmsg(sockfd: RawFd, msgvec: *mut mmsghdr, vlen: c_uint, flags: c_int) /
749    { sockfd: RawFd, vlen: c_uint, flags: c_int, msgvec: Vec<mmsghdr> @ counted_by(raw_args.vlen) } -> c_int
750    ~ [Network] for [x86_64: 307, aarch64: 269, riscv64: 269],
751  sendmsg(sockfd: RawFd, msg: *const msghdr, flags: c_int) / { sockfd: RawFd, flags: c_int, msg: msghdr } -> ssize_t
752    ~ [Network] for [x86_64: 46, aarch64: 211, riscv64: 211],
753  sendto(sockfd: RawFd, buf: *const c_void, len: size_t, flags: c_int, dest_addr: *const sockaddr, addrlen: socklen_t) /
754    { sockfd: RawFd, buf: Vec<u8> @ counted_by(raw_args.len), flags: c_int, dest_addr: Option<sockaddr> } -> ssize_t
755    ~ [Network] for [x86_64: 44, aarch64: 206, riscv64: 206],
756  set_mempolicy(mode: c_int, nodemask: *const c_ulong, maxnode: c_ulong) /
757    { mode: c_int,
758      nodemask: Vec<c_ulong> @ counted_by((raw_args.maxnode as usize + (8 * std::mem::size_of::<c_ulong>() - 1)) / (8 * std::mem::size_of::<c_ulong>())),
759      maxnode: c_ulong }
760     -> c_int ~ [Memory] for [x86_64: 238, aarch64: 237, riscv64: 237],
761  set_mempolicy_home_node(start: c_ulong, len: c_ulong, home_mode: c_ulong, flags: c_ulong) /
762    { start: c_ulong, len: c_ulong, home_mode: c_ulong, flags: c_ulong }
763    -> c_int ~ [Memory] for [x86_64: 450, aarch64: 450, riscv64: 450],
764  set_robust_list(head: *mut robust_list_head, len: size_t) / { head: AddressType, len: size_t } -> c_long
765    ~ [] for [x86_64: 273, aarch64: 99, riscv64: 99],
766  set_thread_area(u_info: *mut user_desc) / { u_info: user_desc } -> c_int ~ [] for [x86_64: 205],
767  set_tid_address(tidptr: *mut c_int) / { tidptr: AddressType } -> pid_t ~ [] for [x86_64: 218, aarch64: 96, riscv64: 96],
768  // setdomainname: FIXME: name doesn't require terminating null.
769  setdomainname(name: *const c_char, len: size_t) / { name: CString } -> c_int ~ [] for [x86_64: 171, aarch64: 162, riscv64: 162],
770  setfsgid(fsgid: gid_t) / { fsgid: gid_t } -> c_int ~ [Creds] for [x86_64: 123, aarch64: 152, riscv64: 152],
771  // setfsgid32
772  setfsuid(fsuid: uid_t) / { fsuid: uid_t } -> c_int ~ [Creds] for [x86_64: 122, aarch64: 151, riscv64: 151],
773  // setfsuid32
774  setgid(gid: gid_t) / { gid: gid_t } -> c_int ~ [Creds] for [x86_64: 106, aarch64: 144, riscv64: 144],
775  // setgid32
776  setgroups(size: size_t, list: *const gid_t) / { list: Option<Vec<gid_t>> @ counted_by(raw_args.size) } -> c_int
777    ~ [Creds] for [x86_64: 116, aarch64: 159, riscv64: 159],
778  // setgroups32
779  // sethae
780  // sethostname: FIXME: name doesn't require terminating null.
781  sethostname(name: *const c_char, len: size_t) / { name: CString, len: size_t } -> c_int
782    ~ [] for [x86_64: 170, aarch64: 161, riscv64: 161],
783  setitimer(which: c_int, new_value: *const itimerval, old_value: *mut itimerval) /
784    { which: c_int, new_value: itimerval, old_value: Option<itimerval> } -> c_int
785    ~ [] for [x86_64: 38, aarch64: 103, riscv64: 103],
786  setns(fd: RawFd, nstype: c_int) / { fd: RawFd, nstype: c_int } -> c_int ~ [Desc] for [x86_64: 308, aarch64: 268, riscv64: 268],
787  setpgid(pid: pid_t, pgid: pid_t) / { pid: pid_t, pgid: pid_t } -> c_int ~ [] for [x86_64: 109, aarch64: 154, riscv64: 154],
788  // setpgrp
789  setpriority(which: c_int, who: id_t, prio: c_int) / { which: c_int, who: id_t, prio: c_int } -> c_int
790    ~ [] for [x86_64: 141, aarch64: 140, riscv64: 140],
791  setregid(rgid: gid_t, egid: gid_t) / { rgid: gid_t, egid: gid_t } -> c_int ~ [Creds] for [x86_64: 114, aarch64: 143, riscv64: 143],
792  // setregid32
793  setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) / { rgid: gid_t, egid: gid_t, sgid: gid_t } -> c_int
794    ~ [Creds] for [x86_64: 119, aarch64: 149, riscv64: 149],
795  // setresgid32
796  setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) / { ruid: uid_t, euid: uid_t, suid: uid_t } -> c_int
797    ~ [Creds] for [x86_64: 117, aarch64: 147, riscv64: 147],
798  // setresuid32
799  setreuid(ruid: uid_t, euid: uid_t) / { ruid: uid_t, euid: uid_t } -> c_int ~ [Creds] for [x86_64: 113, aarch64: 145, riscv64: 145],
800  // setreuid32
801  setrlimit(resource: c_int, rlim: *const rlimit) / { resource: c_int, rlim: rlimit } -> c_int
802    ~ [] for [x86_64: 160, aarch64: 164, riscv64: 164],
803  setsid() / {} -> pid_t ~ [] for [x86_64: 112, aarch64: 157, riscv64: 157],
804  setsockopt(sockfd: RawFd, level: c_int, optname: c_int, optval: *const c_void, optlen: socklen_t) /
805    { sockfd: RawFd, level: c_int, optname: c_int, optval: Vec<u8> @ counted_by(raw_args.optlen) } -> c_int
806    ~ [Network] for [x86_64: 54, aarch64: 208, riscv64: 208],
807  settimeofday(tv: *const timeval, tz: *const timezone) / { tv: timeval, tz: Option<timezone> } -> c_int
808    ~ [Clock] for [x86_64: 164, aarch64: 170, riscv64: 170],
809  setuid(uid: uid_t) / { uid: uid_t } -> c_int ~ [Creds] for [x86_64: 105, aarch64: 146, riscv64: 146],
810  // setuid32
811  setxattr(path: *const c_char, name: *const c_char, value: *const c_void, size: size_t, flags: c_int) /
812    { path: PathBuf, name: CString, value: CString, size: size_t, flags: c_int } -> c_int ~ [File] for [x86_64: 188, aarch64: 5, riscv64: 5],
813  // TODO: same as getxattrat
814  setxattrat(dfd: RawFd, pathname: *const c_char, at_flags: c_uint, name: *const c_char, uargs: *const c_void, r#usize: size_t) /
815    { dfd: RawFd, pathname: PathBuf, at_flags: c_uint, name: CString, uargs: Arc<xattr_args> @ sized_by(raw_args.r#usize) } -> c_int
816    ~ [File, Desc] for [x86_64: 463, aarch64: 463, riscv64: 463],
817  // sgetmask
818  shmat(shmid: c_int, shmaddr: *const c_void, shmflg: c_int) / { shmid: c_int, shmaddr: AddressType, shmflg: c_int } -> AddressType
819    ~ [IPC, Memory] for [x86_64: 30, aarch64: 196, riscv64: 196],
820  shmctl(shmid: c_int, cmd: c_int, buf: *mut shmid_ds) / { shmid: c_int, cmd: c_int, buf: shmid_ds } -> c_int
821    ~ [IPC] for [x86_64: 31, aarch64: 195, riscv64: 195],
822  shmdt(shmaddr: *const c_void) / { shmaddr: AddressType } -> c_int ~ [IPC, Memory] for [x86_64: 67, aarch64: 197, riscv64: 197],
823  shmget(key: key_t, size: size_t, shmflg: c_int) / { key: key_t, size: size_t, shmflg: c_int } -> c_int
824    ~ [IPC] for [x86_64: 29, aarch64: 194, riscv64: 194],
825  shutdown(sockfd: RawFd, how: c_int) / { sockfd: RawFd, how: c_int } -> c_int ~ [Network] for [x86_64: 48, aarch64: 210, riscv64: 210],
826  // sigaction
827  sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) / { ss: Option<stack_t> } -> c_int + { old_ss: Option<stack_t> }
828    ~ [Signal] for [x86_64: 131, aarch64: 132, riscv64: 132],
829  // signal
830  signalfd(fd: RawFd, mask: *const sigset_t, size: size_t) / { fd: RawFd, mask: sigset_t, size: size_t } -> c_int
831    ~ [Desc, Signal] for [x86_64: 282],
832  signalfd4(fd: RawFd, mask: *const sigset_t, size: size_t, flags: c_int) / { fd: RawFd, mask: sigset_t, size: size_t, flags: c_int } -> c_int
833    ~ [Desc, Signal] for [x86_64: 289, aarch64: 74, riscv64: 74],
834  // sigpending
835  // sigprocmask
836  // sigreturn
837  // sigsuspend
838  socket(domain: c_int, r#type: c_int, protocol: c_int) / { domain: c_int, r#type: c_int, protocol: c_int } -> RawFd
839    ~ [Network] for [x86_64: 41, aarch64: 198, riscv64: 198],
840  // socketcall
841  socketpair(domain: c_int, r#type: c_int, protocol: c_int, sv: *mut RawFd) /
842    { domain: c_int, r#type: c_int, protocol: c_int } -> c_int + { sv: [RawFd;2] }
843    ~ [Network] for [x86_64: 53, aarch64: 199, riscv64: 199],
844  splice(fd_in: RawFd, off_in: *mut off_t, fd_out: RawFd, off_out: *mut off_t, len: size_t, flags: c_uint) /
845    { fd_in: RawFd, off_in: off_t, fd_out: RawFd, off_out: off_t, len: size_t, flags: c_uint } -> ssize_t
846    ~ [Desc] for [x86_64: 275, aarch64: 76, riscv64: 76],
847  // spu_create
848  // spu_run
849  // ssetmask
850  stat(pathname: *const c_char, statbuf: *mut stat) / { pathname: PathBuf } -> c_int + { statbuf: stat }
851    ~ [File, Stat, StatLike] for [x86_64: 4],
852  // stat64
853  statfs(path: *const c_char, buf: *mut statfs) / { path: PathBuf } -> c_int + { buf: statfs }
854    ~ [File, StatFs, StatFsLike] for [x86_64: 137, aarch64: 43, riscv64: 43],
855  // statfs64
856  // statmount: TODO: the length is the first field of the struct
857  statmount(req: *const mnt_id_req, buf: *mut c_void, bufsize: size_t, flags: c_uint) /
858    { req: mnt_id_req, bufsize: size_t, flags: c_uint } -> c_int + { buf: Arc<statmount> @ sized_by(raw_args.bufsize) }
859    ~ [] for [x86_64: 457, aarch64: 457, riscv64: 457],
860  statx(dirfd: RawFd, pathname: *const c_char, flags: c_int, mask: c_uint, statxbuf: *mut statx) /
861    { dirfd: RawFd, pathname: PathBuf, flags: c_int, mask: c_uint } -> c_int + { statxbuf: statx }
862    ~ [Desc, File, FStat, StatLike] for [x86_64: 332, aarch64: 291, riscv64: 291],
863  // stime
864  // subpage_prot
865  // swapcontext
866  swapoff(path: *const c_char) / { path: PathBuf } -> c_int ~ [File] for [x86_64: 168, aarch64: 225, riscv64: 225],
867  swapon(path: *const c_char, swapflags: c_int) / { path: PathBuf, swapflags: c_int } -> c_int
868    ~ [File] for [x86_64: 167, aarch64: 224, riscv64: 224],
869  // switch_endian
870  symlink(target: *const c_char, linkpath: *const c_char) / { target: PathBuf, linkpath: PathBuf } -> c_int
871    ~ [File] for [x86_64: 88],
872  symlinkat(target: *const c_char, newdirfd: RawFd, linkpath: *const c_char) /
873    { target: PathBuf, newdirfd: RawFd, linkpath: PathBuf } -> c_int
874    ~ [Desc, File] for [x86_64: 266, aarch64: 36, riscv64: 36],
875  // TODO: sync always returns 0
876  sync() / {} -> c_int ~ [] for [x86_64: 162, aarch64: 81, riscv64: 81],
877  sync_file_range(fd: RawFd, offset: off_t, nbytes: off_t, flags: c_uint) /
878    { fd: RawFd, offset: off_t, nbytes: off_t, flags: c_uint } -> c_int
879    ~ [Desc] for [x86_64: 277, aarch64: 84, riscv64: 84],
880  // sync_file_range2
881  syncfs(fd: RawFd) / { fd: RawFd } -> c_int ~ [Desc] for [x86_64: 306, aarch64: 267, riscv64: 267],
882  // sys_debug_setcontext
883  // syscall
884  sysfs(option: c_int, arg1: c_ulong, arg2: c_ulong) / { option: c_int, arg1: c_ulong, arg2: c_ulong } -> c_int
885    ~ [] for [x86_64: 139],
886  sysinfo(info: *mut sysinfo) / { } -> c_int + { info: sysinfo } ~ [] for [x86_64: 99, aarch64: 179, riscv64: 179],
887  syslog(typ: c_int, buf: *const c_char, len: c_int) / { typ: c_int, buf: CString, len: c_int } -> c_int
888    ~ [] for [x86_64: 103, aarch64: 116, riscv64: 116],
889  // sysmips
890  tee(fd_in: RawFd, fd_out: RawFd, len: size_t, flags: c_uint) / { fd_in: RawFd, fd_out: RawFd, len: size_t, flags: c_uint } -> ssize_t
891    ~ [Desc] for [x86_64: 276, aarch64: 77, riscv64: 77],
892  tgkill(tgid: pid_t, tid: pid_t, sig: c_int) / { tgid: pid_t, tid: pid_t, sig: c_int } -> c_int
893    ~ [Signal, Process] for [x86_64: 234, aarch64: 131, riscv64: 131],
894  time(tloc: *mut time_t) / { } -> time_t + { tloc: Option<time_t> } ~ [Clock] for [x86_64: 201],
895  timer_create(clockid: clockid_t, sevp: *const sigevent, timerid: *mut timer_t) /
896    { clockid: clockid_t, sevp: Option<sigevent> } -> c_int + { timerid: InspectResult<timer_t> }
897    ~ [] for [x86_64: 222, aarch64: 107, riscv64: 107],
898  timer_delete(timerid: timer_t) / { timerid: timer_t } -> c_int ~ [] for [x86_64: 226, aarch64: 111, riscv64: 111],
899  timer_getoverrun(timerid: timer_t) / { timerid: timer_t } -> c_int ~ [] for [x86_64: 225, aarch64: 109, riscv64: 109],
900  timer_gettime(timerid: timer_t, curr_value: *mut itimerspec) / { timerid: timer_t } -> c_int + { curr_value: itimerspec }
901    ~ [] for [x86_64: 224, aarch64: 108, riscv64: 108],
902  // timer_gettime64
903  timer_settime(timerid: timer_t, flags: c_int, new_value: *const itimerspec, old_value: *mut itimerspec) /
904    { timerid: timer_t, flags: c_int, new_value: itimerspec } -> c_int + { old_value: Option<itimerspec> }
905    ~ [] for [x86_64: 223, aarch64: 110, riscv64: 110],
906  // timer_settime64
907  // timerfd
908  timerfd_create(clockid: clockid_t, flags: c_int) / { clockid: clockid_t, flags: c_int } -> RawFd
909    ~ [Desc] for [x86_64: 283, aarch64: 85, riscv64: 85],
910  timerfd_gettime(fd: RawFd, curr_value: *mut itimerspec) / { fd: RawFd } -> c_int + { curr_value: itimerspec }
911    ~ [Desc] for [x86_64: 287, aarch64: 87, riscv64: 87],
912  // timerfd_gettime64
913  timerfd_settime(fd: RawFd, flags: c_int, new_value: *const itimerspec, old_value: *mut itimerspec) /
914    { fd: RawFd, flags: c_int, new_value: itimerspec } -> c_int + { old_value: Option<itimerspec> }
915    ~ [Desc] for [x86_64: 286, aarch64: 86, riscv64: 86],
916  // timerfd_settime64
917  times(buf: *mut tms) / { } -> clock_t + { buf: tms } ~ [] for [x86_64: 100, aarch64: 153, riscv64: 153],
918  tkill(tid: pid_t, sig: c_int) / { tid: pid_t, sig: c_int } -> c_int ~ [Signal, Process] for [x86_64: 200, aarch64: 130, riscv64: 130],
919  truncate(path: *const c_char, length: off_t) / { path: PathBuf, length: off_t } -> c_int
920    ~ [File] for [x86_64: 76, aarch64: 45, riscv64: 45],
921  // truncate64
922  // ugetrlimit
923  umask(mask: mode_t) / { mask: mode_t } -> mode_t ~ [] for [x86_64: 95, aarch64: 166, riscv64: 166],
924  // umount
925  umount2(target: *const c_char, flags: c_int) / { target: PathBuf, flags: c_int } -> c_int
926    ~ [File] for [x86_64: 166, aarch64: 39, riscv64: 39],
927  uname(buf: *mut utsname) / { } -> c_int + { buf: utsname } ~ [] for [x86_64: 63, aarch64: 160, riscv64: 160],
928  unlink(pathname: *const c_char) / { pathname: PathBuf } -> c_int ~ [File] for [x86_64: 87],
929  unlinkat(dirfd: RawFd, pathname: *const c_char, flags: c_int) / { dirfd: RawFd, pathname: PathBuf, flags: c_int } -> c_int
930    ~ [Desc, File] for [x86_64: 263, aarch64: 35, riscv64: 35],
931  unshare(flags: c_int) / { flags: c_int } -> c_int ~ [] for [x86_64: 272, aarch64: 97, riscv64: 97],
932  uretprobe() / { } -> c_int ~ [] for [x86_64: 335],
933  userfaultfd(flags: c_uint) / { flags: c_uint } -> RawFd ~ [Desc] for [x86_64: 323, aarch64: 282, riscv64: 282],
934  ustat(dev: dev_t, ubuf: *mut ustat) / { dev: dev_t } -> c_int + { ubuf: ustat } ~ [] for [x86_64: 136],
935  utime(filename: *const c_char, times: *const utimbuf) / { filename: PathBuf, times: Option<utimbuf> } -> c_int
936    ~ [File] for [x86_64: 132],
937  utimensat(dirfd: RawFd, pathname: *const c_char, times: *const timespec, flags: c_int) /
938    { dirfd: RawFd, pathname: PathBuf, times: Option<[timespec; 2]>, flags: c_int } -> c_int
939    ~ [Desc, File] for [x86_64: 280, aarch64: 88, riscv64: 88],
940  // utimensat_time64
941  utimes(filename: *const c_char, times: *const timeval) / { filename: PathBuf, times: Option<[timeval; 2]> } -> c_int
942    ~ [File] for [x86_64: 235],
943  // utrap_install
944  vfork() / {} -> pid_t ~ [Process] for [x86_64: 58],
945  vhangup() / {} -> c_int ~ [] for [x86_64: 153, aarch64: 58, riscv64: 58],
946  // vm86
947  // vm86old
948  vmsplice(fd: RawFd, iov: *const iovec, nr_segs: size_t, flags: c_uint) /
949    { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.nr_segs), flags: c_uint } -> ssize_t
950    ~ [Desc] for [x86_64: 278, aarch64: 75, riscv64: 75],
951  wait4(pid: pid_t, wstatus: *mut c_int, options: c_int, rusage: *mut rusage) /
952    { pid: pid_t, options: c_int } -> pid_t + { wstatus: InspectResult<c_int>, rusage: Option<rusage> }
953    ~ [Process] for [x86_64: 61, aarch64: 260, riscv64: 260],
954  waitid(idtype: idtype_t, id: id_t, infop: *mut siginfo_t, options: c_int) /
955    { idtype: idtype_t, id: id_t, options: c_int } -> c_int + { infop: Option<siginfo_t> }
956    ~ [Process] for [x86_64: 247, aarch64: 95, riscv64: 95],
957  // waitpid
958  write(fd: RawFd, buf: *const c_void, count: size_t) / { fd: RawFd, buf: Vec<u8> @ counted_by(raw_args.count) } -> ssize_t
959    ~ [Desc] for [x86_64: 1, aarch64: 64, riscv64: 64],
960  writev(fd: RawFd, iov: *const iovec, iovcnt: c_int) / { fd: RawFd, iov: Vec<iovec> @ counted_by(raw_args.iovcnt) } -> ssize_t
961    ~ [Desc] for [x86_64: 20, aarch64: 66, riscv64: 66],
962}
963
964// pub use cfg_if_has_syscall;
965
966impl SyscallRawArgs {
967  /// Get the raw arguments of a syscall on syscall-enter stop.
968  ///
969  /// Calling this function elsewhere will result in incorrect results or errors.
970  pub fn get_on_sysenter(pid: Pid) -> Result<Self, Errno> {
971    let regs = ptrace_getregs(pid)?;
972    Ok(Self::from_regs(&regs))
973  }
974}