From 306cca33d7cf636af9b75ebc021ead91ce89f296 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 29 Apr 2020 16:00:59 -0400 Subject: [PATCH 1/3] Added dup3 syscall, EmulatedFiles : /proc/{self,$PID}/auxv, modified OpenAt() to normalize path to canonical if possible or lexically_normal. Note: canonical will change symlinks, ensure the map keys take this into account. --- .../HLE/EmulatedFiles/EmulatedFiles.cpp | 41 ++++++++++++++++++- .../HLE/EmulatedFiles/EmulatedFiles.h | 2 + .../Source/Interface/HLE/Syscalls/FD.cpp | 5 +++ .../Source/Interface/HLE/Syscalls/FD.h | 1 + .../Source/Interface/HLE/x64/Syscalls.cpp | 1 + .../Source/Interface/HLE/x64/Syscalls.h | 1 + Source/Tests/HarnessHelpers.h | 12 +++++- 7 files changed, 59 insertions(+), 4 deletions(-) diff --git a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp index 21080ae79..2e4127682 100644 --- a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp +++ b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp @@ -1,9 +1,13 @@ +#include #include "LogManager.h" +#include "Tests/HarnessHelpers.h" #include "Interface/Context/Context.h" #include "Interface/HLE/FileManagement.h" #include "Interface/HLE/EmulatedFiles/EmulatedFiles.h" +using string = std::string; + namespace FEXCore::EmulatedFile { static const std::string proc_cpuinfo = R"( processor : 0 @@ -57,17 +61,50 @@ address sizes : 43 bits physical, 48 bits virtual int32_t f = fileno(fp); return f; }; + + string procAuxv = string("/proc/") + std::to_string(getpid()) + string("/auxv"); + EmulatedMap.emplace(procAuxv); // * get pid /proc/$PID/auxv , self is a symlink albeit likely to be what's used + EmulatedMap.emplace("/proc/self/auxv"); + + FDReadCreators[procAuxv] = &EmulatedFDManager::ProcAuxv; + FDReadCreators["/proc/self/auxv"] = &EmulatedFDManager::ProcAuxv; } EmulatedFDManager::~EmulatedFDManager() { } int32_t EmulatedFDManager::OpenAt(int dirfs, const char *pathname, int flags, uint32_t mode) { - if (EmulatedMap.find(pathname) == EmulatedMap.end()) { + std::string cpath = std::filesystem::exists(pathname) ? std::filesystem::canonical(pathname) + : std::filesystem::path(pathname).lexically_normal(); // *Note: this doesn't transform to absolute + + if (EmulatedMap.find(cpath) == EmulatedMap.end()) { return -1; } - return FDReadCreators[pathname](CTX, dirfs, pathname, flags, mode); + return FDReadCreators[cpath](CTX, dirfs, pathname, flags, mode); } + + int32_t EmulatedFDManager::ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode) + { + FEX::HarnessHelper::ELFCodeLoader *const elfLoader = dynamic_cast(ctx->GetCodeLoader()); + if (!elfLoader) { + LogMan::Msg::D("Failed to get ELFCodeLoader"); + return -1; + } + + uint64_t auxvBase=0, auxvSize=0; + elfLoader->GetAuxv(auxvBase, auxvSize); + if (!auxvBase) { + LogMan::Msg::D("Failed to get Auxv stack address"); + return -1; + } + + FILE* fp = tmpfile(); + fwrite((void*)auxvBase, 1, auxvSize, fp); + fseek(fp, 0, SEEK_SET); + int32_t f = fileno(fp); + return f; + } + } diff --git a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.h b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.h index e18dbb38b..445f35345 100644 --- a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.h +++ b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.h @@ -24,5 +24,7 @@ namespace FEXCore::EmulatedFile { using FDReadStringFunc = std::function; std::unordered_set EmulatedMap; std::unordered_map FDReadCreators; + + static int32_t ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode); }; } diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls/FD.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls/FD.cpp index cc843d66a..ec2bc4615 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls/FD.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls/FD.cpp @@ -140,6 +140,11 @@ namespace FEXCore::HLE { SYSCALL_ERRNO(); } + uint64_t Dup3(FEXCore::Core::InternalThreadState* Thread, int oldfd, int newfd, int flags) { + uint64_t Result = ::dup3(oldfd, newfd, flags); + SYSCALL_ERRNO(); + } + uint64_t Fcntl(FEXCore::Core::InternalThreadState *Thread, int fd, int cmd, uint64_t arg) { uint64_t Result = ::fcntl(fd, cmd, arg); SYSCALL_ERRNO(); diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls/FD.h b/External/FEXCore/Source/Interface/HLE/Syscalls/FD.h index a3fbd36f6..866a55a36 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls/FD.h +++ b/External/FEXCore/Source/Interface/HLE/Syscalls/FD.h @@ -31,6 +31,7 @@ namespace FEXCore::HLE { uint64_t Select(FEXCore::Core::InternalThreadState *Thread, int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); uint64_t Dup(FEXCore::Core::InternalThreadState *Thread, int oldfd); uint64_t Dup2(FEXCore::Core::InternalThreadState *Thread, int oldfd, int newfd); + uint64_t Dup3(FEXCore::Core::InternalThreadState* Thread, int oldfd, int newfd, int flags); uint64_t Fcntl(FEXCore::Core::InternalThreadState *Thread, int fd, int cmd, uint64_t arg); uint64_t Flock(FEXCore::Core::InternalThreadState *Thread, int fd, int operation); uint64_t Fsync(FEXCore::Core::InternalThreadState *Thread, int fd); diff --git a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp index 0e0275b96..6a885194a 100644 --- a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp +++ b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp @@ -833,6 +833,7 @@ void x64SyscallHandler::RegisterSyscallHandlers() { {SYSCALL_TIMERFD_CREATE, cvt(&FEXCore::HLE::Timerfd_Create), 2}, {SYSCALL_EVENTFD, cvt(&FEXCore::HLE::Eventfd), 2}, {SYSCALL_EPOLL_CREATE1, cvt(&FEXCore::HLE::EPoll_Create1), 1}, + {SYSCALL_DUP3, cvt(&FEXCore::HLE::Dup3), 3}, {SYSCALL_PIPE2, cvt(&FEXCore::HLE::Pipe2), 2}, {SYSCALL_INOTIFY_INIT1, cvt(&FEXCore::HLE::Inotify_init1), 1}, {SYSCALL_PRLIMIT64, cvt(&FEXCore::HLE::Prlimit64), 4}, diff --git a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.h b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.h index d41bb6d21..a0c7fa3d1 100644 --- a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.h +++ b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.h @@ -170,6 +170,7 @@ enum Syscalls { SYSCALL_TIMERFD_CREATE = 283, ///< __NR_timerfd_create SYSCALL_EVENTFD = 290, ///< __NR_eventfd SYSCALL_EPOLL_CREATE1 = 291, ///< __NR_epoll_create1 + SYSCALL_DUP3 = 292, ///< __NR_dup3 SYSCALL_PIPE2 = 293, ///< __NR_pipe2 SYSCALL_INOTIFY_INIT1 = 294, ///< __NR_inotify_init1 SYSCALL_PRLIMIT64 = 302, ///< __NR_prlimit64 diff --git a/Source/Tests/HarnessHelpers.h b/Source/Tests/HarnessHelpers.h index add9308d3..fe01293d4 100644 --- a/Source/Tests/HarnessHelpers.h +++ b/Source/Tests/HarnessHelpers.h @@ -16,7 +16,7 @@ #include namespace FEX::HarnessHelper { - bool CompareStates(FEXCore::Core::CPUState const& State1, + inline bool CompareStates(FEXCore::Core::CPUState const& State1, FEXCore::Core::CPUState const& State2, uint64_t MatchMask, bool OutputGPRs) { @@ -126,7 +126,7 @@ namespace FEX::HarnessHelper { return Matches; } - void ReadFile(std::string const &Filename, std::vector *Data) { + inline void ReadFile(std::string const &Filename, std::vector *Data) { std::fstream TestFile; TestFile.open(Filename, std::fstream::in | std::fstream::binary); LogMan::Throw::A(TestFile.is_open(), "Failed to open file"); @@ -559,6 +559,9 @@ public: } } + *(uint64_t*)(&AuxTabBase) = uint64_t(AuxVPointers); + *(uint64_t*)(&AuxTabSize) = sizeof(auxv_t) * AuxVariables.size(); + return rsp; } @@ -597,6 +600,10 @@ public: void GetExecveArguments(std::vector *Args) override { *Args = LoaderArgs; } + void GetAuxv(uint64_t& addr, uint64_t& size) { + addr = AuxTabBase; + size = AuxTabSize; + } private: ::ELFLoader::ELFContainer File; ::ELFLoader::ELFSymbolDatabase DB; @@ -608,6 +615,7 @@ private: uint64_t val; }; std::vector AuxVariables; + uint64_t AuxTabBase, AuxTabSize; uint64_t ArgumentBackingSize{}; uint64_t EnvironmentBackingSize{}; uint64_t MemoryBase{}; From f916294772665c8ca89e0b1309abfa30ad5cd2dd Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 29 Apr 2020 16:04:39 -0400 Subject: [PATCH 2/3] Include unistd.h in EmulatedFiles.cpp as CI doesn't build --- .../FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp index 2e4127682..fc250d0e0 100644 --- a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp +++ b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp @@ -1,4 +1,5 @@ #include +#include #include "LogManager.h" #include "Tests/HarnessHelpers.h" From 09f119a3ce4fdfd56f87b7572d648e8bf1b162db Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 29 Apr 2020 16:39:40 -0400 Subject: [PATCH 3/3] removed front end header / class from EmulatedFiles.cpp --- .../HLE/EmulatedFiles/EmulatedFiles.cpp | 18 ++++++------------ .../FEXCore/include/FEXCore/Core/CodeLoader.h | 2 ++ Source/Tests/HarnessHelpers.h | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp index fc250d0e0..6f26b38aa 100644 --- a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp +++ b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp @@ -1,7 +1,7 @@ #include #include #include "LogManager.h" -#include "Tests/HarnessHelpers.h" +#include "FEXCore/Core/CodeLoader.h" #include "Interface/Context/Context.h" #include "Interface/HLE/FileManagement.h" @@ -10,7 +10,7 @@ using string = std::string; namespace FEXCore::EmulatedFile { - static const std::string proc_cpuinfo = R"( + static const string proc_cpuinfo = R"( processor : 0 vendor_id : AuthenticAMD cpu family : 23 @@ -39,7 +39,7 @@ cache_alignment : 64 address sizes : 43 bits physical, 48 bits virtual )"; - static const std::string cpus_online = R"( + static const string cpus_online = R"( 0 )"; @@ -64,7 +64,7 @@ address sizes : 43 bits physical, 48 bits virtual }; string procAuxv = string("/proc/") + std::to_string(getpid()) + string("/auxv"); - EmulatedMap.emplace(procAuxv); // * get pid /proc/$PID/auxv , self is a symlink albeit likely to be what's used + EmulatedMap.emplace(procAuxv); EmulatedMap.emplace("/proc/self/auxv"); FDReadCreators[procAuxv] = &EmulatedFDManager::ProcAuxv; @@ -75,7 +75,7 @@ address sizes : 43 bits physical, 48 bits virtual } int32_t EmulatedFDManager::OpenAt(int dirfs, const char *pathname, int flags, uint32_t mode) { - std::string cpath = std::filesystem::exists(pathname) ? std::filesystem::canonical(pathname) + string cpath = std::filesystem::exists(pathname) ? std::filesystem::canonical(pathname) : std::filesystem::path(pathname).lexically_normal(); // *Note: this doesn't transform to absolute if (EmulatedMap.find(cpath) == EmulatedMap.end()) { @@ -87,14 +87,8 @@ address sizes : 43 bits physical, 48 bits virtual int32_t EmulatedFDManager::ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode) { - FEX::HarnessHelper::ELFCodeLoader *const elfLoader = dynamic_cast(ctx->GetCodeLoader()); - if (!elfLoader) { - LogMan::Msg::D("Failed to get ELFCodeLoader"); - return -1; - } - uint64_t auxvBase=0, auxvSize=0; - elfLoader->GetAuxv(auxvBase, auxvSize); + ctx->GetCodeLoader()->GetAuxv(auxvBase, auxvSize); if (!auxvBase) { LogMan::Msg::D("Failed to get Auxv stack address"); return -1; diff --git a/External/FEXCore/include/FEXCore/Core/CodeLoader.h b/External/FEXCore/include/FEXCore/Core/CodeLoader.h index 172a0d694..8b98f5fbc 100644 --- a/External/FEXCore/include/FEXCore/Core/CodeLoader.h +++ b/External/FEXCore/include/FEXCore/Core/CodeLoader.h @@ -82,6 +82,8 @@ public: virtual char const *FindSymbolNameInRange(uint64_t Address) { return nullptr; } virtual void GetExecveArguments(std::vector *Args) {} + + virtual void GetAuxv(uint64_t& addr, uint64_t& size) {} }; diff --git a/Source/Tests/HarnessHelpers.h b/Source/Tests/HarnessHelpers.h index fe01293d4..dd4b6bbfd 100644 --- a/Source/Tests/HarnessHelpers.h +++ b/Source/Tests/HarnessHelpers.h @@ -600,7 +600,7 @@ public: void GetExecveArguments(std::vector *Args) override { *Args = LoaderArgs; } - void GetAuxv(uint64_t& addr, uint64_t& size) { + void GetAuxv(uint64_t& addr, uint64_t& size) override { addr = AuxTabBase; size = AuxTabSize; }