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.
This commit is contained in:
Bananymous 2023-07-31 22:24:11 +03:00
parent 08cdf88586
commit 8ec6d4c9fc
1 changed files with 8 additions and 280 deletions

View File

@ -27,288 +27,16 @@ 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)
{
errno = -ret;