refactor syscall: move dispatch_syscall to Rust

This commit is contained in:
WangRunji 2019-03-06 16:15:30 +08:00 committed by Tate Tian
parent 0cf714f54e
commit 3b38c3b75a
4 changed files with 518 additions and 512 deletions

@ -1,54 +0,0 @@
#ifndef __OCCLUM_SYSCALL_H__
#define __OCCLUM_SYSCALL_H__
#include <sys/types.h>
#include "syscall_nr.h"
struct iovec;
struct timeval;
#ifdef __cplusplus
extern "C" {
#endif
extern int occlum_open(const char* path, int flags, int mode);
extern int occlum_close(int fd);
extern ssize_t occlum_read(int fd, void* buf, size_t size);
extern ssize_t occlum_readv(int fd, struct iovec* iov, int count);
extern ssize_t occlum_write(int fd, const void* buf, size_t size);
extern ssize_t occlum_writev(int fd, const struct iovec* iov, int count);
extern off_t occlum_lseek(int fd, off_t offset, int whence);
extern int occlum_sync(void);
extern int occlum_pipe(int fds[2]);
extern int occlum_pipe2(int fds[2], int flags);
extern int occlum_dup(int old_fd);
extern int occlum_dup2(int old_fd, int new_fd);
extern int occlum_dup3(int old_fd, int new_fd, int flags);
extern int occlum_spawn(int* child_pid, const char* path,
const char** argv, const char** envp,
void* file_actions);
extern int occlum_wait4(int child_pid, int* status, int options/*, struct rusage* rusage*/);
extern void occlum_exit(int status);
extern unsigned int occlum_getpid(void);
extern unsigned int occlum_getppid(void);
extern void *occlum_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
extern int occlum_munmap(void *addr, size_t length);
extern void *occlum_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address);
extern void* occlum_brk(void* addr);
extern int occlum_gettimeofday(struct timeval* tv/*, struct timezone* tz*/);
extern int occlum_getcwd(char* buf, size_t size);
extern int occlum_unknown(int num);
#ifdef __cplusplus
}
#endif
#endif /* __OCCLUM_SYSCALL_H__ */

