From ea167cf7d97f8aaf5750909fc133fa21db1f0d4e Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 20 Mar 2020 12:30:08 -0700 Subject: [PATCH] Adds a few new syscalls that I saw in app testing madvise, dup, bind, syslog, getresuid, get_mempolicy, newfstatat, execve execve specifically returned error. We don't support it yet. --- External/FEXCore/Source/CMakeLists.txt | 5 +- .../Source/Interface/HLE/FileManagement.cpp | 26 ++++ .../Source/Interface/HLE/FileManagement.h | 6 + .../FEXCore/Source/Interface/HLE/Syscalls.cpp | 116 +++++++++++++++++- .../FEXCore/Source/Interface/HLE/Syscalls.h | 8 ++ 5 files changed, 157 insertions(+), 4 deletions(-) diff --git a/External/FEXCore/Source/CMakeLists.txt b/External/FEXCore/Source/CMakeLists.txt index 195ba87c7..36de3c8dd 100644 --- a/External/FEXCore/Source/CMakeLists.txt +++ b/External/FEXCore/Source/CMakeLists.txt @@ -137,10 +137,13 @@ add_custom_target(IR_INC check_cxx_compiler_flag(-fdiagnostics-color=always GCC_COLOR) check_cxx_compiler_flag(-fcolor-diagnostics CLANG_COLOR) +set(LINUX_LIBS + numa) + function(AddLibrary Name Type) add_library(${Name} ${Type} ${SRCS}) add_dependencies(${Name} IR_INC) - target_link_libraries(${Name} LLVM pthread rt ${JIT_LIBS} dl) + target_link_libraries(${Name} LLVM pthread rt ${JIT_LIBS} ${LINUX_LIBS} dl) set_target_properties(${Name} PROPERTIES OUTPUT_NAME FEXCore) target_include_directories(${Name} PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/External/FEXCore/Source/Interface/HLE/FileManagement.cpp b/External/FEXCore/Source/Interface/HLE/FileManagement.cpp index 9bb310e16..c500046b3 100644 --- a/External/FEXCore/Source/Interface/HLE/FileManagement.cpp +++ b/External/FEXCore/Source/Interface/HLE/FileManagement.cpp @@ -272,6 +272,13 @@ uint64_t FileManager::Readlink(const char *pathname, char *buf, size_t bufsiz) { return ::readlink(pathname, buf, bufsiz); } +uint64_t FileManager::NewFStatAt(int dirfd, const char *pathname, struct stat *buf, int flags) { + int Result = fstatat(dirfd, pathname, buf, flags); + if (Result == -1) + return -errno; + return Result; +} + 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); @@ -481,6 +488,13 @@ uint64_t FileManager::Shutdown(int sockfd, int how) { return shutdown(sockfd, how); } +uint64_t FileManager::Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + int Result = bind(sockfd, addr, addrlen); + if (Result == -1) + return -errno; + return Result; +} + uint64_t FileManager::GetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { return getsockname(sockfd, addr, addrlen); } @@ -571,6 +585,14 @@ uint64_t FileManager::Memfd_Create(const char *name, uint32_t flags) { return fd; } +// Syslog +uint64_t FileManager::Syslog(int type, char *bufp, int len) { + return syscall(SYS_syslog, + static_cast(type), + reinterpret_cast(bufp), + static_cast(len)); +} + int32_t FileManager::FindHostFD(int fd) { return fd; } @@ -588,6 +610,10 @@ FD const* FileManager::GetFDBacking(int fd) { return nullptr; } +int32_t FileManager::DupFD(int prevFD) { + return ::dup(prevFD); +} + int32_t FileManager::DupFD(int prevFD, int newFD) { return ::dup2(prevFD, newFD); } diff --git a/External/FEXCore/Source/Interface/HLE/FileManagement.h b/External/FEXCore/Source/Interface/HLE/FileManagement.h index fa9139c07..64b23277b 100644 --- a/External/FEXCore/Source/Interface/HLE/FileManagement.h +++ b/External/FEXCore/Source/Interface/HLE/FileManagement.h @@ -79,6 +79,7 @@ public: 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 NewFStatAt(int dirfd, const char *pathname, struct stat *buf, int flag); 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); @@ -105,6 +106,7 @@ public: uint64_t Sendmsg(int sockfd, const struct msghdr *msg, int flags); uint64_t Recvmsg(int sockfd, struct msghdr *msg, int flags); uint64_t Shutdown(int sockfd, int how); + uint64_t Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); uint64_t GetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); uint64_t GetPeerName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); uint64_t SetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); @@ -119,10 +121,14 @@ public: // MemFD uint64_t Memfd_Create(const char *name, uint32_t flags); + // Syslog + uint64_t Syslog(int type, char *bufp, int len); + int32_t FindHostFD(int fd); std::string *FindFDName(int fd); FD const* GetFDBacking(int fd); + int32_t DupFD(int prevFD); int32_t DupFD(int prevFD, int newFD); void SetFilename(std::string const &File) { Filename = File; } diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls.cpp index 331ba4db1..89b54dcc7 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls.cpp @@ -9,8 +9,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -113,6 +114,13 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) Args->Argument[3], Ret); break; + case SYSCALL_MADVISE: + LogMan::Msg::D("madvise(0x%lx, 0x%lx, 0x%lx) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Ret); + break; case SYSCALL_SHMGET: LogMan::Msg::D("shmget(0x%lx, 0x%lx, 0x%lx) = %ld", Args->Argument[1], @@ -134,6 +142,11 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) Args->Argument[3], Ret); break; + case SYSCALL_DUP: + LogMan::Msg::D("dup(0x%lx) = %ld", + Args->Argument[1], + Ret); + break; case SYSCALL_DUP2: LogMan::Msg::D("dup2(0x%lx, 0x%lx) = %ld", Args->Argument[1], @@ -166,6 +179,14 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_OPENAT: LogMan::Msg::D("openat(%ld, \"%s\", %d) = %ld", Args->Argument[1], GetPointer(Args->Argument[2]), Args->Argument[3], Ret); break; + case SYSCALL_NEWFSTATAT: + LogMan::Msg::D("newfstatat(%ld, \"%s\", %p, 0x%lx) = %ld", + Args->Argument[1], + GetPointer(Args->Argument[2]), + Args->Argument[3], + Args->Argument[4], + Ret); + break; case SYSCALL_READLINKAT: LogMan::Msg::D("readlinkat(\"%s\") = %ld", GetPointer(Args->Argument[2]), Ret); break; @@ -336,6 +357,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_SHUTDOWN: LogMan::Msg::D("shutdown(%ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Ret); break; + case SYSCALL_BIND: + LogMan::Msg::D("bind(%ld, %p, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], 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; @@ -369,9 +393,23 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) Args->Argument[5], Args->Argument[6]); break; + case SYSCALL_EXECVE: + LogMan::Msg::I("execve('%s', %p, %p) = %ld", + GetPointer(Args->Argument[1]), + Args->Argument[2], + Args->Argument[3], + Ret); + break; case SYSCALL_GETUID: LogMan::Msg::D("getuid() = %ld", Ret); break; + case SYSCALL_SYSLOG: + LogMan::Msg::D("syslog(%ld, %p, 0x%lx) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Ret); + break; case SYSCALL_GETGID: LogMan::Msg::D("getgid() = %ld", Ret); break; @@ -390,6 +428,9 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_SETRESUID: LogMan::Msg::D("setresuid(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; + case SYSCALL_GETRESUID: + LogMan::Msg::D("getresuid(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); + break; case SYSCALL_SETRESGID: LogMan::Msg::D("setresgid(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; @@ -413,6 +454,15 @@ void SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) case SYSCALL_TGKILL: LogMan::Msg::D("tgkill(%ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Ret); break; + case SYSCALL_GET_MEMPOLICY: + LogMan::Msg::D("get_mempolicy(%p, %p, %ld, %p, 0x%lx) = %ld", + Args->Argument[1], + Args->Argument[2], + Args->Argument[3], + Args->Argument[4], + Args->Argument[5], + Ret); + break; case SYSCALL_LSEEK: LogMan::Msg::D("lseek(%ld, %ld, %ld) = %ld", Args->Argument[1], Args->Argument[2], Args->Argument[3], Ret); break; @@ -519,7 +569,7 @@ void *SyscallHandler::GetPointerSizeCheck(uint64_t Offset, uint64_t Size) { uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) { uint64_t Result = 0; - std::scoped_lock lk(SyscallMutex); +// std::scoped_lock lk(SyscallMutex); switch (Args->Argument[0]) { case SYSCALL_UNAME: { @@ -653,7 +703,8 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa } case SYSCALL_PRCTL: { switch (Args->Argument[1]) { - case 0xF: // PR_SET_NAME + case 0x4: // PR_SET_DUMPABLE + case 0xF: // PR_SET_NAME case 0x10: // PR_GET_NAME Result = 0; break; @@ -722,6 +773,11 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa Result = FM.Shutdown(Args->Argument[1], Args->Argument[2]); break; + case SYSCALL_BIND: + Result = FM.Bind(Args->Argument[1], + GetPointer(Args->Argument[2]), + Args->Argument[3]); + break; case SYSCALL_GETSOCKNAME: Result = FM.GetSockName(Args->Argument[1], GetPointer(Args->Argument[2]), @@ -782,6 +838,18 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa // XXX: Not a real result Result = -1; break; + case SYSCALL_GETRESUID: { + uid_t *ruid = GetPointer(Args->Argument[1]); + uid_t *euid = GetPointer(Args->Argument[2]); + uid_t *suid = GetPointer(Args->Argument[3]); + + *ruid = Thread->State.ThreadManager.GetEUID(); + *euid = Thread->State.ThreadManager.GetEUID(); + *suid = Thread->State.ThreadManager.GetEUID(); + + Result = 0; + break; + } case SYSCALL_SETRESGID: // rgid, egid, sgid Result = 0; @@ -1010,6 +1078,15 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa Result = NewThread->State.ThreadManager.GetTID(); break; } + case SYSCALL_EXECVE: + // XXX: Disallow execve for now + Result = -ENOEXEC; + break; + case SYSCALL_SYSLOG: + Result = FM.Syslog(Args->Argument[1], + GetPointer(Args->Argument[2]), + Args->Argument[3]); + break; // File management case SYSCALL_READ: Result = FM.Read(Args->Argument[1], @@ -1057,6 +1134,16 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa CopyStat(guest_data, &host_stat); break; } + case SYSCALL_GET_MEMPOLICY: + Result = get_mempolicy( + GetPointer(Args->Argument[1]), + GetPointer(Args->Argument[2]), + Args->Argument[3], + GetPointer(Args->Argument[4]), + Args->Argument[4]); + if (Result == -1) + Result = -errno; + break; case SYSCALL_LSEEK: Result = FM.Lseek(Args->Argument[1], Args->Argument[2], @@ -1111,6 +1198,19 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa Args->Argument[3], Args->Argument[4]); break; + case SYSCALL_NEWFSTATAT: { + struct stat host_stat{}; + + guest_stat *guest_data = GetPointer(Args->Argument[2]); + Result = FM.NewFStatAt( + Args->Argument[1], + GetPointer(Args->Argument[2]), + &host_stat, + Args->Argument[4]); + + CopyStat(guest_data, &host_stat); + break; + } case SYSCALL_READLINKAT: Result = FM.Readlinkat( Args->Argument[1], @@ -1188,6 +1288,12 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa GetPointer(Args->Argument[3])); break; } + case SYSCALL_MADVISE: { + Result = madvise(GetPointer(Args->Argument[1]), + Args->Argument[2], + Args->Argument[3]); + break; + } case SYSCALL_SHMGET: { Result = shmget(Args->Argument[1], Args->Argument[2], @@ -1236,6 +1342,10 @@ uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::InternalThreadState *Threa } break; } + case SYSCALL_DUP: { + Result = FM.DupFD(Args->Argument[1]); + break; + } case SYSCALL_DUP2: { Result = FM.DupFD(Args->Argument[1], Args->Argument[2]); break; diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls.h b/External/FEXCore/Source/Interface/HLE/Syscalls.h index 5ea00b72e..1f36dee00 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls.h +++ b/External/FEXCore/Source/Interface/HLE/Syscalls.h @@ -40,9 +40,11 @@ enum Syscalls { SYSCALL_SCHED_YIELD = 24, ///< __NR_sched_yield SYSCALL_MREMAP = 25, ///< __NR_mremap SYSCALL_MINCORE = 27, ///< __NR_mincore + SYSCALL_MADVISE = 28, ///< __NR_madvise SYSCALL_SHMGET = 29, ///< __NR_shmget SYSCALL_SHMAT = 30, ///< __NR_shmat SYSCALL_SHMCTL = 31, ///< __NR_shmctl + SYSCALL_DUP = 32, ///< __NR_dup SYSCALL_DUP2 = 33, ///< __NR_dup2 SYSCALL_NANOSLEEP = 35, ///< __NR_nanosleep SYSCALL_GETITIMER = 36, ///< __NR_getitimer @@ -55,11 +57,13 @@ enum Syscalls { SYSCALL_SENDMSG = 46, ///< __NR_sendmsg SYSCALL_RECVMSG = 47, ///< __NR_recvmsg SYSCALL_SHUTDOWN = 48, ///< __NR_shutdown + SYSCALL_BIND = 49, ///< __NR_bind SYSCALL_GETSOCKNAME = 51, ///< __NR_getsockname SYSCALL_GETPEERNAME = 52, ///< __NR_getpeername SYSCALL_SETSOCKOPT = 54, ///< __NR_setsockopt SYSCALL_GETSOCKOPT = 55, ///< __NR_getsockopt SYSCALL_CLONE = 56, ///< __NR_clone + SYSCALL_EXECVE = 59, ///< __NR_execve SYSCALL_EXIT = 60, ///< __NR_exit SYSCALL_WAIT4 = 61, ///< __NR_wait4 SYSCALL_UNAME = 63, ///< __NR_uname @@ -76,12 +80,14 @@ enum Syscalls { SYSCALL_GETTIMEOFDAY = 96, ///< __NR_gettimeofday SYSCALL_SYSINFO = 99, ///< __NR_sysinfo SYSCALL_GETUID = 102, ///< __NR_getuid + SYSCALL_SYSLOG = 103, ///< __NR_syslog 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_GETRESUID = 118, ///< __NR_getresuid SYSCALL_SETRESGID = 119, ///< __NR_setresgid SYSCALL_SIGALTSTACK = 131, ///< __NR_sigaltstack SYSCALL_MKNOD = 133, ///< __NR_mknod @@ -102,7 +108,9 @@ enum Syscalls { SYSCALL_CLOCK_GETRES = 229, ///< __NR_clock_getres SYSCALL_EXIT_GROUP = 231, ///< __NR_exit_group SYSCALL_TGKILL = 234, ///< __NR_tgkill + SYSCALL_GET_MEMPOLICY = 239, ///< __NR_get_mempolicy SYSCALL_OPENAT = 257, ///< __NR_openat + SYSCALL_NEWFSTATAT = 262, ///< __NR_newfstatat SYSCALL_READLINKAT = 267, ///< __NR_readlinkat SYSCALL_FACCESSAT = 269, ///< __NR_faccessat SYSCALL_SET_ROBUST_LIST = 273, ///< __NR_set_robust_list