Syscall additions and improvements

Fixes a bug in writev where we need to parse the iovec struct and
convert it.
Implements 15 new syscalls
This commit is contained in:
Ryan Houdek 2019-12-02 17:28:22 -08:00 committed by Stefanos Kornilios Mitsis Poiitidis
parent 0d782bd515
commit 124dc592a9
4 changed files with 351 additions and 31 deletions

View File

@ -3,6 +3,7 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/FileManagement.h"
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
@ -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<const struct iovec*>(iov);
std::vector<struct iovec> Hostiov;
Hostiov.resize(iovcnt);
for (int i = 0; i < iovcnt; ++i) {
struct iovStruct {
uint64_t base;
size_t len;
};
iovStruct *iovObject = reinterpret_cast<iovStruct*>(iov);
const char *String = CTX->MemoryMapper.GetPointer<const char*>(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<uint64_t>(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<struct stat*>(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, "<Pipe>", 0, 0};
fdPtr->SetHostFD(HostFD[0]);
pipefd[0] = fd;
FDMap[CurrentFDOffset++] = fdPtr;
}
{
int32_t fd = CurrentFDOffset;
auto fdPtr = new FD{CTX, fd, "<Pipe>", 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, "<Pipe>", 0, 0};
fdPtr->SetHostFD(HostFD[0]);
pipefd[0] = fd;
FDMap[CurrentFDOffset++] = fdPtr;
}
{
int32_t fd = CurrentFDOffset;
auto fdPtr = new FD{CTX, fd, "<Pipe>", 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<uint64_t>(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, "<EPoll>", 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<iovec> Hostvec;
struct msghdr Hosthdr;
memcpy(&Hosthdr, msg, sizeof(struct msghdr));
if (Hosthdr.msg_name)
Hosthdr.msg_name = CTX->MemoryMapper.GetPointer(reinterpret_cast<uint64_t>(Hosthdr.msg_name));
if (Hosthdr.msg_control)
Hosthdr.msg_control = CTX->MemoryMapper.GetPointer(reinterpret_cast<uint64_t>(Hosthdr.msg_control));
Hostvec.resize(Hosthdr.msg_iovlen);
struct iovec *Guestiov = CTX->MemoryMapper.GetPointer<struct iovec*>(reinterpret_cast<uint64_t>(Hosthdr.msg_iov));
for (int i = 0; i < Hosthdr.msg_iovlen; ++i) {
Hostvec[i].iov_base = CTX->MemoryMapper.GetPointer(reinterpret_cast<uint64_t>(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<pollfd> 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) {

View File

@ -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);

View File

@ -11,6 +11,9 @@
#include <poll.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/random.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#include <unistd.h>
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<char const*>(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<char const*>(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<char const*>(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<char const*>(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<char const*>(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<const struct sockaddr *>(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<struct sockaddr *>(Args->Argument[5]),
CTX->MemoryMapper.GetPointer<socklen_t*>(Args->Argument[6]));
break;
case SYSCALL_RECVMSG:
Result = FM.Recvmsg(Args->Argument[1],
CTX->MemoryMapper.GetPointer<struct msghdr*>(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<struct sockaddr *>(Args->Argument[2]),
CTX->MemoryMapper.GetPointer<socklen_t *>(Args->Argument[3]));
break;
case SYSCALL_GETPEERNAME:
Result = FM.GetPeerName(Args->Argument[1],
CTX->MemoryMapper.GetPointer<struct sockaddr *>(Args->Argument[2]),
CTX->MemoryMapper.GetPointer<socklen_t *>(Args->Argument[3]));
break;
case SYSCALL_POLL:
Result = FM.Poll(CTX->MemoryMapper.GetPointer<struct pollfd*>(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<char const*>(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<const char*>(Args->Argument[1]),
Args->Argument[2]);
break;
case SYSCALL_PIPE:
Result = FM.Pipe(
CTX->MemoryMapper.GetPointer<int*>(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<void*>(Args->Argument[3]));
break;
case SYSCALL_PREAD64:
Result = FM.PRead64(
Args->Argument[1],
CTX->MemoryMapper.GetPointer<void*>(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<struct sysinfo*>(Args->Argument[1]);
Result = sysinfo(info);
}
break;
case SYSCALL_CLOCK_GETRES: {
struct timespec *res{};
if (Args->Argument[2])
res = CTX->MemoryMapper.GetPointer<struct timespec*>(Args->Argument[2]);
Result = clock_getres(Args->Argument[1], res);
}
break;
case SYSCALL_NANOSLEEP: {
timespec const* req = CTX->MemoryMapper.GetPointer<timespec const*>(Args->Argument[1]);
timespec *rem = CTX->MemoryMapper.GetPointer<timespec*>(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<int*>(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<void*>(Args->Argument[1]),
Args->Argument[2],
Args->Argument[3]);
break;
// Currently unhandled
// Return fake result
case SYSCALL_RT_SIGACTION:

View File

@ -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 {