@ -0,0 +1,330 @@
//! Syscall numbers
const SYS_read: usize = 0;
const SYS_write: usize = 1;
const SYS_open: usize = 2;
const SYS_close: usize = 3;
const SYS_stat: usize = 4;
const SYS_fstat: usize = 5;
const SYS_lstat: usize = 6;
const SYS_poll: usize = 7;
const SYS_lseek: usize = 8;
const SYS_mmap: usize = 9;
const SYS_mprotect: usize = 10;
const SYS_munmap: usize = 11;
const SYS_brk: usize = 12;
const SYS_rt_sigaction: usize = 13;
const SYS_rt_sigprocmask: usize = 14;
const SYS_rt_sigreturn: usize = 15;
const SYS_ioctl: usize = 16;
const SYS_pread64: usize = 17;
const SYS_pwrite64: usize = 18;
const SYS_readv: usize = 19;
const SYS_writev: usize = 20;
const SYS_access: usize = 21;
const SYS_pipe: usize = 22;
const SYS_select: usize = 23;
const SYS_sched_yield: usize = 24;
const SYS_mremap: usize = 25;
const SYS_msync: usize = 26;
const SYS_mincore: usize = 27;
const SYS_madvise: usize = 28;
const SYS_shmget: usize = 29;
const SYS_shmat: usize = 30;
const SYS_shmctl: usize = 31;
const SYS_dup: usize = 32;
const SYS_dup2: usize = 33;
const SYS_pause: usize = 34;
const SYS_nanosleep: usize = 35;
const SYS_getitimer: usize = 36;
const SYS_alarm: usize = 37;
const SYS_setitimer: usize = 38;
const SYS_getpid: usize = 39;
const SYS_sendfile: usize = 40;
const SYS_socket: usize = 41;
const SYS_connect: usize = 42;
const SYS_accept: usize = 43;
const SYS_sendto: usize = 44;
const SYS_recvfrom: usize = 45;
const SYS_sendmsg: usize = 46;
const SYS_recvmsg: usize = 47;
const SYS_shutdown: usize = 48;
const SYS_bind: usize = 49;
const SYS_listen: usize = 50;
const SYS_getsockname: usize = 51;
const SYS_getpeername: usize = 52;
const SYS_socketpair: usize = 53;
const SYS_setsockopt: usize = 54;
const SYS_getsockopt: usize = 55;
const SYS_clone: usize = 56;
const SYS_fork: usize = 57;
const SYS_vfork: usize = 58;
const SYS_execve: usize = 59;
const SYS_exit: usize = 60;
const SYS_wait4: usize = 61;
const SYS_kill: usize = 62;
const SYS_uname: usize = 63;
const SYS_semget: usize = 64;
const SYS_semop: usize = 65;
const SYS_semctl: usize = 66;
const SYS_shmdt: usize = 67;
const SYS_msgget: usize = 68;
const SYS_msgsnd: usize = 69;
const SYS_msgrcv: usize = 70;
const SYS_msgctl: usize = 71;
const SYS_fcntl: usize = 72;
const SYS_flock: usize = 73;
const SYS_fsync: usize = 74;
const SYS_fdatasync: usize = 75;
const SYS_truncate: usize = 76;
const SYS_ftruncate: usize = 77;
const SYS_getdents: usize = 78;
const SYS_getcwd: usize = 79;
const SYS_chdir: usize = 80;
const SYS_fchdir: usize = 81;
const SYS_rename: usize = 82;
const SYS_mkdir: usize = 83;
const SYS_rmdir: usize = 84;
const SYS_creat: usize = 85;
const SYS_link: usize = 86;
const SYS_unlink: usize = 87;
const SYS_symlink: usize = 88;
const SYS_readlink: usize = 89;
const SYS_chmod: usize = 90;
const SYS_fchmod: usize = 91;
const SYS_chown: usize = 92;
const SYS_fchown: usize = 93;
const SYS_lchown: usize = 94;
const SYS_umask: usize = 95;
const SYS_gettimeofday: usize = 96;
const SYS_getrlimit: usize = 97;
const SYS_getrusage: usize = 98;
const SYS_sysinfo: usize = 99;
const SYS_times: usize = 100;
const SYS_ptrace: usize = 101;
const SYS_getuid: usize = 102;
const SYS_syslog: usize = 103;
const SYS_getgid: usize = 104;
const SYS_setuid: usize = 105;
const SYS_setgid: usize = 106;
const SYS_geteuid: usize = 107;
const SYS_getegid: usize = 108;
const SYS_setpgid: usize = 109;
const SYS_getppid: usize = 110;
const SYS_getpgrp: usize = 111;
const SYS_setsid: usize = 112;
const SYS_setreuid: usize = 113;
const SYS_setregid: usize = 114;
const SYS_getgroups: usize = 115;
const SYS_setgroups: usize = 116;
const SYS_setresuid: usize = 117;
const SYS_getresuid: usize = 118;
const SYS_setresgid: usize = 119;
const SYS_getresgid: usize = 120;
const SYS_getpgid: usize = 121;
const SYS_setfsuid: usize = 122;
const SYS_setfsgid: usize = 123;
const SYS_getsid: usize = 124;
const SYS_capget: usize = 125;
const SYS_capset: usize = 126;
const SYS_rt_sigpending: usize = 127;
const SYS_rt_sigtimedwait: usize = 128;
const SYS_rt_sigqueueinfo: usize = 129;
const SYS_rt_sigsuspend: usize = 130;
const SYS_sigaltstack: usize = 131;
const SYS_utime: usize = 132;
const SYS_mknod: usize = 133;
const SYS_uselib: usize = 134;
const SYS_personality: usize = 135;
const SYS_ustat: usize = 136;
const SYS_statfs: usize = 137;
const SYS_fstatfs: usize = 138;
const SYS_sysfs: usize = 139;
const SYS_getpriority: usize = 140;
const SYS_setpriority: usize = 141;
const SYS_sched_setparam: usize = 142;
const SYS_sched_getparam: usize = 143;
const SYS_sched_setscheduler: usize = 144;
const SYS_sched_getscheduler: usize = 145;
const SYS_sched_get_priority_max: usize = 146;
const SYS_sched_get_priority_min: usize = 147;
const SYS_sched_rr_get_interval: usize = 148;
const SYS_mlock: usize = 149;
const SYS_munlock: usize = 150;
const SYS_mlockall: usize = 151;
const SYS_munlockall: usize = 152;
const SYS_vhangup: usize = 153;
const SYS_modify_ldt: usize = 154;
const SYS_pivot_root: usize = 155;
const SYS__sysctl: usize = 156;
const SYS_prctl: usize = 157;
const SYS_arch_prctl: usize = 158;
const SYS_adjtimex: usize = 159;
const SYS_setrlimit: usize = 160;
const SYS_chroot: usize = 161;
const SYS_sync: usize = 162;
const SYS_acct: usize = 163;
const SYS_settimeofday: usize = 164;
const SYS_mount: usize = 165;
const SYS_umount2: usize = 166;
const SYS_swapon: usize = 167;
const SYS_swapoff: usize = 168;
const SYS_reboot: usize = 169;
const SYS_sethostname: usize = 170;
const SYS_setdomainname: usize = 171;
const SYS_iopl: usize = 172;
const SYS_ioperm: usize = 173;
const SYS_create_module: usize = 174;
const SYS_init_module: usize = 175;
const SYS_delete_module: usize = 176;
const SYS_get_kernel_syms: usize = 177;
const SYS_query_module: usize = 178;
const SYS_quotactl: usize = 179;
const SYS_nfsservctl: usize = 180;
const SYS_getpmsg: usize = 181;
const SYS_putpmsg: usize = 182;
const SYS_afs_syscall: usize = 183;
const SYS_tuxcall: usize = 184;
const SYS_security: usize = 185;
const SYS_gettid: usize = 186;
const SYS_readahead: usize = 187;
const SYS_setxattr: usize = 188;
const SYS_lsetxattr: usize = 189;
const SYS_fsetxattr: usize = 190;
const SYS_getxattr: usize = 191;
const SYS_lgetxattr: usize = 192;
const SYS_fgetxattr: usize = 193;
const SYS_listxattr: usize = 194;
const SYS_llistxattr: usize = 195;
const SYS_flistxattr: usize = 196;
const SYS_removexattr: usize = 197;
const SYS_lremovexattr: usize = 198;
const SYS_fremovexattr: usize = 199;
const SYS_tkill: usize = 200;
const SYS_time: usize = 201;
const SYS_futex: usize = 202;
const SYS_sched_setaffinity: usize = 203;
const SYS_sched_getaffinity: usize = 204;
const SYS_set_thread_area: usize = 205;
const SYS_io_setup: usize = 206;
const SYS_io_destroy: usize = 207;
const SYS_io_getevents: usize = 208;
const SYS_io_submit: usize = 209;
const SYS_io_cancel: usize = 210;
const SYS_get_thread_area: usize = 211;
const SYS_lookup_dcookie: usize = 212;
const SYS_epoll_create: usize = 213;
const SYS_epoll_ctl_old: usize = 214;
const SYS_epoll_wait_old: usize = 215;
const SYS_remap_file_pages: usize = 216;
const SYS_getdents64: usize = 217;
const SYS_set_tid_address: usize = 218;
const SYS_restart_syscall: usize = 219;
const SYS_semtimedop: usize = 220;
const SYS_fadvise64: usize = 221;
const SYS_timer_create: usize = 222;
const SYS_timer_settime: usize = 223;
const SYS_timer_gettime: usize = 224;
const SYS_timer_getoverrun: usize = 225;
const SYS_timer_delete: usize = 226;
const SYS_clock_settime: usize = 227;
const SYS_clock_gettime: usize = 228;
const SYS_clock_getres: usize = 229;
const SYS_clock_nanosleep: usize = 230;
const SYS_exit_group: usize = 231;
const SYS_epoll_wait: usize = 232;
const SYS_epoll_ctl: usize = 233;
const SYS_tgkill: usize = 234;
const SYS_utimes: usize = 235;
const SYS_vserver: usize = 236;
const SYS_mbind: usize = 237;
const SYS_set_mempolicy: usize = 238;
const SYS_get_mempolicy: usize = 239;
const SYS_mq_open: usize = 240;
const SYS_mq_unlink: usize = 241;
const SYS_mq_timedsend: usize = 242;
const SYS_mq_timedreceive: usize = 243;
const SYS_mq_notify: usize = 244;
const SYS_mq_getsetattr: usize = 245;
const SYS_kexec_load: usize = 246;
const SYS_waitid: usize = 247;
const SYS_add_key: usize = 248;
const SYS_request_key: usize = 249;
const SYS_keyctl: usize = 250;
const SYS_ioprio_set: usize = 251;
const SYS_ioprio_get: usize = 252;
const SYS_inotify_init: usize = 253;
const SYS_inotify_add_watch: usize = 254;
const SYS_inotify_rm_watch: usize = 255;
const SYS_migrate_pages: usize = 256;
const SYS_openat: usize = 257;
const SYS_mkdirat: usize = 258;
const SYS_mknodat: usize = 259;
const SYS_fchownat: usize = 260;
const SYS_futimesat: usize = 261;
const SYS_newfstatat: usize = 262;
const SYS_unlinkat: usize = 263;
const SYS_renameat: usize = 264;
const SYS_linkat: usize = 265;
const SYS_symlinkat: usize = 266;
const SYS_readlinkat: usize = 267;
const SYS_fchmodat: usize = 268;
const SYS_faccessat: usize = 269;
const SYS_pselect6: usize = 270;
const SYS_ppoll: usize = 271;
const SYS_unshare: usize = 272;
const SYS_set_robust_list: usize = 273;
const SYS_get_robust_list: usize = 274;
const SYS_splice: usize = 275;
const SYS_tee: usize = 276;
const SYS_sync_file_range: usize = 277;
const SYS_vmsplice: usize = 278;
const SYS_move_pages: usize = 279;
const SYS_utimensat: usize = 280;
const SYS_epoll_pwait: usize = 281;
const SYS_signalfd: usize = 282;
const SYS_timerfd_create: usize = 283;
const SYS_eventfd: usize = 284;
const SYS_fallocate: usize = 285;
const SYS_timerfd_settime: usize = 286;
const SYS_timerfd_gettime: usize = 287;
const SYS_accept4: usize = 288;
const SYS_signalfd4: usize = 289;
const SYS_eventfd2: usize = 290;
const SYS_epoll_create1: usize = 291;
const SYS_dup3: usize = 292;
const SYS_pipe2: usize = 293;
const SYS_inotify_init1: usize = 294;
const SYS_preadv: usize = 295;
const SYS_pwritev: usize = 296;
const SYS_rt_tgsigqueueinfo: usize = 297;
const SYS_perf_event_open: usize = 298;
const SYS_recvmmsg: usize = 299;
const SYS_fanotify_init: usize = 300;
const SYS_fanotify_mark: usize = 301;
const SYS_prlimit64: usize = 302;
const SYS_name_to_handle_at: usize = 303;
const SYS_open_by_handle_at: usize = 304;
const SYS_clock_adjtime: usize = 305;
const SYS_syncfs: usize = 306;
const SYS_sendmmsg: usize = 307;
const SYS_setns: usize = 308;
const SYS_getcpu: usize = 309;
const SYS_process_vm_readv: usize = 310;
const SYS_process_vm_writev: usize = 311;
const SYS_kcmp: usize = 312;
const SYS_finit_module: usize = 313;
const SYS_sched_setattr: usize = 314;
const SYS_sched_getattr: usize = 315;
const SYS_renameat2: usize = 316;
const SYS_seccomp: usize = 317;
const SYS_getrandom: usize = 318;
const SYS_memfd_create: usize = 319;
const SYS_kexec_file_load: usize = 320;
const SYS_bpf: usize = 321;
const SYS_execveat: usize = 322;
const SYS_userfaultfd: usize = 323;
const SYS_membarrier: usize = 324;
const SYS_mlock2: usize = 325;
const SYS_spawn: usize = 360;

