From 124dc592a98866823984dd54282ba41e95cd3627 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 2 Dec 2019 17:28:22 -0800 Subject: [PATCH] Syscall additions and improvements Fixes a bug in writev where we need to parse the iovec struct and convert it. Implements 15 new syscalls --- Source/Interface/HLE/FileManagement.cpp | 170 +++++++++++++++++++--- Source/Interface/HLE/FileManagement.h | 15 ++ Source/Interface/HLE/Syscalls.cpp | 182 ++++++++++++++++++++++-- Source/Interface/HLE/Syscalls.h | 15 ++ 4 files changed, 351 insertions(+), 31 deletions(-) diff --git a/Source/Interface/HLE/FileManagement.cpp b/Source/Interface/HLE/FileManagement.cpp index 2863faf72..4f885bd2d 100644 --- a/Source/Interface/HLE/FileManagement.cpp +++ b/Source/Interface/HLE/FileManagement.cpp @@ -3,6 +3,7 @@ #include "Interface/Context/Context.h" #include "Interface/HLE/FileManagement.h" #include +#include #include #include #include @@ -121,23 +122,15 @@ uint64_t FD::read(int fd, void *buf, size_t count) { } ssize_t FD::writev(int fd, void *iov, int iovcnt) { - ssize_t FinalSize {}; - LogMan::Msg::I(">>> writev: %d %p %d", fd, iov, iovcnt); + const struct iovec *Guestiov = reinterpret_cast(iov); + std::vector Hostiov; + Hostiov.resize(iovcnt); for (int i = 0; i < iovcnt; ++i) { - struct iovStruct { - uint64_t base; - size_t len; - }; - iovStruct *iovObject = reinterpret_cast(iov); - const char *String = CTX->MemoryMapper.GetPointer(iovObject->base); - LogMan::Msg::I("\t0x%lx Size: 0x%zx %p", iovObject->base, iovObject->len, String); - for (size_t j = 0; j < iovObject->len; ++j) { - LogMan::Msg::I("%c", String[j]); - } - FinalSize += iovObject->len; + Hostiov[i].iov_base = CTX->MemoryMapper.GetPointer(reinterpret_cast(Guestiov[i].iov_base)); + Hostiov[i].iov_len = Guestiov[i].iov_len; } - return FinalSize; + return ::writev(HostFD, &Hostiov.at(0), iovcnt); } uint64_t FD::write(int fd, void *buf, size_t count) { @@ -247,6 +240,10 @@ uint64_t FileManager::Fstat(int fd, void *buf) { return -1LL; } +uint64_t FileManager::Lstat(const char *path, void *buf) { + return lstat(path, reinterpret_cast(buf)); +} + uint64_t FileManager::Lseek(int fd, uint64_t offset, int whence) { auto fdPtr = FDMap.find(fd); if (fdPtr == FDMap.end()) { @@ -270,8 +267,51 @@ uint64_t FileManager::Access(const char *pathname, [[maybe_unused]] int mode) { return access(pathname, mode); } +uint64_t FileManager::Pipe(int pipefd[2]) { + int HostFD[2]; + int Result = ::pipe(HostFD); + + { + int32_t fd = CurrentFDOffset; + auto fdPtr = new FD{CTX, fd, "", 0, 0}; + fdPtr->SetHostFD(HostFD[0]); + pipefd[0] = fd; + FDMap[CurrentFDOffset++] = fdPtr; + } + { + int32_t fd = CurrentFDOffset; + auto fdPtr = new FD{CTX, fd, "", 0, 0}; + fdPtr->SetHostFD(HostFD[1]); + pipefd[1] = fd; + FDMap[CurrentFDOffset++] = fdPtr; + } + + return Result; +} +uint64_t FileManager::Pipe2(int pipefd[2], int flags) { + int HostFD[2]; + int Result = ::pipe2(HostFD, flags); + + { + int32_t fd = CurrentFDOffset; + auto fdPtr = new FD{CTX, fd, "", 0, 0}; + fdPtr->SetHostFD(HostFD[0]); + pipefd[0] = fd; + FDMap[CurrentFDOffset++] = fdPtr; + } + { + int32_t fd = CurrentFDOffset; + auto fdPtr = new FD{CTX, fd, "", 0, 0}; + fdPtr->SetHostFD(HostFD[1]); + pipefd[1] = fd; + FDMap[CurrentFDOffset++] = fdPtr; + } + + return Result; +} + + uint64_t FileManager::Readlink(const char *pathname, char *buf, size_t bufsiz) { - LogMan::Msg::D("Attemptign to readlink: '%s'", pathname); if (strcmp(pathname, "/proc/self/exe") == 0) { strncpy(buf, Filename.c_str(), bufsiz); return std::min(bufsiz, Filename.size()); @@ -321,6 +361,23 @@ uint64_t FileManager::GetDents(int fd, void *dirp, uint32_t count) { static_cast(count)); } +uint64_t FileManager::PRead64(int fd, void *buf, size_t count, off_t offset) { + auto FD = FDMap.find(fd); + if (FD == FDMap.end()) { + return -1; + } + return pread(FD->second->GetHostFD(), buf, count, offset); +} + +uint64_t FileManager::EPoll_Create1(int flags) { + int HostFD = epoll_create1(flags); + int32_t fd = CurrentFDOffset; + auto fdPtr = new FD{CTX, fd, "", 0, 0}; + fdPtr->SetHostFD(HostFD); + FDMap[CurrentFDOffset++] = fdPtr; + return fd; +} + uint64_t FileManager::Socket(int domain, int type, int protocol) { int32_t fd = CurrentFDOffset; @@ -346,18 +403,97 @@ uint64_t FileManager::Connect(int sockfd, const struct sockaddr *addr, socklen_t return connect(FD->second->GetHostFD(), addr, addrlen); } +uint64_t FileManager::Recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { + auto FD = FDMap.find(sockfd); + if (FD == FDMap.end()) { + return -1; + } + + return recvfrom(FD->second->GetHostFD(), buf, len, flags, src_addr, addrlen); +} + +uint64_t FileManager::Recvmsg(int sockfd, struct msghdr *msg, int flags) { + auto FD = FDMap.find(sockfd); + if (FD == FDMap.end()) { + return -1; + } + + std::vector Hostvec; + struct msghdr Hosthdr; + memcpy(&Hosthdr, msg, sizeof(struct msghdr)); + + if (Hosthdr.msg_name) + Hosthdr.msg_name = CTX->MemoryMapper.GetPointer(reinterpret_cast(Hosthdr.msg_name)); + + if (Hosthdr.msg_control) + Hosthdr.msg_control = CTX->MemoryMapper.GetPointer(reinterpret_cast(Hosthdr.msg_control)); + + Hostvec.resize(Hosthdr.msg_iovlen); + + struct iovec *Guestiov = CTX->MemoryMapper.GetPointer(reinterpret_cast(Hosthdr.msg_iov)); + for (int i = 0; i < Hosthdr.msg_iovlen; ++i) { + Hostvec[i].iov_base = CTX->MemoryMapper.GetPointer(reinterpret_cast(Guestiov[i].iov_base)); + Hostvec[i].iov_len = Guestiov[i].iov_len; + } + + Hosthdr.msg_iov = &Hostvec.at(0); + + int Result = recvmsg(FD->second->GetHostFD(), &Hosthdr, flags); + if (Result == -1) { + if (errno == EAGAIN || + errno == EWOULDBLOCK) { + return -errno; + } + } + return Result; +} + +uint64_t FileManager::Shutdown(int sockfd, int how) { + auto FD = FDMap.find(sockfd); + if (FD == FDMap.end()) { + return -1; + } + + return shutdown(FD->second->GetHostFD(), how); +} + +uint64_t FileManager::GetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + auto FD = FDMap.find(sockfd); + if (FD == FDMap.end()) { + return -1; + } + + return getsockname(FD->second->GetHostFD(), addr, addrlen); +} + +uint64_t FileManager::GetPeerName(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + auto FD = FDMap.find(sockfd); + if (FD == FDMap.end()) { + return -1; + } + + return getpeername(FD->second->GetHostFD(), addr, addrlen); +} + uint64_t FileManager::Poll(struct pollfd *fds, nfds_t nfds, int timeout) { std::vector HostFDs; HostFDs.resize(nfds); memcpy(&HostFDs.at(0), fds, sizeof(pollfd) * nfds); for (auto &FD : HostFDs) { auto HostFD = FDMap.find(FD.fd); - if (HostFD == FDMap.end()) + if (HostFD == FDMap.end()) { + LogMan::Msg::D("Poll. Failed to map FD: %d", FD.fd); return -1; + } FD.fd = HostFD->second->GetHostFD(); } - return poll(fds, nfds, timeout); + int Result = poll(&HostFDs.at(0), nfds, timeout); + + for (int i = 0; i < nfds; ++i) { + fds[i].revents = HostFDs[i].revents; + } + return Result; } uint64_t FileManager::Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { diff --git a/Source/Interface/HLE/FileManagement.h b/Source/Interface/HLE/FileManagement.h index 2bbb16944..18f57fd83 100644 --- a/Source/Interface/HLE/FileManagement.h +++ b/Source/Interface/HLE/FileManagement.h @@ -36,6 +36,9 @@ public: int lseek(int fd, off_t offset, int wehnce); int GetHostFD() const { return HostFD; } + void SetHostFD(int fd) { HostFD = fd; } + + std::string const& GetName() const { return PathName; } protected: FEXCore::Context::Context *CTX; @@ -60,17 +63,29 @@ public: uint64_t Close(int fd); uint64_t Stat(const char *pathname, void *buf); uint64_t Fstat(int fd, void *buf); + uint64_t Lstat(const char *path, void *buf); uint64_t Lseek(int fd, uint64_t offset, int whence); uint64_t Writev(int fd, void *iov, int iovcnt); uint64_t Access(const char *pathname, int mode); + uint64_t Pipe(int pipefd[2]); + uint64_t Pipe2(int pipefd[2], int flags); uint64_t Readlink(const char *pathname, char *buf, size_t bufsiz); uint64_t Openat(int dirfs, const char *pathname, int flags, uint32_t mode); uint64_t Ioctl(int fd, uint64_t request, void *args); uint64_t GetDents(int fd, void *dirp, uint32_t count); + uint64_t PRead64(int fd, void *buf, size_t count, off_t offset); + + // EPoll + uint64_t EPoll_Create1(int flags); // Sockets uint64_t Socket(int domain, int type, int protocol); uint64_t Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + uint64_t Recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); + uint64_t Recvmsg(int sockfd, struct msghdr *msg, int flags); + uint64_t Shutdown(int sockfd, int how); + uint64_t GetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + uint64_t GetPeerName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); uint64_t Poll(struct pollfd *fds, nfds_t nfds, int timeout); uint64_t Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); diff --git a/Source/Interface/HLE/Syscalls.cpp b/Source/Interface/HLE/Syscalls.cpp index 61313b0d9..5e655925d 100644 --- a/Source/Interface/HLE/Syscalls.cpp +++ b/Source/Interface/HLE/Syscalls.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include constexpr uint64_t PAGE_SIZE = 4096; @@ -23,6 +26,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_ACCESS: LogMan::Msg::D("access(\"%s\", %d) = %ld", CTX->MemoryMapper.GetPointer(Args->Argument[1]), Args->Argument[2], Ret); break; + case SYSCALL_PIPE: + LogMan::Msg::D("pipe({...}) = %ld", Ret); + break; case SYSCALL_SELECT: LogMan::Msg::D("select(%ld, 0x%lx, 0x%lx, 0x%lx, 0x%lx) = %ld", Args->Argument[1], @@ -32,6 +38,12 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) Args->Argument[5], Ret); break; + case SYSCALL_NANOSLEEP: + LogMan::Msg::D("nanosleep(0x%ld, 0x%lx) = %ld", + Args->Argument[1], + Args->Argument[2], + Ret); + break; case SYSCALL_OPENAT: LogMan::Msg::D("openat(%ld, \"%s\", %d) = %ld", Args->Argument[1], CTX->MemoryMapper.GetPointer(Args->Argument[2]), Args->Argument[3], Ret); break; @@ -41,6 +53,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_FSTAT: LogMan::Msg::D("fstat(%ld, {...}) = %ld", Args->Argument[1], Ret); break; + case SYSCALL_LSTAT: + LogMan::Msg::D("lstat(\"%s\", {...}) = %ld", CTX->MemoryMapper.GetPointer(Args->Argument[1]), Ret); + break; case SYSCALL_POLL: LogMan::Msg::D("poll(0x%lx, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; @@ -66,7 +81,7 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) LogMan::Msg::D("uname ({...}) = %ld", Ret); break; case SYSCALL_FCNTL: - LogMan::Msg::D("uname (%ld, %ld, 0x%lx) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); + LogMan::Msg::D("fcntl (%ld, %ld, 0x%lx) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; case SYSCALL_UMASK: LogMan::Msg::D("umask(0x%lx) = %ld", Args->Argument[1], Ret); @@ -74,6 +89,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_GETTIMEOFDAY: LogMan::Msg::D("gettimeofday(0x%lx, 0x%lx) = %ld", Args->Argument[1], Args->Argument[2], Ret); break; + case SYSCALL_SYSINFO: + LogMan::Msg::D("sysinfo(0x%lx) = %ld", Args->Argument[1], Ret); + break; case SYSCALL_GETCWD: LogMan::Msg::D("getcwd(\"%s\", %ld) = %ld", CTX->MemoryMapper.GetPointer(Args->Argument[1]), Args->Argument[2], Ret); break; @@ -107,6 +125,12 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_SET_ROBUST_LIST: LogMan::Msg::D("set_robust_list(%p, %ld) = %ld", Args->Argument[1], Args->Argument[2], Ret); break; + case SYSCALL_EPOLL_CREATE1: + LogMan::Msg::D("epoll_create1(%ld) = %ld", Args->Argument[1], Ret); + break; + case SYSCALL_PIPE2: + LogMan::Msg::D("pipe2({...}, %d) = %ld", Args->Argument[2], Ret); + break; case SYSCALL_RT_SIGACTION: LogMan::Msg::D("rt_sigaction(%ld, %p, %p) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; @@ -125,12 +149,50 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_CONNECT: LogMan::Msg::D("connect(%ld, 0x%lx, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; + case SYSCALL_RECVFROM: + LogMan::Msg::D("recvfrom(%ld, 0x%lx, %ld, %ld, 0x%lx, 0x%lx) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Args->Argument[4], + Args->Argument[5], + Args->Argument[6], + Ret); + break; + case SYSCALL_RECVMSG: + LogMan::Msg::D("recvmsg(%ld, 0x%lx, %ld) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Ret); + break; + case SYSCALL_SHUTDOWN: + LogMan::Msg::D("shutdown(%ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Ret); + break; + case SYSCALL_GETSOCKNAME: + LogMan::Msg::D("getsockname(%ld, 0x%lx, 0x%lx) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); + break; + case SYSCALL_GETPEERNAME: + LogMan::Msg::D("getpeername(%ld, 0x%lx, 0x%lx) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); + break; + case SYSCALL_CLONE: + LogMan::Msg::I("clone(%lx,\n\t%lx,\n\t%lx,\n\t%lx,\n\t%lx,\n\t%lx,\n\t%lx)", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Args->Argument[4], + Args->Argument[5], + Args->Argument[6]); + break; case SYSCALL_GETUID: LogMan::Msg::D("getuid() = %ld", Ret); break; case SYSCALL_GETGID: LogMan::Msg::D("getgid() = %ld", Ret); break; + case SYSCALL_SETUID: + LogMan::Msg::D("setuid(%ld) = %ld", Args->Argument[1], Ret); + break; case SYSCALL_GETEUID: LogMan::Msg::D("geteuid() = %ld", Ret); break; @@ -140,6 +202,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_SETREGID: LogMan::Msg::D("setregid(%ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Ret); break; + case SYSCALL_SETRESUID: + LogMan::Msg::D("setresuid(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); + break; case SYSCALL_GETTID: LogMan::Msg::D("gettid() = %ld", Ret); break; @@ -152,15 +217,38 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_IOCTL: LogMan::Msg::D("ioctl(%ld, %ld, %p) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; + case SYSCALL_PREAD64: + LogMan::Msg::D("pread64(%ld, 0x%lx, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Args->Argument[4], Ret); + break; case SYSCALL_TIME: LogMan::Msg::D("time(%p) = %ld", Args->Argument[1], Ret); break; + case SYSCALL_FUTEX: + LogMan::Msg::D("futex(%p, %ld, %ld, 0x%lx, 0x%lx, %ld) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Args->Argument[4], + Args->Argument[5], + Args->Argument[6], + Ret); + break; case SYSCALL_CLOCK_GETTIME: LogMan::Msg::D("clock_gettime(%ld, %p) = %ld", Args->Argument[1], Args->Argument[2], Ret); break; + case SYSCALL_CLOCK_GETRES: + LogMan::Msg::D("clock_getres(%ld, %p) = %ld", Args->Argument[1], Args->Argument[2], Ret); + break; case SYSCALL_READLINK: LogMan::Msg::D("readlink(\"%s\") = %ld", CTX->MemoryMapper.GetPointer(Args->Argument[1]), Ret); break; + case SYSCALL_GETRANDOM: + LogMan::Msg::D("getrandom(0x%lx, 0x%lx, 0x%lx) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Ret); + break; default: LogMan::Msg::D("Unknown strace: %d", Args->Argument[0]); } } @@ -240,9 +328,6 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa if (!HostPtr) { HostPtr = CTX->MapRegion(Thread, Base, Size, true); } - else { - LogMan::Msg::D("\tMapping Fixed pointer in already mapped space: 0x%lx -> %p", Base, HostPtr); - } if (HostFD != -1) { void *FileMem = mmap(HostPtr, FileSizeToUse, Prot, MAP_DENYWRITE | MAP_PRIVATE | MAP_FIXED, HostFD, Args->Argument[6]); @@ -263,9 +348,6 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa if (!HostPtr) { HostPtr = CTX->MapRegion(Thread, Base, Size, true); } - else { - LogMan::Msg::D("\tMapping Fixed pointer in already mapped space: 0x%lx -> %p", Base, HostPtr); - } if (HostFD != -1) { void *FileMem = mmap(HostPtr, FileSizeToUse, Prot, MAP_PRIVATE | MAP_FIXED, HostFD, Args->Argument[6]); @@ -323,6 +405,33 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa CTX->MemoryMapper.GetPointer(Args->Argument[2]), Args->Argument[3]); break; + case SYSCALL_RECVFROM: + Result = FM.Recvfrom(Args->Argument[1], + CTX->MemoryMapper.GetPointer(Args->Argument[2]), + Args->Argument[3], + Args->Argument[4], + CTX->MemoryMapper.GetPointer(Args->Argument[5]), + CTX->MemoryMapper.GetPointer(Args->Argument[6])); + break; + case SYSCALL_RECVMSG: + Result = FM.Recvmsg(Args->Argument[1], + CTX->MemoryMapper.GetPointer(Args->Argument[2]), + Args->Argument[3]); + break; + case SYSCALL_SHUTDOWN: + Result = FM.Shutdown(Args->Argument[1], + Args->Argument[2]); + break; + case SYSCALL_GETSOCKNAME: + Result = FM.GetSockName(Args->Argument[1], + CTX->MemoryMapper.GetPointer(Args->Argument[2]), + CTX->MemoryMapper.GetPointer(Args->Argument[3])); + break; + case SYSCALL_GETPEERNAME: + Result = FM.GetPeerName(Args->Argument[1], + CTX->MemoryMapper.GetPointer(Args->Argument[2]), + CTX->MemoryMapper.GetPointer(Args->Argument[3])); + break; case SYSCALL_POLL: Result = FM.Poll(CTX->MemoryMapper.GetPointer(Args->Argument[1]), Args->Argument[2], Args->Argument[3]); break; @@ -333,6 +442,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa case SYSCALL_GETGID: Result = Thread->State.ThreadManager.GetGID(); break; + case SYSCALL_SETUID: + // XXX: Not a real result + Result = -1; + break; case SYSCALL_GETEUID: Result = Thread->State.ThreadManager.GetEUID(); break; @@ -343,6 +456,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa // XXX: Not a real result Result = 0; break; + case SYSCALL_SETRESUID: + // XXX: Not a real result + Result = -1; + break; case SYSCALL_GETTID: Result = Thread->State.ThreadManager.GetTID(); break; @@ -415,13 +532,6 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa // 2: parent tidptr // 3: child tidptr // 4: TLS - LogMan::Msg::I("clone(%lx,\n\t%lx,\n\t%lx,\n\t%lx,\n\t%lx,\n\t%lx,\n\t%lx)", - Args->Argument[0], - Args->Argument[1], - Args->Argument[2], - Args->Argument[3], - Args->Argument[4], - Args->Argument[5]); uint32_t Flags = Args->Argument[1]; uint64_t NewSP = Args->Argument[2]; uint64_t ParentTID = Args->Argument[3]; @@ -523,6 +633,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa Result = FM.Fstat(Args->Argument[1], CTX->MemoryMapper.GetPointer(Args->Argument[2])); break; + case SYSCALL_LSTAT: + Result = FM.Lstat(CTX->MemoryMapper.GetPointer(Args->Argument[1]), + CTX->MemoryMapper.GetPointer(Args->Argument[2])); + break; case SYSCALL_LSEEK: Result = FM.Lseek(Args->Argument[1], Args->Argument[2], @@ -538,6 +652,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa CTX->MemoryMapper.GetPointer(Args->Argument[1]), Args->Argument[2]); break; + case SYSCALL_PIPE: + Result = FM.Pipe( + CTX->MemoryMapper.GetPointer(Args->Argument[1])); + break; case SYSCALL_SELECT: { fd_set *readfds{}; fd_set *writefds{}; @@ -576,6 +694,13 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa Args->Argument[2], CTX->MemoryMapper.GetPointer(Args->Argument[3])); break; + case SYSCALL_PREAD64: + Result = FM.PRead64( + Args->Argument[1], + CTX->MemoryMapper.GetPointer(Args->Argument[2]), + Args->Argument[3], + Args->Argument[4]); + break; case SYSCALL_TIME: { time_t TmpTime; TmpTime = time(nullptr); @@ -596,6 +721,18 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa // memset(ClockResult, 0, sizeof(timespec)); } break; + case SYSCALL_SYSINFO: { + struct sysinfo *info = CTX->MemoryMapper.GetPointer(Args->Argument[1]); + Result = sysinfo(info); + } + break; + case SYSCALL_CLOCK_GETRES: { + struct timespec *res{}; + if (Args->Argument[2]) + res = CTX->MemoryMapper.GetPointer(Args->Argument[2]); + Result = clock_getres(Args->Argument[1], res); + } + break; case SYSCALL_NANOSLEEP: { timespec const* req = CTX->MemoryMapper.GetPointer(Args->Argument[1]); timespec *rem = CTX->MemoryMapper.GetPointer(Args->Argument[2]); @@ -618,6 +755,15 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa Result = 0; break; } + case SYSCALL_EPOLL_CREATE1: { + Result = FM.EPoll_Create1(Args->Argument[1]); + break; + } + case SYSCALL_PIPE2: + Result = FM.Pipe2( + CTX->MemoryMapper.GetPointer(Args->Argument[1]), + Args->Argument[2]); + break; case SYSCALL_PRLIMIT64: { LogMan::Throw::A(Args->Argument[3] == 0, "Guest trying to set limit for %d", Args->Argument[2]); struct rlimit { @@ -678,6 +824,9 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa case 1: // F_GETFD Result = fcntl(HostFD, Cmd); break; + case 2: // F_SETFD + Result = fcntl(HostFD, Cmd, Args->Argument[3]); + break; case 3: // F_GETFL Result = fcntl(HostFD, Cmd); break; @@ -688,6 +837,11 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa } break; } + case SYSCALL_GETRANDOM: + Result = getrandom(CTX->MemoryMapper.GetPointer(Args->Argument[1]), + Args->Argument[2], + Args->Argument[3]); + break; // Currently unhandled // Return fake result case SYSCALL_RT_SIGACTION: diff --git a/Source/Interface/HLE/Syscalls.h b/Source/Interface/HLE/Syscalls.h index 5450a85c1..133787d1d 100644 --- a/Source/Interface/HLE/Syscalls.h +++ b/Source/Interface/HLE/Syscalls.h @@ -27,6 +27,7 @@ enum Syscalls { SYSCALL_CLOSE = 3, ///< __NR_close SYSCALL_STAT = 4, ///< __NR_stat SYSCALL_FSTAT = 5, ///< __NR_fstat + SYSCALL_LSTAT = 6, ///< __NR_lstat SYSCALL_POLL = 7, ///< __NR_poll SYSCALL_LSEEK = 8, ///< __NR_lseek SYSCALL_MMAP = 9, ///< __NR_mmap @@ -36,13 +37,20 @@ enum Syscalls { SYSCALL_RT_SIGACTION = 13, ///< __NR_rt_sigaction SYSCALL_RT_SIGPROCMASK = 14, ///< __NR_rt_sigprocmask SYSCALL_IOCTL = 16, ///< __NR_ioctl + SYSCALL_PREAD64 = 17, ///< __NR_pread64 SYSCALL_WRITEV = 20, ///< __NR_writev SYSCALL_ACCESS = 21, ///< __NR_access + SYSCALL_PIPE = 22, ///< __NR_pipe SYSCALL_SELECT = 23, ///< __NR_select SYSCALL_NANOSLEEP = 35, ///< __NR_nanosleep SYSCALL_GETPID = 39, ///< __NR_getpid SYSCALL_SOCKET = 41, ///< __NR_socket SYSCALL_CONNECT = 42, ///< __NR_connect + SYSCALL_RECVFROM = 45, ///< __NR_recvfrom + SYSCALL_RECVMSG = 47, ///< __NR_recvmsg + SYSCALL_SHUTDOWN = 48, ///< __NR_shutdown + SYSCALL_GETSOCKNAME = 51, ///< __NR_getsockname + SYSCALL_GETPEERNAME = 52, ///< __NR_getpeername SYSCALL_CLONE = 56, ///< __NR_clone SYSCALL_EXIT = 60, ///< __NR_exit SYSCALL_WAIT4 = 61, ///< __NR_wait4 @@ -55,11 +63,14 @@ enum Syscalls { SYSCALL_READLINK = 89, ///< __NR_readlink SYSCALL_UMASK = 95, ///< __NR_umask SYSCALL_GETTIMEOFDAY = 96, ///< __NR_gettimeofday + SYSCALL_SYSINFO = 99, ///< __NR_sysinfo SYSCALL_GETUID = 102, ///< __NR_getuid SYSCALL_GETGID = 104, ///< __NR_getgid + SYSCALL_SETUID = 105, ///< __NR_setuid SYSCALL_GETEUID = 107, ///< __NR_geteuid SYSCALL_GETEGID = 108, ///< __NR_getegid SYSCALL_SETREGID = 114, ///< __NR_setregid + SYSCALL_SETRESUID = 117, ///< __NR_setresuid SYSCALL_ARCH_PRCTL = 158, ///< __NR_arch_prctl SYSCALL_GETTID = 186, ///< __NR_gettid SYSCALL_TIME = 201, ///< __NR_time @@ -67,11 +78,15 @@ enum Syscalls { SYSCALL_GETDENTS64 = 217, ///< __NR_getdents64 SYSCALL_SET_TID_ADDRESS = 218, ///< __NR_set_tid_address SYSCALL_CLOCK_GETTIME = 228, ///< __NR_clock_gettime + SYSCALL_CLOCK_GETRES = 229, ///< __NR_clock_getres SYSCALL_EXIT_GROUP = 231, ///< __NR_exit_group SYSCALL_TGKILL = 234, ///< __NR_tgkill SYSCALL_OPENAT = 257, ///< __NR_openat SYSCALL_SET_ROBUST_LIST = 273, ///< __NR_set_robust_list + SYSCALL_EPOLL_CREATE1 = 291, ///< __NR_epoll_create1 + SYSCALL_PIPE2 = 293, ///< __NR_pipe2 SYSCALL_PRLIMIT64 = 302, ///< __NR_prlimit64 + SYSCALL_GETRANDOM = 318, ///< __NR_getrandom }; struct Futex {