/* * This file implements the system call handler. It is called by the exc128 * handler function and just switches the syscall number into the syscall list * and runs the relevant function. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Structure for a System Call Entry */ struct SyscallEntry { int argc; void *function; }; /* List of syscalls */ struct SyscallEntry syscalls[] = { /* Kernel */ [SYSCALL_DBGPRINTF] = { 1, dbgprintf }, [SYSCALL_UNAME] = { 1, uname }, /* Task */ [SYSCALL_CLONE] = { 1, clone }, [SYSCALL_EXIT] = { 1, exit }, [SYSCALL_GETPID] = { 0, getpid }, [SYSCALL_GETUID] = { 0, getuid }, [SYSCALL_SETUID] = { 1, setuid }, [SYSCALL_GETEUID] = { 0, geteuid }, [SYSCALL_SETEUID] = { 1, seteuid }, [SYSCALL_GETGID] = { 0, getgid }, [SYSCALL_SETGID] = { 1, setgid }, [SYSCALL_GETEGID] = { 0, getegid }, [SYSCALL_SETEGID] = { 1, setegid }, [SYSCALL_EXECVE] = { 3, execve }, [SYSCALL_WAITPID] = { 3, waitpid }, // [SYSCALL_TIME] = { 1, time }, // [SYSCALL_TIMES] = { 1, times }, // [SYSCALL_SLEEP] = { 1, sleep }, /* Files */ [SYSCALL_OPEN] = { 3, open }, [SYSCALL_CLOSE] = { 1, close }, [SYSCALL_READ] = { 3, read }, [SYSCALL_WRITE] = { 3, write }, [SYSCALL_IOCTL] = { 3, ioctl }, [SYSCALL_LSEEK] = { 3, lseek }, [SYSCALL_STAT] = { 2, stat }, [SYSCALL_FSTAT] = { 2, fstat }, [SYSCALL_GETDENTS] = { 3, getdents }, [SYSCALL_MKDIR] = { 2, mkdir }, // [SYSCALL_RMDIR] = { 1, rmdir }, [SYSCALL_MKNOD] = { 3, mknod }, // [SYSCALL_RENAME] = { 2, rename }, [SYSCALL_DUP] = { 1, dup }, [SYSCALL_DUP2] = { 2, dup2 }, // [SYSCALL_ISATTY] = { 1, isatty }, // [SYSCALL_PIPE] = { 1, pipe }, /* File System */ [SYSCALL_MOUNT] = { 5, mount }, [SYSCALL_CHDIR] = { 1, chdir }, [SYSCALL_CHROOT] = { 1, chroot }, [SYSCALL_GETCWD] = { 2, getcwd }, /* Memory */ [SYSCALL_MMAP] = { 6, mmap }, /* Signals */ [SYSCALL_TGKILL] = { 3, tgkill }, [SYSCALL_KILL] = { 2, kill }, [SYSCALL_SIGNAL] = { 2, signal }, [SYSCALL_SIGPROCMASK] = { 3, sigprocmask }, }; /* Handle a syscall */ void syscall_handler(struct InterruptFrame *frame) { int num = frame->eax; uintptr_t args = frame->esi; int ret = -EINVAL; enter_syscall_context(); /* Find syscall entry */ if (num >= sizeof(syscalls) / sizeof(syscalls[0])) goto end; struct SyscallEntry *syscall = &syscalls[num]; if (!syscall->function) goto end; /* Copy arguments onto stack */ if (syscall->argc) { int *val = (int *) args; int argc = syscall->argc; if (!verify_access(val, argc * sizeof(int), PROT_READ)) goto end; while (argc--) asm volatile("pushl %0" :: "r" (val[argc])); } /* Call function */ asm volatile( "sti;" "call *%1;" "cli" : "=a" (ret) : "r" (syscall->function) ); end: exit_syscall_context(); frame->eax = ret; }