2023-08-24 04:45:13 +03:00

1089 lines
37 KiB
C++

/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <syscalls.hpp>
#include <debug.h>
#include <cpu.hpp>
#include <errno.h>
#include "../../kernel.h"
#include "linux_syscalls.hpp"
struct SyscallData
{
const char *Name;
void *Handler;
};
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::TaskStatus::Ready;
using Tasking::TaskStatus::Terminated;
#define ARCH_SET_GS 0x1001
#define ARCH_SET_FS 0x1002
#define ARCH_GET_FS 0x1003
#define ARCH_GET_GS 0x1004
#define ARCH_GET_CPUID 0x1011
#define ARCH_SET_CPUID 0x1012
#define ARCH_GET_XCOMP_SUPP 0x1021
#define ARCH_GET_XCOMP_PERM 0x1022
#define ARCH_REQ_XCOMP_PERM 0x1023
#define ARCH_GET_XCOMP_GUEST_PERM 0x1024
#define ARCH_REQ_XCOMP_GUEST_PERM 0x1025
#define ARCH_XCOMP_TILECFG 17
#define ARCH_XCOMP_TILEDATA 18
#define ARCH_MAP_VDSO_X32 0x2001
#define ARCH_MAP_VDSO_32 0x2002
#define ARCH_MAP_VDSO_64 0x2003
#define ARCH_GET_UNTAG_MASK 0x4001
#define ARCH_ENABLE_TAGGED_ADDR 0x4002
#define ARCH_GET_MAX_TAG_BITS 0x4003
#define ARCH_FORCE_TAGGED_SVA 0x4004
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define PROT_GROWSDOWN 0x01000000
#define PROT_GROWSUP 0x02000000
#define MAP_TYPE 0x0f
#define MAP_FILE 0
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_SHARED_VALIDATE 0x03
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_NORESERVE 0x4000
#define MAP_GROWSDOWN 0x0100
#define MAP_DENYWRITE 0x0800
#define MAP_EXECUTABLE 0x1000
#define MAP_LOCKED 0x2000
#define MAP_POPULATE 0x8000
#define MAP_NONBLOCK 0x10000
#define MAP_STACK 0x20000
#define MAP_HUGETLB 0x40000
#define MAP_SYNC 0x80000
#define MAP_FIXED_NOREPLACE 0x100000
typedef int pid_t;
struct iovec
{
void *iov_base;
size_t iov_len;
};
#if defined(a64) || defined(aa64)
static ssize_t ConvertErrno(ssize_t r)
{
if (r >= 0)
return r;
return -errno;
}
#endif
static int ConvertErrno(int r)
{
if (r >= 0)
return r;
return -errno;
}
/* https://man7.org/linux/man-pages/man2/read.2.html */
static ssize_t sys_read(int fd, void *buf, size_t count)
{
debug("Reading %d bytes from fd %d", count, fd);
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check(buf, Memory::US))
{
warn("Invalid address %#lx", buf);
return -EFAULT;
}
auto pBuf = pcb->PageTable->Get(buf);
ssize_t ret = ConvertErrno(fdt->_read(fd, pBuf, count));
debug("Read %d bytes from fd %d, got %d", count, fd, ret);
return ret;
}
/* https://man7.org/linux/man-pages/man2/write.2.html */
static ssize_t sys_write(int fd, const void *buf, size_t count)
{
debug("Writing %d bytes to fd %d", count, fd);
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)buf, Memory::US))
{
warn("Invalid address %#lx", buf);
return -EFAULT;
}
auto pBuf = pcb->PageTable->Get(buf);
ssize_t ret = ConvertErrno(fdt->_write(fd, pBuf, count));
debug("Wrote %d bytes to fd %d, got %d", count, fd, ret);
return ret;
}
/* https://man7.org/linux/man-pages/man2/open.2.html */
static int sys_open(const char *pathname, int flags, mode_t mode)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)pathname, Memory::US))
{
warn("Invalid address %#lx", pathname);
return -EFAULT;
}
auto pPathname = pcb->PageTable->Get(pathname);
int ret = ConvertErrno(fdt->_open(pPathname, flags, mode));
debug("Opened %s with flags %d and mode %d, got fd %d",
pPathname, flags, mode, ret);
return ret;
}
/* https://man7.org/linux/man-pages/man2/close.2.html */
static int sys_close(int fd)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
int ret = ConvertErrno(fdt->_close(fd));
debug("Closed fd %d, got %d", fd, ret);
return ret;
}
/* https://man7.org/linux/man-pages/man3/stat.3p.html */
static int sys_stat(const char *pathname, struct stat *statbuf)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)pathname, Memory::US))
{
warn("Invalid address %#lx", pathname);
return -EFAULT;
}
auto pPathname = pcb->PageTable->Get(pathname);
return ConvertErrno(fdt->_stat(pPathname, statbuf));
}
/* https://man7.org/linux/man-pages/man3/fstat.3p.html */
static int sys_fstat(int fd, struct stat *statbuf)
{
#undef fstat
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)statbuf, Memory::US))
{
warn("Invalid address %#lx", statbuf);
return -EFAULT;
}
auto pStatbuf = pcb->PageTable->Get(statbuf);
return ConvertErrno(fdt->_fstat(fd, pStatbuf));
}
/* https://man7.org/linux/man-pages/man2/lstat.2.html */
static int sys_lstat(const char *pathname, struct stat *statbuf)
{
#undef lstat
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)pathname, Memory::US))
{
warn("Invalid address %#lx", pathname);
return -EFAULT;
}
if (!vmm.Check((void *)statbuf, Memory::US))
{
warn("Invalid address %#lx", statbuf);
return -EFAULT;
}
auto pPathname = pcb->PageTable->Get(pathname);
auto pStatbuf = pcb->PageTable->Get(statbuf);
return ConvertErrno(fdt->_lstat(pPathname, pStatbuf));
}
/* https://man7.org/linux/man-pages/man2/lseek.2.html */
static off_t sys_lseek(int fd, off_t offset, int whence)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
off_t ret = ConvertErrno(fdt->_lseek(fd, offset, whence));
debug("(%d, %d, %d) = %d", fd, offset, whence, ret);
return ret;
}
/* https://man7.org/linux/man-pages/man3/mmap.3p.html */
static void *sys_mmap(void *addr, size_t length, int prot,
int flags, int fildes, off_t offset)
{
UNUSED(offset); /* FIXME */
Tasking::PCB *pcb = thisProcess;
Memory::MemMgr *mm = pcb->Memory;
void *newPages = mm->RequestPages(TO_PAGES(length));
if (newPages == nullptr)
return (void *)-ENOMEM;
bool MustUseAddr = (flags & MAP_FIXED) != 0;
if (addr == NULL && !MustUseAddr)
addr = newPages;
if (MustUseAddr)
{
debug("Using fixed address %#lx", addr);
}
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
uint64_t MapFlags = Memory::P;
if (prot & PROT_READ)
MapFlags |= Memory::US;
if (prot & PROT_WRITE)
MapFlags |= Memory::RW;
if (prot & PROT_EXEC)
{
debug("PROT_EXEC ignored"); /* MapFlags |= Memory::XD; */
}
switch (flags & MAP_TYPE)
{
case MAP_FILE:
debug("MAP_FILE ignored");
[[fallthrough]];
case MAP_SHARED:
fixme("MAP_SHARED not implemented");
[[fallthrough]];
case MAP_SHARED_VALIDATE:
fixme("MAP_SHARED_VALIDATE not implemented");
[[fallthrough]];
case MAP_PRIVATE:
debug("MAP_PRIVATE ignored");
[[fallthrough]];
case MAP_ANONYMOUS:
fixme("MAP_ANONYMOUS not implemented");
[[fallthrough]];
default:
{
debug("mmap flags %#x", flags);
break;
}
}
vmm.Map(addr, newPages, length, MapFlags, Memory::Virtual::FourKiB);
debug("Mapped %#lx to %#lx (%d pages)", addr, newPages, TO_PAGES(length));
if (fildes != -1)
{
fixme("File mapping not implemented");
mm->FreePages(newPages, TO_PAGES(length));
return (void *)-ENOSYS;
}
return addr;
}
/* https://man7.org/linux/man-pages/man3/mprotect.3p.html */
static int sys_mprotect(void *addr, size_t len, int prot)
{
Tasking::PCB *pcb = thisProcess;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
vmm.Map(addr, addr, len, Memory::P, Memory::Virtual::FourKiB);
if (prot & PROT_READ)
vmm.Map(addr, addr, len, Memory::P | Memory::US, Memory::Virtual::FourKiB);
if (prot & PROT_WRITE)
vmm.Map(addr, addr, len, Memory::RW, Memory::Virtual::FourKiB);
if (prot & PROT_EXEC)
{
debug("PROT_EXEC ignored"); /* MapFlags |= Memory::XD; */
}
return 0;
}
/* https://man7.org/linux/man-pages/man3/munmap.3p.html */
static int sys_munmap(void *addr, size_t length)
{
Tasking::PCB *pcb = thisProcess;
Memory::MemMgr *mm = pcb->Memory;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
mm->FreePages(addr, TO_PAGES(length));
vmm.Unmap(addr, length, Memory::Virtual::FourKiB);
return 0;
}
/* https://man7.org/linux/man-pages/man2/brk.2.html */
static void *sys_brk(void *addr)
{
trace("Ignoring brk syscall...");
return (void *)-ENOSYS;
// Tasking::PCB *pcb = thisProcess;
// void *ret = pcb->ProgramBreak->brk(addr);
// debug("brk(%#lx) = %#lx", addr, ret);
// return ret;
}
/* https://man7.org/linux/man-pages/man2/ioctl.2.html */
static int sys_ioctl(int fd, unsigned long request, void *argp)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)argp, Memory::US))
{
warn("Invalid address %#lx", argp);
return -EFAULT;
}
auto pArgp = pcb->PageTable->Get(argp);
return ConvertErrno(fdt->_ioctl(fd, request, pArgp));
}
/* https://man7.org/linux/man-pages/man3/readv.3p.html */
static ssize_t sys_readv(int fildes, const struct iovec *iov, int iovcnt)
{
ssize_t Total = 0;
for (int i = 0; i < iovcnt; i++)
{
debug("%d: iov[%d]: %p %d", fildes, i, iov[i].iov_base, iov[i].iov_len);
ssize_t n = sys_read(fildes, iov[i].iov_base, iov[i].iov_len);
if (n < 0)
return n;
debug("n: %d", n);
Total += n;
if (n < (ssize_t)iov[i].iov_len)
{
debug("break");
break;
}
}
debug("readv: %d", Total);
return Total;
}
/* https://man7.org/linux/man-pages/man3/writev.3p.html */
static ssize_t sys_writev(int fildes, const struct iovec *iov, int iovcnt)
{
ssize_t Total = 0;
for (int i = 0; i < iovcnt; i++)
{
debug("%d: iov[%d]: %p %d", fildes, i, iov[i].iov_base, iov[i].iov_len);
ssize_t n = sys_write(fildes, iov[i].iov_base, iov[i].iov_len);
if (n < 0)
return n;
debug("n: %d", n);
Total += n;
if (n < (ssize_t)iov[i].iov_len)
{
debug("break");
break;
}
}
debug("writev: %d", Total);
return Total;
}
/* https://man7.org/linux/man-pages/man2/dup.2.html */
static int sys_dup(int oldfd)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
return ConvertErrno(fdt->_dup(oldfd));
}
/* https://man7.org/linux/man-pages/man2/dup.2.html */
static int sys_dup2(int oldfd, int newfd)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
return ConvertErrno(fdt->_dup2(oldfd, newfd));
}
/* https://man7.org/linux/man-pages/man3/exit.3.html */
static __noreturn void sys_exit(int status)
{
trace("Userspace thread %s(%d) exited with code %d (%#x)",
thisThread->Name,
thisThread->ID, status,
status < 0 ? -status : status);
thisThread->ExitCode = status;
thisThread->Status = Terminated;
TaskManager->Yield();
__builtin_unreachable();
}
/* https://man7.org/linux/man-pages/man3/creat.3p.html */
static int sys_creat(const char *pathname, mode_t mode)
{
Tasking::PCB *pcb = thisProcess;
VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors;
return ConvertErrno(fdt->_creat(pathname, mode));
}
/* https://man7.org/linux/man-pages/man2/arch_prctl.2.html */
static int sys_arch_prctl(int code, unsigned long addr)
{
Tasking::PCB *pcb = thisProcess;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
if (!vmm.Check((void *)addr))
{
warn("Invalid address %#lx", addr);
return -EFAULT;
}
if (!vmm.Check((void *)addr, Memory::US))
{
warn("Address %#lx is not user accessible", addr);
return -EPERM;
}
switch (code)
{
case ARCH_SET_GS:
{
#if defined(a64)
CPU::x64::wrmsr(CPU::x64::MSRID::MSR_GS_BASE, addr);
#elif defined(a32)
CPU::x32::wrmsr(CPU::x32::MSRID::MSR_GS_BASE, addr);
#endif
return 0;
}
case ARCH_SET_FS:
{
#if defined(a64)
CPU::x64::wrmsr(CPU::x64::MSRID::MSR_FS_BASE, addr);
#elif defined(a32)
CPU::x32::wrmsr(CPU::x32::MSRID::MSR_FS_BASE, addr);
#endif
return 0;
}
case ARCH_GET_FS:
{
#if defined(a64)
*r_cst(uint64_t *, addr) =
CPU::x64::rdmsr(CPU::x64::MSRID::MSR_FS_BASE);
#elif defined(a32)
*r_cst(uint64_t *, addr) =
CPU::x32::rdmsr(CPU::x32::MSRID::MSR_FS_BASE);
#endif
return 0;
}
case ARCH_GET_GS:
{
#if defined(a64)
*r_cst(uint64_t *, addr) =
CPU::x64::rdmsr(CPU::x64::MSRID::MSR_GS_BASE);
#elif defined(a32)
*r_cst(uint64_t *, addr) =
CPU::x32::rdmsr(CPU::x32::MSRID::MSR_GS_BASE);
#endif
return 0;
}
case ARCH_GET_CPUID:
case ARCH_SET_CPUID:
case ARCH_GET_XCOMP_SUPP:
case ARCH_GET_XCOMP_PERM:
case ARCH_REQ_XCOMP_PERM:
case ARCH_GET_XCOMP_GUEST_PERM:
case ARCH_REQ_XCOMP_GUEST_PERM:
case ARCH_XCOMP_TILECFG:
case ARCH_XCOMP_TILEDATA:
case ARCH_MAP_VDSO_X32:
case ARCH_MAP_VDSO_32:
case ARCH_MAP_VDSO_64:
case ARCH_GET_UNTAG_MASK:
case ARCH_ENABLE_TAGGED_ADDR:
case ARCH_GET_MAX_TAG_BITS:
case ARCH_FORCE_TAGGED_SVA:
{
fixme("Code %#lx not implemented", code);
return -ENOSYS;
}
default:
{
warn("Invalid code %#lx", code);
return -EINVAL;
}
}
}
/* https://man7.org/linux/man-pages/man2/set_tid_address.2.html */
static pid_t sys_set_tid_address(int *tidptr)
{
if (tidptr == nullptr)
return -EINVAL;
Tasking::TCB *tcb = thisThread;
tcb->Linux.clear_child_tid = tidptr;
return tcb->ID;
}
/* https://man7.org/linux/man-pages/man2/exit_group.2.html */
static __noreturn void sys_exit_group(int status)
{
fixme("status=%d", status);
sys_exit(status);
}
static SyscallData LinuxSyscallsTable[] = {
[__NR_read] = {"read", (void *)sys_read},
[__NR_write] = {"write", (void *)sys_write},
[__NR_open] = {"open", (void *)sys_open},
[__NR_close] = {"close", (void *)sys_close},
[__NR_stat] = {"stat", (void *)sys_stat},
[__NR_fstat] = {"fstat", (void *)sys_fstat},
[__NR_lstat] = {"lstat", (void *)sys_lstat},
[__NR_poll] = {"poll", (void *)nullptr},
[__NR_lseek] = {"lseek", (void *)sys_lseek},
[__NR_mmap] = {"mmap", (void *)sys_mmap},
[__NR_mprotect] = {"mprotect", (void *)sys_mprotect},
[__NR_munmap] = {"munmap", (void *)sys_munmap},
[__NR_brk] = {"brk", (void *)sys_brk},
[__NR_rt_sigaction] = {"rt_sigaction", (void *)nullptr},
[__NR_rt_sigprocmask] = {"rt_sigprocmask", (void *)nullptr},
[__NR_rt_sigreturn] = {"rt_sigreturn", (void *)nullptr},
[__NR_ioctl] = {"ioctl", (void *)sys_ioctl},
[__NR_pread64] = {"pread64", (void *)nullptr},
[__NR_pwrite64] = {"pwrite64", (void *)nullptr},
[__NR_readv] = {"readv", (void *)sys_readv},
[__NR_writev] = {"writev", (void *)sys_writev},
[__NR_access] = {"access", (void *)nullptr},
[__NR_pipe] = {"pipe", (void *)nullptr},
[__NR_select] = {"select", (void *)nullptr},
[__NR_sched_yield] = {"sched_yield", (void *)nullptr},
[__NR_mremap] = {"mremap", (void *)nullptr},
[__NR_msync] = {"msync", (void *)nullptr},
[__NR_mincore] = {"mincore", (void *)nullptr},
[__NR_madvise] = {"madvise", (void *)nullptr},
[__NR_shmget] = {"shmget", (void *)nullptr},
[__NR_shmat] = {"shmat", (void *)nullptr},
[__NR_shmctl] = {"shmctl", (void *)nullptr},
[__NR_dup] = {"dup", (void *)sys_dup},
[__NR_dup2] = {"dup2", (void *)sys_dup2},
[__NR_pause] = {"pause", (void *)nullptr},
[__NR_nanosleep] = {"nanosleep", (void *)nullptr},
[__NR_getitimer] = {"getitimer", (void *)nullptr},
[__NR_alarm] = {"alarm", (void *)nullptr},
[__NR_setitimer] = {"setitimer", (void *)nullptr},
[__NR_getpid] = {"getpid", (void *)nullptr},
[__NR_sendfile] = {"sendfile", (void *)nullptr},
[__NR_socket] = {"socket", (void *)nullptr},
[__NR_connect] = {"connect", (void *)nullptr},
[__NR_accept] = {"accept", (void *)nullptr},
[__NR_sendto] = {"sendto", (void *)nullptr},
[__NR_recvfrom] = {"recvfrom", (void *)nullptr},
[__NR_sendmsg] = {"sendmsg", (void *)nullptr},
[__NR_recvmsg] = {"recvmsg", (void *)nullptr},
[__NR_shutdown] = {"shutdown", (void *)nullptr},
[__NR_bind] = {"bind", (void *)nullptr},
[__NR_listen] = {"listen", (void *)nullptr},
[__NR_getsockname] = {"getsockname", (void *)nullptr},
[__NR_getpeername] = {"getpeername", (void *)nullptr},
[__NR_socketpair] = {"socketpair", (void *)nullptr},
[__NR_setsockopt] = {"setsockopt", (void *)nullptr},
[__NR_getsockopt] = {"getsockopt", (void *)nullptr},
[__NR_clone] = {"clone", (void *)nullptr},
[__NR_fork] = {"fork", (void *)nullptr},
[__NR_vfork] = {"vfork", (void *)nullptr},
[__NR_execve] = {"execve", (void *)nullptr},
[__NR_exit] = {"exit", (void *)sys_exit},
[__NR_wait4] = {"wait4", (void *)nullptr},
[__NR_kill] = {"kill", (void *)nullptr},
[__NR_uname] = {"uname", (void *)nullptr},
[__NR_semget] = {"semget", (void *)nullptr},
[__NR_semop] = {"semop", (void *)nullptr},
[__NR_semctl] = {"semctl", (void *)nullptr},
[__NR_shmdt] = {"shmdt", (void *)nullptr},
[__NR_msgget] = {"msgget", (void *)nullptr},
[__NR_msgsnd] = {"msgsnd", (void *)nullptr},
[__NR_msgrcv] = {"msgrcv", (void *)nullptr},
[__NR_msgctl] = {"msgctl", (void *)nullptr},
[__NR_fcntl] = {"fcntl", (void *)nullptr},
[__NR_flock] = {"flock", (void *)nullptr},
[__NR_fsync] = {"fsync", (void *)nullptr},
[__NR_fdatasync] = {"fdatasync", (void *)nullptr},
[__NR_truncate] = {"truncate", (void *)nullptr},
[__NR_ftruncate] = {"ftruncate", (void *)nullptr},
[__NR_getdents] = {"getdents", (void *)nullptr},
[__NR_getcwd] = {"getcwd", (void *)nullptr},
[__NR_chdir] = {"chdir", (void *)nullptr},
[__NR_fchdir] = {"fchdir", (void *)nullptr},
[__NR_rename] = {"rename", (void *)nullptr},
[__NR_mkdir] = {"mkdir", (void *)nullptr},
[__NR_rmdir] = {"rmdir", (void *)nullptr},
[__NR_creat] = {"creat", (void *)sys_creat},
[__NR_link] = {"link", (void *)nullptr},
[__NR_unlink] = {"unlink", (void *)nullptr},
[__NR_symlink] = {"symlink", (void *)nullptr},
[__NR_readlink] = {"readlink", (void *)nullptr},
[__NR_chmod] = {"chmod", (void *)nullptr},
[__NR_fchmod] = {"fchmod", (void *)nullptr},
[__NR_chown] = {"chown", (void *)nullptr},
[__NR_fchown] = {"fchown", (void *)nullptr},
[__NR_lchown] = {"lchown", (void *)nullptr},
[__NR_umask] = {"umask", (void *)nullptr},
[__NR_gettimeofday] = {"gettimeofday", (void *)nullptr},
[__NR_getrlimit] = {"getrlimit", (void *)nullptr},
[__NR_getrusage] = {"getrusage", (void *)nullptr},
[__NR_sysinfo] = {"sysinfo", (void *)nullptr},
[__NR_times] = {"times", (void *)nullptr},
[__NR_ptrace] = {"ptrace", (void *)nullptr},
[__NR_getuid] = {"getuid", (void *)nullptr},
[__NR_syslog] = {"syslog", (void *)nullptr},
[__NR_getgid] = {"getgid", (void *)nullptr},
[__NR_setuid] = {"setuid", (void *)nullptr},
[__NR_setgid] = {"setgid", (void *)nullptr},
[__NR_geteuid] = {"geteuid", (void *)nullptr},
[__NR_getegid] = {"getegid", (void *)nullptr},
[__NR_setpgid] = {"setpgid", (void *)nullptr},
[__NR_getppid] = {"getppid", (void *)nullptr},
[__NR_getpgrp] = {"getpgrp", (void *)nullptr},
[__NR_setsid] = {"setsid", (void *)nullptr},
[__NR_setreuid] = {"setreuid", (void *)nullptr},
[__NR_setregid] = {"setregid", (void *)nullptr},
[__NR_getgroups] = {"getgroups", (void *)nullptr},
[__NR_setgroups] = {"setgroups", (void *)nullptr},
[__NR_setresuid] = {"setresuid", (void *)nullptr},
[__NR_getresuid] = {"getresuid", (void *)nullptr},
[__NR_setresgid] = {"setresgid", (void *)nullptr},
[__NR_getresgid] = {"getresgid", (void *)nullptr},
[__NR_getpgid] = {"getpgid", (void *)nullptr},
[__NR_setfsuid] = {"setfsuid", (void *)nullptr},
[__NR_setfsgid] = {"setfsgid", (void *)nullptr},
[__NR_getsid] = {"getsid", (void *)nullptr},
[__NR_capget] = {"capget", (void *)nullptr},
[__NR_capset] = {"capset", (void *)nullptr},
[__NR_rt_sigpending] = {"rt_sigpending", (void *)nullptr},
[__NR_rt_sigtimedwait] = {"rt_sigtimedwait", (void *)nullptr},
[__NR_rt_sigqueueinfo] = {"rt_sigqueueinfo", (void *)nullptr},
[__NR_rt_sigsuspend] = {"rt_sigsuspend", (void *)nullptr},
[__NR_sigaltstack] = {"sigaltstack", (void *)nullptr},
[__NR_utime] = {"utime", (void *)nullptr},
[__NR_mknod] = {"mknod", (void *)nullptr},
[__NR_uselib] = {"uselib", (void *)nullptr},
[__NR_personality] = {"personality", (void *)nullptr},
[__NR_ustat] = {"ustat", (void *)nullptr},
[__NR_statfs] = {"statfs", (void *)nullptr},
[__NR_fstatfs] = {"fstatfs", (void *)nullptr},
[__NR_sysfs] = {"sysfs", (void *)nullptr},
[__NR_getpriority] = {"getpriority", (void *)nullptr},
[__NR_setpriority] = {"setpriority", (void *)nullptr},
[__NR_sched_setparam] = {"sched_setparam", (void *)nullptr},
[__NR_sched_getparam] = {"sched_getparam", (void *)nullptr},
[__NR_sched_setscheduler] = {"sched_setscheduler", (void *)nullptr},
[__NR_sched_getscheduler] = {"sched_getscheduler", (void *)nullptr},
[__NR_sched_get_priority_max] = {"sched_get_priority_max", (void *)nullptr},
[__NR_sched_get_priority_min] = {"sched_get_priority_min", (void *)nullptr},
[__NR_sched_rr_get_interval] = {"sched_rr_get_interval", (void *)nullptr},
[__NR_mlock] = {"mlock", (void *)nullptr},
[__NR_munlock] = {"munlock", (void *)nullptr},
[__NR_mlockall] = {"mlockall", (void *)nullptr},
[__NR_munlockall] = {"munlockall", (void *)nullptr},
[__NR_vhangup] = {"vhangup", (void *)nullptr},
[__NR_modify_ldt] = {"modify_ldt", (void *)nullptr},
[__NR_pivot_root] = {"pivot_root", (void *)nullptr},
[__NR__sysctl] = {"_sysctl", (void *)nullptr},
[__NR_prctl] = {"prctl", (void *)nullptr},
[__NR_arch_prctl] = {"arch_prctl", (void *)sys_arch_prctl},
[__NR_adjtimex] = {"adjtimex", (void *)nullptr},
[__NR_setrlimit] = {"setrlimit", (void *)nullptr},
[__NR_chroot] = {"chroot", (void *)nullptr},
[__NR_sync] = {"sync", (void *)nullptr},
[__NR_acct] = {"acct", (void *)nullptr},
[__NR_settimeofday] = {"settimeofday", (void *)nullptr},
[__NR_mount] = {"mount", (void *)nullptr},
[__NR_umount2] = {"umount2", (void *)nullptr},
[__NR_swapon] = {"swapon", (void *)nullptr},
[__NR_swapoff] = {"swapoff", (void *)nullptr},
[__NR_reboot] = {"reboot", (void *)nullptr},
[__NR_sethostname] = {"sethostname", (void *)nullptr},
[__NR_setdomainname] = {"setdomainname", (void *)nullptr},
[__NR_iopl] = {"iopl", (void *)nullptr},
[__NR_ioperm] = {"ioperm", (void *)nullptr},
[__NR_create_module] = {"create_module", (void *)nullptr},
[__NR_init_module] = {"init_module", (void *)nullptr},
[__NR_delete_module] = {"delete_module", (void *)nullptr},
[__NR_get_kernel_syms] = {"get_kernel_syms", (void *)nullptr},
[__NR_query_module] = {"query_module", (void *)nullptr},
[__NR_quotactl] = {"quotactl", (void *)nullptr},
[__NR_nfsservctl] = {"nfsservctl", (void *)nullptr},
[__NR_getpmsg] = {"getpmsg", (void *)nullptr},
[__NR_putpmsg] = {"putpmsg", (void *)nullptr},
[__NR_afs_syscall] = {"afs_syscall", (void *)nullptr},
[__NR_tuxcall] = {"tuxcall", (void *)nullptr},
[__NR_security] = {"security", (void *)nullptr},
[__NR_gettid] = {"gettid", (void *)nullptr},
[__NR_readahead] = {"readahead", (void *)nullptr},
[__NR_setxattr] = {"setxattr", (void *)nullptr},
[__NR_lsetxattr] = {"lsetxattr", (void *)nullptr},
[__NR_fsetxattr] = {"fsetxattr", (void *)nullptr},
[__NR_getxattr] = {"getxattr", (void *)nullptr},
[__NR_lgetxattr] = {"lgetxattr", (void *)nullptr},
[__NR_fgetxattr] = {"fgetxattr", (void *)nullptr},
[__NR_listxattr] = {"listxattr", (void *)nullptr},
[__NR_llistxattr] = {"llistxattr", (void *)nullptr},
[__NR_flistxattr] = {"flistxattr", (void *)nullptr},
[__NR_removexattr] = {"removexattr", (void *)nullptr},
[__NR_lremovexattr] = {"lremovexattr", (void *)nullptr},
[__NR_fremovexattr] = {"fremovexattr", (void *)nullptr},
[__NR_tkill] = {"tkill", (void *)nullptr},
[__NR_time] = {"time", (void *)nullptr},
[__NR_futex] = {"futex", (void *)nullptr},
[__NR_sched_setaffinity] = {"sched_setaffinity", (void *)nullptr},
[__NR_sched_getaffinity] = {"sched_getaffinity", (void *)nullptr},
[__NR_set_thread_area] = {"set_thread_area", (void *)nullptr},
[__NR_io_setup] = {"io_setup", (void *)nullptr},
[__NR_io_destroy] = {"io_destroy", (void *)nullptr},
[__NR_io_getevents] = {"io_getevents", (void *)nullptr},
[__NR_io_submit] = {"io_submit", (void *)nullptr},
[__NR_io_cancel] = {"io_cancel", (void *)nullptr},
[__NR_get_thread_area] = {"get_thread_area", (void *)nullptr},
[__NR_lookup_dcookie] = {"lookup_dcookie", (void *)nullptr},
[__NR_epoll_create] = {"epoll_create", (void *)nullptr},
[__NR_epoll_ctl_old] = {"epoll_ctl_old", (void *)nullptr},
[__NR_epoll_wait_old] = {"epoll_wait_old", (void *)nullptr},
[__NR_remap_file_pages] = {"remap_file_pages", (void *)nullptr},
[__NR_getdents64] = {"getdents64", (void *)nullptr},
[__NR_set_tid_address] = {"set_tid_address", (void *)sys_set_tid_address},
[__NR_restart_syscall] = {"restart_syscall", (void *)nullptr},
[__NR_semtimedop] = {"semtimedop", (void *)nullptr},
[__NR_fadvise64] = {"fadvise64", (void *)nullptr},
[__NR_timer_create] = {"timer_create", (void *)nullptr},
[__NR_timer_settime] = {"timer_settime", (void *)nullptr},
[__NR_timer_gettime] = {"timer_gettime", (void *)nullptr},
[__NR_timer_getoverrun] = {"timer_getoverrun", (void *)nullptr},
[__NR_timer_delete] = {"timer_delete", (void *)nullptr},
[__NR_clock_settime] = {"clock_settime", (void *)nullptr},
[__NR_clock_gettime] = {"clock_gettime", (void *)nullptr},
[__NR_clock_getres] = {"clock_getres", (void *)nullptr},
[__NR_clock_nanosleep] = {"clock_nanosleep", (void *)nullptr},
[__NR_exit_group] = {"exit_group", (void *)sys_exit_group},
[__NR_epoll_wait] = {"epoll_wait", (void *)nullptr},
[__NR_epoll_ctl] = {"epoll_ctl", (void *)nullptr},
[__NR_tgkill] = {"tgkill", (void *)nullptr},
[__NR_utimes] = {"utimes", (void *)nullptr},
[__NR_vserver] = {"vserver", (void *)nullptr},
[__NR_mbind] = {"mbind", (void *)nullptr},
[__NR_set_mempolicy] = {"set_mempolicy", (void *)nullptr},
[__NR_get_mempolicy] = {"get_mempolicy", (void *)nullptr},
[__NR_mq_open] = {"mq_open", (void *)nullptr},
[__NR_mq_unlink] = {"mq_unlink", (void *)nullptr},
[__NR_mq_timedsend] = {"mq_timedsend", (void *)nullptr},
[__NR_mq_timedreceive] = {"mq_timedreceive", (void *)nullptr},
[__NR_mq_notify] = {"mq_notify", (void *)nullptr},
[__NR_mq_getsetattr] = {"mq_getsetattr", (void *)nullptr},
[__NR_kexec_load] = {"kexec_load", (void *)nullptr},
[__NR_waitid] = {"waitid", (void *)nullptr},
[__NR_add_key] = {"add_key", (void *)nullptr},
[__NR_request_key] = {"request_key", (void *)nullptr},
[__NR_keyctl] = {"keyctl", (void *)nullptr},
[__NR_ioprio_set] = {"ioprio_set", (void *)nullptr},
[__NR_ioprio_get] = {"ioprio_get", (void *)nullptr},
[__NR_inotify_init] = {"inotify_init", (void *)nullptr},
[__NR_inotify_add_watch] = {"inotify_add_watch", (void *)nullptr},
[__NR_inotify_rm_watch] = {"inotify_rm_watch", (void *)nullptr},
[__NR_migrate_pages] = {"migrate_pages", (void *)nullptr},
[__NR_openat] = {"openat", (void *)nullptr},
[__NR_mkdirat] = {"mkdirat", (void *)nullptr},
[__NR_mknodat] = {"mknodat", (void *)nullptr},
[__NR_fchownat] = {"fchownat", (void *)nullptr},
[__NR_futimesat] = {"futimesat", (void *)nullptr},
[__NR_newfstatat] = {"newfstatat", (void *)nullptr},
[__NR_unlinkat] = {"unlinkat", (void *)nullptr},
[__NR_renameat] = {"renameat", (void *)nullptr},
[__NR_linkat] = {"linkat", (void *)nullptr},
[__NR_symlinkat] = {"symlinkat", (void *)nullptr},
[__NR_readlinkat] = {"readlinkat", (void *)nullptr},
[__NR_fchmodat] = {"fchmodat", (void *)nullptr},
[__NR_faccessat] = {"faccessat", (void *)nullptr},
[__NR_pselect6] = {"pselect6", (void *)nullptr},
[__NR_ppoll] = {"ppoll", (void *)nullptr},
[__NR_unshare] = {"unshare", (void *)nullptr},
[__NR_set_robust_list] = {"set_robust_list", (void *)nullptr},
[__NR_get_robust_list] = {"get_robust_list", (void *)nullptr},
[__NR_splice] = {"splice", (void *)nullptr},
[__NR_tee] = {"tee", (void *)nullptr},
[__NR_sync_file_range] = {"sync_file_range", (void *)nullptr},
[__NR_vmsplice] = {"vmsplice", (void *)nullptr},
[__NR_move_pages] = {"move_pages", (void *)nullptr},
[__NR_utimensat] = {"utimensat", (void *)nullptr},
[__NR_epoll_pwait] = {"epoll_pwait", (void *)nullptr},
[__NR_signalfd] = {"signalfd", (void *)nullptr},
[__NR_timerfd_create] = {"timerfd_create", (void *)nullptr},
[__NR_eventfd] = {"eventfd", (void *)nullptr},
[__NR_fallocate] = {"fallocate", (void *)nullptr},
[__NR_timerfd_settime] = {"timerfd_settime", (void *)nullptr},
[__NR_timerfd_gettime] = {"timerfd_gettime", (void *)nullptr},
[__NR_accept4] = {"accept4", (void *)nullptr},
[__NR_signalfd4] = {"signalfd4", (void *)nullptr},
[__NR_eventfd2] = {"eventfd2", (void *)nullptr},
[__NR_epoll_create1] = {"epoll_create1", (void *)nullptr},
[__NR_dup3] = {"dup3", (void *)nullptr},
[__NR_pipe2] = {"pipe2", (void *)nullptr},
[__NR_inotify_init1] = {"inotify_init1", (void *)nullptr},
[__NR_preadv] = {"preadv", (void *)nullptr},
[__NR_pwritev] = {"pwritev", (void *)nullptr},
[__NR_rt_tgsigqueueinfo] = {"rt_tgsigqueueinfo", (void *)nullptr},
[__NR_perf_event_open] = {"perf_event_open", (void *)nullptr},
[__NR_recvmmsg] = {"recvmmsg", (void *)nullptr},
[__NR_fanotify_init] = {"fanotify_init", (void *)nullptr},
[__NR_fanotify_mark] = {"fanotify_mark", (void *)nullptr},
[__NR_prlimit64] = {"prlimit64", (void *)nullptr},
[__NR_name_to_handle_at] = {"name_to_handle_at", (void *)nullptr},
[__NR_open_by_handle_at] = {"open_by_handle_at", (void *)nullptr},
[__NR_clock_adjtime] = {"clock_adjtime", (void *)nullptr},
[__NR_syncfs] = {"syncfs", (void *)nullptr},
[__NR_sendmmsg] = {"sendmmsg", (void *)nullptr},
[__NR_setns] = {"setns", (void *)nullptr},
[__NR_getcpu] = {"getcpu", (void *)nullptr},
[__NR_process_vm_readv] = {"process_vm_readv", (void *)nullptr},
[__NR_process_vm_writev] = {"process_vm_writev", (void *)nullptr},
[__NR_kcmp] = {"kcmp", (void *)nullptr},
[__NR_finit_module] = {"finit_module", (void *)nullptr},
[__NR_sched_setattr] = {"sched_setattr", (void *)nullptr},
[__NR_sched_getattr] = {"sched_getattr", (void *)nullptr},
[__NR_renameat2] = {"renameat2", (void *)nullptr},
[__NR_seccomp] = {"seccomp", (void *)nullptr},
[__NR_getrandom] = {"getrandom", (void *)nullptr},
[__NR_memfd_create] = {"memfd_create", (void *)nullptr},
[__NR_kexec_file_load] = {"kexec_file_load", (void *)nullptr},
[__NR_bpf] = {"bpf", (void *)nullptr},
[__NR_execveat] = {"execveat", (void *)nullptr},
[__NR_userfaultfd] = {"userfaultfd", (void *)nullptr},
[__NR_membarrier] = {"membarrier", (void *)nullptr},
[__NR_mlock2] = {"mlock2", (void *)nullptr},
[__NR_copy_file_range] = {"copy_file_range", (void *)nullptr},
[__NR_preadv2] = {"preadv2", (void *)nullptr},
[__NR_pwritev2] = {"pwritev2", (void *)nullptr},
[__NR_pkey_mprotect] = {"pkey_mprotect", (void *)nullptr},
[__NR_pkey_alloc] = {"pkey_alloc", (void *)nullptr},
[__NR_pkey_free] = {"pkey_free", (void *)nullptr},
[__NR_statx] = {"statx", (void *)nullptr},
[__NR_io_pgetevents] = {"io_pgetevents", (void *)nullptr},
[__NR_rseq] = {"rseq", (void *)nullptr},
[335] = {"reserved", (void *)nullptr},
[336] = {"reserved", (void *)nullptr},
[337] = {"reserved", (void *)nullptr},
[338] = {"reserved", (void *)nullptr},
[339] = {"reserved", (void *)nullptr},
[340] = {"reserved", (void *)nullptr},
[341] = {"reserved", (void *)nullptr},
[342] = {"reserved", (void *)nullptr},
[343] = {"reserved", (void *)nullptr},
[344] = {"reserved", (void *)nullptr},
[345] = {"reserved", (void *)nullptr},
[346] = {"reserved", (void *)nullptr},
[347] = {"reserved", (void *)nullptr},
[348] = {"reserved", (void *)nullptr},
[349] = {"reserved", (void *)nullptr},
[350] = {"reserved", (void *)nullptr},
[351] = {"reserved", (void *)nullptr},
[352] = {"reserved", (void *)nullptr},
[353] = {"reserved", (void *)nullptr},
[354] = {"reserved", (void *)nullptr},
[355] = {"reserved", (void *)nullptr},
[356] = {"reserved", (void *)nullptr},
[357] = {"reserved", (void *)nullptr},
[358] = {"reserved", (void *)nullptr},
[359] = {"reserved", (void *)nullptr},
[360] = {"reserved", (void *)nullptr},
[361] = {"reserved", (void *)nullptr},
[362] = {"reserved", (void *)nullptr},
[363] = {"reserved", (void *)nullptr},
[364] = {"reserved", (void *)nullptr},
[365] = {"reserved", (void *)nullptr},
[366] = {"reserved", (void *)nullptr},
[367] = {"reserved", (void *)nullptr},
[368] = {"reserved", (void *)nullptr},
[369] = {"reserved", (void *)nullptr},
[370] = {"reserved", (void *)nullptr},
[371] = {"reserved", (void *)nullptr},
[372] = {"reserved", (void *)nullptr},
[373] = {"reserved", (void *)nullptr},
[374] = {"reserved", (void *)nullptr},
[375] = {"reserved", (void *)nullptr},
[376] = {"reserved", (void *)nullptr},
[377] = {"reserved", (void *)nullptr},
[378] = {"reserved", (void *)nullptr},
[379] = {"reserved", (void *)nullptr},
[380] = {"reserved", (void *)nullptr},
[381] = {"reserved", (void *)nullptr},
[382] = {"reserved", (void *)nullptr},
[383] = {"reserved", (void *)nullptr},
[384] = {"reserved", (void *)nullptr},
[385] = {"reserved", (void *)nullptr},
[386] = {"reserved", (void *)nullptr},
[387] = {"reserved", (void *)nullptr},
[388] = {"reserved", (void *)nullptr},
[389] = {"reserved", (void *)nullptr},
[390] = {"reserved", (void *)nullptr},
[391] = {"reserved", (void *)nullptr},
[392] = {"reserved", (void *)nullptr},
[393] = {"reserved", (void *)nullptr},
[394] = {"reserved", (void *)nullptr},
[395] = {"reserved", (void *)nullptr},
[396] = {"reserved", (void *)nullptr},
[397] = {"reserved", (void *)nullptr},
[398] = {"reserved", (void *)nullptr},
[399] = {"reserved", (void *)nullptr},
[400] = {"reserved", (void *)nullptr},
[401] = {"reserved", (void *)nullptr},
[402] = {"reserved", (void *)nullptr},
[403] = {"reserved", (void *)nullptr},
[404] = {"reserved", (void *)nullptr},
[405] = {"reserved", (void *)nullptr},
[406] = {"reserved", (void *)nullptr},
[407] = {"reserved", (void *)nullptr},
[408] = {"reserved", (void *)nullptr},
[409] = {"reserved", (void *)nullptr},
[410] = {"reserved", (void *)nullptr},
[411] = {"reserved", (void *)nullptr},
[412] = {"reserved", (void *)nullptr},
[413] = {"reserved", (void *)nullptr},
[414] = {"reserved", (void *)nullptr},
[415] = {"reserved", (void *)nullptr},
[416] = {"reserved", (void *)nullptr},
[417] = {"reserved", (void *)nullptr},
[418] = {"reserved", (void *)nullptr},
[419] = {"reserved", (void *)nullptr},
[420] = {"reserved", (void *)nullptr},
[421] = {"reserved", (void *)nullptr},
[422] = {"reserved", (void *)nullptr},
[423] = {"reserved", (void *)nullptr},
[__NR_pidfd_send_signal] = {"pidfd_send_signal", (void *)nullptr},
[__NR_io_uring_setup] = {"io_uring_setup", (void *)nullptr},
[__NR_io_uring_enter] = {"io_uring_enter", (void *)nullptr},
[__NR_io_uring_register] = {"io_uring_register", (void *)nullptr},
[__NR_open_tree] = {"open_tree", (void *)nullptr},
[__NR_move_mount] = {"move_mount", (void *)nullptr},
[__NR_fsopen] = {"fsopen", (void *)nullptr},
[__NR_fsconfig] = {"fsconfig", (void *)nullptr},
[__NR_fsmount] = {"fsmount", (void *)nullptr},
[__NR_fspick] = {"fspick", (void *)nullptr},
[__NR_pidfd_open] = {"pidfd_open", (void *)nullptr},
[__NR_clone3] = {"clone3", (void *)nullptr},
[__NR_close_range] = {"close_range", (void *)nullptr},
[__NR_openat2] = {"openat2", (void *)nullptr},
[__NR_pidfd_getfd] = {"pidfd_getfd", (void *)nullptr},
[__NR_faccessat2] = {"faccessat2", (void *)nullptr},
[__NR_process_madvise] = {"process_madvise", (void *)nullptr},
[__NR_epoll_pwait2] = {"epoll_pwait2", (void *)nullptr},
[__NR_mount_setattr] = {"mount_setattr", (void *)nullptr},
[443] = {"reserved", (void *)nullptr},
[__NR_landlock_create_ruleset] = {"landlock_create_ruleset", (void *)nullptr},
[__NR_landlock_add_rule] = {"landlock_add_rule", (void *)nullptr},
[__NR_landlock_restrict_self] = {"landlock_restrict_self", (void *)nullptr},
};
uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame)
{
#if defined(a64)
if (Frame->rax > sizeof(LinuxSyscallsTable) / sizeof(SyscallData))
{
fixme("Syscall %d not implemented",
Frame->rax);
return -ENOSYS;
}
SyscallData Syscall = LinuxSyscallsTable[Frame->rax];
long (*call)(long, ...) = r_cst(long (*)(long, ...),
Syscall.Handler);
if (unlikely(!call))
{
fixme("Syscall %s(%d) not implemented.",
Syscall.Name, Frame->rax);
return -ENOSYS;
}
debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )",
Frame->rax, Syscall.Name,
Frame->rdi, Frame->rsi, Frame->rdx,
Frame->r10, Frame->r8, Frame->r9);
return call(Frame->rdi, Frame->rsi, Frame->rdx,
Frame->r10, Frame->r8, Frame->r9);
#elif defined(a32)
if (Frame->eax > sizeof(LinuxSyscallsTable) / sizeof(SyscallData))
{
fixme("Syscall %d not implemented",
Frame->eax);
return -ENOSYS;
}
SyscallData Syscall = LinuxSyscallsTable[Frame->eax];
long (*call)(long, ...) = r_cst(long (*)(long, ...),
Syscall.Handler);
if (unlikely(!call))
{
fixme("Syscall %s(%d) not implemented.",
Syscall.Name, Frame->eax);
return -ENOSYS;
}
debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )",
Frame->eax, Syscall.Name,
Frame->ebx, Frame->ecx, Frame->edx,
Frame->esi, Frame->edi, Frame->ebp);
return call(Frame->ebx, Frame->ecx, Frame->edx,
Frame->esi, Frame->edi, Frame->ebp);
#elif defined(aa64)
return 0;
#endif
}