Extract x86-specific syscall dispatch to arch/x86

This commit is contained in:
YanWQ-monad
2024-05-04 04:36:19 +08:00
committed by Tate, Hongliang Tian
parent f19dfc7873
commit 0d5131c822
110 changed files with 444 additions and 776 deletions

View File

@ -4,127 +4,12 @@
//! The each sub module contains functions that handle real syscall logic.
use aster_frame::cpu::UserContext;
use self::{
accept::{sys_accept, sys_accept4},
alarm::sys_alarm,
bind::sys_bind,
connect::sys_connect,
eventfd::{sys_eventfd, sys_eventfd2},
execve::sys_execveat,
getgroups::sys_getgroups,
getpeername::sys_getpeername,
getrandom::sys_getrandom,
getresgid::sys_getresgid,
getresuid::sys_getresuid,
getsid::sys_getsid,
getsockname::sys_getsockname,
getsockopt::sys_getsockopt,
listen::sys_listen,
pread64::sys_pread64,
recvfrom::sys_recvfrom,
rt_sigsuspend::sys_rt_sigsuspend,
sendto::sys_sendto,
setfsgid::sys_setfsgid,
setfsuid::sys_setfsuid,
setgid::sys_setgid,
setgroups::sys_setgroups,
setregid::sys_setregid,
setresgid::sys_setresgid,
setresuid::sys_setresuid,
setreuid::sys_setreuid,
setsid::sys_setsid,
setsockopt::sys_setsockopt,
setuid::sys_setuid,
shutdown::sys_shutdown,
sigaltstack::sys_sigaltstack,
socket::sys_socket,
socketpair::sys_socketpair,
};
use crate::{
prelude::*,
syscall::{
access::sys_access,
arch_prctl::sys_arch_prctl,
brk::sys_brk,
chdir::{sys_chdir, sys_fchdir},
chmod::{sys_chmod, sys_fchmod, sys_fchmodat},
chown::{sys_chown, sys_fchown, sys_fchownat, sys_lchown},
chroot::sys_chroot,
clock_gettime::sys_clock_gettime,
clone::sys_clone,
close::sys_close,
dup::{sys_dup, sys_dup2},
epoll::{
sys_epoll_create, sys_epoll_create1, sys_epoll_ctl, sys_epoll_pwait, sys_epoll_wait,
},
execve::sys_execve,
exit::sys_exit,
exit_group::sys_exit_group,
fcntl::sys_fcntl,
fork::sys_fork,
fsync::sys_fsync,
futex::sys_futex,
getcwd::sys_getcwd,
getdents64::sys_getdents64,
getegid::sys_getegid,
geteuid::sys_geteuid,
getgid::sys_getgid,
getpgrp::sys_getpgrp,
getpid::sys_getpid,
getppid::sys_getppid,
gettid::sys_gettid,
gettimeofday::sys_gettimeofday,
getuid::sys_getuid,
ioctl::sys_ioctl,
kill::sys_kill,
link::{sys_link, sys_linkat},
lseek::sys_lseek,
madvise::sys_madvise,
mkdir::{sys_mkdir, sys_mkdirat},
mmap::sys_mmap,
mprotect::sys_mprotect,
munmap::sys_munmap,
nanosleep::{sys_clock_nanosleep, sys_nanosleep},
open::{sys_open, sys_openat},
pause::sys_pause,
pipe::{sys_pipe, sys_pipe2},
poll::sys_poll,
prctl::sys_prctl,
prlimit64::sys_prlimit64,
read::sys_read,
readlink::{sys_readlink, sys_readlinkat},
rename::{sys_rename, sys_renameat},
rmdir::sys_rmdir,
rt_sigaction::sys_rt_sigaction,
rt_sigprocmask::sys_rt_sigprocmask,
rt_sigreturn::sys_rt_sigreturn,
sched_yield::sys_sched_yield,
select::sys_select,
set_get_priority::{sys_get_priority, sys_set_priority},
set_robust_list::sys_set_robust_list,
set_tid_address::sys_set_tid_address,
setpgid::sys_setpgid,
stat::{sys_fstat, sys_fstatat, sys_lstat, sys_stat},
statfs::{sys_fstatfs, sys_statfs},
symlink::{sys_symlink, sys_symlinkat},
sync::sys_sync,
tgkill::sys_tgkill,
time::sys_time,
truncate::{sys_ftruncate, sys_truncate},
umask::sys_umask,
uname::sys_uname,
unlink::{sys_unlink, sys_unlinkat},
utimens::sys_utimensat,
wait4::sys_wait4,
waitid::sys_waitid,
write::sys_write,
writev::sys_writev,
},
};
use crate::prelude::*;
mod accept;
mod access;
mod alarm;
mod arch;
mod arch_prctl;
mod bind;
mod brk;
@ -231,22 +116,14 @@ mod waitid;
mod write;
mod writev;
macro_rules! define_syscall_nums {
( $( $name: ident = $num: expr ),+ ) => {
$(
const $name: u64 = $num;
)*
}
}
/// This macro is used to define syscall handler.
/// The first param is ths number of parameters,
/// The second param is the function name of syscall handler,
/// The third is optional, means the args(if parameter number > 0),
/// The third is optional, means if cpu context is required.
macro_rules! syscall_handler {
(0, $fn_name: ident) => { $fn_name() };
(0, $fn_name: ident, $context: expr) => { $fn_name($context) };
(0, $fn_name: ident, $args: ident) => { $fn_name() };
(0, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($context) };
(1, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _) };
(1, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $context) };
(2, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _)};
@ -261,144 +138,54 @@ macro_rules! syscall_handler {
(6, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _, $context)};
}
define_syscall_nums!(
SYS_READ = 0,
SYS_WRITE = 1,
SYS_OPEN = 2,
SYS_CLOSE = 3,
SYS_STAT = 4,
SYS_FSTAT = 5,
SYS_LSTAT = 6,
SYS_POLL = 7,
SYS_LSEEK = 8,
SYS_MMAP = 9,
SYS_MPROTECT = 10,
SYS_MUNMAP = 11,
SYS_BRK = 12,
SYS_RT_SIGACTION = 13,
SYS_RT_SIGPROCMASK = 14,
SYS_RT_SIGRETURN = 15,
SYS_IOCTL = 16,
SYS_PREAD64 = 17,
SYS_WRITEV = 20,
SYS_ACCESS = 21,
SYS_PIPE = 22,
SYS_SELECT = 23,
SYS_SCHED_YIELD = 24,
SYS_MADVISE = 28,
SYS_DUP = 32,
SYS_DUP2 = 33,
SYS_PAUSE = 34,
SYS_NANOSLEEP = 35,
SYS_ALARM = 37,
SYS_GETPID = 39,
SYS_SOCKET = 41,
SYS_CONNECT = 42,
SYS_ACCEPT = 43,
SYS_SENDTO = 44,
SYS_RECVFROM = 45,
SYS_SHUTDOWN = 48,
SYS_BIND = 49,
SYS_LISTEN = 50,
SYS_GETSOCKNAME = 51,
SYS_GETPEERNAME = 52,
SYS_SOCKETPAIR = 53,
SYS_SETSOCKOPT = 54,
SYS_GETSOCKOPT = 55,
SYS_CLONE = 56,
SYS_FORK = 57,
SYS_EXECVE = 59,
SYS_EXIT = 60,
SYS_WAIT4 = 61,
SYS_KILL = 62,
SYS_UNAME = 63,
SYS_FCNTL = 72,
SYS_FSYNC = 74,
SYS_TRUNCATE = 76,
SYS_FTRUNCATE = 77,
SYS_GETCWD = 79,
SYS_CHDIR = 80,
SYS_FCHDIR = 81,
SYS_RENAME = 82,
SYS_MKDIR = 83,
SYS_RMDIR = 84,
SYS_LINK = 86,
SYS_UNLINK = 87,
SYS_SYMLINK = 88,
SYS_READLINK = 89,
SYS_CHMOD = 90,
SYS_FCHMOD = 91,
SYS_CHOWN = 92,
SYS_FCHOWN = 93,
SYS_LCHOWN = 94,
SYS_UMASK = 95,
SYS_GETTIMEOFDAY = 96,
SYS_GETUID = 102,
SYS_GETGID = 104,
SYS_SETUID = 105,
SYS_SETGID = 106,
SYS_GETEUID = 107,
SYS_GETEGID = 108,
SYS_SETPGID = 109,
SYS_GETPPID = 110,
SYS_GETPGRP = 111,
SYS_SETSID = 112,
SYS_SETREUID = 113,
SYS_SETREGID = 114,
SYS_GETGROUPS = 115,
SYS_SETGROUPS = 116,
SYS_SETRESUID = 117,
SYS_GETRESUID = 118,
SYS_SETRESGID = 119,
SYS_GETRESGID = 120,
SYS_SETFSUID = 122,
SYS_SETFSGID = 123,
SYS_GETSID = 124,
SYS_RT_SIGSUSPEND = 130,
SYS_SIGALTSTACK = 131,
SYS_STATFS = 137,
SYS_FSTATFS = 138,
SYS_GET_PRIORITY = 140,
SYS_SET_PRIORITY = 141,
SYS_PRCTL = 157,
SYS_ARCH_PRCTL = 158,
SYS_CHROOT = 161,
SYS_SYNC = 162,
SYS_GETTID = 186,
SYS_TIME = 201,
SYS_FUTEX = 202,
SYS_EPOLL_CREATE = 213,
SYS_GETDENTS64 = 217,
SYS_SET_TID_ADDRESS = 218,
SYS_CLOCK_GETTIME = 228,
SYS_CLOCK_NANOSLEEP = 230,
SYS_EXIT_GROUP = 231,
SYS_EPOLL_WAIT = 232,
SYS_EPOLL_CTL = 233,
SYS_TGKILL = 234,
SYS_WAITID = 247,
SYS_OPENAT = 257,
SYS_MKDIRAT = 258,
SYS_FCHOWNAT = 260,
SYS_FSTATAT = 262,
SYS_UNLINKAT = 263,
SYS_RENAMEAT = 264,
SYS_LINKAT = 265,
SYS_SYMLINKAT = 266,
SYS_READLINKAT = 267,
SYS_FCHMODAT = 268,
SYS_SET_ROBUST_LIST = 273,
SYS_UTIMENSAT = 280,
SYS_EPOLL_PWAIT = 281,
SYS_EVENTFD = 284,
SYS_ACCEPT4 = 288,
SYS_EVENTFD2 = 290,
SYS_EPOLL_CREATE1 = 291,
SYS_PIPE2 = 293,
SYS_PRLIMIT64 = 302,
SYS_GETRANDOM = 318,
SYS_EXECVEAT = 322
);
macro_rules! dispatch_fn_inner {
( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] ) ) => {
$crate::syscall::syscall_handler!($cnt, $handler, $args)
};
( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] , &context ) ) => {
$crate::syscall::syscall_handler!($cnt, $handler, $args, &$context)
};
( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] , &mut context ) ) => {
// `$context` is already of type `&mut aster_frame::cpu::UserContext`,
// so no need to take `&mut` again
$crate::syscall::syscall_handler!($cnt, $handler, $args, $context)
};
}
macro_rules! impl_syscall_nums_and_dispatch_fn {
// $args, $context, and $dispatcher_name are needed since Rust macro is hygienic
( $( $name: ident = $num: literal => $handler: ident $args: tt );* $(;)? ) => {
// First, define the syscall numbers
$(
pub const $name: u64 = $num;
)*
// Then, define the dispatcher function
pub fn syscall_dispatch(
syscall_number: u64,
args: [u64; 6],
context: &mut aster_frame::cpu::UserContext,
) -> $crate::prelude::Result<$crate::syscall::SyscallReturn> {
match syscall_number {
$(
$num => {
$crate::log_syscall_entry!($name);
$crate::syscall::dispatch_fn_inner!(args, context, $handler $args)
}
)*
_ => {
log::warn!("Unimplemented syscall number: {}", syscall_number);
$crate::return_errno_with_message!($crate::error::Errno::ENOSYS, "Syscall was unimplemented");
}
}
}
}
}
// Export macros to sub-modules
use dispatch_fn_inner;
use impl_syscall_nums_and_dispatch_fn;
use syscall_handler;
pub struct SyscallArgument {
syscall_number: u64,
@ -434,7 +221,7 @@ impl SyscallArgument {
pub fn handle_syscall(context: &mut UserContext) {
let syscall_frame = SyscallArgument::new_from_context(context);
let syscall_return =
syscall_dispatch(syscall_frame.syscall_number, syscall_frame.args, context);
arch::syscall_dispatch(syscall_frame.syscall_number, syscall_frame.args, context);
match syscall_return {
Ok(return_value) => {
@ -450,165 +237,19 @@ pub fn handle_syscall(context: &mut UserContext) {
}
}
pub fn syscall_dispatch(
syscall_number: u64,
args: [u64; 6],
context: &mut UserContext,
) -> Result<SyscallReturn> {
match syscall_number {
SYS_READ => syscall_handler!(3, sys_read, args),
SYS_WRITE => syscall_handler!(3, sys_write, args),
SYS_OPEN => syscall_handler!(3, sys_open, args),
SYS_CLOSE => syscall_handler!(1, sys_close, args),
SYS_STAT => syscall_handler!(2, sys_stat, args),
SYS_FSTAT => syscall_handler!(2, sys_fstat, args),
SYS_LSTAT => syscall_handler!(2, sys_lstat, args),
SYS_POLL => syscall_handler!(3, sys_poll, args),
SYS_LSEEK => syscall_handler!(3, sys_lseek, args),
SYS_MMAP => syscall_handler!(6, sys_mmap, args),
SYS_MPROTECT => syscall_handler!(3, sys_mprotect, args),
SYS_MUNMAP => syscall_handler!(2, sys_munmap, args),
SYS_BRK => syscall_handler!(1, sys_brk, args),
SYS_RT_SIGACTION => syscall_handler!(4, sys_rt_sigaction, args),
SYS_RT_SIGPROCMASK => syscall_handler!(4, sys_rt_sigprocmask, args),
SYS_RT_SIGRETURN => syscall_handler!(0, sys_rt_sigreturn, context),
SYS_IOCTL => syscall_handler!(3, sys_ioctl, args),
SYS_PREAD64 => syscall_handler!(4, sys_pread64, args),
SYS_WRITEV => syscall_handler!(3, sys_writev, args),
SYS_ACCESS => syscall_handler!(2, sys_access, args),
SYS_PIPE => syscall_handler!(1, sys_pipe, args),
SYS_SELECT => syscall_handler!(5, sys_select, args),
SYS_SCHED_YIELD => syscall_handler!(0, sys_sched_yield),
SYS_MADVISE => syscall_handler!(3, sys_madvise, args),
SYS_DUP => syscall_handler!(1, sys_dup, args),
SYS_DUP2 => syscall_handler!(2, sys_dup2, args),
SYS_PAUSE => syscall_handler!(0, sys_pause),
SYS_NANOSLEEP => syscall_handler!(2, sys_nanosleep, args),
SYS_ALARM => syscall_handler!(1, sys_alarm, args),
SYS_GETPID => syscall_handler!(0, sys_getpid),
SYS_SOCKET => syscall_handler!(3, sys_socket, args),
SYS_CONNECT => syscall_handler!(3, sys_connect, args),
SYS_ACCEPT => syscall_handler!(3, sys_accept, args),
SYS_SENDTO => syscall_handler!(6, sys_sendto, args),
SYS_RECVFROM => syscall_handler!(6, sys_recvfrom, args),
SYS_SHUTDOWN => syscall_handler!(2, sys_shutdown, args),
SYS_BIND => syscall_handler!(3, sys_bind, args),
SYS_LISTEN => syscall_handler!(2, sys_listen, args),
SYS_GETSOCKNAME => syscall_handler!(3, sys_getsockname, args),
SYS_GETPEERNAME => syscall_handler!(3, sys_getpeername, args),
SYS_SOCKETPAIR => syscall_handler!(4, sys_socketpair, args),
SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args),
SYS_GETSOCKOPT => syscall_handler!(5, sys_getsockopt, args),
SYS_CLONE => syscall_handler!(5, sys_clone, args, *context),
SYS_FORK => syscall_handler!(0, sys_fork, *context),
SYS_EXECVE => syscall_handler!(3, sys_execve, args, context),
SYS_EXIT => syscall_handler!(1, sys_exit, args),
SYS_WAIT4 => syscall_handler!(3, sys_wait4, args),
SYS_KILL => syscall_handler!(2, sys_kill, args),
SYS_UNAME => syscall_handler!(1, sys_uname, args),
SYS_FCNTL => syscall_handler!(3, sys_fcntl, args),
SYS_FSYNC => syscall_handler!(1, sys_fsync, args),
SYS_TRUNCATE => syscall_handler!(2, sys_truncate, args),
SYS_FTRUNCATE => syscall_handler!(2, sys_ftruncate, args),
SYS_GETCWD => syscall_handler!(2, sys_getcwd, args),
SYS_CHDIR => syscall_handler!(1, sys_chdir, args),
SYS_FCHDIR => syscall_handler!(1, sys_fchdir, args),
SYS_RENAME => syscall_handler!(2, sys_rename, args),
SYS_MKDIR => syscall_handler!(2, sys_mkdir, args),
SYS_RMDIR => syscall_handler!(1, sys_rmdir, args),
SYS_LINK => syscall_handler!(2, sys_link, args),
SYS_UNLINK => syscall_handler!(1, sys_unlink, args),
SYS_SYMLINK => syscall_handler!(2, sys_symlink, args),
SYS_READLINK => syscall_handler!(3, sys_readlink, args),
SYS_CHMOD => syscall_handler!(2, sys_chmod, args),
SYS_FCHMOD => syscall_handler!(2, sys_fchmod, args),
SYS_CHOWN => syscall_handler!(3, sys_chown, args),
SYS_FCHOWN => syscall_handler!(3, sys_fchown, args),
SYS_LCHOWN => syscall_handler!(3, sys_lchown, args),
SYS_UMASK => syscall_handler!(1, sys_umask, args),
SYS_GETTIMEOFDAY => syscall_handler!(1, sys_gettimeofday, args),
SYS_GETUID => syscall_handler!(0, sys_getuid),
SYS_GETGID => syscall_handler!(0, sys_getgid),
SYS_SETUID => syscall_handler!(1, sys_setuid, args),
SYS_SETGID => syscall_handler!(1, sys_setgid, args),
SYS_GETEUID => syscall_handler!(0, sys_geteuid),
SYS_GETEGID => syscall_handler!(0, sys_getegid),
SYS_SETPGID => syscall_handler!(2, sys_setpgid, args),
SYS_GETPPID => syscall_handler!(0, sys_getppid),
SYS_GETPGRP => syscall_handler!(0, sys_getpgrp),
SYS_SETSID => syscall_handler!(0, sys_setsid),
SYS_SETREUID => syscall_handler!(2, sys_setreuid, args),
SYS_SETREGID => syscall_handler!(2, sys_setregid, args),
SYS_GETGROUPS => syscall_handler!(2, sys_getgroups, args),
SYS_SETGROUPS => syscall_handler!(2, sys_setgroups, args),
SYS_SETRESUID => syscall_handler!(3, sys_setresuid, args),
SYS_GETRESUID => syscall_handler!(3, sys_getresuid, args),
SYS_SETRESGID => syscall_handler!(3, sys_setresgid, args),
SYS_GETRESGID => syscall_handler!(3, sys_getresgid, args),
SYS_SETFSUID => syscall_handler!(1, sys_setfsuid, args),
SYS_SETFSGID => syscall_handler!(1, sys_setfsgid, args),
SYS_GETSID => syscall_handler!(1, sys_getsid, args),
SYS_RT_SIGSUSPEND => syscall_handler!(2, sys_rt_sigsuspend, args),
SYS_SIGALTSTACK => syscall_handler!(2, sys_sigaltstack, args),
SYS_STATFS => syscall_handler!(2, sys_statfs, args),
SYS_FSTATFS => syscall_handler!(2, sys_fstatfs, args),
SYS_GET_PRIORITY => syscall_handler!(2, sys_get_priority, args),
SYS_SET_PRIORITY => syscall_handler!(3, sys_set_priority, args),
SYS_PRCTL => syscall_handler!(5, sys_prctl, args),
SYS_ARCH_PRCTL => syscall_handler!(2, sys_arch_prctl, args, context),
SYS_CHROOT => syscall_handler!(1, sys_chroot, args),
SYS_SYNC => syscall_handler!(0, sys_sync),
SYS_GETTID => syscall_handler!(0, sys_gettid),
SYS_TIME => syscall_handler!(1, sys_time, args),
SYS_FUTEX => syscall_handler!(6, sys_futex, args),
SYS_EPOLL_CREATE => syscall_handler!(1, sys_epoll_create, args),
SYS_GETDENTS64 => syscall_handler!(3, sys_getdents64, args),
SYS_SET_TID_ADDRESS => syscall_handler!(1, sys_set_tid_address, args),
SYS_CLOCK_GETTIME => syscall_handler!(2, sys_clock_gettime, args),
SYS_CLOCK_NANOSLEEP => syscall_handler!(4, sys_clock_nanosleep, args),
SYS_EXIT_GROUP => syscall_handler!(1, sys_exit_group, args),
SYS_EPOLL_WAIT => syscall_handler!(4, sys_epoll_wait, args),
SYS_EPOLL_CTL => syscall_handler!(4, sys_epoll_ctl, args),
SYS_TGKILL => syscall_handler!(3, sys_tgkill, args),
SYS_WAITID => syscall_handler!(5, sys_waitid, args),
SYS_OPENAT => syscall_handler!(4, sys_openat, args),
SYS_MKDIRAT => syscall_handler!(3, sys_mkdirat, args),
SYS_FCHOWNAT => syscall_handler!(5, sys_fchownat, args),
SYS_FSTATAT => syscall_handler!(4, sys_fstatat, args),
SYS_UNLINKAT => syscall_handler!(3, sys_unlinkat, args),
SYS_RENAMEAT => syscall_handler!(4, sys_renameat, args),
SYS_LINKAT => syscall_handler!(5, sys_linkat, args),
SYS_SYMLINKAT => syscall_handler!(3, sys_symlinkat, args),
SYS_READLINKAT => syscall_handler!(4, sys_readlinkat, args),
SYS_FCHMODAT => syscall_handler!(3, sys_fchmodat, args),
SYS_SET_ROBUST_LIST => syscall_handler!(2, sys_set_robust_list, args),
SYS_UTIMENSAT => syscall_handler!(4, sys_utimensat, args),
SYS_EPOLL_PWAIT => syscall_handler!(5, sys_epoll_pwait, args),
SYS_EVENTFD => syscall_handler!(1, sys_eventfd, args),
SYS_ACCEPT4 => syscall_handler!(4, sys_accept4, args),
SYS_EVENTFD2 => syscall_handler!(2, sys_eventfd2, args),
SYS_EPOLL_CREATE1 => syscall_handler!(1, sys_epoll_create1, args),
SYS_PIPE2 => syscall_handler!(2, sys_pipe2, args),
SYS_PRLIMIT64 => syscall_handler!(4, sys_prlimit64, args),
SYS_GETRANDOM => syscall_handler!(3, sys_getrandom, args),
SYS_EXECVEAT => syscall_handler!(5, sys_execveat, args, context),
_ => {
warn!("Unimplemented syscall number: {}", syscall_number);
return_errno_with_message!(Errno::ENOSYS, "Syscall was unimplemented");
}
}
}
#[macro_export]
macro_rules! log_syscall_entry {
($syscall_name: tt) => {
if log_enabled!(log::Level::Info) {
if log::log_enabled!(log::Level::Info) {
let syscall_name_str = stringify!($syscall_name);
let pid = $crate::current!().pid();
let tid = $crate::current_thread!().tid();
info!(
log::info!(
"[pid={}][tid={}][id={}][{}]",
pid, tid, $syscall_name, syscall_name_str
pid,
tid,
$syscall_name,
syscall_name_str
);
}
};