blob: 946782086f45ef3e84fd468903266032745b412e [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
use fuchsia_zircon as zx;
use paste::paste;
use std::fmt;
use zerocopy::{AsBytes, FromBytes};
use crate::fs::FdNumber;
pub use crate::user_address::*;
#[cfg(target_arch = "x86_64")]
use linux_uapi::x86_64 as uapi;
pub use uapi::*;
pub type dev_t = uapi::__kernel_old_dev_t;
pub type gid_t = uapi::__kernel_gid_t;
pub type ino_t = uapi::__kernel_ino_t;
pub type mode_t = uapi::__kernel_mode_t;
pub type off_t = uapi::__kernel_off_t;
pub type pid_t = uapi::__kernel_pid_t;
pub type uid_t = uapi::__kernel_uid_t;
#[derive(Debug, Eq, PartialEq)]
pub struct Errno {
value: u32,
name: &'static str,
}
impl Errno {
pub fn value(&self) -> i32 {
self.value as i32
}
}
impl fmt::Display for Errno {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "error {}: {}", self.value, self.name)
}
}
pub const EPERM: Errno = Errno { value: uapi::EPERM, name: "EPERM" };
pub const ENOENT: Errno = Errno { value: uapi::ENOENT, name: "ENOENT" };
pub const ESRCH: Errno = Errno { value: uapi::ESRCH, name: "ESRCH" };
pub const EINTR: Errno = Errno { value: uapi::EINTR, name: "EINTR" };
pub const EIO: Errno = Errno { value: uapi::EIO, name: "EIO" };
pub const ENXIO: Errno = Errno { value: uapi::ENXIO, name: "ENXIO" };
pub const E2BIG: Errno = Errno { value: uapi::E2BIG, name: "E2BIG" };
pub const ENOEXEC: Errno = Errno { value: uapi::ENOEXEC, name: "ENOEXEC" };
pub const EBADF: Errno = Errno { value: uapi::EBADF, name: "EBADF" };
pub const ECHILD: Errno = Errno { value: uapi::ECHILD, name: "ECHILD" };
pub const EAGAIN: Errno = Errno { value: uapi::EAGAIN, name: "EAGAIN" };
pub const ENOMEM: Errno = Errno { value: uapi::ENOMEM, name: "ENOMEM" };
pub const EACCES: Errno = Errno { value: uapi::EACCES, name: "EACCES" };
pub const EFAULT: Errno = Errno { value: uapi::EFAULT, name: "EFAULT" };
pub const ENOTBLK: Errno = Errno { value: uapi::ENOTBLK, name: "ENOTBLK" };
pub const EBUSY: Errno = Errno { value: uapi::EBUSY, name: "EBUSY" };
pub const EEXIST: Errno = Errno { value: uapi::EEXIST, name: "EEXIST" };
pub const EXDEV: Errno = Errno { value: uapi::EXDEV, name: "EXDEV" };
pub const ENODEV: Errno = Errno { value: uapi::ENODEV, name: "ENODEV" };
pub const ENOTDIR: Errno = Errno { value: uapi::ENOTDIR, name: "ENOTDIR" };
pub const EISDIR: Errno = Errno { value: uapi::EISDIR, name: "EISDIR" };
pub const EINVAL: Errno = Errno { value: uapi::EINVAL, name: "EINVAL" };
pub const ENFILE: Errno = Errno { value: uapi::ENFILE, name: "ENFILE" };
pub const EMFILE: Errno = Errno { value: uapi::EMFILE, name: "EMFILE" };
pub const ENOTTY: Errno = Errno { value: uapi::ENOTTY, name: "ENOTTY" };
pub const ETXTBSY: Errno = Errno { value: uapi::ETXTBSY, name: "ETXTBSY" };
pub const EFBIG: Errno = Errno { value: uapi::EFBIG, name: "EFBIG" };
pub const ENOSPC: Errno = Errno { value: uapi::ENOSPC, name: "ENOSPC" };
pub const ESPIPE: Errno = Errno { value: uapi::ESPIPE, name: "ESPIPE" };
pub const EROFS: Errno = Errno { value: uapi::EROFS, name: "EROFS" };
pub const EMLINK: Errno = Errno { value: uapi::EMLINK, name: "EMLINK" };
pub const EPIPE: Errno = Errno { value: uapi::EPIPE, name: "EPIPE" };
pub const EDOM: Errno = Errno { value: uapi::EDOM, name: "EDOM" };
pub const ERANGE: Errno = Errno { value: uapi::ERANGE, name: "ERANGE" };
pub const EDEADLK: Errno = Errno { value: uapi::EDEADLK, name: "EDEADLK" };
pub const ENAMETOOLONG: Errno = Errno { value: uapi::ENAMETOOLONG, name: "ENAMETOOLONG" };
pub const ENOLCK: Errno = Errno { value: uapi::ENOLCK, name: "ENOLCK" };
pub const ENOSYS: Errno = Errno { value: uapi::ENOSYS, name: "ENOSYS" };
pub const ENOTEMPTY: Errno = Errno { value: uapi::ENOTEMPTY, name: "ENOTEMPTY" };
pub const ELOOP: Errno = Errno { value: uapi::ELOOP, name: "ELOOP" };
pub const EWOULDBLOCK: Errno = Errno { value: uapi::EWOULDBLOCK, name: "EWOULDBLOCK" };
pub const ENOMSG: Errno = Errno { value: uapi::ENOMSG, name: "ENOMSG" };
pub const EIDRM: Errno = Errno { value: uapi::EIDRM, name: "EIDRM" };
pub const ECHRNG: Errno = Errno { value: uapi::ECHRNG, name: "ECHRNG" };
pub const EL2NSYNC: Errno = Errno { value: uapi::EL2NSYNC, name: "EL2NSYNC" };
pub const EL3HLT: Errno = Errno { value: uapi::EL3HLT, name: "EL3HLT" };
pub const EL3RST: Errno = Errno { value: uapi::EL3RST, name: "EL3RST" };
pub const ELNRNG: Errno = Errno { value: uapi::ELNRNG, name: "ELNRNG" };
pub const EUNATCH: Errno = Errno { value: uapi::EUNATCH, name: "EUNATCH" };
pub const ENOCSI: Errno = Errno { value: uapi::ENOCSI, name: "ENOCSI" };
pub const EL2HLT: Errno = Errno { value: uapi::EL2HLT, name: "EL2HLT" };
pub const EBADE: Errno = Errno { value: uapi::EBADE, name: "EBADE" };
pub const EBADR: Errno = Errno { value: uapi::EBADR, name: "EBADR" };
pub const EXFULL: Errno = Errno { value: uapi::EXFULL, name: "EXFULL" };
pub const ENOANO: Errno = Errno { value: uapi::ENOANO, name: "ENOANO" };
pub const EBADRQC: Errno = Errno { value: uapi::EBADRQC, name: "EBADRQC" };
pub const EBADSLT: Errno = Errno { value: uapi::EBADSLT, name: "EBADSLT" };
pub const EDEADLOCK: Errno = Errno { value: uapi::EDEADLOCK, name: "EDEADLOCK" };
pub const EBFONT: Errno = Errno { value: uapi::EBFONT, name: "EBFONT" };
pub const ENOSTR: Errno = Errno { value: uapi::ENOSTR, name: "ENOSTR" };
pub const ENODATA: Errno = Errno { value: uapi::ENODATA, name: "ENODATA" };
pub const ETIME: Errno = Errno { value: uapi::ETIME, name: "ETIME" };
pub const ENOSR: Errno = Errno { value: uapi::ENOSR, name: "ENOSR" };
pub const ENONET: Errno = Errno { value: uapi::ENONET, name: "ENONET" };
pub const ENOPKG: Errno = Errno { value: uapi::ENOPKG, name: "ENOPKG" };
pub const EREMOTE: Errno = Errno { value: uapi::EREMOTE, name: "EREMOTE" };
pub const ENOLINK: Errno = Errno { value: uapi::ENOLINK, name: "ENOLINK" };
pub const EADV: Errno = Errno { value: uapi::EADV, name: "EADV" };
pub const ESRMNT: Errno = Errno { value: uapi::ESRMNT, name: "ESRMNT" };
pub const ECOMM: Errno = Errno { value: uapi::ECOMM, name: "ECOMM" };
pub const EPROTO: Errno = Errno { value: uapi::EPROTO, name: "EPROTO" };
pub const EMULTIHOP: Errno = Errno { value: uapi::EMULTIHOP, name: "EMULTIHOP" };
pub const EDOTDOT: Errno = Errno { value: uapi::EDOTDOT, name: "EDOTDOT" };
pub const EBADMSG: Errno = Errno { value: uapi::EBADMSG, name: "EBADMSG" };
pub const EOVERFLOW: Errno = Errno { value: uapi::EOVERFLOW, name: "EOVERFLOW" };
pub const ENOTUNIQ: Errno = Errno { value: uapi::ENOTUNIQ, name: "ENOTUNIQ" };
pub const EBADFD: Errno = Errno { value: uapi::EBADFD, name: "EBADFD" };
pub const EREMCHG: Errno = Errno { value: uapi::EREMCHG, name: "EREMCHG" };
pub const ELIBACC: Errno = Errno { value: uapi::ELIBACC, name: "ELIBACC" };
pub const ELIBBAD: Errno = Errno { value: uapi::ELIBBAD, name: "ELIBBAD" };
pub const ELIBSCN: Errno = Errno { value: uapi::ELIBSCN, name: "ELIBSCN" };
pub const ELIBMAX: Errno = Errno { value: uapi::ELIBMAX, name: "ELIBMAX" };
pub const ELIBEXEC: Errno = Errno { value: uapi::ELIBEXEC, name: "ELIBEXEC" };
pub const EILSEQ: Errno = Errno { value: uapi::EILSEQ, name: "EILSEQ" };
pub const ERESTART: Errno = Errno { value: uapi::ERESTART, name: "ERESTART" };
pub const ESTRPIPE: Errno = Errno { value: uapi::ESTRPIPE, name: "ESTRPIPE" };
pub const EUSERS: Errno = Errno { value: uapi::EUSERS, name: "EUSERS" };
pub const ENOTSOCK: Errno = Errno { value: uapi::ENOTSOCK, name: "ENOTSOCK" };
pub const EDESTADDRREQ: Errno = Errno { value: uapi::EDESTADDRREQ, name: "EDESTADDRREQ" };
pub const EMSGSIZE: Errno = Errno { value: uapi::EMSGSIZE, name: "EMSGSIZE" };
pub const EPROTOTYPE: Errno = Errno { value: uapi::EPROTOTYPE, name: "EPROTOTYPE" };
pub const ENOPROTOOPT: Errno = Errno { value: uapi::ENOPROTOOPT, name: "ENOPROTOOPT" };
pub const EPROTONOSUPPORT: Errno = Errno { value: uapi::EPROTONOSUPPORT, name: "EPROTONOSUPPORT" };
pub const ESOCKTNOSUPPORT: Errno = Errno { value: uapi::ESOCKTNOSUPPORT, name: "ESOCKTNOSUPPORT" };
pub const EOPNOTSUPP: Errno = Errno { value: uapi::EOPNOTSUPP, name: "EOPNOTSUPP" };
pub const EPFNOSUPPORT: Errno = Errno { value: uapi::EPFNOSUPPORT, name: "EPFNOSUPPORT" };
pub const EAFNOSUPPORT: Errno = Errno { value: uapi::EAFNOSUPPORT, name: "EAFNOSUPPORT" };
pub const EADDRINUSE: Errno = Errno { value: uapi::EADDRINUSE, name: "EADDRINUSE" };
pub const EADDRNOTAVAIL: Errno = Errno { value: uapi::EADDRNOTAVAIL, name: "EADDRNOTAVAIL" };
pub const ENETDOWN: Errno = Errno { value: uapi::ENETDOWN, name: "ENETDOWN" };
pub const ENETUNREACH: Errno = Errno { value: uapi::ENETUNREACH, name: "ENETUNREACH" };
pub const ENETRESET: Errno = Errno { value: uapi::ENETRESET, name: "ENETRESET" };
pub const ECONNABORTED: Errno = Errno { value: uapi::ECONNABORTED, name: "ECONNABORTED" };
pub const ECONNRESET: Errno = Errno { value: uapi::ECONNRESET, name: "ECONNRESET" };
pub const ENOBUFS: Errno = Errno { value: uapi::ENOBUFS, name: "ENOBUFS" };
pub const EISCONN: Errno = Errno { value: uapi::EISCONN, name: "EISCONN" };
pub const ENOTCONN: Errno = Errno { value: uapi::ENOTCONN, name: "ENOTCONN" };
pub const ESHUTDOWN: Errno = Errno { value: uapi::ESHUTDOWN, name: "ESHUTDOWN" };
pub const ETOOMANYREFS: Errno = Errno { value: uapi::ETOOMANYREFS, name: "ETOOMANYREFS" };
pub const ETIMEDOUT: Errno = Errno { value: uapi::ETIMEDOUT, name: "ETIMEDOUT" };
pub const ECONNREFUSED: Errno = Errno { value: uapi::ECONNREFUSED, name: "ECONNREFUSED" };
pub const EHOSTDOWN: Errno = Errno { value: uapi::EHOSTDOWN, name: "EHOSTDOWN" };
pub const EHOSTUNREACH: Errno = Errno { value: uapi::EHOSTUNREACH, name: "EHOSTUNREACH" };
pub const EALREADY: Errno = Errno { value: uapi::EALREADY, name: "EALREADY" };
pub const EINPROGRESS: Errno = Errno { value: uapi::EINPROGRESS, name: "EINPROGRESS" };
pub const ESTALE: Errno = Errno { value: uapi::ESTALE, name: "ESTALE" };
pub const EUCLEAN: Errno = Errno { value: uapi::EUCLEAN, name: "EUCLEAN" };
pub const ENOTNAM: Errno = Errno { value: uapi::ENOTNAM, name: "ENOTNAM" };
pub const ENAVAIL: Errno = Errno { value: uapi::ENAVAIL, name: "ENAVAIL" };
pub const EISNAM: Errno = Errno { value: uapi::EISNAM, name: "EISNAM" };
pub const EREMOTEIO: Errno = Errno { value: uapi::EREMOTEIO, name: "EREMOTEIO" };
pub const EDQUOT: Errno = Errno { value: uapi::EDQUOT, name: "EDQUOT" };
pub const ENOMEDIUM: Errno = Errno { value: uapi::ENOMEDIUM, name: "ENOMEDIUM" };
pub const EMEDIUMTYPE: Errno = Errno { value: uapi::EMEDIUMTYPE, name: "EMEDIUMTYPE" };
pub const ECANCELED: Errno = Errno { value: uapi::ECANCELED, name: "ECANCELED" };
pub const ENOKEY: Errno = Errno { value: uapi::ENOKEY, name: "ENOKEY" };
pub const EKEYEXPIRED: Errno = Errno { value: uapi::EKEYEXPIRED, name: "EKEYEXPIRED" };
pub const EKEYREVOKED: Errno = Errno { value: uapi::EKEYREVOKED, name: "EKEYREVOKED" };
pub const EKEYREJECTED: Errno = Errno { value: uapi::EKEYREJECTED, name: "EKEYREJECTED" };
pub const EOWNERDEAD: Errno = Errno { value: uapi::EOWNERDEAD, name: "EOWNERDEAD" };
pub const ENOTRECOVERABLE: Errno = Errno { value: uapi::ENOTRECOVERABLE, name: "ENOTRECOVERABLE" };
pub const ERFKILL: Errno = Errno { value: uapi::ERFKILL, name: "ERFKILL" };
pub const EHWPOISON: Errno = Errno { value: uapi::EHWPOISON, name: "EHWPOISON" };
// There isn't really a mapping from zx::Status to Errno. The correct mapping is context-speific
// but this converter is a reasonable first-approximation. The translation matches
// fdio_status_to_errno. See fxbug.dev/30921 for more context.
// TODO: Replace clients with more context-specific mappings.
impl Errno {
pub fn from_status_like_fdio(status: zx::Status) -> Self {
match status {
zx::Status::NOT_FOUND => ENOENT,
zx::Status::NO_MEMORY => ENOMEM,
zx::Status::INVALID_ARGS => EINVAL,
zx::Status::BUFFER_TOO_SMALL => EINVAL,
zx::Status::TIMED_OUT => ETIMEDOUT,
zx::Status::UNAVAILABLE => EBUSY,
zx::Status::ALREADY_EXISTS => EEXIST,
zx::Status::PEER_CLOSED => EPIPE,
zx::Status::BAD_STATE => EPIPE,
zx::Status::BAD_PATH => ENAMETOOLONG,
zx::Status::IO => EIO,
zx::Status::NOT_FILE => EISDIR,
zx::Status::NOT_DIR => ENOTDIR,
zx::Status::NOT_SUPPORTED => EOPNOTSUPP,
zx::Status::WRONG_TYPE => EOPNOTSUPP,
zx::Status::OUT_OF_RANGE => EINVAL,
zx::Status::NO_RESOURCES => ENOMEM,
zx::Status::BAD_HANDLE => EBADF,
zx::Status::ACCESS_DENIED => EACCES,
zx::Status::SHOULD_WAIT => EAGAIN,
zx::Status::FILE_BIG => EFBIG,
zx::Status::NO_SPACE => ENOSPC,
zx::Status::NOT_EMPTY => ENOTEMPTY,
zx::Status::IO_REFUSED => ECONNREFUSED,
zx::Status::IO_INVALID => EIO,
zx::Status::CANCELED => EBADF,
zx::Status::PROTOCOL_NOT_SUPPORTED => EPROTONOSUPPORT,
zx::Status::ADDRESS_UNREACHABLE => ENETUNREACH,
zx::Status::ADDRESS_IN_USE => EADDRINUSE,
zx::Status::NOT_CONNECTED => ENOTCONN,
zx::Status::CONNECTION_REFUSED => ECONNREFUSED,
zx::Status::CONNECTION_RESET => ECONNRESET,
zx::Status::CONNECTION_ABORTED => ECONNABORTED,
_ => EIO,
}
}
}
/// Calls the given callback with the given context, delimited with semicolons,
/// followed by each syscall, delimited with commas.
///
/// Intended to be used with other macros to produce code that needs to handle
/// each syscall.
macro_rules! for_each_syscall {
{$callback:ident $(,$context:ident)*} => {
$callback!{
$($context;)*
read,
write,
open,
close,
stat,
fstat,
lstat,
poll,
lseek,
mmap,
mprotect,
munmap,
brk,
rt_sigaction,
rt_sigprocmask,
rt_sigreturn,
ioctl,
pread64,
pwrite64,
readv,
writev,
access,
pipe,
select,
sched_yield,
mremap,
msync,
mincore,
madvise,
shmget,
shmat,
shmctl,
dup,
dup2,
pause,
nanosleep,
getitimer,
alarm,
setitimer,
getpid,
sendfile,
socket,
connect,
accept,
sendto,
recvfrom,
sendmsg,
recvmsg,
shutdown,
bind,
listen,
getsockname,
getpeername,
socketpair,
setsockopt,
getsockopt,
clone,
fork,
vfork,
execve,
exit,
wait4,
kill,
uname,
semget,
semop,
semctl,
shmdt,
msgget,
msgsnd,
msgrcv,
msgctl,
fcntl,
flock,
fsync,
fdatasync,
truncate,
ftruncate,
getdents,
getcwd,
chdir,
fchdir,
rename,
mkdir,
rmdir,
creat,
link,
unlink,
symlink,
readlink,
chmod,
fchmod,
chown,
fchown,
lchown,
umask,
gettimeofday,
getrlimit,
getrusage,
sysinfo,
times,
ptrace,
getuid,
syslog,
getgid,
setuid,
setgid,
geteuid,
getegid,
setpgid,
getppid,
getpgrp,
setsid,
setreuid,
setregid,
getgroups,
setgroups,
setresuid,
getresuid,
setresgid,
getresgid,
getpgid,
setfsuid,
setfsgid,
getsid,
capget,
capset,
rt_sigpending,
rt_sigtimedwait,
rt_sigqueueinfo,
rt_sigsuspend,
sigaltstack,
utime,
mknod,
uselib,
personality,
ustat,
statfs,
fstatfs,
sysfs,
getpriority,
setpriority,
sched_setparam,
sched_getparam,
sched_setscheduler,
sched_getscheduler,
sched_get_priority_max,
sched_get_priority_min,
sched_rr_get_interval,
mlock,
munlock,
mlockall,
munlockall,
vhangup,
modify_ldt,
pivot_root,
_sysctl,
prctl,
arch_prctl,
adjtimex,
setrlimit,
chroot,
sync,
acct,
settimeofday,
mount,
umount2,
swapon,
swapoff,
reboot,
sethostname,
setdomainname,
iopl,
ioperm,
create_module,
init_module,
delete_module,
get_kernel_syms,
query_module,
quotactl,
nfsservctl,
getpmsg,
putpmsg,
afs_syscall,
tuxcall,
security,
gettid,
readahead,
setxattr,
lsetxattr,
fsetxattr,
getxattr,
lgetxattr,
fgetxattr,
listxattr,
llistxattr,
flistxattr,
removexattr,
lremovexattr,
fremovexattr,
tkill,
time,
futex,
sched_setaffinity,
sched_getaffinity,
set_thread_area,
io_setup,
io_destroy,
io_getevents,
io_submit,
io_cancel,
get_thread_area,
lookup_dcookie,
epoll_create,
epoll_ctl_old,
epoll_wait_old,
remap_file_pages,
getdents64,
set_tid_address,
restart_syscall,
semtimedop,
fadvise64,
timer_create,
timer_settime,
timer_gettime,
timer_getoverrun,
timer_delete,
clock_settime,
clock_gettime,
clock_getres,
clock_nanosleep,
exit_group,
epoll_wait,
epoll_ctl,
tgkill,
utimes,
vserver,
mbind,
set_mempolicy,
get_mempolicy,
mq_open,
mq_unlink,
mq_timedsend,
mq_timedreceive,
mq_notify,
mq_getsetattr,
kexec_load,
waitid,
add_key,
request_key,
keyctl,
ioprio_set,
ioprio_get,
inotify_init,
inotify_add_watch,
inotify_rm_watch,
migrate_pages,
openat,
mkdirat,
mknodat,
fchownat,
futimesat,
newfstatat,
unlinkat,
renameat,
linkat,
symlinkat,
readlinkat,
fchmodat,
faccessat,
pselect6,
ppoll,
unshare,
set_robust_list,
get_robust_list,
splice,
tee,
sync_file_range,
vmsplice,
move_pages,
utimensat,
epoll_pwait,
signalfd,
timerfd_create,
eventfd,
fallocate,
timerfd_settime,
timerfd_gettime,
accept4,
signalfd4,
eventfd2,
epoll_create1,
dup3,
pipe2,
inotify_init1,
preadv,
pwritev,
rt_tgsigqueueinfo,
perf_event_open,
recvmmsg,
fanotify_init,
fanotify_mark,
prlimit64,
name_to_handle_at,
open_by_handle_at,
clock_adjtime,
syncfs,
sendmmsg,
setns,
getcpu,
process_vm_readv,
process_vm_writev,
kcmp,
finit_module,
sched_setattr,
sched_getattr,
renameat2,
seccomp,
getrandom,
memfd_create,
kexec_file_load,
bpf,
execveat,
userfaultfd,
membarrier,
mlock2,
copy_file_range,
preadv2,
pwritev2,
pkey_mprotect,
pkey_alloc,
pkey_free,
statx,
io_pgetevents,
rseq,
pidfd_send_signal,
io_uring_setup,
io_uring_enter,
io_uring_register,
open_tree,
move_mount,
fsopen,
fsconfig,
fsmount,
fspick,
pidfd_open,
clone3,
close_range,
openat2,
pidfd_getfd,
faccessat2,
process_madvise,
}
}
}
/// A system call declaration.
///
/// Describes the name of the syscall and its number.
///
/// TODO: Add information about the number of arguments (and their types) so
/// that we can make strace more useful.
pub struct SyscallDecl {
pub name: &'static str,
pub number: u64,
}
/// A macro for declaring a const SyscallDecl for a given syscall.
///
/// The constant will be called DECL_<SYSCALL>.
macro_rules! syscall_decl {
{$($name:ident,)*} => {
paste! {
$(pub const [<DECL_ $name:upper>]: SyscallDecl = SyscallDecl { name: stringify!($name), number: [<__NR_ $name>] as u64};)*
}
}
}
// Produce each syscall declaration.
for_each_syscall! {syscall_decl}
/// A declaration for an unknown syscall.
///
/// Useful so that functions that return a SyscallDecl have a sentinel
/// to return when they cannot find an appropriate syscall.
pub const DECL_UNKNOWN: SyscallDecl = SyscallDecl { name: "<unknown>", number: 0xFFFF };
/// A macro for the body of SyscallDecl::from_number.
///
/// Evaluates to the &'static SyscallDecl for the given number or to
/// &DECL_UNKNOWN if the number is unknown.
macro_rules! syscall_match {
{$number:ident; $($name:ident,)*} => {
paste! {
match $number as u32 {
$([<__NR_ $name>] => &[<DECL_ $name:upper>],)*
_ => &DECL_UNKNOWN,
}
}
}
}
impl SyscallDecl {
/// The SyscallDecl for the given syscall number.
///
/// Returns &DECL_UNKNOWN if the given syscall number is not known.
pub fn from_number(number: u64) -> &'static SyscallDecl {
for_each_syscall! { syscall_match, number }
}
}
/// The result of executing a syscall.
///
/// It would be nice to have this also cover errors, but currently there is no stable way
/// to implement `std::ops::Try` (for the `?` operator) for custom enums, making it difficult
/// to work with.
#[derive(Debug, Eq, PartialEq)]
pub enum SyscallResult {
/// The process exited as a result of the syscall. The associated `u64` represents the process'
/// exit code.
Exit(i32),
/// The syscall completed successfully. The associated `u64` is the return value from the
/// syscall.
Success(u64),
}
pub const SUCCESS: SyscallResult = SyscallResult::Success(0);
impl From<UserAddress> for SyscallResult {
fn from(value: UserAddress) -> Self {
SyscallResult::Success(value.ptr() as u64)
}
}
impl From<FdNumber> for SyscallResult {
fn from(value: FdNumber) -> Self {
SyscallResult::Success(value.raw() as u64)
}
}
impl From<bool> for SyscallResult {
fn from(value: bool) -> Self {
SyscallResult::Success(if value { 1 } else { 0 })
}
}
impl From<i32> for SyscallResult {
fn from(value: i32) -> Self {
SyscallResult::Success(value as u64)
}
}
impl From<u32> for SyscallResult {
fn from(value: u32) -> Self {
SyscallResult::Success(value as u64)
}
}
impl From<u64> for SyscallResult {
fn from(value: u64) -> Self {
SyscallResult::Success(value)
}
}
impl From<usize> for SyscallResult {
fn from(value: usize) -> Self {
SyscallResult::Success(value as u64)
}
}
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, AsBytes, FromBytes)]
#[repr(C)]
pub struct utsname_t {
pub sysname: [u8; 65],
pub nodename: [u8; 65],
pub release: [u8; 65],
pub version: [u8; 65],
pub machine: [u8; 65],
}
#[derive(Debug, Default, Clone, Copy, AsBytes, FromBytes)]
#[repr(C)]
pub struct stat_t {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_nlink: u64,
pub st_mode: mode_t,
pub st_uid: uid_t,
pub st_gid: gid_t,
pub _pad0: u32,
pub st_rdev: dev_t,
pub st_size: off_t,
pub st_blksize: i64,
pub st_blocks: i64,
pub st_atim: timespec,
pub st_mtim: timespec,
pub st_ctim: timespec,
pub _pad3: [i64; 3],
}
#[derive(Debug, Default, Clone, Copy, AsBytes, FromBytes)]
#[repr(C)]
pub struct iovec_t {
pub iov_base: UserAddress,
pub iov_len: usize,
}
#[derive(Debug, Default, Clone, Copy, AsBytes, FromBytes)]
#[repr(C)]
pub struct statfs {
f_type: i64,
f_bsize: i64,
f_blocks: i64,
f_bfree: i64,
f_bavail: i64,
f_files: i64,
f_ffree: i64,
f_fsid: i64,
f_namelen: i64,
f_frsize: i64,
f_flags: i64,
f_spare: [i64; 4],
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, AsBytes, FromBytes)]
#[repr(C)]
pub struct sigaltstack_t {
pub ss_sp: UserAddress,
pub ss_flags: u32,
pub _pad0: u32,
pub ss_size: usize,
}