blob: 96c8cd5811f7dd54878a45577ed961b674e6aad1 [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.
use paste::paste;
use zerocopy::{AsBytes, FromBytes};
use crate::fs::socket::syscalls::*;
use crate::fs::syscalls::*;
use crate::fs::FdNumber;
use crate::mm::syscalls::*;
use crate::signals::syscalls::*;
use crate::syscalls::system::*;
use crate::syscalls::{CurrentTask, SyscallResult};
use crate::task::syscalls::*;
use crate::types::*;
macro_rules! syscall_match {
{
$current_task:ident; $syscall_number:ident; $args:ident;
$($call:ident [$num_args:tt],)*
} => {
paste! {
match $syscall_number as u32 {
$(
crate::types::[<__NR_ $call>] => {
match syscall_match!(@call $current_task; $args; [<sys_ $call>][$num_args]) {
Ok(x) => Ok(SyscallResult::from(x)),
Err(err) => Err(err),
}
},
)*
_ => sys_unknown($current_task, $syscall_number),
}
}
};
(@call $current_task:ident; $args:ident; $func:ident [0]) => ($func($current_task));
(@call $current_task:ident; $args:ident; $func:ident [1]) => ($func($current_task, $args.0.into_arg()));
(@call $current_task:ident; $args:ident; $func:ident [2]) => ($func($current_task, $args.0.into_arg(), $args.1.into_arg()));
(@call $current_task:ident; $args:ident; $func:ident [3]) => ($func($current_task, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg()));
(@call $current_task:ident; $args:ident; $func:ident [4]) => ($func($current_task, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg()));
(@call $current_task:ident; $args:ident; $func:ident [5]) => ($func($current_task, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg(), $args.4.into_arg()));
(@call $current_task:ident; $args:ident; $func:ident [6]) => ($func($current_task, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg(), $args.4.into_arg(), $args.5.into_arg()));
}
pub fn dispatch_syscall(
current_task: &mut CurrentTask,
syscall_number: u64,
args: (u64, u64, u64, u64, u64, u64),
) -> Result<SyscallResult, Errno> {
syscall_match! {
current_task; syscall_number; args;
accept4[4],
accept[3],
access[2],
arch_prctl[2],
bind[3],
brk[1],
capget[2],
chdir[1],
chmod[2],
chroot[1],
clock_getres[2],
clock_gettime[2],
clone[5],
close[1],
connect[3],
dup2[2],
dup3[3],
dup[1],
epoll_create1[1],
epoll_create[1],
epoll_ctl[4],
epoll_pwait[5],
epoll_wait[4],
eventfd2[2],
eventfd[1],
execve[3],
exit[1],
exit_group[1],
faccessat[3],
fchdir[1],
fchmod[2],
fchmodat[3],
fchown[3],
fchownat[5],
fcntl[3],
fdatasync[1],
fgetxattr[4],
flistxattr[3],
flock[2],
fremovexattr[2],
fsetxattr[5],
fstat[2],
fstatfs[2],
fsync[1],
ftruncate[2],
futex[6],
getcwd[2],
getdents64[3],
getdents[3],
getegid[0],
geteuid[0],
getgid[0],
getgroups[2],
getitimer[2],
getpeername[3],
getpgid[1],
getpgrp[0],
getpid[0],
getppid[0],
getpriority[2],
getrandom[3],
getresgid[3],
getresuid[3],
getrlimit[2],
getrusage[2],
getsid[1],
getsockname[3],
getsockopt[5],
gettid[0],
gettimeofday[2],
getuid[0],
getxattr[4],
ioctl[3],
kill[2],
lgetxattr[4],
linkat[5],
listen[2],
listxattr[3],
llistxattr[3],
lremovexattr[2],
lseek[3],
lsetxattr[5],
lstat[2],
madvise[3],
membarrier[3],
memfd_create[2],
mkdir[2],
mkdirat[3],
mknodat[4],
mmap[6],
mount[5],
mprotect[3],
mremap[5],
msync[3],
munmap[2],
nanosleep[2],
newfstatat[4],
open[3],
openat[4],
pipe2[2],
pipe[1],
poll[3],
ppoll[4],
prctl[5],
pread64[4],
process_vm_readv[6],
pselect6[6],
prlimit64[4],
pwrite64[4],
read[3],
readlink[3],
readlinkat[4],
readv[3],
reboot[4],
recvfrom[6],
recvmmsg[5],
recvmsg[3],
removexattr[2],
rename[2],
renameat[4],
rmdir[1],
rt_sigaction[4],
rt_sigprocmask[4],
rt_sigreturn[0],
rt_sigsuspend[2],
rt_sigtimedwait[4],
rt_tgsigqueueinfo[4],
sched_getaffinity[3],
sched_getparam[2],
sched_getscheduler[1],
sched_setaffinity[3],
sendmmsg[4],
sendmsg[3],
sendto[6],
setgid[1],
setgroups[2],
setitimer[3],
setpgid[2],
setpriority[3],
setresgid[3],
setresuid[3],
setrlimit[2],
setsid[0],
setsockopt[5],
set_tid_address[1],
setuid[1],
setxattr[5],
shutdown[2],
sigaltstack[2],
signalfd4[4],
socket[3],
socketpair[4],
stat[2],
statfs[2],
symlinkat[3],
tgkill[3],
time[1],
timerfd_create[2],
timerfd_gettime[2],
timerfd_settime[4],
tkill[2],
truncate[2],
umask[1],
uname[1],
unlink[1],
unlinkat[3],
unshare[1],
vfork[0],
wait4[4],
waitid[4],
write[3],
writev[3],
}
}
trait FromSyscallArg {
fn from_arg(arg: u64) -> Self;
}
impl FromSyscallArg for i32 {
fn from_arg(arg: u64) -> i32 {
arg as i32
}
}
impl FromSyscallArg for u32 {
fn from_arg(arg: u64) -> u32 {
arg as u32
}
}
impl FromSyscallArg for usize {
fn from_arg(arg: u64) -> usize {
arg as usize
}
}
impl FromSyscallArg for i64 {
fn from_arg(arg: u64) -> i64 {
arg as i64
}
}
impl FromSyscallArg for u64 {
fn from_arg(arg: u64) -> u64 {
arg
}
}
impl FromSyscallArg for UserAddress {
fn from_arg(arg: u64) -> UserAddress {
UserAddress::from(arg)
}
}
impl<T: AsBytes + FromBytes> FromSyscallArg for UserRef<T> {
fn from_arg(arg: u64) -> UserRef<T> {
UserRef::<T>::new(UserAddress::from(arg))
}
}
impl FromSyscallArg for UserCString {
fn from_arg(arg: u64) -> UserCString {
UserCString::new(UserAddress::from(arg))
}
}
impl FromSyscallArg for FdNumber {
fn from_arg(arg: u64) -> FdNumber {
FdNumber::from_raw(arg as i32)
}
}
impl FromSyscallArg for FileMode {
fn from_arg(arg: u64) -> FileMode {
FileMode::from_bits(arg as u32)
}
}
impl FromSyscallArg for DeviceType {
fn from_arg(arg: u64) -> DeviceType {
DeviceType::from_bits(arg)
}
}
impl FromSyscallArg for UncheckedSignal {
fn from_arg(arg: u64) -> UncheckedSignal {
UncheckedSignal::new(arg)
}
}
trait IntoSyscallArg<T> {
fn into_arg(self) -> T;
}
impl<T> IntoSyscallArg<T> for u64
where
T: FromSyscallArg,
{
fn into_arg(self) -> T {
T::from_arg(self)
}
}