@ -12,6 +12,79 @@ use {fs, process, std, vm};
//use std::libc_fs as fs; //use std::libc_fs as fs;
//use std::libc_io as io; //use std::libc_io as io;
use self::consts::*;
use fs::File;
mod consts;
#[no_mangle]
pub extern "C" fn dispatch_syscall(
num: u32,
arg0: isize,
arg1: isize,
arg2: isize,
arg3: isize,
arg4: isize,
arg5: isize,
) -> isize {
let ret = match num {
SYS_open => do_open(arg0 as *const i8, arg1 as u32, arg2 as u32),
SYS_close => do_close(arg0 as FileDesc),
SYS_read => do_read(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize),
SYS_write => do_write(arg0 as FileDesc, arg1 as *const u8, arg2 as usize),
SYS_readv => do_readv(arg0 as FileDesc, arg1 as *mut iovec_t, arg2 as i32),
SYS_writev => do_writev(arg0 as FileDesc, arg1 as *mut iovec_t, arg2 as i32),
SYS_lseek => do_lseek(arg0 as FileDesc, arg1 as off_t, arg2 as i32),
SYS_sync => do_sync(),
SYS_getcwd => do_getcwd(arg0 as *mut u8, arg1 as usize),
SYS_exit => do_exit(arg0 as i32),
SYS_spawn => do_spawn(
arg0 as *mut u32,
arg1 as *mut i8,
arg2 as *const *const i8,
arg3 as *const *const i8,
arg4 as *const FdOp,
),
SYS_wait4 => do_wait4(arg0 as i32, arg1 as *mut i32),
SYS_getpid => do_getpid(),
SYS_getppid => do_getppid(),
SYS_mmap => do_mmap(
arg0 as usize,
arg1 as usize,
arg2 as i32,
arg3 as i32,
arg4 as FileDesc,
arg5 as off_t,
),
SYS_munmap => do_munmap(arg0 as usize, arg1 as usize),
SYS_mremap => do_mremap(
arg0 as usize,
arg1 as usize,
arg2 as usize,
arg3 as i32,
arg4 as usize,
),
SYS_brk => do_brk(arg0 as usize),
SYS_pipe => do_pipe2(arg0 as *mut i32, 0),
SYS_pipe2 => do_pipe2(arg0 as *mut i32, arg1 as u32),
SYS_dup => do_dup(arg0 as FileDesc),
SYS_dup2 => do_dup2(arg0 as FileDesc, arg1 as FileDesc),
SYS_dup3 => do_dup3(arg0 as FileDesc, arg1 as FileDesc, arg2 as u32),
SYS_gettimeofday => do_gettimeofday(arg0 as *mut timeval_t),
_ => do_unknown(num),
};
match ret {
Ok(code) => code as isize,
Err(e) => e.errno.as_retval() as isize,
}
}
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct iovec_t { pub struct iovec_t {
base: *const c_void, base: *const c_void,
@ -67,12 +140,12 @@ fn clone_file_actions_safely(fdop_ptr: *const FdOp) -> Result<Vec<FileAction>, E
} }
fn do_spawn( fn do_spawn(
child_pid_ptr: *mut c_uint, child_pid_ptr: *mut u32,
path: *const c_char, path: *const i8,
argv: *const *const c_char, argv: *const *const i8,
envp: *const *const c_char, envp: *const *const i8,
fdop_list: *const FdOp, fdop_list: *const FdOp,
) -> Result<(), Error> { ) -> Result<isize, Error> {
check_mut_ptr(child_pid_ptr)?; check_mut_ptr(child_pid_ptr)?;
let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); let path = clone_cstring_safely(path)?.to_string_lossy().into_owned();
let argv = clone_cstrings_safely(argv)?; let argv = clone_cstrings_safely(argv)?;
@ -83,34 +156,39 @@ fn do_spawn(
let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?; let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?;
unsafe { *child_pid_ptr = child_pid }; unsafe { *child_pid_ptr = child_pid };
Ok(()) Ok(0)
} }
fn do_read(fd: c_int, buf: *mut c_void, size: size_t) -> Result<size_t, Error> { fn do_open(path_buf: *const i8, flags: u32, mode: u32) -> Result<isize, Error> {
let fd = fd as FileDesc; let path = unsafe { CStr::from_ptr(path_buf).to_string_lossy().into_owned() };
let fd = fs::do_open(&path, flags, mode)?;
Ok(fd as isize)
}
fn do_close(fd: FileDesc) -> Result<isize, Error> {
fs::do_close(fd)?;
Ok(0)
}
fn do_read(fd: FileDesc, buf: *mut u8, size: usize) -> Result<isize, Error> {
let safe_buf = { let safe_buf = {
let buf = buf as *mut u8;
let size = size as usize;
check_mut_array(buf, size)?; check_mut_array(buf, size)?;
unsafe { std::slice::from_raw_parts_mut(buf, size) } unsafe { std::slice::from_raw_parts_mut(buf, size) }
}; };
fs::do_read(fd, safe_buf) let len = fs::do_read(fd, safe_buf)?;
Ok(len as isize)
} }
fn do_write(fd: c_int, buf: *const c_void, size: size_t) -> Result<size_t, Error> { fn do_write(fd: FileDesc, buf: *const u8, size: usize) -> Result<isize, Error> {
let fd = fd as FileDesc;
let safe_buf = { let safe_buf = {
let buf = buf as *mut u8;
let size = size as usize;
check_array(buf, size)?; check_array(buf, size)?;
unsafe { std::slice::from_raw_parts(buf, size) } unsafe { std::slice::from_raw_parts(buf, size) }
}; };
fs::do_write(fd, safe_buf) let len = fs::do_write(fd, safe_buf)?;
Ok(len as isize)
} }
fn do_writev(fd: c_int, iov: *const iovec_t, count: c_int) -> Result<size_t, Error> { fn do_writev(fd: FileDesc, iov: *const iovec_t, count: i32) -> Result<isize, Error> {
let fd = fd as FileDesc;
let count = { let count = {
if count < 0 { if count < 0 {
return Err(Error::new(Errno::EINVAL, "Invalid count of iovec")); return Err(Error::new(Errno::EINVAL, "Invalid count of iovec"));
@ -131,12 +209,11 @@ fn do_writev(fd: c_int, iov: *const iovec_t, count: c_int) -> Result<size_t, Err
}; };
let bufs = &bufs_vec[..]; let bufs = &bufs_vec[..];
fs::do_writev(fd, bufs) let len = fs::do_writev(fd, bufs)?;
Ok(len as isize)
} }
fn do_readv(fd: c_int, iov: *mut iovec_t, count: c_int) -> Result<size_t, Error> { fn do_readv(fd: FileDesc, iov: *mut iovec_t, count: i32) -> Result<isize, Error> {
let fd = fd as FileDesc;
let count = { let count = {
if count < 0 { if count < 0 {
return Err(Error::new(Errno::EINVAL, "Invalid count of iovec")); return Err(Error::new(Errno::EINVAL, "Invalid count of iovec"));
@ -157,12 +234,11 @@ fn do_readv(fd: c_int, iov: *mut iovec_t, count: c_int) -> Result<size_t, Error>
}; };
let bufs = &mut bufs_vec[..]; let bufs = &mut bufs_vec[..];
fs::do_readv(fd, bufs) let len = fs::do_readv(fd, bufs)?;
Ok(len as isize)
} }
pub fn do_lseek(fd: c_int, offset: off_t, whence: c_int) -> Result<off_t, Error> { fn do_lseek(fd: FileDesc, offset: off_t, whence: i32) -> Result<isize, Error> {
let fd = fd as FileDesc;
let seek_from = match whence { let seek_from = match whence {
0 => { 0 => {
// SEEK_SET // SEEK_SET
@ -184,50 +260,53 @@ pub fn do_lseek(fd: c_int, offset: off_t, whence: c_int) -> Result<off_t, Error>
} }
}; };
fs::do_lseek(fd, seek_from) let offset = fs::do_lseek(fd, seek_from)?;
Ok(offset as isize)
}
fn do_sync() -> Result<isize, Error> {
fs::do_sync()?;
Ok(0)
} }
fn do_mmap( fn do_mmap(
addr: *const c_void, addr: usize,
size: size_t, size: usize,
prot: c_int, prot: i32,
flags: c_int, flags: i32,
fd: c_int, fd: FileDesc,
offset: off_t, offset: off_t,
) -> Result<*const c_void, Error> { ) -> Result<isize, Error> {
let addr = addr as usize;
let size = size as usize;
let flags = VMAreaFlags(prot as u32); let flags = VMAreaFlags(prot as u32);
vm::do_mmap(addr, size, flags).map(|ret_addr| ret_addr as *const c_void) let addr = vm::do_mmap(addr, size, flags)?;
Ok(addr as isize)
} }
fn do_munmap(addr: *const c_void, size: size_t) -> Result<(), Error> { fn do_munmap(addr: usize, size: usize) -> Result<isize, Error> {
let addr = addr as usize; vm::do_munmap(addr, size)?;
let size = size as usize; Ok(0)
vm::do_munmap(addr, size)
} }
fn do_mremap( fn do_mremap(
old_addr: *const c_void, old_addr: usize,
old_size: size_t, old_size: usize,
new_size: size_t, new_size: usize,
flags: c_int, flags: i32,
new_addr: *const c_void, new_addr: usize,
) -> Result<*const c_void, Error> { ) -> Result<isize, Error> {
let old_addr = old_addr as usize;
let old_size = old_size as usize;
let mut options = VMResizeOptions::new(new_size)?; let mut options = VMResizeOptions::new(new_size)?;
// TODO: handle flags and new_addr // TODO: handle flags and new_addr
vm::do_mremap(old_addr, old_size, &options).map(|ret_addr| ret_addr as *const c_void) let ret_addr = vm::do_mremap(old_addr, old_size, &options)?;
Ok(ret_addr as isize)
} }
fn do_brk(new_brk_addr: *const c_void) -> Result<*const c_void, Error> { fn do_brk(new_brk_addr: usize) -> Result<isize, Error> {
let new_brk_addr = new_brk_addr as usize; let ret_brk_addr = vm::do_brk(new_brk_addr)?;
vm::do_brk(new_brk_addr).map(|ret_brk_addr| ret_brk_addr as *const c_void) Ok(ret_brk_addr as isize)
} }
fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result<pid_t, Error> { fn do_wait4(pid: i32, _exit_status: *mut i32) -> Result<isize, Error> {
if _exit_status != 0 as *mut c_int { if !_exit_status.is_null() {
check_mut_ptr(_exit_status)?; check_mut_ptr(_exit_status)?;
} }
@ -246,18 +325,28 @@ fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result<pid_t, Error> {
let mut exit_status = 0; let mut exit_status = 0;
match process::do_wait4(&child_process_filter, &mut exit_status) { match process::do_wait4(&child_process_filter, &mut exit_status) {
Ok(pid) => { Ok(pid) => {
if _exit_status != 0 as *mut c_int { if !_exit_status.is_null() {
unsafe { unsafe {
*_exit_status = exit_status; *_exit_status = exit_status;
} }
} }
Ok(pid) Ok(pid as isize)
} }
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> { fn do_getpid() -> Result<isize, Error> {
let pid = process::do_getpid();
Ok(pid as isize)
}
fn do_getppid() -> Result<isize, Error> {
let ppid = process::do_getppid();
Ok(ppid as isize)
}
fn do_pipe2(fds_u: *mut i32, flags: u32) -> Result<isize, Error> {
check_mut_array(fds_u, 2)?; check_mut_array(fds_u, 2)?;
// TODO: how to deal with open flags??? // TODO: how to deal with open flags???
let fds = fs::do_pipe2(flags as u32)?; let fds = fs::do_pipe2(flags as u32)?;
@ -265,257 +354,66 @@ fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> {
*fds_u.offset(0) = fds[0] as c_int; *fds_u.offset(0) = fds[0] as c_int;
*fds_u.offset(1) = fds[1] as c_int; *fds_u.offset(1) = fds[1] as c_int;
} }
Ok(()) Ok(0)
} }
fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<(), Error> { fn do_dup(old_fd: FileDesc) -> Result<isize, Error> {
let new_fd = fs::do_dup(old_fd)?;
Ok(new_fd as isize)
}
fn do_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<isize, Error> {
let new_fd = fs::do_dup2(old_fd, new_fd)?;
Ok(new_fd as isize)
}
fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<isize, Error> {
let new_fd = fs::do_dup3(old_fd, new_fd, flags)?;
Ok(new_fd as isize)
}
// TODO: handle tz: timezone_t
fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<isize, Error> {
check_mut_ptr(tv_u)?; check_mut_ptr(tv_u)?;
let tv = time::do_gettimeofday(); let tv = time::do_gettimeofday();
unsafe { unsafe {
*tv_u = tv; *tv_u = tv;
} }
Ok(()) Ok(0)
} }
// FIXME: use this
const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void; const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void;
#[no_mangle] fn do_exit(status: i32) -> ! {
pub extern "C" fn occlum_mmap( extern "C" {
addr: *const c_void, fn do_exit_task() -> !;
length: size_t,
prot: c_int,
flags: c_int,
fd: c_int,
offset: off_t,
) -> *const c_void {
match do_mmap(addr, length, prot, flags, fd, offset) {
Ok(ret_addr) => ret_addr,
Err(e) => MAP_FAILED,
} }
}
#[no_mangle]
pub extern "C" fn occlum_munmap(addr: *const c_void, length: size_t) -> c_int {
match do_munmap(addr, length) {
Ok(()) => 0,
Err(e) => -1,
}
}
#[no_mangle]
pub extern "C" fn occlum_mremap(
old_addr: *const c_void,
old_size: size_t,
new_size: size_t,
flags: c_int,
new_addr: *const c_void,
) -> *const c_void {
match do_mremap(old_addr, old_size, new_size, flags, new_addr) {
Ok(ret_addr) => ret_addr,
Err(e) => MAP_FAILED,
}
}
#[no_mangle]
pub extern "C" fn occlum_brk(addr: *const c_void) -> *const c_void {
match do_brk(addr) {
Ok(ret_addr) => ret_addr,
Err(e) => MAP_FAILED,
}
}
#[no_mangle]
pub extern "C" fn occlum_pipe(fds: *mut c_int) -> c_int {
occlum_pipe2(fds, 0)
}
#[no_mangle]
pub extern "C" fn occlum_pipe2(fds: *mut c_int, flags: c_int) -> c_int {
match do_pipe2(fds, flags) {
Ok(()) => 0,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_open(path_buf: *const c_char, flags: c_int, mode: c_int) -> c_int {
let path = unsafe {
CStr::from_ptr(path_buf as *const i8)
.to_string_lossy()
.into_owned()
};
match fs::do_open(&path, flags as u32, mode as u32) {
Ok(fd) => fd as c_int,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_close(fd: c_int) -> c_int {
match fs::do_close(fd as FileDesc) {
Ok(()) => 0,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_read(fd: c_int, buf: *mut c_void, size: size_t) -> ssize_t {
match do_read(fd, buf, size) {
Ok(read_len) => read_len as ssize_t,
Err(e) => e.errno.as_retval() as ssize_t,
}
}
#[no_mangle]
pub extern "C" fn occlum_write(fd: c_int, buf: *const c_void, size: size_t) -> ssize_t {
match do_write(fd, buf, size) {
Ok(write_len) => write_len as ssize_t,
Err(e) => e.errno.as_retval() as ssize_t,
}
}
#[no_mangle]
pub extern "C" fn occlum_readv(fd: c_int, iov: *mut iovec_t, count: c_int) -> ssize_t {
match do_readv(fd, iov, count) {
Ok(read_len) => read_len as ssize_t,
Err(e) => e.errno.as_retval() as ssize_t,
}
}
#[no_mangle]
pub extern "C" fn occlum_writev(fd: c_int, iov: *const iovec_t, count: c_int) -> ssize_t {
match do_writev(fd, iov, count) {
Ok(write_len) => write_len as ssize_t,
Err(e) => e.errno.as_retval() as ssize_t,
}
}
#[no_mangle]
pub extern "C" fn occlum_lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
match do_lseek(fd, offset, whence) {
Ok(ret) => ret,
Err(e) => {
-1 as off_t // this special value indicates error
}
}
}
#[no_mangle]
pub extern "C" fn occlum_getpid() -> c_uint {
process::do_getpid()
}
#[no_mangle]
pub extern "C" fn occlum_getppid() -> c_uint {
process::do_getppid()
}
#[no_mangle]
pub extern "C" fn occlum_exit(status: i32) {
process::do_exit(status); process::do_exit(status);
unsafe {
do_exit_task();
}
} }
#[no_mangle] fn do_unknown(num: u32) -> Result<isize, Error> {
pub extern "C" fn occlum_unknown(num: u32) {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
//println!("[WARNING] Unknown syscall (num = {})", num); //println!("[WARNING] Unknown syscall (num = {})", num);
} }
Err(Error::new(ENOSYS, "Unknown syscall"))
} }
#[no_mangle] fn do_getcwd(buf: *mut u8, size: usize) -> Result<isize, Error> {
pub extern "C" fn occlum_spawn( let safe_buf = {
child_pid: *mut c_uint, check_mut_array(buf, size)?;
path: *const c_char, unsafe { std::slice::from_raw_parts_mut(buf, size) }
argv: *const *const c_char, };
envp: *const *const c_char, let proc_ref = process::get_current();
fdop_list: *const FdOp, let mut proc = proc_ref.lock().unwrap();
) -> c_int { let cwd = proc.get_exec_path();
match do_spawn(child_pid, path, argv, envp, fdop_list) { if cwd.len() + 1 > safe_buf.len() {
Ok(()) => 0, return Err(Error::new(ERANGE, "buf is not long enough"));
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_wait4(
child_pid: c_int,
exit_status: *mut c_int,
options: c_int, /*, rusage: *mut Rusage*/
) -> c_int {
match do_wait4(child_pid, exit_status) {
Ok(pid) => pid as c_int,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_dup(old_fd: c_int) -> c_int {
let old_fd = old_fd as FileDesc;
match fs::do_dup(old_fd) {
Ok(new_fd) => new_fd as c_int,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_dup2(old_fd: c_int, new_fd: c_int) -> c_int {
let old_fd = old_fd as FileDesc;
let new_fd = new_fd as FileDesc;
match fs::do_dup2(old_fd, new_fd) {
Ok(new_fd) => new_fd as c_int,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_dup3(old_fd: c_int, new_fd: c_int, flags: c_int) -> c_int {
let old_fd = old_fd as FileDesc;
let new_fd = new_fd as FileDesc;
let flags = flags as u32;
match fs::do_dup3(old_fd, new_fd, flags) {
Ok(new_fd) => new_fd as c_int,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_sync() -> c_int {
match fs::do_sync() {
Ok(()) => 0 as c_int,
Err(e) => e.errno.as_retval(),
}
}
// TODO: handle tz: timezone_t
#[no_mangle]
pub extern "C" fn occlum_gettimeofday(tv: *mut timeval_t) -> c_int {
match do_gettimeofday(tv) {
Ok(()) => 0,
Err(e) => e.errno.as_retval(),
}
}
#[no_mangle]
pub extern "C" fn occlum_getcwd(buf: *mut c_void, size: size_t) -> c_int {
fn do_getcwd(buf: *mut u8, size: usize) -> Result<(), Error> {
let safe_buf = {
check_mut_array(buf, size)?;
unsafe { std::slice::from_raw_parts_mut(buf, size) }
};
let proc_ref = process::get_current();
let mut proc = proc_ref.lock().unwrap();
let cwd = proc.get_exec_path();
if cwd.len() + 1 > safe_buf.len() {
return Err(Error::new(ERANGE, "buf is not long enough"));
}
safe_buf[..cwd.len()].copy_from_slice(cwd.as_bytes());
safe_buf[cwd.len()] = 0;
Ok(())
}
match do_getcwd(buf as *mut u8, size as usize) {
Ok(()) => 0 as c_int,
Err(e) => e.errno.as_retval(),
} }
safe_buf[..cwd.len()].copy_from_slice(cwd.as_bytes());
safe_buf[cwd.len()] = 0;
Ok(0)
} }

@ -1,168 +0,0 @@
#include "syscall.h"
#include "task.h"
#define DECL_SYSCALL_ARG(_type, _name, _arg) \
_type _name = (_type) (_arg)
long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
long ret = 0;
switch (num) {
case SYS_exit: {
DECL_SYSCALL_ARG(int, status, arg0);
occlum_exit(status);
do_exit_task();
break;
}
case SYS_open: {
DECL_SYSCALL_ARG(const void*, path, arg0);
DECL_SYSCALL_ARG(int, flags, arg1);
DECL_SYSCALL_ARG(int, mode, arg2);
ret = occlum_open(path, flags, mode);
break;
}
case SYS_close: {
DECL_SYSCALL_ARG(int, fd, arg0);
ret = occlum_close(fd);
break;
}
case SYS_write: {
DECL_SYSCALL_ARG(int, fd, arg0);
DECL_SYSCALL_ARG(const void*, buf, arg1);
DECL_SYSCALL_ARG(size_t, buf_size, arg2);
ret = occlum_write(fd, buf, buf_size);
break;
}
case SYS_read: {
DECL_SYSCALL_ARG(int, fd, arg0);
DECL_SYSCALL_ARG(void*, buf, arg1);
DECL_SYSCALL_ARG(size_t, buf_size, arg2);
ret = occlum_read(fd, buf, buf_size);
break;
}
case SYS_writev: {
DECL_SYSCALL_ARG(int, fd, arg0);
DECL_SYSCALL_ARG(const struct iovec*, iov, arg1);
DECL_SYSCALL_ARG(int, count, arg2);
ret = occlum_writev(fd, iov, count);
break;
}
case SYS_readv: {
DECL_SYSCALL_ARG(int, fd, arg0);
DECL_SYSCALL_ARG(struct iovec*, iov, arg1);
DECL_SYSCALL_ARG(int, count, arg2);
ret = occlum_readv(fd, iov, count);
break;
}
case SYS_lseek: {
DECL_SYSCALL_ARG(int, fd, arg0);
DECL_SYSCALL_ARG(off_t, offset, arg1);
DECL_SYSCALL_ARG(int, whence, arg2);
ret = occlum_lseek(fd, offset, whence);
break;
}
case SYS_spawn: {
DECL_SYSCALL_ARG(int*, child_pid, arg0);
DECL_SYSCALL_ARG(const char*, path, arg1);
DECL_SYSCALL_ARG(const char**, argv, arg2);
DECL_SYSCALL_ARG(const char**, envp, arg3);
DECL_SYSCALL_ARG(void*, file_actions, arg4);
ret = occlum_spawn(child_pid, path, argv, envp, file_actions);
break;
}
case SYS_wait4: {
DECL_SYSCALL_ARG(int, child_pid, arg0);
DECL_SYSCALL_ARG(int*, status, arg1);
DECL_SYSCALL_ARG(int, options, arg2);
//DECL_SYSCALL_ARG(struct rusage*, rusage, arg3);
ret = occlum_wait4(child_pid, status, options/*, rusage*/);
break;
}
case SYS_getpid: {
ret = occlum_getpid();
break;
}
case SYS_getppid: {
ret = occlum_getppid();
break;
}
case SYS_sync: {
ret = occlum_sync();
break;
}
case SYS_mmap: {
DECL_SYSCALL_ARG(void*, addr, arg0);
DECL_SYSCALL_ARG(size_t, length, arg1);
DECL_SYSCALL_ARG(int, prot, arg2);
DECL_SYSCALL_ARG(int, flags, arg3);
DECL_SYSCALL_ARG(int, fd, arg4);
DECL_SYSCALL_ARG(off_t, offset, arg5);
ret = (long) occlum_mmap(addr, length, prot, flags, fd, offset);
break;
}
case SYS_munmap: {
DECL_SYSCALL_ARG(void*, addr, arg0);
DECL_SYSCALL_ARG(size_t, length, arg1);
ret = occlum_munmap(addr, length);
break;
}
case SYS_mremap: {
DECL_SYSCALL_ARG(void*, old_addr, arg0);
DECL_SYSCALL_ARG(size_t, old_size, arg1);
DECL_SYSCALL_ARG(size_t, new_size, arg2);
DECL_SYSCALL_ARG(int, flags, arg3);
DECL_SYSCALL_ARG(void*, new_addr, arg4);
ret = (long) occlum_mremap(old_addr, old_size, new_size, flags, new_addr);
break;
}
case SYS_brk: {
DECL_SYSCALL_ARG(void*, addr, arg0);
ret = (long) occlum_brk(addr);
break;
}
case SYS_pipe: {
DECL_SYSCALL_ARG(int*, fds, arg0);
ret = (long) occlum_pipe(fds);
break;
}
case SYS_pipe2: {
DECL_SYSCALL_ARG(int*, fds, arg0);
DECL_SYSCALL_ARG(int, flags, arg1);
ret = (long) occlum_pipe2(fds, flags);
break;
}
case SYS_dup: {
DECL_SYSCALL_ARG(int, old_fd, arg0);
ret = (long) occlum_dup(old_fd);
break;
}
case SYS_dup2: {
DECL_SYSCALL_ARG(int, old_fd, arg0);
DECL_SYSCALL_ARG(int, new_fd, arg1);
ret = (long) occlum_dup2(old_fd, new_fd);
break;
}
case SYS_dup3: {
DECL_SYSCALL_ARG(int, old_fd, arg0);
DECL_SYSCALL_ARG(int, new_fd, arg1);
DECL_SYSCALL_ARG(int, flags, arg2);
ret = (long) occlum_dup3(old_fd, new_fd, flags);
break;
}
case SYS_gettimeofday: {
DECL_SYSCALL_ARG(struct timeval*, tv, arg0);
//DECL_SYSCALL_ARG(struct timezone*, tz, arg1);
ret = (long) occlum_gettimeofday(tv/*, tz*/);
break;
}
case SYS_getcwd: {
DECL_SYSCALL_ARG(char*, buf, arg0);
DECL_SYSCALL_ARG(size_t, buf_size, arg1);
ret = (long) occlum_getcwd(buf, buf_size);
break;
}
default:
ret = occlum_unknown(num);
break;
}
return ret;
}