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.

This commit is contained in:
David Miller committed 2020-04-29 16:00:59 -04:00
1 parent f3f63251ea
commit 306cca33d7
7 files changed
+59 -4

No files matched your search

@@ -1,9 +1,13 @@
#include <filesystem>
#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<FEX::HarnessHelper::ELFCodeLoader *const>(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;
}
}
@@ -24,5 +24,7 @@ namespace FEXCore::EmulatedFile {
using FDReadStringFunc = std::function<int32_t(FEXCore::Context::Context *ctx, int32_t fd, const char *pathname, int32_t flags, mode_t mode)>;
std::unordered_set<std::string> EmulatedMap;
std::unordered_map<std::string, FDReadStringFunc> FDReadCreators;
static int32_t ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode);
};
}
+5
View File
@@ -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();
+1
View File
@@ -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);
@@ -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},
+1
View File
@@ -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
+10 -2
View File
@@ -16,7 +16,7 @@
#include <FEXCore/Core/X86Enums.h>
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<char> *Data) {
inline void ReadFile(std::string const &Filename, std::vector<char> *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<char const*> *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<auxv_t> AuxVariables;
uint64_t AuxTabBase, AuxTabSize;
uint64_t ArgumentBackingSize{};
uint64_t EnvironmentBackingSize{};
uint64_t MemoryBase{};