mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 09:00:40 +02:00
Merge pull request #170 from dmiller423/procfs_auxv
Added dup3 syscall, EmulatedFiles : /proc/{self,$PID}/auxv, modified …
This commit is contained in:
8 files changed
+58
-6
No files matched your search
@@ -1,11 +1,16 @@
|
||||
#include <filesystem>
|
||||
#include <unistd.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
|
||||
virtual char const *FindSymbolNameInRange(uint64_t Address) { return nullptr; }
|
||||
virtual void GetExecveArguments(std::vector<char const*> *Args) {}
|
||||
|
||||
virtual void GetAuxv(uint64_t& addr, uint64_t& size) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
@@ -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<char const*> *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<auxv_t> AuxVariables;
|
||||
uint64_t AuxTabBase, AuxTabSize;
|
||||
uint64_t ArgumentBackingSize{};
|
||||
uint64_t EnvironmentBackingSize{};
|
||||
uint64_t MemoryBase{};
|
||||
|
||||
Reference in new issue
Block a user