From 834bf33e5717c01fe250c677fa854e7e3ee5fdcf Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 31 Jul 2023 22:24:11 +0300 Subject: [PATCH] LibC: we don't parse syscall arguments in unistd We just call Kernel::syscall() with 5 arguments from the variadic function. This was a necessary addition since the syscall() function used over 2 KiB of stack space. --- libc/unistd.cpp | 288 ++---------------------------------------------- 1 file changed, 8 insertions(+), 280 deletions(-) diff --git a/libc/unistd.cpp b/libc/unistd.cpp index a13cb02c..4f6dd6ef 100644 --- a/libc/unistd.cpp +++ b/libc/unistd.cpp @@ -27,287 +27,15 @@ long syscall(long syscall, ...) va_list args; va_start(args, syscall); - long ret = -1; - - switch (syscall) - { - case SYS_EXIT: - { - int exit_code = va_arg(args, int); - ret = Kernel::syscall(SYS_EXIT, exit_code); - break; - } - case SYS_READ: - { - int fd = va_arg(args, int); - void* buffer = va_arg(args, void*); - size_t bytes = va_arg(args, size_t); - ret = Kernel::syscall(SYS_READ, fd, (uintptr_t)buffer, bytes); - break; - } - case SYS_WRITE: - { - int fd = va_arg(args, int); - const void* buffer = va_arg(args, const void*); - size_t bytes = va_arg(args, size_t); - ret = Kernel::syscall(SYS_WRITE, fd, (uintptr_t)buffer, bytes); - break; - } - case SYS_TERMID: - { - char* buffer = va_arg(args, char*); - ret = Kernel::syscall(SYS_TERMID, (uintptr_t)buffer); - break; - } - case SYS_CLOSE: - { - int fd = va_arg(args, int); - ret = Kernel::syscall(SYS_CLOSE, fd); - break; - } - case SYS_OPEN: - { - const char* path = va_arg(args, const char*); - int oflags = va_arg(args, int); - mode_t mode = va_arg(args, mode_t); - ret = Kernel::syscall(SYS_OPEN, (uintptr_t)path, oflags, mode); - break; - } - case SYS_OPENAT: - { - int fd = va_arg(args, int); - const char* path = va_arg(args, const char*); - int oflags = va_arg(args, int); - mode_t mode = va_arg(args, mode_t); - ret = Kernel::syscall(SYS_OPENAT, fd, (uintptr_t)path, oflags, mode); - break; - } - case SYS_ALLOC: - { - size_t bytes = va_arg(args, size_t); - ret = Kernel::syscall(SYS_ALLOC, bytes); - break; - } - case SYS_REALLOC: - { - void* ptr = va_arg(args, void*); - size_t size = va_arg(args, size_t); - ret = Kernel::syscall(SYS_REALLOC, (uintptr_t)ptr, size); - break; - } - case SYS_FREE: - { - void* ptr = va_arg(args, void*); - ret = Kernel::syscall(SYS_FREE, (uintptr_t)ptr); - break; - } - case SYS_SEEK: - { - int fd = va_arg(args, int); - off_t offset = va_arg(args, off_t); - int whence = va_arg(args, int); - ret = Kernel::syscall(SYS_SEEK, fd, offset, whence); - break; - } - case SYS_TELL: - { - int fd = va_arg(args, int); - ret = Kernel::syscall(SYS_TELL, fd); - break; - } - case SYS_GET_TERMIOS: - { - struct termios* termios = va_arg(args, struct termios*); - ret = Kernel::syscall(SYS_GET_TERMIOS, (uintptr_t)termios); - break; - } - case SYS_SET_TERMIOS: - { - const struct termios* termios = va_arg(args, const struct termios*); - ret = Kernel::syscall(SYS_SET_TERMIOS, (uintptr_t)termios); - break; - } - case SYS_FORK: - { - ret = Kernel::syscall(SYS_FORK); - break; - } - case SYS_EXEC: - { - const char* pathname = va_arg(args, const char*); - const char* const* argv = va_arg(args, const char* const*); - const char* const* envp = va_arg(args, const char* const*); - ret = Kernel::syscall(SYS_EXEC, (uintptr_t)pathname, (uintptr_t)argv, (uintptr_t)envp); - break; - } - case SYS_SLEEP: - { - unsigned int seconds = va_arg(args, unsigned int); - ret = Kernel::syscall(SYS_SLEEP, seconds); - break; - } - case SYS_WAIT: - { - pid_t pid = va_arg(args, pid_t); - int* stat_loc = va_arg(args, int*); - int options = va_arg(args, int); - ret = Kernel::syscall(SYS_WAIT, pid, (uintptr_t)stat_loc, options); - break; - } - case SYS_FSTAT: - { - int fd = va_arg(args, int); - struct stat* buf = va_arg(args, struct stat*); - ret = Kernel::syscall(SYS_FSTAT, (uintptr_t)fd, (uintptr_t)buf); - break; - } - case SYS_SETENVP: - { - char** envp = va_arg(args, char**); - ret = Kernel::syscall(SYS_SETENVP, (uintptr_t)envp); - break; - } - case SYS_READ_DIR_ENTRIES: - { - int fd = va_arg(args, int); - void* buffer = va_arg(args, void*); - size_t buffer_size = va_arg(args, size_t); - ret = Kernel::syscall(SYS_READ_DIR_ENTRIES, fd, (uintptr_t)buffer, buffer_size); - break; - } - case SYS_SET_UID: - { - uid_t uid = va_arg(args, uid_t); - ret = Kernel::syscall(SYS_SET_UID, uid); - break; - } - case SYS_SET_GID: - { - gid_t gid = va_arg(args, gid_t); - ret = Kernel::syscall(SYS_SET_GID, gid); - break; - } - case SYS_SET_EUID: - { - uid_t uid = va_arg(args, uid_t); - ret = Kernel::syscall(SYS_SET_EUID, uid); - break; - } - case SYS_SET_EGID: - { - gid_t gid = va_arg(args, gid_t); - ret = Kernel::syscall(SYS_SET_EGID, gid); - break; - } - case SYS_SET_REUID: - { - uid_t ruid = va_arg(args, uid_t); - uid_t euid = va_arg(args, uid_t); - ret = Kernel::syscall(SYS_SET_REUID, ruid, euid); - break; - } - case SYS_SET_REGID: - { - gid_t rgid = va_arg(args, gid_t); - gid_t egid = va_arg(args, gid_t); - ret = Kernel::syscall(SYS_SET_REGID, rgid, egid); - break; - } - case SYS_GET_UID: - { - ret = Kernel::syscall(SYS_GET_UID); - break; - } - case SYS_GET_GID: - { - ret = Kernel::syscall(SYS_GET_GID); - break; - } - case SYS_GET_EUID: - { - ret = Kernel::syscall(SYS_GET_EUID); - break; - } - case SYS_GET_EGID: - { - ret = Kernel::syscall(SYS_GET_EGID); - break; - } - case SYS_GET_PWD: - { - char* buffer = va_arg(args, char*); - size_t size = va_arg(args, size_t); - ret = Kernel::syscall(SYS_GET_PWD, (uintptr_t)buffer, size); - break; - } - case SYS_SET_PWD: - { - const char* path = va_arg(args, const char*); - ret = Kernel::syscall(SYS_SET_PWD, (uintptr_t)path); - break; - } - case SYS_CLOCK_GETTIME: - { - clockid_t clock_id = va_arg(args, clockid_t); - timespec* tp = va_arg(args, timespec*); - ret = Kernel::syscall(SYS_CLOCK_GETTIME, clock_id, (uintptr_t)tp); - break; - } - case SYS_PIPE: - { - int* fildes = va_arg(args, int*); - ret = Kernel::syscall(SYS_PIPE, (uintptr_t)fildes); - break; - } - case SYS_DUP2: - { - int fildes = va_arg(args, int); - int fildes2 = va_arg(args, int); - ret = Kernel::syscall(SYS_DUP2, fildes, fildes2); - break; - } - case SYS_RAISE: - { - int signal = va_arg(args, int); - ret = Kernel::syscall(SYS_RAISE, signal); - break; - } - case SYS_KILL: - { - pid_t pid = va_arg(args, pid_t); - int signal = va_arg(args, int); - ret = Kernel::syscall(SYS_KILL, pid, signal); - break; - } - case SYS_SIGNAL: - { - int signal = va_arg(args, int); - void (*handler)(int) = va_arg(args, void(*)(int)); - ret = Kernel::syscall(SYS_SIGNAL, signal, (uintptr_t)handler); - break; - } - case SYS_TCSETPGRP: - { - int fd = va_arg(args, int); - pid_t pgrp = va_arg(args, pid_t); - ret = Kernel::syscall(SYS_TCSETPGRP, fd, pgrp); - break; - } - case SYS_GET_PID: - { - ret = Kernel::syscall(SYS_GET_PID); - break; - } - case SYS_SIGNAL_DONE: - // Should not be called by an user - // fall through - default: - puts("LibC: Unhandeled syscall"); - ret = -ENOSYS; - break; - } - + uintptr_t arg1 = va_arg(args, uintptr_t); + uintptr_t arg2 = va_arg(args, uintptr_t); + uintptr_t arg3 = va_arg(args, uintptr_t); + uintptr_t arg4 = va_arg(args, uintptr_t); + uintptr_t arg5 = va_arg(args, uintptr_t); + va_end(args); + + long ret = Kernel::syscall(syscall, arg1, arg2, arg3, arg4, arg5); if (ret < 0) {