diff --git a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp index 21080ae79..6f26b38aa 100644 --- a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp +++ b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp @@ -1,11 +1,16 @@ +#include +#include #include "LogManager.h" +#include "FEXCore/Core/CodeLoader.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"( + static const string proc_cpuinfo = R"( processor : 0 vendor_id : AuthenticAMD cpu family : 23 @@ -34,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 )"; @@ -57,17 +62,44 @@ 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); + 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()) { + 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) + { + uint64_t auxvBase=0, auxvSize=0; + ctx->GetCodeLoader()->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 a54246a4a..ea96636c4 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 f92391499..9a3dd1df2 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 f445722bc..977cecece 100644 --- a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp +++ b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp @@ -870,6 +870,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 f1742b8e3..5d1d37765 100644 --- a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.h +++ b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.h @@ -177,6 +177,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/External/FEXCore/include/FEXCore/Core/CodeLoader.h b/External/FEXCore/include/FEXCore/Core/CodeLoader.h index dd0b5b21d..d024bdf28 100644 --- a/External/FEXCore/include/FEXCore/Core/CodeLoader.h +++ b/External/FEXCore/include/FEXCore/Core/CodeLoader.h @@ -72,6 +72,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 278aaa978..df3ead7e7 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"); @@ -558,6 +558,9 @@ public: } } + *(uint64_t*)(&AuxTabBase) = uint64_t(AuxVPointers); + *(uint64_t*)(&AuxTabSize) = sizeof(auxv_t) * AuxVariables.size(); + return rsp; } @@ -595,6 +598,10 @@ public: void GetExecveArguments(std::vector *Args) override { *Args = LoaderArgs; } + void GetAuxv(uint64_t& addr, uint64_t& size) override { + addr = AuxTabBase; + size = AuxTabSize; + } private: ::ELFLoader::ELFContainer File; ::ELFLoader::ELFSymbolDatabase DB; @@ -606,6 +613,7 @@ private: uint64_t val; }; std::vector AuxVariables; + uint64_t AuxTabBase, AuxTabSize; uint64_t ArgumentBackingSize{}; uint64_t EnvironmentBackingSize{}; uint64_t MemoryBase{};