mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-25 18:00:49 +01:00
Syscall additions and fixes
Adds unified memory support for most things Fixes a couple of bugs
This commit is contained in:
1 parent
8d293e9184
commit
6f5b9358e2
7 files changed
+472
-138
No files matched your search
@@ -8,6 +8,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <unistd.h>
|
||||
@@ -22,16 +23,25 @@ public:
|
||||
}
|
||||
|
||||
ssize_t writev(int fd, void *iov, int iovcnt) override {
|
||||
iovec *iovObject = reinterpret_cast<iovec*>(iov);
|
||||
struct Object {
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
Object *iovObject = reinterpret_cast<Object*>(iov);
|
||||
|
||||
if (CTX->Config.AccurateSTDOut) {
|
||||
std::vector<iovec> HostStructs(iovcnt);
|
||||
for (int i = 0; i < iovcnt; ++i) {
|
||||
HostStructs[i].iov_base = CTX->MemoryMapper.GetPointer<void*>(reinterpret_cast<uint64_t>(iovObject[i].iov_base));
|
||||
HostStructs[i].iov_len = iovObject[i].iov_len;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
return ::writev(fd, reinterpret_cast<iovec const *>(iov), iovcnt);
|
||||
}
|
||||
else {
|
||||
std::vector<iovec> HostStructs(iovcnt);
|
||||
for (int i = 0; i < iovcnt; ++i) {
|
||||
HostStructs[i].iov_base = CTX->MemoryMapper.GetPointer<void*>(reinterpret_cast<uint64_t>(iovObject[i].iov_base));
|
||||
HostStructs[i].iov_len = iovObject[i].iov_len;
|
||||
}
|
||||
|
||||
return ::writev(fd, &HostStructs.at(0), iovcnt);
|
||||
return ::writev(fd, &HostStructs.at(0), iovcnt);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssize_t FinalSize {};
|
||||
@@ -39,7 +49,12 @@ public:
|
||||
|
||||
for (int i = 0; i < iovcnt; ++i) {
|
||||
const char *String{};
|
||||
String = CTX->MemoryMapper.GetPointer<const char*>(reinterpret_cast<uint64_t>(iovObject[i].iov_base));
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
String = reinterpret_cast<const char*>(iovObject[i].iov_base);
|
||||
}
|
||||
else {
|
||||
String = CTX->MemoryMapper.GetPointer<const char*>(reinterpret_cast<uint64_t>(iovObject[i].iov_base));
|
||||
}
|
||||
for (size_t j = 0; j < iovObject[i].iov_len; ++j) {
|
||||
OutputString += String[j];
|
||||
}
|
||||
@@ -48,10 +63,11 @@ public:
|
||||
|
||||
OutputString += '\0';
|
||||
|
||||
if (FDOffset == STDOUT_FILENO)
|
||||
LogMan::Msg::OUT("[%ld] %s", FinalSize, OutputString.c_str());
|
||||
else if (FDOffset == STDERR_FILENO)
|
||||
if (FDOffset == STDERR_FILENO)
|
||||
LogMan::Msg::ERR("[%ld] %s", FinalSize, OutputString.c_str());
|
||||
else
|
||||
LogMan::Msg::OUT("[%ld] %s", FinalSize, OutputString.c_str());
|
||||
|
||||
return FinalSize;
|
||||
}
|
||||
}
|
||||
@@ -61,10 +77,10 @@ public:
|
||||
return ::write(fd, buf, count);
|
||||
}
|
||||
else {
|
||||
if (FDOffset == STDOUT_FILENO)
|
||||
LogMan::Msg::OUT("%s", reinterpret_cast<char*>(buf));
|
||||
else if (FDOffset == STDERR_FILENO)
|
||||
if (FDOffset == STDERR_FILENO)
|
||||
LogMan::Msg::ERR("%s", reinterpret_cast<char*>(buf));
|
||||
else
|
||||
LogMan::Msg::OUT("%s", reinterpret_cast<char*>(buf));
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -90,16 +106,34 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class TimerFD final : public FD {
|
||||
public:
|
||||
TimerFD(FEXCore::Context::Context *ctx, int32_t fd, int32_t clockid, int32_t flags)
|
||||
: FD (ctx, fd, "Timer", 0, 0) {
|
||||
HostFD = timerfd_create(clockid, flags);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
uint64_t FD::read(int fd, void *buf, size_t count) {
|
||||
return ::read(HostFD, buf, count);
|
||||
}
|
||||
|
||||
ssize_t FD::writev(int fd, void *iov, int iovcnt) {
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
return ::writev(HostFD, reinterpret_cast<const struct iovec*>(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) {
|
||||
Hostiov[i].iov_base = CTX->MemoryMapper.GetPointer(reinterpret_cast<uint64_t>(Guestiov[i].iov_base));
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
Hostiov[i].iov_base = reinterpret_cast<void*>(Guestiov[i].iov_base);
|
||||
}
|
||||
else {
|
||||
Hostiov[i].iov_base = CTX->MemoryMapper.GetPointer(reinterpret_cast<uint64_t>(Guestiov[i].iov_base));
|
||||
}
|
||||
Hostiov[i].iov_len = Guestiov[i].iov_len;
|
||||
}
|
||||
|
||||
@@ -224,7 +258,7 @@ uint64_t FileManager::Fstat(int fd, void *buf) {
|
||||
}
|
||||
}
|
||||
|
||||
LogMan::Msg::D("Attempting to stat: %d", fd);
|
||||
LogMan::Msg::D("Attempting to fstat: %d", fd);
|
||||
return -1LL;
|
||||
}
|
||||
|
||||
@@ -272,6 +306,20 @@ uint64_t FileManager::Access(const char *pathname, [[maybe_unused]] int mode) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t FileManager::FAccessat(int dirfd, const char *pathname, int mode, int flags) {
|
||||
auto Path = GetEmulatedPath(pathname);
|
||||
if (!Path.empty()) {
|
||||
uint64_t Result = ::faccessat(dirfd, Path.c_str(), mode, flags);
|
||||
if (Result != -1)
|
||||
return Result;
|
||||
}
|
||||
|
||||
int Result = ::faccessat(dirfd, pathname, mode, flags);
|
||||
if (Result == -1)
|
||||
return -errno;
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t FileManager::Pipe(int pipefd[2]) {
|
||||
int HostFD[2];
|
||||
int Result = ::pipe(HostFD);
|
||||
@@ -331,6 +379,22 @@ uint64_t FileManager::Readlink(const char *pathname, char *buf, size_t bufsiz) {
|
||||
return ::readlink(pathname, buf, bufsiz);
|
||||
}
|
||||
|
||||
uint64_t FileManager::Readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
|
||||
if (strcmp(pathname, "/proc/self/exe") == 0) {
|
||||
strncpy(buf, Filename.c_str(), bufsiz);
|
||||
return std::min(bufsiz, Filename.size());
|
||||
}
|
||||
|
||||
auto Path = GetEmulatedPath(pathname);
|
||||
if (!Path.empty()) {
|
||||
uint64_t Result = ::readlinkat(dirfd, Path.c_str(), buf, bufsiz);
|
||||
if (Result != -1)
|
||||
return Result;
|
||||
}
|
||||
|
||||
return ::readlinkat(dirfd, pathname, buf, bufsiz);
|
||||
}
|
||||
|
||||
uint64_t FileManager::Openat([[maybe_unused]] int dirfs, const char *pathname, int flags, uint32_t mode) {
|
||||
int32_t fd = CurrentFDOffset;
|
||||
if (!strcmp(pathname, "/dev/tty")) {
|
||||
@@ -353,7 +417,7 @@ uint64_t FileManager::Openat([[maybe_unused]] int dirfs, const char *pathname, i
|
||||
|
||||
if (Result == -1) {
|
||||
delete fdPtr;
|
||||
return -1;
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +432,12 @@ uint64_t FileManager::Ioctl(int fd, uint64_t request, void *args) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return FD->second->ioctl(fd, request, args);
|
||||
uint64_t Result = FD->second->ioctl(fd, request, args);
|
||||
if (Result == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t FileManager::GetDents(int fd, void *dirp, uint32_t count) {
|
||||
@@ -495,7 +564,8 @@ uint64_t FileManager::Recvfrom(int sockfd, void *buf, size_t len, int flags, str
|
||||
}
|
||||
|
||||
uint64_t FileManager::Sendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
||||
auto FD = FDMap.find(sockfd);
|
||||
LogMan::Throw::A(!CTX->Config.UnifiedMemory, "Not yet supported");
|
||||
auto FD = FDMap.find(sockfd);
|
||||
if (FD == FDMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
@@ -531,38 +601,67 @@ uint64_t FileManager::Sendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
||||
}
|
||||
|
||||
uint64_t FileManager::Recvmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||
auto FD = FDMap.find(sockfd);
|
||||
auto FD = FDMap.find(sockfd);
|
||||
if (FD == FDMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<iovec> Hostvec;
|
||||
struct msghdr Hosthdr;
|
||||
memcpy(&Hosthdr, msg, sizeof(struct msghdr));
|
||||
int Result{};
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
Result = recvmsg(FD->second->GetHostFD(), msg, flags);
|
||||
}
|
||||
else {
|
||||
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_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));
|
||||
if (Hosthdr.msg_control)
|
||||
Hosthdr.msg_control = CTX->MemoryMapper.GetPointer(reinterpret_cast<uint64_t>(Hosthdr.msg_control));
|
||||
|
||||
Hostvec.resize(Hosthdr.msg_iovlen);
|
||||
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;
|
||||
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);
|
||||
|
||||
Result = recvmsg(FD->second->GetHostFD(), &Hosthdr, flags);
|
||||
}
|
||||
|
||||
Hosthdr.msg_iov = &Hostvec.at(0);
|
||||
|
||||
int Result = recvmsg(FD->second->GetHostFD(), &Hosthdr, flags);
|
||||
if (Result == -1) {
|
||||
if (errno == EAGAIN ||
|
||||
errno == EWOULDBLOCK) {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->msg_control && msg->msg_controllen > 0) {
|
||||
// Handle the Linux ancillary data
|
||||
struct cmsghdr *cmsg = reinterpret_cast<struct cmsghdr*>(msg->msg_control);
|
||||
switch (cmsg->cmsg_type) {
|
||||
case SCM_RIGHTS: {
|
||||
uint32_t *HostFDs = reinterpret_cast<uint32_t*>(CMSG_DATA(cmsg));
|
||||
uint32_t NumFiles = (msg->msg_controllen - cmsg->cmsg_len) / sizeof(uint32_t);
|
||||
for (size_t i = 0; i < NumFiles; ++i) {
|
||||
int32_t fd = CurrentFDOffset;
|
||||
auto fdPtr = new FEXCore::FD{CTX, fd, "<Shared>", 0, 0};
|
||||
fdPtr->SetHostFD(HostFDs[i]);
|
||||
FDMap[CurrentFDOffset++] = fdPtr;
|
||||
|
||||
// Remap host FD to guest
|
||||
HostFDs[i] = fd;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: LogMan::Msg::A("Unhandled Ancillary socket type: 0x%x", cmsg->cmsg_type); break;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -685,6 +784,8 @@ uint64_t FileManager::Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set
|
||||
}
|
||||
|
||||
uint64_t FileManager::Sendmmsg(int sockfd, struct mmsghdr *msgvec, uint32_t vlen, int flags) {
|
||||
LogMan::Throw::A(!CTX->Config.UnifiedMemory, "Not yet supported");
|
||||
|
||||
auto FD = FDMap.find(sockfd);
|
||||
if (FD == FDMap.end()) {
|
||||
return -1;
|
||||
@@ -730,6 +831,22 @@ uint64_t FileManager::Sendmmsg(int sockfd, struct mmsghdr *msgvec, uint32_t vlen
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t FileManager::Timer_Create(int32_t clockid, int32_t flags) {
|
||||
int32_t fd = CurrentFDOffset;
|
||||
|
||||
auto fdPtr = new TimerFD{CTX, fd, clockid, flags};
|
||||
|
||||
auto Result = fdPtr->GetHostFD();
|
||||
if (Result == -1) {
|
||||
delete fdPtr;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
FDMap[CurrentFDOffset++] = fdPtr;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int32_t FileManager::FindHostFD(int fd) {
|
||||
auto FD = FDMap.find(fd);
|
||||
if (FD == FDMap.end()) {
|
||||
@@ -757,6 +874,7 @@ int32_t FileManager::DupFD(int prevFD, int newFD) {
|
||||
int32_t fd = CurrentFDOffset;
|
||||
|
||||
auto fdPtr = new FD{prevFDClass->second, fd};
|
||||
fdPtr->SetHostFD(newFD);
|
||||
FDMap[CurrentFDOffset++] = fdPtr;
|
||||
|
||||
return fd;
|
||||
|
||||
@@ -77,9 +77,11 @@ public:
|
||||
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 FAccessat(int dirfd, const char *pathname, int mode, int flags);
|
||||
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 Readlinkat(int dirfd, 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);
|
||||
@@ -111,6 +113,9 @@ public:
|
||||
uint64_t Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
uint64_t Sendmmsg(int sockfd, struct mmsghdr *msgvec, uint32_t vlen, int flags);
|
||||
|
||||
// Timers
|
||||
uint64_t Timer_Create(int32_t clockid, int32_t flags);
|
||||
|
||||
int32_t FindHostFD(int fd);
|
||||
|
||||
FD const* GetFDBacking(int fd);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <sys/random.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/shm.h>
|
||||
#include <unistd.h>
|
||||
|
||||
constexpr uint64_t PAGE_SIZE = 4096;
|
||||
@@ -76,7 +77,7 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
switch (Args->Argument[0]) {
|
||||
case SYSCALL_BRK: LogMan::Msg::D("brk(%p) = 0x%lx", Args->Argument[1], Ret); break;
|
||||
case SYSCALL_ACCESS:
|
||||
LogMan::Msg::D("access(\"%s\", %d) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
LogMan::Msg::D("access(\"%s\", %d) = %ld", GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_PIPE:
|
||||
LogMan::Msg::D("pipe({...}) = %ld", Ret);
|
||||
@@ -101,34 +102,79 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
Args->Argument[3],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_SHMGET:
|
||||
LogMan::Msg::D("shmget(0x%lx, 0x%lx, 0x%lx) = %ld",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_SHMAT:
|
||||
LogMan::Msg::D("shmat(0x%lx, 0x%lx, 0x%lx) = %lx",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_SHMCTL:
|
||||
LogMan::Msg::D("shmctl(0x%lx, 0x%lx, 0x%lx) = %ld",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_DUP2:
|
||||
LogMan::Msg::D("dup2(0x%lx, 0x%lx) = %ld",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_NANOSLEEP:
|
||||
LogMan::Msg::D("nanosleep(0x%ld, 0x%lx) = %ld",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_GETITIMER:
|
||||
LogMan::Msg::D("getitimer(0x%ld, 0x%lx) = %ld",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_ALARM:
|
||||
LogMan::Msg::D("alarm(%ld) = %ld",
|
||||
Args->Argument[1],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_SETITIMER:
|
||||
LogMan::Msg::D("setitimer(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);
|
||||
LogMan::Msg::D("openat(%ld, \"%s\", %d) = %ld", Args->Argument[1], GetPointer<char const*>(Args->Argument[2]), Args->Argument[3], Ret);
|
||||
break;
|
||||
case SYSCALL_READLINKAT:
|
||||
LogMan::Msg::D("readlinkat(\"%s\") = %ld", GetPointer<char const*>(Args->Argument[2]), Ret);
|
||||
break;
|
||||
case SYSCALL_FACCESSAT:
|
||||
LogMan::Msg::D("faccessat(\"%s\", %d) = %ld", GetPointer<char const*>(Args->Argument[2]), Args->Argument[3], Ret);
|
||||
break;
|
||||
case SYSCALL_STAT:
|
||||
LogMan::Msg::D("stat(\"%s\", {...}) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
LogMan::Msg::D("stat(\"%s\", {...}) = %ld", GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
break;
|
||||
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);
|
||||
LogMan::Msg::D("lstat(\"%s\", {...}) = %ld", 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;
|
||||
case SYSCALL_MMAP:
|
||||
LogMan::Msg::D("mmap(%p, %ld, %ld, %ld, %d, %p) = %p", Args->Argument[1], Args->Argument[2], Args->Argument[3], Args->Argument[4], static_cast<int32_t>(Args->Argument[5]), Args->Argument[6], Ret);
|
||||
LogMan::Msg::D("mmap(%p, 0x%lx, %ld, %lx, %d, %p) = %p", Args->Argument[1], Args->Argument[2], Args->Argument[3], Args->Argument[4], static_cast<int32_t>(Args->Argument[5]), Args->Argument[6], Ret);
|
||||
break;
|
||||
case SYSCALL_CLOSE:
|
||||
LogMan::Msg::D("close(%ld) = %ld", Args->Argument[1], Ret);
|
||||
@@ -144,7 +190,7 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_ARCH_PRCTL:
|
||||
LogMan::Msg::D("arch_prctl(%ld, %p) = %ld", Args->Argument[1], Args->Argument[2], Ret);
|
||||
LogMan::Msg::D("arch_prctl(0x%lx, %p) = %ld", Args->Argument[1], Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_MPROTECT:
|
||||
LogMan::Msg::D("mprotect(%p, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret);
|
||||
@@ -155,6 +201,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
case SYSCALL_UNAME:
|
||||
LogMan::Msg::D("uname ({...}) = %ld", Ret);
|
||||
break;
|
||||
case SYSCALL_SHMDT:
|
||||
LogMan::Msg::D("shmdt(%p)= %ld", Args->Argument[1], Ret);
|
||||
break;
|
||||
case SYSCALL_FCNTL:
|
||||
LogMan::Msg::D("fcntl (%ld, %ld, 0x%lx) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret);
|
||||
break;
|
||||
@@ -168,19 +217,19 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
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);
|
||||
LogMan::Msg::D("getcwd(\"%s\", %ld) = %ld", GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_CHDIR:
|
||||
LogMan::Msg::D("chdir(\"%s\") = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
LogMan::Msg::D("chdir(\"%s\") = %ld", GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
break;
|
||||
case SYSCALL_MKDIR:
|
||||
LogMan::Msg::D("mkdir(\"%s\", 0x%lx) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
LogMan::Msg::D("mkdir(\"%s\", 0x%lx) = %ld", GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_RMDIR:
|
||||
LogMan::Msg::D("rmdir(\"%s\", 0x%lx) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
LogMan::Msg::D("rmdir(\"%s\", 0x%lx) = %ld", GetPointer<char const*>(Args->Argument[1]), Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_UNLINK:
|
||||
LogMan::Msg::D("unlink(\"%s\", 0x%lx) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
LogMan::Msg::D("unlink(\"%s\", 0x%lx) = %ld", GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
break;
|
||||
case SYSCALL_EXIT:
|
||||
LogMan::Msg::D("exit(0x%lx)", Args->Argument[1]);
|
||||
@@ -203,6 +252,9 @@ 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_TIMERFD_CREATE:
|
||||
LogMan::Msg::D("timerfd_create(%lx, %lx) = %ld", Args->Argument[1], Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_EVENTFD:
|
||||
LogMan::Msg::D("eventfd(%lx, %ld) = %ld", Args->Argument[1], Args->Argument[2], Ret);
|
||||
break;
|
||||
@@ -317,13 +369,16 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
case SYSCALL_SETRESGID:
|
||||
LogMan::Msg::D("setresgid(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret);
|
||||
break;
|
||||
case SYSCALL_SIGALTSTACK:
|
||||
LogMan::Msg::D("sigaltstack(%lx, %lx) = %ld", Args->Argument[1], Args->Argument[2], Ret);
|
||||
break;
|
||||
case SYSCALL_MKNOD:
|
||||
LogMan::Msg::D("mknod(\"%s\", %ld, %ld) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]),
|
||||
LogMan::Msg::D("mknod(\"%s\", %ld, %ld) = %ld", GetPointer<char const*>(Args->Argument[1]),
|
||||
Args->Argument[2], Args->Argument[3],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_STATFS:
|
||||
LogMan::Msg::D("statfs(\"%s\", {...}) = %ld", CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
LogMan::Msg::D("statfs(\"%s\", {...}) = %ld", GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
break;
|
||||
case SYSCALL_GETTID:
|
||||
LogMan::Msg::D("gettid() = %ld", Ret);
|
||||
@@ -335,7 +390,7 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
LogMan::Msg::D("lseek(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret);
|
||||
break;
|
||||
case SYSCALL_IOCTL:
|
||||
LogMan::Msg::D("ioctl(%ld, %ld, %p) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret);
|
||||
LogMan::Msg::D("ioctl(%ld, 0x%lx, %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);
|
||||
@@ -353,6 +408,13 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
Args->Argument[6],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_SCHED_GETAFFINITY:
|
||||
LogMan::Msg::D("sched_getaffinity(%ld, %ld, %ld, 0x%lx) = %ld",
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3],
|
||||
Ret);
|
||||
break;
|
||||
case SYSCALL_CLOCK_GETTIME:
|
||||
LogMan::Msg::D("clock_gettime(%ld, %p) = %ld", Args->Argument[1], Args->Argument[2], Ret);
|
||||
break;
|
||||
@@ -360,7 +422,7 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
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);
|
||||
LogMan::Msg::D("readlink(\"%s\") = %ld", GetPointer<char const*>(Args->Argument[1]), Ret);
|
||||
break;
|
||||
case SYSCALL_GETRANDOM:
|
||||
LogMan::Msg::D("getrandom(0x%lx, 0x%lx, 0x%lx) = %ld",
|
||||
@@ -372,7 +434,7 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
case SYSCALL_STATX:
|
||||
LogMan::Msg::D("statx(%ld, \"%s\", 0x%lx, 0x%lx, {...}) = %ld",
|
||||
Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[2]),
|
||||
GetPointer<char const*>(Args->Argument[2]),
|
||||
Args->Argument[3], Args->Argument[4],
|
||||
Ret);
|
||||
break;
|
||||
@@ -382,15 +444,42 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret)
|
||||
#endif
|
||||
void SyscallHandler::DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thread, uint64_t Addr) {
|
||||
DataSpaceSize = 0;
|
||||
DataSpace = Addr;
|
||||
DefaultProgramBreakAddress = Addr;
|
||||
|
||||
// Just allocate 1GB of data memory past the default program break location at this point
|
||||
CTX->MapRegion(Thread, Addr, 0x1000'0000, true);
|
||||
|
||||
if (UnifiedMemory) {
|
||||
Addr += CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
}
|
||||
|
||||
DataSpace = Addr;
|
||||
DefaultProgramBreakAddress = Addr;
|
||||
}
|
||||
|
||||
SyscallHandler::SyscallHandler(FEXCore::Context::Context *ctx)
|
||||
: CTX {ctx}
|
||||
, UnifiedMemory {CTX->Config.UnifiedMemory}
|
||||
, FM {ctx} {
|
||||
}
|
||||
|
||||
void *SyscallHandler::GetPointer(uint64_t Offset) {
|
||||
if (UnifiedMemory)
|
||||
return reinterpret_cast<void*>(Offset);
|
||||
else
|
||||
return CTX->MemoryMapper.GetPointer(Offset);
|
||||
}
|
||||
|
||||
void *SyscallHandler::GetPointerSizeCheck(uint64_t Offset, uint64_t Size) {
|
||||
if (UnifiedMemory) {
|
||||
return reinterpret_cast<void*>(Offset);
|
||||
}
|
||||
else {
|
||||
return CTX->MemoryMapper.GetPointerSizeCheck(Offset, Size);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) {
|
||||
uint64_t Result = 0;
|
||||
std::scoped_lock<std::mutex> lk(SyscallMutex);
|
||||
|
||||
switch (Args->Argument[0]) {
|
||||
case SYSCALL_UNAME: {
|
||||
@@ -401,7 +490,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
char version[65];
|
||||
char machine[65];
|
||||
};
|
||||
_utsname *Local = CTX->MemoryMapper.GetPointer<_utsname*>(Args->Argument[1]);
|
||||
_utsname *Local = GetPointer<_utsname*>(Args->Argument[1]);
|
||||
strcpy(Local->sysname, "Linux");
|
||||
strcpy(Local->nodename, "FEXCore");
|
||||
strcpy(Local->release, "5.0.0");
|
||||
@@ -453,9 +542,16 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
break;
|
||||
}
|
||||
|
||||
if (UnifiedMemory) {
|
||||
// If we are running unified memory then we want to be after our base
|
||||
// This makes code page loading less of a burden
|
||||
Base += CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
}
|
||||
|
||||
if (Flags & MAP_FIXED) {
|
||||
Base = Args->Argument[1];
|
||||
void *HostPtr = CTX->MemoryMapper.GetPointerSizeCheck(Base, FileSizeToUse);
|
||||
|
||||
void *HostPtr = GetPointerSizeCheck(Base, FileSizeToUse);
|
||||
if (!HostPtr) {
|
||||
HostPtr = CTX->MapRegion(Thread, Base, Size, true);
|
||||
}
|
||||
@@ -475,7 +571,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
else {
|
||||
// XXX: MMAP should map memory regions for all threads
|
||||
void *HostPtr = CTX->MemoryMapper.GetPointerSizeCheck(Base, FileSizeToUse);
|
||||
void *HostPtr = GetPointerSizeCheck(Base, FileSizeToUse);
|
||||
if (!HostPtr) {
|
||||
HostPtr = CTX->MapRegion(Thread, Base, Size, true);
|
||||
}
|
||||
@@ -524,11 +620,11 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
Result = 0;
|
||||
break;
|
||||
case 0x1003: // ARCH_GET_FS
|
||||
*CTX->MemoryMapper.GetPointer<uint64_t*>(Args->Argument[2]) = Thread->State.State.fs;
|
||||
*GetPointer<uint64_t*>(Args->Argument[2]) = Thread->State.State.fs;
|
||||
Result = 0;
|
||||
break;
|
||||
case 0x1004: // ARCH_GET_GS
|
||||
*CTX->MemoryMapper.GetPointer<uint64_t*>(Args->Argument[2]) = Thread->State.State.gs;
|
||||
*GetPointer<uint64_t*>(Args->Argument[2]) = Thread->State.State.gs;
|
||||
Result = 0;
|
||||
break;
|
||||
case 0x3001: // ARCH_CET_STATUS
|
||||
@@ -546,25 +642,25 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
break;
|
||||
case SYSCALL_CONNECT:
|
||||
Result = FM.Connect(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<const struct sockaddr *>(Args->Argument[2]),
|
||||
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]),
|
||||
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]));
|
||||
GetPointer<struct sockaddr *>(Args->Argument[5]),
|
||||
GetPointer<socklen_t*>(Args->Argument[6]));
|
||||
break;
|
||||
case SYSCALL_SENDMSG:
|
||||
Result = FM.Sendmsg(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<const struct msghdr*>(Args->Argument[2]),
|
||||
GetPointer<const struct msghdr*>(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_RECVMSG:
|
||||
Result = FM.Recvmsg(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<struct msghdr*>(Args->Argument[2]),
|
||||
GetPointer<struct msghdr*>(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_SHUTDOWN:
|
||||
@@ -573,30 +669,30 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
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]));
|
||||
GetPointer<struct sockaddr *>(Args->Argument[2]),
|
||||
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]));
|
||||
GetPointer<struct sockaddr *>(Args->Argument[2]),
|
||||
GetPointer<socklen_t *>(Args->Argument[3]));
|
||||
break;
|
||||
case SYSCALL_SETSOCKOPT:
|
||||
Result = FM.SetSockOpt(Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3],
|
||||
CTX->MemoryMapper.GetPointer<const void*>(Args->Argument[4]),
|
||||
GetPointer<const void*>(Args->Argument[4]),
|
||||
Args->Argument[5]);
|
||||
break;
|
||||
case SYSCALL_GETSOCKOPT:
|
||||
Result = FM.GetSockOpt(Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3],
|
||||
CTX->MemoryMapper.GetPointer<void*>(Args->Argument[4]),
|
||||
CTX->MemoryMapper.GetPointer<socklen_t *>(Args->Argument[5]));
|
||||
GetPointer<void*>(Args->Argument[4]),
|
||||
GetPointer<socklen_t *>(Args->Argument[5]));
|
||||
break;
|
||||
case SYSCALL_POLL:
|
||||
Result = FM.Poll(CTX->MemoryMapper.GetPointer<struct pollfd*>(Args->Argument[1]), Args->Argument[2], Args->Argument[3]);
|
||||
Result = FM.Poll(GetPointer<struct pollfd*>(Args->Argument[1]), Args->Argument[2], Args->Argument[3]);
|
||||
break;
|
||||
// Thread management
|
||||
case SYSCALL_GETUID:
|
||||
@@ -647,13 +743,16 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
|
||||
break;
|
||||
case SYSCALL_SIGALTSTACK:
|
||||
Result = 0;
|
||||
break;
|
||||
case SYSCALL_MKNOD:
|
||||
Result = FM.Mknod(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]),
|
||||
Result = FM.Mknod(GetPointer<char const*>(Args->Argument[1]),
|
||||
Args->Argument[2], Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_STATFS:
|
||||
Result = FM.Statfs(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]),
|
||||
CTX->MemoryMapper.GetPointer(Args->Argument[2]));
|
||||
Result = FM.Statfs(GetPointer<char const*>(Args->Argument[1]),
|
||||
GetPointer(Args->Argument[2]));
|
||||
break;
|
||||
case SYSCALL_GETTID:
|
||||
Result = Thread->State.ThreadManager.GetTID();
|
||||
@@ -686,13 +785,6 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
// 3: utime
|
||||
// 4: uaddr2
|
||||
// 5: val3
|
||||
LogMan::Msg::I("futex(%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]);
|
||||
|
||||
uint8_t Command = Args->Argument[2] & 0xF;
|
||||
Result = 0;
|
||||
@@ -703,7 +795,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
|
||||
if (!futex) {
|
||||
futex = new Futex{}; // XXX: Definitely a memory leak. When should we free this?
|
||||
futex->Addr = CTX->MemoryMapper.GetPointer<std::atomic<uint32_t>*>(Args->Argument[1]);
|
||||
futex->Addr = GetPointer<std::atomic<uint32_t>*>(Args->Argument[1]);
|
||||
futex->Val = Args->Argument[3];
|
||||
EmplaceFutex(Args->Argument[1], futex);
|
||||
}
|
||||
@@ -745,6 +837,13 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYSCALL_SCHED_GETAFFINITY: {
|
||||
cpu_set_t *mask = GetPointer<cpu_set_t*>(Args->Argument[3]);
|
||||
// Claim 1 CPU core
|
||||
CPU_SET(0, mask);
|
||||
Result = 0;
|
||||
break;
|
||||
}
|
||||
case SYSCALL_CLONE: {
|
||||
// 0: clone_flags
|
||||
// 1: New SP
|
||||
@@ -803,13 +902,13 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
|
||||
// Sets the child TID to pointer in ParentTID
|
||||
if (Flags & CLONE_PARENT_SETTID) {
|
||||
uint64_t *TIDPtr = CTX->MemoryMapper.GetPointer<uint64_t*>(ParentTID);
|
||||
uint64_t *TIDPtr = GetPointer<uint64_t*>(ParentTID);
|
||||
TIDPtr[0] = NewThread->State.ThreadManager.GetTID();
|
||||
}
|
||||
|
||||
// Sets the child TID to the pointer in ChildTID
|
||||
if (Flags & CLONE_CHILD_SETTID) {
|
||||
uint64_t *TIDPtr = CTX->MemoryMapper.GetPointer<uint64_t*>(ChildTID);
|
||||
uint64_t *TIDPtr = GetPointer<uint64_t*>(ChildTID);
|
||||
TIDPtr[0] = NewThread->State.ThreadManager.GetTID();
|
||||
}
|
||||
|
||||
@@ -818,7 +917,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
// Address /may/ be changed with SET_TID_ADDRESS syscall
|
||||
if (Flags & CLONE_CHILD_CLEARTID) {
|
||||
Futex *futex = new Futex{}; // XXX: Definitely a memory leak. When should we free this?
|
||||
futex->Addr = CTX->MemoryMapper.GetPointer<std::atomic<uint32_t>*>(ChildTID);
|
||||
futex->Addr = GetPointer<std::atomic<uint32_t>*>(ChildTID);
|
||||
futex->Val = NewThread->State.ThreadManager.GetTID();
|
||||
EmplaceFutex(ChildTID, futex);
|
||||
NewThread->State.ThreadManager.clear_tid = true;
|
||||
@@ -836,16 +935,16 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
// File management
|
||||
case SYSCALL_READ:
|
||||
Result = FM.Read(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer(Args->Argument[2]),
|
||||
GetPointer(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_WRITE:
|
||||
Result = FM.Write(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer(Args->Argument[2]),
|
||||
GetPointer(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_OPEN:
|
||||
Result = FM.Open(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]),
|
||||
Result = FM.Open(GetPointer<char const*>(Args->Argument[1]),
|
||||
Args->Argument[2],
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
@@ -854,10 +953,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
break;
|
||||
case SYSCALL_STAT: {
|
||||
struct stat host_stat{};
|
||||
Result = FM.Stat(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]),
|
||||
Result = FM.Stat(GetPointer<char const*>(Args->Argument[1]),
|
||||
&host_stat);
|
||||
|
||||
guest_stat *guest_data = CTX->MemoryMapper.GetPointer<guest_stat*>(Args->Argument[2]);
|
||||
guest_stat *guest_data = GetPointer<guest_stat*>(Args->Argument[2]);
|
||||
CopyStat(guest_data, &host_stat);
|
||||
break;
|
||||
}
|
||||
@@ -866,17 +965,17 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
|
||||
Result = FM.Fstat(Args->Argument[1], &host_stat);
|
||||
|
||||
guest_stat *guest_data = CTX->MemoryMapper.GetPointer<guest_stat*>(Args->Argument[2]);
|
||||
guest_stat *guest_data = GetPointer<guest_stat*>(Args->Argument[2]);
|
||||
CopyStat(guest_data, &host_stat);
|
||||
break;
|
||||
}
|
||||
case SYSCALL_LSTAT: {
|
||||
struct stat host_stat{};
|
||||
|
||||
Result = FM.Lstat(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]),
|
||||
Result = FM.Lstat(GetPointer<char const*>(Args->Argument[1]),
|
||||
&host_stat);
|
||||
|
||||
guest_stat *guest_data = CTX->MemoryMapper.GetPointer<guest_stat*>(Args->Argument[2]);
|
||||
guest_stat *guest_data = GetPointer<guest_stat*>(Args->Argument[2]);
|
||||
CopyStat(guest_data, &host_stat);
|
||||
break;
|
||||
}
|
||||
@@ -887,17 +986,17 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
break;
|
||||
case SYSCALL_WRITEV:
|
||||
Result = FM.Writev(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer(Args->Argument[2]),
|
||||
GetPointer(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_ACCESS:
|
||||
Result = FM.Access(
|
||||
CTX->MemoryMapper.GetPointer<const char*>(Args->Argument[1]),
|
||||
GetPointer<const char*>(Args->Argument[1]),
|
||||
Args->Argument[2]);
|
||||
break;
|
||||
case SYSCALL_PIPE:
|
||||
Result = FM.Pipe(
|
||||
CTX->MemoryMapper.GetPointer<int*>(Args->Argument[1]));
|
||||
GetPointer<int*>(Args->Argument[1]));
|
||||
break;
|
||||
case SYSCALL_SELECT: {
|
||||
fd_set *readfds{};
|
||||
@@ -906,13 +1005,13 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
struct timeval *timeout{};
|
||||
|
||||
if (Args->Argument[2])
|
||||
readfds = CTX->MemoryMapper.GetPointer<fd_set*>(Args->Argument[2]);
|
||||
readfds = GetPointer<fd_set*>(Args->Argument[2]);
|
||||
if (Args->Argument[3])
|
||||
writefds = CTX->MemoryMapper.GetPointer<fd_set*>(Args->Argument[3]);
|
||||
writefds = GetPointer<fd_set*>(Args->Argument[3]);
|
||||
if (Args->Argument[4])
|
||||
exceptfds = CTX->MemoryMapper.GetPointer<fd_set*>(Args->Argument[4]);
|
||||
exceptfds = GetPointer<fd_set*>(Args->Argument[4]);
|
||||
if (Args->Argument[5])
|
||||
timeout = CTX->MemoryMapper.GetPointer<struct timeval*>(Args->Argument[5]);
|
||||
timeout = GetPointer<struct timeval*>(Args->Argument[5]);
|
||||
|
||||
Result = select(Args->Argument[1],
|
||||
readfds, writefds, exceptfds, timeout);
|
||||
@@ -923,27 +1022,41 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
break;
|
||||
case SYSCALL_READLINK:
|
||||
Result = FM.Readlink(
|
||||
CTX->MemoryMapper.GetPointer<const char*>(Args->Argument[1]),
|
||||
CTX->MemoryMapper.GetPointer<char*>(Args->Argument[2]),
|
||||
GetPointer<const char*>(Args->Argument[1]),
|
||||
GetPointer<char*>(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_OPENAT:
|
||||
Result = FM.Openat(
|
||||
Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<const char*>(Args->Argument[2]),
|
||||
GetPointer<const char*>(Args->Argument[2]),
|
||||
Args->Argument[3],
|
||||
Args->Argument[4]);
|
||||
break;
|
||||
case SYSCALL_READLINKAT:
|
||||
Result = FM.Readlinkat(
|
||||
Args->Argument[1],
|
||||
GetPointer<const char*>(Args->Argument[2]),
|
||||
GetPointer<char*>(Args->Argument[3]),
|
||||
Args->Argument[4]);
|
||||
break;
|
||||
case SYSCALL_FACCESSAT:
|
||||
Result = FM.FAccessat(
|
||||
Args->Argument[1],
|
||||
GetPointer<const char*>(Args->Argument[2]),
|
||||
Args->Argument[2],
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_IOCTL:
|
||||
Result = FM.Ioctl(
|
||||
Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
CTX->MemoryMapper.GetPointer<void*>(Args->Argument[3]));
|
||||
Args->Argument[3] ? GetPointer<void*>(Args->Argument[3]) : nullptr);
|
||||
break;
|
||||
case SYSCALL_PREAD64:
|
||||
Result = FM.PRead64(
|
||||
Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<void*>(Args->Argument[2]),
|
||||
GetPointer<void*>(Args->Argument[2]),
|
||||
Args->Argument[3],
|
||||
Args->Argument[4]);
|
||||
break;
|
||||
@@ -951,7 +1064,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
time_t TmpTime;
|
||||
TmpTime = time(nullptr);
|
||||
if (Args->Argument[1]) {
|
||||
time_t *ClockResult = CTX->MemoryMapper.GetPointer<time_t*>(Args->Argument[1]);
|
||||
time_t *ClockResult = GetPointer<time_t*>(Args->Argument[1]);
|
||||
*ClockResult = TmpTime;
|
||||
#ifdef DEBUG_TIME
|
||||
memset(ClockResult, 0, sizeof(time_t));
|
||||
@@ -964,7 +1077,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
break;
|
||||
case SYSCALL_CLOCK_GETTIME: {
|
||||
timespec *ClockResult = CTX->MemoryMapper.GetPointer<timespec*>(Args->Argument[2]);
|
||||
timespec *ClockResult = GetPointer<timespec*>(Args->Argument[2]);
|
||||
Result = clock_gettime(Args->Argument[1], ClockResult);
|
||||
#ifdef DEBUG_TIME
|
||||
memset(ClockResult, 0, sizeof(timespec));
|
||||
@@ -972,37 +1085,105 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
break;
|
||||
case SYSCALL_SYSINFO: {
|
||||
struct sysinfo *info = CTX->MemoryMapper.GetPointer<struct sysinfo*>(Args->Argument[1]);
|
||||
struct sysinfo *info = 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]);
|
||||
res = GetPointer<struct timespec*>(Args->Argument[2]);
|
||||
Result = clock_getres(Args->Argument[1], res);
|
||||
}
|
||||
break;
|
||||
case SYSCALL_MINCORE: {
|
||||
Result = mincore(CTX->MemoryMapper.GetPointer(Args->Argument[1]),
|
||||
Result = mincore(GetPointer(Args->Argument[1]),
|
||||
Args->Argument[2],
|
||||
CTX->MemoryMapper.GetPointer<unsigned char*>(Args->Argument[3]));
|
||||
GetPointer<unsigned char*>(Args->Argument[3]));
|
||||
break;
|
||||
}
|
||||
case SYSCALL_SHMGET: {
|
||||
Result = shmget(Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
Args->Argument[3]);
|
||||
if (Result == -1) {
|
||||
Result = -errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYSCALL_SHMAT: {
|
||||
void* HostPointer{};
|
||||
if (Args->Argument[2]) {
|
||||
HostPointer = GetPointer<unsigned char*>(Args->Argument[2]);
|
||||
}
|
||||
else {
|
||||
HostPointer = reinterpret_cast<void*>(GetPointer<uint64_t>(0) + CTX->MemoryMapper.GetSHMSize());
|
||||
}
|
||||
|
||||
Result = (uint64_t)shmat(Args->Argument[1],
|
||||
HostPointer,
|
||||
Args->Argument[3]);
|
||||
if (Result == -1) {
|
||||
Result = -errno;
|
||||
}
|
||||
else {
|
||||
if (Args->Argument[2]) {
|
||||
Result = Args->Argument[2];
|
||||
}
|
||||
else {
|
||||
Result = Result - GetPointer<uint64_t>(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYSCALL_SHMCTL: {
|
||||
struct shmid_ds * HostPointer{};
|
||||
if (Args->Argument[3]) {
|
||||
HostPointer = GetPointer<struct shmid_ds*>(Args->Argument[3]);
|
||||
}
|
||||
|
||||
Result = shmctl(Args->Argument[1],
|
||||
Args->Argument[2],
|
||||
HostPointer);
|
||||
if (Result == -1) {
|
||||
Result = -errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYSCALL_DUP2: {
|
||||
auto FD = FM.GetFDBacking(Args->Argument[1]);
|
||||
if (!FD) {
|
||||
Result = EBADF;
|
||||
}
|
||||
else {
|
||||
Result = FM.DupFD(Args->Argument[1], dup(FD->GetHostFD()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYSCALL_NANOSLEEP: {
|
||||
timespec const* req = CTX->MemoryMapper.GetPointer<timespec const*>(Args->Argument[1]);
|
||||
timespec *rem = CTX->MemoryMapper.GetPointer<timespec*>(Args->Argument[2]);
|
||||
timespec const* req = GetPointer<timespec const*>(Args->Argument[1]);
|
||||
timespec *rem = GetPointer<timespec*>(Args->Argument[2]);
|
||||
Result = nanosleep(req, rem);
|
||||
break;
|
||||
}
|
||||
case SYSCALL_GETITIMER: {
|
||||
// XXX: Not a real result
|
||||
Result = 0;
|
||||
break;
|
||||
}
|
||||
case SYSCALL_ALARM: {
|
||||
// XXX: Not a real result
|
||||
Result = 0;
|
||||
break;
|
||||
}
|
||||
case SYSCALL_SETITIMER: {
|
||||
// XXX: Not a real result
|
||||
Result = 0;
|
||||
break;
|
||||
}
|
||||
case SYSCALL_GETDENTS64: {
|
||||
Result = FM.GetDents(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer(Args->Argument[2]),
|
||||
GetPointer(Args->Argument[2]),
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
}
|
||||
@@ -1011,7 +1192,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
// If a futex for this address changes then the futex location needs to change...
|
||||
if (futex) {
|
||||
RemoveFutex(Thread->State.ThreadManager.child_tid);
|
||||
futex->Addr = CTX->MemoryMapper.GetPointer<std::atomic<uint32_t>*>(Args->Argument[1]);
|
||||
futex->Addr = GetPointer<std::atomic<uint32_t>*>(Args->Argument[1]);
|
||||
EmplaceFutex(Args->Argument[1], futex);
|
||||
}
|
||||
|
||||
@@ -1024,6 +1205,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
Result = 0;
|
||||
break;
|
||||
}
|
||||
case SYSCALL_TIMERFD_CREATE: {
|
||||
Result = FM.Timer_Create(Args->Argument[1], Args->Argument[2]);;
|
||||
break;
|
||||
}
|
||||
case SYSCALL_EVENTFD: {
|
||||
Result = FM.Eventfd(Args->Argument[1], Args->Argument[2]);
|
||||
break;
|
||||
@@ -1034,7 +1219,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
case SYSCALL_PIPE2:
|
||||
Result = FM.Pipe2(
|
||||
CTX->MemoryMapper.GetPointer<int*>(Args->Argument[1]),
|
||||
GetPointer<int*>(Args->Argument[1]),
|
||||
Args->Argument[2]);
|
||||
break;
|
||||
case SYSCALL_PRLIMIT64: {
|
||||
@@ -1045,7 +1230,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
};
|
||||
switch (Args->Argument[2]) {
|
||||
case 3: { // Stack limits
|
||||
rlimit *old_limit = CTX->MemoryMapper.GetPointer<rlimit*>(Args->Argument[3]);
|
||||
rlimit *old_limit = GetPointer<rlimit*>(Args->Argument[4]);
|
||||
// Default size
|
||||
old_limit->rlim_cur = 8 * 1024;
|
||||
old_limit->rlim_max = ~0ULL;
|
||||
@@ -1058,7 +1243,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
}
|
||||
case SYSCALL_SENDMMSG:
|
||||
Result = FM.Sendmmsg(Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<struct mmsghdr*>(Args->Argument[2]),
|
||||
GetPointer<struct mmsghdr*>(Args->Argument[2]),
|
||||
Args->Argument[3],
|
||||
Args->Argument[4]);
|
||||
break;
|
||||
@@ -1070,33 +1255,39 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
struct timeval *tv{};
|
||||
struct timezone *tz{};
|
||||
if (Args->Argument[1])
|
||||
tv = CTX->MemoryMapper.GetPointer<struct timeval*>(Args->Argument[1]);
|
||||
tv = GetPointer<struct timeval*>(Args->Argument[1]);
|
||||
if (Args->Argument[2])
|
||||
tz = CTX->MemoryMapper.GetPointer<struct timezone*>(Args->Argument[2]);
|
||||
tz = GetPointer<struct timezone*>(Args->Argument[2]);
|
||||
Result = gettimeofday(tv, tz);
|
||||
break;
|
||||
}
|
||||
case SYSCALL_GETCWD:
|
||||
{
|
||||
char *ptr = getcwd(CTX->MemoryMapper.GetPointer<char *>(Args->Argument[1]), Args->Argument[2]);
|
||||
char *ptr = getcwd(GetPointer<char *>(Args->Argument[1]), Args->Argument[2]);
|
||||
if (!ptr) {
|
||||
Result = errno;
|
||||
Result = -errno;
|
||||
} else {
|
||||
Result = strlen(ptr) + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYSCALL_CHDIR:
|
||||
Result = chdir(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]));
|
||||
Result = chdir(GetPointer<char const*>(Args->Argument[1]));
|
||||
break;
|
||||
case SYSCALL_MKDIR:
|
||||
Result = mkdir(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]), Args->Argument[2]);
|
||||
Result = mkdir(GetPointer<char const*>(Args->Argument[1]), Args->Argument[2]);
|
||||
break;
|
||||
case SYSCALL_RMDIR:
|
||||
Result = rmdir(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]));
|
||||
Result = rmdir(GetPointer<char const*>(Args->Argument[1]));
|
||||
break;
|
||||
case SYSCALL_UNLINK:
|
||||
Result = unlink(CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[1]));
|
||||
Result = unlink(GetPointer<char const*>(Args->Argument[1]));
|
||||
break;
|
||||
case SYSCALL_SHMDT:
|
||||
Result = shmdt(reinterpret_cast<void*>(GetPointer<uint64_t>(Args->Argument[1])));
|
||||
if (Result == -1) {
|
||||
Result = -errno;
|
||||
}
|
||||
break;
|
||||
case SYSCALL_FCNTL: {
|
||||
int Cmd = Args->Argument[2];
|
||||
@@ -1109,8 +1300,7 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
switch (Cmd) {
|
||||
case 0: // F_DUPFD
|
||||
case 1030:{ // F_DUPFD_CLOEXEC
|
||||
int NewFD = fcntl(HostFD, Cmd);
|
||||
Result = FM.DupFD(Args->Argument[1], NewFD);
|
||||
Result = FM.DupFD(Args->Argument[1], dup(HostFD));
|
||||
break;
|
||||
}
|
||||
case 1: // F_GETFD
|
||||
@@ -1131,16 +1321,16 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa
|
||||
break;
|
||||
}
|
||||
case SYSCALL_GETRANDOM:
|
||||
Result = getrandom(CTX->MemoryMapper.GetPointer<void*>(Args->Argument[1]),
|
||||
Result = getrandom(GetPointer<void*>(Args->Argument[1]),
|
||||
Args->Argument[2],
|
||||
Args->Argument[3]);
|
||||
break;
|
||||
case SYSCALL_STATX:
|
||||
Result = FM.Statx(
|
||||
Args->Argument[1],
|
||||
CTX->MemoryMapper.GetPointer<char const*>(Args->Argument[2]),
|
||||
GetPointer<char const*>(Args->Argument[2]),
|
||||
Args->Argument[3], Args->Argument[4],
|
||||
CTX->MemoryMapper.GetPointer<struct statx*>(Args->Argument[5]));
|
||||
GetPointer<struct statx*>(Args->Argument[5]));
|
||||
break;
|
||||
// Currently unhandled
|
||||
// Return fake result
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
namespace FEXCore::Context {
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace FEXCore::Core {
|
||||
struct InternalThreadState;
|
||||
}
|
||||
@@ -44,8 +39,14 @@ enum Syscalls {
|
||||
SYSCALL_SELECT = 23, ///< __NR_select
|
||||
SYSCALL_SCHED_YIELD = 24, ///< __NR_sched_yield
|
||||
SYSCALL_MINCORE = 27, ///< __NR_mincore
|
||||
SYSCALL_SHMGET = 29, ///< __NR_shmget
|
||||
SYSCALL_SHMAT = 30, ///< __NR_shmat
|
||||
SYSCALL_SHMCTL = 31, ///< __NR_shmctl
|
||||
SYSCALL_DUP2 = 33, ///< __NR_dup2
|
||||
SYSCALL_NANOSLEEP = 35, ///< __NR_nanosleep
|
||||
SYSCALL_GETITIMER = 36, ///< __NR_getitimer
|
||||
SYSCALL_ALARM = 37, ///< __NR_alarm
|
||||
SYSCALL_SETITIMER = 38, ///< __NR_setitimer
|
||||
SYSCALL_GETPID = 39, ///< __NR_getpid
|
||||
SYSCALL_SOCKET = 41, ///< __NR_socket
|
||||
SYSCALL_CONNECT = 42, ///< __NR_connect
|
||||
@@ -61,6 +62,7 @@ enum Syscalls {
|
||||
SYSCALL_EXIT = 60, ///< __NR_exit
|
||||
SYSCALL_WAIT4 = 61, ///< __NR_wait4
|
||||
SYSCALL_UNAME = 63, ///< __NR_uname
|
||||
SYSCALL_SHMDT = 67, ///< __NR_shmdt
|
||||
SYSCALL_FCNTL = 72, ///< __NR_fcntl
|
||||
SYSCALL_GETCWD = 79, ///< __NR_getcwd
|
||||
SYSCALL_CHDIR = 80, ///< __NR_chdir
|
||||
@@ -79,6 +81,7 @@ enum Syscalls {
|
||||
SYSCALL_SETREGID = 114, ///< __NR_setregid
|
||||
SYSCALL_SETRESUID = 117, ///< __NR_setresuid
|
||||
SYSCALL_SETRESGID = 119, ///< __NR_setresgid
|
||||
SYSCALL_SIGALTSTACK = 131, ///< __NR_sigaltstack
|
||||
SYSCALL_MKNOD = 133, ///< __NR_mknod
|
||||
SYSCALL_STATFS = 137, ///< __NR_statfs
|
||||
SYSCALL_PRCTL = 157, ///< __NR_prctl
|
||||
@@ -86,6 +89,7 @@ enum Syscalls {
|
||||
SYSCALL_GETTID = 186, ///< __NR_gettid
|
||||
SYSCALL_TIME = 201, ///< __NR_time
|
||||
SYSCALL_FUTEX = 202, ///< __NR_futex
|
||||
SYSCALL_SCHED_GETAFFINITY = 204, ///< __NR_sched_getaffinity
|
||||
SYSCALL_GETDENTS64 = 217, ///< __NR_getdents64
|
||||
SYSCALL_SET_TID_ADDRESS = 218, ///< __NR_set_tid_address
|
||||
SYSCALL_CLOCK_GETTIME = 228, ///< __NR_clock_gettime
|
||||
@@ -93,7 +97,10 @@ enum Syscalls {
|
||||
SYSCALL_EXIT_GROUP = 231, ///< __NR_exit_group
|
||||
SYSCALL_TGKILL = 234, ///< __NR_tgkill
|
||||
SYSCALL_OPENAT = 257, ///< __NR_openat
|
||||
SYSCALL_READLINKAT = 267, ///< __NR_readlinkat
|
||||
SYSCALL_FACCESSAT = 269, ///< __NR_faccessat
|
||||
SYSCALL_SET_ROBUST_LIST = 273, ///< __NR_set_robust_list
|
||||
SYSCALL_TIMERFD_CREATE = 283, ///< __NR_timerfd_create
|
||||
SYSCALL_EVENTFD = 290, ///< __NR_eventfd
|
||||
SYSCALL_EPOLL_CREATE1 = 291, ///< __NR_epoll_create1
|
||||
SYSCALL_PIPE2 = 293, ///< __NR_pipe2
|
||||
@@ -114,7 +121,7 @@ struct Futex {
|
||||
// #define DEBUG_STRACE
|
||||
class SyscallHandler final {
|
||||
public:
|
||||
SyscallHandler(FEXCore::Context::Context *ctx) : CTX {ctx}, FM {ctx} {}
|
||||
SyscallHandler(FEXCore::Context::Context *ctx);
|
||||
uint64_t HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args);
|
||||
|
||||
// XXX: This leaks memory.
|
||||
@@ -132,6 +139,7 @@ public:
|
||||
}
|
||||
|
||||
void RemoveFutex(uint64_t Addr) {
|
||||
std::scoped_lock<std::mutex> lk (FutexMutex);
|
||||
Futexes.erase(Addr);
|
||||
}
|
||||
|
||||
@@ -142,11 +150,13 @@ public:
|
||||
|
||||
private:
|
||||
FEXCore::Context::Context *CTX;
|
||||
bool const &UnifiedMemory;
|
||||
FileManager FM;
|
||||
|
||||
// Futex management
|
||||
std::unordered_map<uint64_t, Futex*> Futexes;
|
||||
std::mutex FutexMutex;
|
||||
std::mutex SyscallMutex;
|
||||
|
||||
// BRK management
|
||||
uint64_t DataSpace {};
|
||||
@@ -159,7 +169,13 @@ private:
|
||||
#ifdef DEBUG_STRACE
|
||||
void Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret);
|
||||
#endif
|
||||
template<typename T>
|
||||
T GetPointer(uint64_t Offset) {
|
||||
return reinterpret_cast<T>(GetPointer(Offset));
|
||||
}
|
||||
|
||||
void *GetPointer(uint64_t Offset);
|
||||
void *GetPointerSizeCheck(uint64_t Offset, uint64_t Size);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -16,6 +16,9 @@ namespace FEXCore::Memory {
|
||||
void SetBaseRegion(FEXCore::SHM::SHMObject *NewSHM) {
|
||||
SHM = reinterpret_cast<FEXCore::SHM::InternalSHMObject*>(NewSHM);
|
||||
}
|
||||
size_t GetSHMSize() const {
|
||||
return SHM->Size;
|
||||
}
|
||||
|
||||
void *MapRegion(uint64_t Offset, size_t Size, bool Fixed = true);
|
||||
void *MapRegion(uint64_t Offset, size_t Size, uint32_t Flags, bool Fixed = true);
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace FEXCore::SHM {
|
||||
}
|
||||
|
||||
SHM->Object.Ptr = MapRegionFlags(SHM, 0, Size, PROT_READ | PROT_WRITE, false);
|
||||
SHM->Size = Size;
|
||||
if (SHM->Object.Ptr == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -8,5 +8,6 @@ namespace FEXCore::SHM {
|
||||
struct InternalSHMObject {
|
||||
SHMObject Object;
|
||||
int SHMFD;
|
||||
size_t Size;
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user