From d93a4062a280740047dc2c422c2cf82218ef1c87 Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 27 Oct 2022 17:42:00 +0200 Subject: [PATCH] libc: Do not use the heavy variadic syscall() function for wrappers That function is meant more for user programs, and should still be rarely used, since it's not portable. Instead, we already know the number of arguments. We just call __lc_fast_syscallN, which also sets errno. --- libs/libc/include/luna/syscall.h | 61 ++++++++++++++++++++++++++++---- libs/libc/src/fcntl.cpp | 6 ++-- libs/libc/src/luna.cpp | 6 ++-- libs/libc/src/luna/dirent.cpp | 4 +-- libs/libc/src/luna/pstat.cpp | 4 +-- libs/libc/src/sched.cpp | 4 +-- libs/libc/src/stdlib.cpp | 3 +- libs/libc/src/sys/mman.cpp | 9 ++--- libs/libc/src/sys/stat.cpp | 8 ++--- libs/libc/src/sys/wait.cpp | 4 +-- libs/libc/src/time.cpp | 3 +- libs/libc/src/unistd.cpp | 19 +++++----- 12 files changed, 92 insertions(+), 39 deletions(-) diff --git a/libs/libc/include/luna/syscall.h b/libs/libc/include/luna/syscall.h index 3f46dd27..850d1007 100644 --- a/libs/libc/include/luna/syscall.h +++ b/libs/libc/include/luna/syscall.h @@ -1,18 +1,67 @@ #ifndef _LUNA_SYSCALL_H #define _LUNA_SYSCALL_H +#include + +typedef unsigned long sysarg_t; + #ifdef __cplusplus extern "C" { #endif long __luna_syscall0(long sys_num); - long __luna_syscall1(long sys_num, unsigned long arg0); - long __luna_syscall2(long sys_num, unsigned long arg0, unsigned long arg1); - long __luna_syscall3(long sys_num, unsigned long arg0, unsigned long arg1, unsigned long arg2); - long __luna_syscall4(long sys_num, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3); - long __luna_syscall5(long sys_num, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, - unsigned long arg4); + long __luna_syscall1(long sys_num, sysarg_t arg0); + long __luna_syscall2(long sys_num, sysarg_t arg0, sysarg_t arg1); + long __luna_syscall3(long sys_num, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2); + long __luna_syscall4(long sys_num, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3); + long __luna_syscall5(long sys_num, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4); + + inline long __fast_syscall0(long number) + { + long result = __luna_syscall0(number); + _RETURN_WITH_ERRNO(result, long); + } + + inline long __fast_syscall1(long number, sysarg_t arg0) + { + long result = __luna_syscall1(number, arg0); + _RETURN_WITH_ERRNO(result, long); + } + + inline long __fast_syscall2(long number, sysarg_t arg0, sysarg_t arg1) + { + long result = __luna_syscall2(number, arg0, arg1); + _RETURN_WITH_ERRNO(result, long); + } + + inline long __fast_syscall3(long number, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2) + { + long result = __luna_syscall3(number, arg0, arg1, arg2); + _RETURN_WITH_ERRNO(result, long); + } + + inline long __fast_syscall4(long number, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) + { + long result = __luna_syscall4(number, arg0, arg1, arg2, arg3); + _RETURN_WITH_ERRNO(result, long); + } + + inline long __fast_syscall5(long number, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) + { + long result = __luna_syscall5(number, arg0, arg1, arg2, arg3, arg4); + _RETURN_WITH_ERRNO(result, long); + } + +#define __lc_fast_syscall0(number) __fast_syscall0(number) +#define __lc_fast_syscall1(number, arg0) __fast_syscall1(number, (sysarg_t)arg0) +#define __lc_fast_syscall2(number, arg0, arg1) __fast_syscall2(number, (sysarg_t)arg0, (sysarg_t)arg1) +#define __lc_fast_syscall3(number, arg0, arg1, arg2) \ + __fast_syscall3(number, (sysarg_t)arg0, (sysarg_t)arg1, (sysarg_t)arg2) +#define __lc_fast_syscall4(number, arg0, arg1, arg2, arg3) \ + __fast_syscall4(number, (sysarg_t)arg0, (sysarg_t)arg1, (sysarg_t)arg2, (sysarg_t)arg3) +#define __lc_fast_syscall5(number, arg0, arg1, arg2, arg3, arg4) \ + __fast_syscall5(number, (sysarg_t)arg0, (sysarg_t)arg1, (sysarg_t)arg2, (sysarg_t)arg3, (sysarg_t)arg4) #ifdef __cplusplus } diff --git a/libs/libc/src/fcntl.cpp b/libs/libc/src/fcntl.cpp index 5c623d43..0d37118c 100644 --- a/libs/libc/src/fcntl.cpp +++ b/libs/libc/src/fcntl.cpp @@ -1,8 +1,8 @@ #include +#include #include #include #include -#include extern "C" { @@ -10,7 +10,7 @@ extern "C" { va_list ap; va_start(ap, flags); - long result = syscall(SYS_open, pathname, flags, va_arg(ap, unsigned int)); + long result = __lc_fast_syscall3(SYS_open, pathname, flags, va_arg(ap, unsigned int)); va_end(ap); return (int)result; } @@ -19,7 +19,7 @@ extern "C" { va_list ap; va_start(ap, cmd); - long result = syscall(SYS_fcntl, fd, cmd, va_arg(ap, uintptr_t)); + long result = __lc_fast_syscall3(SYS_fcntl, fd, cmd, va_arg(ap, uintptr_t)); va_end(ap); return (int)result; } diff --git a/libs/libc/src/luna.cpp b/libs/libc/src/luna.cpp index 9fef0d0f..48dc1285 100644 --- a/libs/libc/src/luna.cpp +++ b/libs/libc/src/luna.cpp @@ -1,20 +1,20 @@ #include +#include #include #include #include #include -#include extern "C" { long getprocid(int field) { - return syscall(SYS_getprocid, field); + return __lc_fast_syscall1(SYS_getprocid, field); } unsigned int msleep(unsigned int ms) { - return (unsigned int)syscall(SYS_sleep, ms); + return (unsigned int)__lc_fast_syscall1(SYS_sleep, ms); } __lc_noreturn void __luna_abort(const char* message) diff --git a/libs/libc/src/luna/dirent.cpp b/libs/libc/src/luna/dirent.cpp index cd1e490f..967e2e5b 100644 --- a/libs/libc/src/luna/dirent.cpp +++ b/libs/libc/src/luna/dirent.cpp @@ -1,11 +1,11 @@ #include +#include #include -#include extern "C" { ssize_t getdents(int fd, struct luna_dirent* buf, size_t count) { - return syscall(SYS_getdents, fd, buf, count); + return __lc_fast_syscall3(SYS_getdents, fd, buf, count); } } \ No newline at end of file diff --git a/libs/libc/src/luna/pstat.cpp b/libs/libc/src/luna/pstat.cpp index 86edc206..1221b6de 100644 --- a/libs/libc/src/luna/pstat.cpp +++ b/libs/libc/src/luna/pstat.cpp @@ -1,12 +1,12 @@ #include +#include #include -#include extern "C" { pid_t pstat(pid_t pid, struct pstat* buf) { - return syscall(SYS_pstat, pid, buf); + return __lc_fast_syscall2(SYS_pstat, pid, buf); } const char* pstatname(struct pstat* buf) diff --git a/libs/libc/src/sched.cpp b/libs/libc/src/sched.cpp index 43d977ff..917b17d6 100644 --- a/libs/libc/src/sched.cpp +++ b/libs/libc/src/sched.cpp @@ -1,11 +1,11 @@ +#include #include #include -#include extern "C" { int sched_yield() { - return (int)syscall(SYS_yield); + return (int)__lc_fast_syscall0(SYS_yield); } } \ No newline at end of file diff --git a/libs/libc/src/stdlib.cpp b/libs/libc/src/stdlib.cpp index 48f9184b..f6e99102 100644 --- a/libs/libc/src/stdlib.cpp +++ b/libs/libc/src/stdlib.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -82,7 +83,7 @@ extern "C" __lc_noreturn void _Exit(int status) { - syscall(SYS_exit, status); + __lc_fast_syscall1(SYS_exit, status); __lc_unreachable(); } diff --git a/libs/libc/src/sys/mman.cpp b/libs/libc/src/sys/mman.cpp index 7868da6d..ec4356f1 100644 --- a/libs/libc/src/sys/mman.cpp +++ b/libs/libc/src/sys/mman.cpp @@ -1,22 +1,23 @@ +#include #include #include -#include extern "C" { // FIXME: Implement a POSIX-compliant mmap. void* mmap(void* addr, size_t len, int prot, int, int, off_t) { - return (void*)syscall(SYS_mmap, addr, len, prot); + long result = __luna_syscall3(SYS_mmap, (sysarg_t)addr, (sysarg_t)len, (sysarg_t)prot); + _RETURN_WITH_MEMORY_ERRNO(result, void*); } int munmap(void* addr, size_t len) { - return (int)syscall(SYS_munmap, addr, len); + return (int)__lc_fast_syscall2(SYS_munmap, addr, len); } int mprotect(void* addr, size_t size, int prot) { - return (int)syscall(SYS_mprotect, addr, size, prot); + return (int)__lc_fast_syscall3(SYS_mprotect, addr, size, prot); } } \ No newline at end of file diff --git a/libs/libc/src/sys/stat.cpp b/libs/libc/src/sys/stat.cpp index 387e6b71..5161058c 100644 --- a/libs/libc/src/sys/stat.cpp +++ b/libs/libc/src/sys/stat.cpp @@ -1,21 +1,21 @@ +#include #include #include -#include extern "C" { int mkdir(const char* pathname, mode_t) { - return (int)syscall(SYS_mkdir, pathname); + return (int)__lc_fast_syscall1(SYS_mkdir, pathname); } int fstat(int fd, struct stat* buf) { - return (int)syscall(SYS_fstat, fd, buf); + return (int)__lc_fast_syscall2(SYS_fstat, fd, buf); } int stat(const char* path, struct stat* buf) { - return (int)syscall(SYS_stat, path, buf); + return (int)__lc_fast_syscall2(SYS_stat, path, buf); } } \ No newline at end of file diff --git a/libs/libc/src/sys/wait.cpp b/libs/libc/src/sys/wait.cpp index 0458d2b2..ca9e524e 100644 --- a/libs/libc/src/sys/wait.cpp +++ b/libs/libc/src/sys/wait.cpp @@ -1,12 +1,12 @@ +#include #include #include -#include extern "C" { pid_t waitpid(pid_t pid, int* wstatus, int options) { - return syscall(SYS_waitpid, pid, wstatus, options); + return __lc_fast_syscall3(SYS_waitpid, pid, wstatus, options); } pid_t wait(int* wstatus) diff --git a/libs/libc/src/time.cpp b/libs/libc/src/time.cpp index 70f3b8df..319507f0 100644 --- a/libs/libc/src/time.cpp +++ b/libs/libc/src/time.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,7 +8,7 @@ extern "C" { clock_t clock() { - return syscall(SYS_clock); + return __lc_fast_syscall0(SYS_clock); } time_t time( diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp index 73967432..f9c5fb83 100644 --- a/libs/libc/src/unistd.cpp +++ b/libs/libc/src/unistd.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -10,7 +11,7 @@ extern "C" { int execv(const char* program, char* const argv[]) { - return (int)syscall(SYS_execv, program, argv); + return (int)__lc_fast_syscall2(SYS_execv, program, argv); } int execve(const char*, char* const[], char* const[]) @@ -24,7 +25,7 @@ extern "C" pid_t fork(void) { - return syscall(SYS_fork); + return __lc_fast_syscall0(SYS_fork); } pid_t getpid(void) @@ -44,27 +45,27 @@ extern "C" ssize_t read(int fd, void* buf, size_t count) { - return syscall(SYS_read, fd, count, buf); // yes, our read() syscall is in the wrong order. + return __lc_fast_syscall3(SYS_read, fd, count, buf); // yes, our read() syscall is in the wrong order. } ssize_t write(int fd, const void* buf, size_t count) { - return syscall(SYS_write, fd, count, buf); // yes, our write() syscall is in the wrong order. + return __lc_fast_syscall3(SYS_write, fd, count, buf); // yes, our write() syscall is in the wrong order. } int close(int fd) { - return (int)syscall(SYS_close, fd); + return (int)__lc_fast_syscall1(SYS_close, fd); } off_t lseek(int fd, off_t offset, int whence) { - return syscall(SYS_seek, fd, offset, whence); + return __lc_fast_syscall3(SYS_seek, fd, offset, whence); } __lc_noreturn void _exit(int status) { - syscall(SYS_exit, status); + __lc_fast_syscall1(SYS_exit, status); __lc_unreachable(); } @@ -75,12 +76,12 @@ extern "C" int dup2(int fd, int fd2) { - return (int)syscall(SYS_dup2, fd, fd2); + return (int)__lc_fast_syscall2(SYS_dup2, fd, fd2); } int access(const char* path, int amode) { - return (int)syscall(SYS_access, path, amode); + return (int)__lc_fast_syscall2(SYS_access, path, amode); } int isatty(int fd)