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.
This commit is contained in:
apio 2022-10-27 17:42:00 +02:00
parent 0eb0ca4028
commit d93a4062a2
12 changed files with 92 additions and 39 deletions

View File

@ -1,18 +1,67 @@
#ifndef _LUNA_SYSCALL_H
#define _LUNA_SYSCALL_H
#include <bits/error.h>
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
}

View File

@ -1,8 +1,8 @@
#include <fcntl.h>
#include <luna/syscall.h>
#include <stdarg.h>
#include <stdint.h>
#include <sys/syscall.h>
#include <unistd.h>
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;
}

View File

@ -1,20 +1,20 @@
#include <luna.h>
#include <luna/syscall.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
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)

View File

@ -1,11 +1,11 @@
#include <luna/dirent.h>
#include <luna/syscall.h>
#include <sys/syscall.h>
#include <unistd.h>
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);
}
}

View File

@ -1,12 +1,12 @@
#include <luna/pstat.h>
#include <luna/syscall.h>
#include <sys/syscall.h>
#include <unistd.h>
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)

View File

@ -1,11 +1,11 @@
#include <luna/syscall.h>
#include <sched.h>
#include <sys/syscall.h>
#include <unistd.h>
extern "C"
{
int sched_yield()
{
return (int)syscall(SYS_yield);
return (int)__lc_fast_syscall0(SYS_yield);
}
}

View File

@ -1,5 +1,6 @@
#include <ctype.h>
#include <luna.h>
#include <luna/syscall.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
@ -82,7 +83,7 @@ extern "C"
__lc_noreturn void _Exit(int status)
{
syscall(SYS_exit, status);
__lc_fast_syscall1(SYS_exit, status);
__lc_unreachable();
}

View File

@ -1,22 +1,23 @@
#include <luna/syscall.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
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);
}
}

View File

@ -1,21 +1,21 @@
#include <luna/syscall.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
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);
}
}

View File

@ -1,12 +1,12 @@
#include <luna/syscall.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
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)

View File

@ -1,4 +1,5 @@
#include <luna.h>
#include <luna/syscall.h>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>
@ -7,7 +8,7 @@ extern "C"
{
clock_t clock()
{
return syscall(SYS_clock);
return __lc_fast_syscall0(SYS_clock);
}
time_t time(

View File

@ -1,6 +1,7 @@
#include <errno.h>
#include <fcntl.h>
#include <luna.h>
#include <luna/syscall.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
@ -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)