blob: a779045dfea795e3df66f3b1b5426efefc16bebd [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 crate::executive::ThreadContext;
use crate::syscalls::*;
use crate::types::*;
trait FromSyscallArg {
fn from_arg(arg: u64) -> Self;
}
impl FromSyscallArg for i32 {
fn from_arg(arg: u64) -> i32 {
arg as i32
}
}
impl FromSyscallArg for usize {
fn from_arg(arg: u64) -> usize {
arg as usize
}
}
impl FromSyscallArg for u64 {
fn from_arg(arg: u64) -> u64 {
arg
}
}
impl FromSyscallArg for UserAddress {
fn from_arg(arg: u64) -> UserAddress {
UserAddress::from(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)
}
}
macro_rules! syscall_match {
{
$ctx:ident; $syscall_number:ident; $args:ident;
$($call:ident => $func:ident $arg_spec:tt,)*
} => {
match $syscall_number {
$($call => syscall_match!(@call $ctx; $args; $func $arg_spec),)*
_ => sys_unknown($ctx, $syscall_number),
}
};
(@call $ctx:ident; $args:ident; $func:ident [0]) => ($func($ctx));
(@call $ctx:ident; $args:ident; $func:ident [1]) => ($func($ctx, $args.0.into_arg()));
(@call $ctx:ident; $args:ident; $func:ident [2]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg()));
(@call $ctx:ident; $args:ident; $func:ident [3]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg()));
(@call $ctx:ident; $args:ident; $func:ident [4]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg()));
(@call $ctx:ident; $args:ident; $func:ident [5]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg(), $args.4.into_arg()));
(@call $ctx:ident; $args:ident; $func:ident [6]) => ($func($ctx, $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(
ctx: &mut ThreadContext,
syscall_number: syscall_number_t,
args: (u64, u64, u64, u64, u64, u64),
) -> Result<SyscallResult, Errno> {
syscall_match! {
ctx; syscall_number; args;
SYS_WRITE => sys_write[3],
SYS_FSTAT => sys_fstat[2],
SYS_MMAP => sys_mmap[6],
SYS_MPROTECT => sys_mprotect[3],
SYS_BRK => sys_brk[1],
SYS_PREAD64 => sys_pread64[4],
SYS_WRITEV => sys_writev[3],
SYS_ACCESS => sys_access[2],
SYS_GETPID => sys_getpid[0],
SYS_EXIT => sys_exit[1],
SYS_UNAME => sys_uname[1],
SYS_READLINK => sys_readlink[3],
SYS_GETUID => sys_getuid[0],
SYS_GETGID => sys_getgid[0],
SYS_GETEUID => sys_geteuid[0],
SYS_GETEGID => sys_getegid[0],
SYS_FSTATFS => sys_fstatfs[2],
SYS_SCHED_GETSCHEDULER => sys_sched_getscheduler[1],
SYS_ARCH_PRCTL => sys_arch_prctl[2],
SYS_EXIT_GROUP => sys_exit_group[1],
SYS_OPENAT => sys_openat[4],
SYS_GETRANDOM => sys_getrandom[3],
}
}