Kernel: Improve syscall handling
Syscalls are now called from a list of function pointers
This commit is contained in:
parent
78ef7e804f
commit
9314528b9b
|
@ -1,7 +1,5 @@
|
|||
.section .userspace, "aw"
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
// stack contains
|
||||
// return address
|
||||
// signal number
|
||||
|
|
|
@ -96,6 +96,8 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_getegid() const { return m_credentials.egid(); }
|
||||
BAN::ErrorOr<long> sys_getpgid(pid_t);
|
||||
|
||||
BAN::ErrorOr<long> sys_getpid() const { return pid(); }
|
||||
|
||||
BAN::ErrorOr<long> open_inode(BAN::RefPtr<Inode>, int flags);
|
||||
|
||||
BAN::ErrorOr<void> create_file_or_dir(BAN::StringView name, mode_t mode);
|
||||
|
@ -148,7 +150,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
|
||||
|
||||
BAN::ErrorOr<long> sys_read_dir_entries(int fd, DirectoryEntryList* buffer, size_t buffer_size);
|
||||
BAN::ErrorOr<long> sys_readdir(int fd, DirectoryEntryList* buffer, size_t buffer_size);
|
||||
|
||||
BAN::ErrorOr<long> sys_mmap(const sys_mmap_t*);
|
||||
BAN::ErrorOr<long> sys_munmap(void* addr, size_t len);
|
||||
|
@ -157,7 +159,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_tty_ctrl(int fildes, int command, int flags);
|
||||
|
||||
BAN::ErrorOr<long> sys_signal(int, void (*)(int));
|
||||
static BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);
|
||||
BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);
|
||||
|
||||
BAN::ErrorOr<long> sys_tcsetpgrp(int fd, pid_t pgid);
|
||||
|
||||
|
|
|
@ -1218,7 +1218,7 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(EUNKNOWN);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_read_dir_entries(int fd, DirectoryEntryList* list, size_t list_size)
|
||||
BAN::ErrorOr<long> Process::sys_readdir(int fd, DirectoryEntryList* list, size_t list_size)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
TRY(validate_pointer_access(list, list_size));
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <BAN/Bitcast.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/InterruptStack.h>
|
||||
#include <kernel/Process.h>
|
||||
|
@ -19,6 +20,14 @@ namespace Kernel
|
|||
|
||||
extern "C" long sys_fork_trampoline();
|
||||
|
||||
using SyscallHandler = BAN::ErrorOr<long> (Process::*)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
|
||||
static const SyscallHandler s_syscall_handlers[] = {
|
||||
#define O(enum, name) BAN::bit_cast<SyscallHandler>(&Process::sys_ ## name),
|
||||
__SYSCALL_LIST(O)
|
||||
#undef O
|
||||
};
|
||||
|
||||
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack& interrupt_stack)
|
||||
{
|
||||
ASSERT((interrupt_stack.cs & 0b11) == 0b11);
|
||||
|
@ -28,222 +37,14 @@ namespace Kernel
|
|||
|
||||
asm volatile("sti");
|
||||
|
||||
(void)arg1;
|
||||
(void)arg2;
|
||||
(void)arg3;
|
||||
(void)arg4;
|
||||
(void)arg5;
|
||||
(void)interrupt_stack;
|
||||
|
||||
BAN::ErrorOr<long> ret = BAN::Error::from_errno(ENOSYS);
|
||||
|
||||
switch (syscall)
|
||||
{
|
||||
case SYS_EXIT:
|
||||
ret = Process::current().sys_exit((int)arg1);
|
||||
break;
|
||||
case SYS_READ:
|
||||
ret = Process::current().sys_read((int)arg1, (void*)arg2, (size_t)arg3);
|
||||
break;
|
||||
case SYS_WRITE:
|
||||
ret = Process::current().sys_write((int)arg1, (const void*)arg2, (size_t)arg3);
|
||||
break;
|
||||
case SYS_TERMID:
|
||||
ret = Process::current().sys_termid((char*)arg1);
|
||||
break;
|
||||
case SYS_CLOSE:
|
||||
ret = Process::current().sys_close((int)arg1);
|
||||
break;
|
||||
case SYS_OPEN:
|
||||
ret = Process::current().sys_open((const char*)arg1, (int)arg2, (mode_t)arg3);
|
||||
break;
|
||||
case SYS_OPENAT:
|
||||
ret = Process::current().sys_openat((int)arg1, (const char*)arg2, (int)arg3, (mode_t)arg4);
|
||||
break;
|
||||
case SYS_SEEK:
|
||||
ret = Process::current().sys_seek((int)arg1, (long)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_TELL:
|
||||
ret = Process::current().sys_tell((int)arg1);
|
||||
break;
|
||||
case SYS_GET_TERMIOS:
|
||||
ret = Process::current().sys_gettermios((::termios*)arg1);
|
||||
break;
|
||||
case SYS_SET_TERMIOS:
|
||||
ret = Process::current().sys_settermios((const ::termios*)arg1);
|
||||
break;
|
||||
case SYS_FORK:
|
||||
if (syscall < 0 || syscall >= __SYSCALL_COUNT)
|
||||
dwarnln("No syscall {}", syscall);
|
||||
else if (syscall == SYS_FORK)
|
||||
ret = sys_fork_trampoline();
|
||||
break;
|
||||
case SYS_EXEC:
|
||||
ret = Process::current().sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
|
||||
break;
|
||||
case SYS_SLEEP:
|
||||
ret = Process::current().sys_sleep((unsigned int)arg1);
|
||||
break;
|
||||
case SYS_WAIT:
|
||||
ret = Process::current().sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_FSTAT:
|
||||
ret = Process::current().sys_fstat((int)arg1, (struct stat*)arg2);
|
||||
break;
|
||||
case SYS_READ_DIR_ENTRIES:
|
||||
ret = Process::current().sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
|
||||
break;
|
||||
case SYS_SET_UID:
|
||||
ret = Process::current().sys_setuid((uid_t)arg1);
|
||||
break;
|
||||
case SYS_SET_GID:
|
||||
ret = Process::current().sys_setgid((gid_t)arg1);
|
||||
break;
|
||||
case SYS_SET_EUID:
|
||||
ret = Process::current().sys_seteuid((uid_t)arg1);
|
||||
break;
|
||||
case SYS_SET_EGID:
|
||||
ret = Process::current().sys_setegid((gid_t)arg1);
|
||||
break;
|
||||
case SYS_SET_REUID:
|
||||
ret = Process::current().sys_setreuid((uid_t)arg1, (uid_t)arg2);
|
||||
break;
|
||||
case SYS_SET_REGID:
|
||||
ret = Process::current().sys_setregid((gid_t)arg1, (gid_t)arg2);
|
||||
break;
|
||||
case SYS_GET_UID:
|
||||
ret = Process::current().sys_getuid();
|
||||
break;
|
||||
case SYS_GET_GID:
|
||||
ret = Process::current().sys_getgid();
|
||||
break;
|
||||
case SYS_GET_EUID:
|
||||
ret = Process::current().sys_geteuid();
|
||||
break;
|
||||
case SYS_GET_EGID:
|
||||
ret = Process::current().sys_getegid();
|
||||
break;
|
||||
case SYS_GET_PWD:
|
||||
ret = Process::current().sys_getpwd((char*)arg1, (size_t)arg2);
|
||||
break;
|
||||
case SYS_SET_PWD:
|
||||
ret = Process::current().sys_setpwd((const char*)arg1);
|
||||
break;
|
||||
case SYS_CLOCK_GETTIME:
|
||||
ret = Process::current().sys_clock_gettime((clockid_t)arg1, (timespec*)arg2);
|
||||
break;
|
||||
case SYS_PIPE:
|
||||
ret = Process::current().sys_pipe((int*)arg1);
|
||||
break;
|
||||
case SYS_DUP:
|
||||
ret = Process::current().sys_dup((int)arg1);
|
||||
break;
|
||||
case SYS_DUP2:
|
||||
ret = Process::current().sys_dup2((int)arg1, (int)arg2);
|
||||
break;
|
||||
case SYS_KILL:
|
||||
ret = Process::current().sys_kill((pid_t)arg1, (int)arg2);
|
||||
break;
|
||||
case SYS_SIGNAL:
|
||||
ret = Process::current().sys_signal((int)arg1, (void (*)(int))arg2);
|
||||
break;
|
||||
case SYS_TCSETPGRP:
|
||||
ret = Process::current().sys_tcsetpgrp((int)arg1, (pid_t)arg2);
|
||||
break;
|
||||
case SYS_GET_PID:
|
||||
ret = Process::current().pid();
|
||||
break;
|
||||
case SYS_GET_PGID:
|
||||
ret = Process::current().sys_getpgid((pid_t)arg1);
|
||||
break;
|
||||
case SYS_SET_PGID:
|
||||
ret = Process::current().sys_setpgid((pid_t)arg1, (pid_t)arg2);
|
||||
break;
|
||||
case SYS_FCNTL:
|
||||
ret = Process::current().sys_fcntl((int)arg1, (int)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_NANOSLEEP:
|
||||
ret = Process::current().sys_nanosleep((const timespec*)arg1, (timespec*)arg2);
|
||||
break;
|
||||
case SYS_FSTATAT:
|
||||
ret = Process::current().sys_fstatat((int)arg1, (const char*)arg2, (struct stat*)arg3, (int)arg4);
|
||||
break;
|
||||
case SYS_STAT:
|
||||
ret = Process::current().sys_stat((const char*)arg1, (struct stat*)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_SYNC:
|
||||
ret = Process::current().sys_sync((bool)arg1);
|
||||
break;
|
||||
case SYS_MMAP:
|
||||
ret = Process::current().sys_mmap((const sys_mmap_t*)arg1);
|
||||
break;
|
||||
case SYS_MUNMAP:
|
||||
ret = Process::current().sys_munmap((void*)arg1, (size_t)arg2);
|
||||
break;
|
||||
case SYS_TTY_CTRL:
|
||||
ret = Process::current().sys_tty_ctrl((int)arg1, (int)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_POWEROFF:
|
||||
ret = Process::current().sys_poweroff((int)arg1);
|
||||
break;
|
||||
case SYS_CHMOD:
|
||||
ret = Process::current().sys_chmod((const char*)arg1, (mode_t)arg2);
|
||||
break;
|
||||
case SYS_CREATE:
|
||||
ret = Process::current().sys_create((const char*)arg1, (mode_t)arg2);
|
||||
break;
|
||||
case SYS_CREATE_DIR:
|
||||
ret = Process::current().sys_create_dir((const char*)arg1, (mode_t)arg2);
|
||||
break;
|
||||
case SYS_UNLINK:
|
||||
ret = Process::current().sys_unlink((const char*)arg1);
|
||||
break;
|
||||
case SYS_READLINK:
|
||||
ret = Process::current().sys_readlink((const char*)arg1, (char*)arg2, (size_t)arg3);
|
||||
break;
|
||||
case SYS_READLINKAT:
|
||||
ret = Process::current().sys_readlinkat((int)arg1, (const char*)arg2, (char*)arg3, (size_t)arg4);
|
||||
break;
|
||||
case SYS_MSYNC:
|
||||
ret = Process::current().sys_msync((void*)arg1, (size_t)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_PREAD:
|
||||
ret = Process::current().sys_pread((int)arg1, (void*)arg2, (size_t)arg3, (off_t)arg4);
|
||||
break;
|
||||
case SYS_CHOWN:
|
||||
ret = Process::current().sys_chown((const char*)arg1, (uid_t)arg2, (gid_t)arg3);
|
||||
break;
|
||||
case SYS_LOAD_KEYMAP:
|
||||
ret = Process::current().sys_load_keymap((const char*)arg1);
|
||||
break;
|
||||
case SYS_SOCKET:
|
||||
ret = Process::current().sys_socket((int)arg1, (int)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_BIND:
|
||||
ret = Process::current().sys_bind((int)arg1, (const sockaddr*)arg2, (socklen_t)arg3);
|
||||
break;
|
||||
case SYS_SENDTO:
|
||||
ret = Process::current().sys_sendto((const sys_sendto_t*)arg1);
|
||||
break;
|
||||
case SYS_RECVFROM:
|
||||
ret = Process::current().sys_recvfrom((sys_recvfrom_t*)arg1);
|
||||
break;
|
||||
case SYS_IOCTL:
|
||||
ret = Process::current().sys_ioctl((int)arg1, (int)arg2, (void*)arg3);
|
||||
break;
|
||||
case SYS_ACCEPT:
|
||||
ret = Process::current().sys_accept((int)arg1, (sockaddr*)arg2, (socklen_t*)arg3);
|
||||
break;
|
||||
case SYS_CONNECT:
|
||||
ret = Process::current().sys_connect((int)arg1, (const sockaddr*)arg2, (socklen_t)arg3);
|
||||
break;
|
||||
case SYS_LISTEN:
|
||||
ret = Process::current().sys_listen((int)arg1, (int)arg2);
|
||||
break;
|
||||
case SYS_PSELECT:
|
||||
ret = Process::current().sys_pselect((sys_pselect_t*)arg1);
|
||||
break;
|
||||
default:
|
||||
dwarnln("Unknown syscall {}", syscall);
|
||||
break;
|
||||
}
|
||||
else
|
||||
ret = (Process::current().*s_syscall_handlers[syscall])(arg1, arg2, arg3, arg4, arg5);
|
||||
|
||||
asm volatile("cli");
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ namespace Kernel
|
|||
// ^C
|
||||
if (ch == '\x03')
|
||||
{
|
||||
if (auto ret = Process::sys_kill(-m_foreground_pgrp, SIGINT); ret.is_error())
|
||||
if (auto ret = Process::current().sys_kill(-m_foreground_pgrp, SIGINT); ret.is_error())
|
||||
dwarnln("TTY: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ struct dirent* readdir(DIR* dirp)
|
|||
return &dirp->current->dirent;
|
||||
}
|
||||
|
||||
if (syscall(SYS_READ_DIR_ENTRIES, dirp->fd, dirp->buffer, dirp->buffer_size) == -1)
|
||||
if (syscall(SYS_READ_DIR, dirp->fd, dirp->buffer, dirp->buffer_size) == -1)
|
||||
return nullptr;
|
||||
|
||||
if (dirp->buffer->entry_count == 0)
|
||||
|
|
|
@ -5,73 +5,82 @@
|
|||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define SYS_EXIT 1
|
||||
#define SYS_READ 2
|
||||
#define SYS_WRITE 3
|
||||
#define SYS_TERMID 4
|
||||
#define SYS_CLOSE 5
|
||||
#define SYS_OPEN 6
|
||||
#define SYS_OPENAT 7
|
||||
#define SYS_SEEK 11
|
||||
#define SYS_TELL 12
|
||||
#define SYS_GET_TERMIOS 13
|
||||
#define SYS_SET_TERMIOS 14
|
||||
#define SYS_FORK 15
|
||||
#define SYS_EXEC 16
|
||||
#define SYS_SLEEP 17
|
||||
#define SYS_WAIT 18
|
||||
#define SYS_FSTAT 19
|
||||
#define SYS_READ_DIR_ENTRIES 21
|
||||
#define SYS_SET_UID 22
|
||||
#define SYS_SET_GID 23
|
||||
#define SYS_SET_EUID 24
|
||||
#define SYS_SET_EGID 25
|
||||
#define SYS_SET_REUID 26
|
||||
#define SYS_SET_REGID 27
|
||||
#define SYS_GET_UID 28
|
||||
#define SYS_GET_GID 29
|
||||
#define SYS_GET_EUID 30
|
||||
#define SYS_GET_EGID 31
|
||||
#define SYS_GET_PWD 32
|
||||
#define SYS_SET_PWD 33
|
||||
#define SYS_CLOCK_GETTIME 34
|
||||
#define SYS_PIPE 35
|
||||
#define SYS_DUP 36
|
||||
#define SYS_DUP2 37
|
||||
#define SYS_KILL 39
|
||||
#define SYS_SIGNAL 40
|
||||
#define SYS_TCSETPGRP 42
|
||||
#define SYS_GET_PID 43
|
||||
#define SYS_GET_PGID 44
|
||||
#define SYS_SET_PGID 45
|
||||
#define SYS_FCNTL 46
|
||||
#define SYS_NANOSLEEP 47
|
||||
#define SYS_FSTATAT 48
|
||||
#define SYS_STAT 49 // stat/lstat
|
||||
#define SYS_SYNC 50
|
||||
#define SYS_MMAP 51
|
||||
#define SYS_MUNMAP 52
|
||||
#define SYS_TTY_CTRL 53
|
||||
#define SYS_POWEROFF 54
|
||||
#define SYS_CHMOD 55
|
||||
#define SYS_CREATE 56 // creat, mkfifo
|
||||
#define SYS_CREATE_DIR 57 // mkdir
|
||||
#define SYS_UNLINK 58
|
||||
#define SYS_READLINK 59
|
||||
#define SYS_READLINKAT 60
|
||||
#define SYS_MSYNC 61
|
||||
#define SYS_PREAD 62
|
||||
#define SYS_CHOWN 63
|
||||
#define SYS_LOAD_KEYMAP 64
|
||||
#define SYS_SOCKET 65
|
||||
#define SYS_BIND 66
|
||||
#define SYS_SENDTO 67
|
||||
#define SYS_RECVFROM 68
|
||||
#define SYS_IOCTL 69
|
||||
#define SYS_ACCEPT 70
|
||||
#define SYS_CONNECT 71
|
||||
#define SYS_LISTEN 72
|
||||
#define SYS_PSELECT 73
|
||||
#define __SYSCALL_LIST(O) \
|
||||
O(SYS_EXIT, exit) \
|
||||
O(SYS_READ, read) \
|
||||
O(SYS_WRITE, write) \
|
||||
O(SYS_TERMID, termid) \
|
||||
O(SYS_CLOSE, close) \
|
||||
O(SYS_OPEN, open) \
|
||||
O(SYS_OPENAT, openat) \
|
||||
O(SYS_SEEK, seek) \
|
||||
O(SYS_TELL, tell) \
|
||||
O(SYS_GET_TERMIOS, gettermios) \
|
||||
O(SYS_SET_TERMIOS, settermios) \
|
||||
O(SYS_FORK, fork) \
|
||||
O(SYS_EXEC, exec) \
|
||||
O(SYS_SLEEP, sleep) \
|
||||
O(SYS_WAIT, wait) \
|
||||
O(SYS_FSTAT, fstat) \
|
||||
O(SYS_READ_DIR, readdir) \
|
||||
O(SYS_SET_UID, setuid) \
|
||||
O(SYS_SET_GID, setgid) \
|
||||
O(SYS_SET_EUID, seteuid) \
|
||||
O(SYS_SET_EGID, setegid) \
|
||||
O(SYS_SET_REUID, setreuid) \
|
||||
O(SYS_SET_REGID, setregid) \
|
||||
O(SYS_GET_UID, getuid) \
|
||||
O(SYS_GET_GID, getgid) \
|
||||
O(SYS_GET_EUID, geteuid) \
|
||||
O(SYS_GET_EGID, getegid) \
|
||||
O(SYS_GET_PWD, getpwd) \
|
||||
O(SYS_SET_PWD, setpwd) \
|
||||
O(SYS_CLOCK_GETTIME, clock_gettime) \
|
||||
O(SYS_PIPE, pipe) \
|
||||
O(SYS_DUP, dup) \
|
||||
O(SYS_DUP2, dup2) \
|
||||
O(SYS_KILL, kill) \
|
||||
O(SYS_SIGNAL, signal) \
|
||||
O(SYS_TCSETPGRP, tcsetpgrp) \
|
||||
O(SYS_GET_PID, getpid) \
|
||||
O(SYS_GET_PGID, getpgid) \
|
||||
O(SYS_SET_PGID, setpgid) \
|
||||
O(SYS_FCNTL, fcntl) \
|
||||
O(SYS_NANOSLEEP, nanosleep) \
|
||||
O(SYS_FSTATAT, fstatat) \
|
||||
O(SYS_STAT, stat) \
|
||||
O(SYS_SYNC, sync) \
|
||||
O(SYS_MMAP, mmap) \
|
||||
O(SYS_MUNMAP, munmap) \
|
||||
O(SYS_TTY_CTRL, tty_ctrl) \
|
||||
O(SYS_POWEROFF, poweroff) \
|
||||
O(SYS_CHMOD, chmod) \
|
||||
O(SYS_CREATE, create) \
|
||||
O(SYS_CREATE_DIR, create_dir) \
|
||||
O(SYS_UNLINK, unlink) \
|
||||
O(SYS_READLINK, readlink) \
|
||||
O(SYS_READLINKAT, readlinkat) \
|
||||
O(SYS_MSYNC, msync) \
|
||||
O(SYS_PREAD, pread) \
|
||||
O(SYS_CHOWN, chown) \
|
||||
O(SYS_LOAD_KEYMAP, load_keymap) \
|
||||
O(SYS_SOCKET, socket) \
|
||||
O(SYS_BIND, bind) \
|
||||
O(SYS_SENDTO, sendto) \
|
||||
O(SYS_RECVFROM, recvfrom) \
|
||||
O(SYS_IOCTL, ioctl) \
|
||||
O(SYS_ACCEPT, accept) \
|
||||
O(SYS_CONNECT, connect) \
|
||||
O(SYS_LISTEN, listen) \
|
||||
O(SYS_PSELECT, pselect) \
|
||||
|
||||
enum Syscall
|
||||
{
|
||||
#define O(enum, name) enum,
|
||||
__SYSCALL_LIST(O)
|
||||
#undef O
|
||||
__SYSCALL_COUNT
|
||||
};
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
Loading…
Reference in New Issue