mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-23 05:00:48 +02:00
Merge pull request #827 from FEX-Emu/skmp/thunks-json
Thunks: Add Thunk json, thunk guest folder
This commit is contained in:
commit
e9afabc4cb
7 files changed
+166
-22
No files matched your search
+1
-1
@@ -82,7 +82,7 @@ namespace FEXCore::Context {
|
||||
FEX_CONFIG_OPT(Core, DEFAULTCORE);
|
||||
FEX_CONFIG_OPT(MaxInstPerBlock, MAXBLOCKINST);
|
||||
FEX_CONFIG_OPT(RootFSPath, ROOTFSPATH);
|
||||
FEX_CONFIG_OPT(ThunkLibsPath, THUNKLIBSPATH);
|
||||
FEX_CONFIG_OPT(ThunkHostLibsPath, THUNKHOSTLIBSPATH);
|
||||
FEX_CONFIG_OPT(DumpIR, DUMPIR);
|
||||
} Config;
|
||||
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ namespace FEXCore {
|
||||
auto Name = Args->Name;
|
||||
auto CallbackThunks = Args->CallbackThunks;
|
||||
|
||||
auto SOName = CTX->Config.ThunkLibsPath() + "/" + (const char*)Name + "-host.so";
|
||||
auto SOName = CTX->Config.ThunkHostLibsPath() + "/" + (const char*)Name + "-host.so";
|
||||
|
||||
LogMan::Msg::D("Load lib: %s -> %s", Name, SOName.c_str());
|
||||
|
||||
|
||||
@@ -36,8 +36,9 @@ OPT_INT32 (CPU, MAXBLOCKINST, MaxInst, MAXINST, 5000)
|
||||
OPT_INT32 (CPU, EMULATED_CPU_CORES, Threads, THREADS, 1)
|
||||
|
||||
OPT_STR (EMULATION, ROOTFSPATH, RootFS, ROOTFS, "")
|
||||
OPT_STR (EMULATION, THUNKLIBSPATH, ThunkLibs, THUNKLIBS, "")
|
||||
OPT_STR (EMULATION, THUNKSCONFIGPATH, ThunksConfigPath, THUNKSCONFIGPATH, "")
|
||||
OPT_STR (EMULATION, THUNKHOSTLIBSPATH, ThunkHostLibs, THUNKHOSTLIBS, "")
|
||||
OPT_STR (EMULATION, THUNKGUESTLIBSPATH, ThunkGuestLibs, THUNKGUESTLIBS, "")
|
||||
OPT_STR (EMULATION, THUNKCONFIGPATH, ThunkConfig, THUNKCONFIG, "")
|
||||
|
||||
OPT_STR (EMULATION, ENVIRONMENT, Env, ENV, "")
|
||||
|
||||
|
||||
@@ -94,16 +94,26 @@ namespace FEX::ArgLoader {
|
||||
}
|
||||
{
|
||||
Parser.set_defaults("RootFS", "");
|
||||
Parser.set_defaults("ThunkLibs", "");
|
||||
Parser.set_defaults("ThunkHostLibs", "");
|
||||
Parser.set_defaults("ThunkGuestLibs", "");
|
||||
Parser.set_defaults("ThunkConfig", "");
|
||||
|
||||
EmulationGroup.add_option("-R", "--rootfs")
|
||||
.dest("RootFS")
|
||||
.help("Which Root filesystem prefix to use");
|
||||
|
||||
EmulationGroup.add_option("-t", "--thunklibs")
|
||||
.dest("ThunkLibs")
|
||||
EmulationGroup.add_option("-t", "--thunkhostlibs")
|
||||
.dest("ThunkHostLibs")
|
||||
.help("Folder to find the host-side thunking libs");
|
||||
|
||||
EmulationGroup.add_option("-j", "--thunkguestlibs")
|
||||
.dest("ThunkGuestLibs")
|
||||
.help("Folder to find the guest-side thunking libs");
|
||||
|
||||
EmulationGroup.add_option("-k", "--thunkconfig")
|
||||
.dest("ThunkConfig")
|
||||
.help("A json file specifying where to overlay the thunks");
|
||||
|
||||
EmulationGroup.add_option("-E", "--env")
|
||||
.dest("Env")
|
||||
.help("Adds an environment variable")
|
||||
@@ -248,9 +258,19 @@ namespace FEX::ArgLoader {
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_ROOTFSPATH, Option);
|
||||
}
|
||||
|
||||
if (Options.is_set_by_user("ThunkLibs")) {
|
||||
std::string Option = Options["ThunkLibs"];
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_THUNKLIBSPATH, Option);
|
||||
if (Options.is_set_by_user("ThunkHostLibs")) {
|
||||
std::string Option = Options["ThunkHostLibs"];
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_THUNKHOSTLIBSPATH, Option);
|
||||
}
|
||||
|
||||
if (Options.is_set_by_user("ThunkGuestLibs")) {
|
||||
std::string Option = Options["ThunkGuestLibs"];
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_THUNKGUESTLIBSPATH, Option);
|
||||
}
|
||||
|
||||
if (Options.is_set_by_user("ThunkConfig")) {
|
||||
std::string Option = Options["ThunkConfig"];
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_THUNKCONFIGPATH, Option);
|
||||
}
|
||||
|
||||
if (Options.is_set_by_user("Env")) {
|
||||
|
||||
@@ -15,18 +15,109 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <tiny-json.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
namespace FEX::HLE {
|
||||
|
||||
static bool LoadFile(std::vector<char> &Data, const std::string &Filename) {
|
||||
std::fstream File;
|
||||
File.open(Filename, std::ios::in);
|
||||
|
||||
if (!File.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.seekg(0, std::fstream::end)) {
|
||||
LogMan::Msg::D("Couldn't load configuration file: Seek end");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto FileSize = File.tellg();
|
||||
if (File.fail()) {
|
||||
LogMan::Msg::D("Couldn't load configuration file: tellg");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.seekg(0, std::fstream::beg)) {
|
||||
LogMan::Msg::D("Couldn't load configuration file: Seek beginning");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FileSize > 0) {
|
||||
Data.resize(FileSize);
|
||||
if (!File.read(&Data.at(0), FileSize)) {
|
||||
// Probably means permissions aren't set. Just early exit
|
||||
return false;
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FileManager::FileManager(FEXCore::Context::Context *ctx)
|
||||
: EmuFD {ctx} {
|
||||
// calculate the non-self link to exe
|
||||
// Some executables do getpid, stat("/proc/$pid/exe")
|
||||
int pid = getpid();
|
||||
// calculate the non-self link to exe
|
||||
// Some executables do getpid, stat("/proc/$pid/exe")
|
||||
int pid = getpid();
|
||||
|
||||
char buf[50];
|
||||
snprintf(buf, 50, "/proc/%i/exe", pid);
|
||||
char buf[50];
|
||||
snprintf(buf, 50, "/proc/%i/exe", pid);
|
||||
|
||||
PidSelfPath = std::string(buf);
|
||||
PidSelfPath = std::string(buf);
|
||||
|
||||
|
||||
auto ThunkConfigFile = ThunkConfig();
|
||||
|
||||
if (ThunkConfigFile.size()) {
|
||||
|
||||
auto ThunkGuestPath = std::filesystem::path(ThunkGuestLibs());
|
||||
|
||||
std::vector<char> FileData;
|
||||
if (LoadFile(FileData, ThunkConfigFile)) {
|
||||
FileData.push_back(0);
|
||||
|
||||
json_t mem[128];
|
||||
json_t const* json = json_create( &FileData.at(0), mem, sizeof mem / sizeof *mem );
|
||||
|
||||
json_t const* thunks = json_getProperty( json, "thunks" );
|
||||
if ( !thunks || JSON_OBJ != json_getType( thunks ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
json_t const* thunk;
|
||||
for( thunk = json_getChild( thunks ); thunk != 0; thunk = json_getSibling( thunk )) {
|
||||
char const* GuestThunk = json_getName( thunk );
|
||||
jsonType_t propertyType = json_getType( thunk );
|
||||
|
||||
if (propertyType == JSON_TEXT) {
|
||||
char const* RootFSLib = json_getValue( thunk );
|
||||
ThunkOverlays.emplace(RootFSLib, ThunkGuestPath / GuestThunk);
|
||||
} else if (propertyType == JSON_ARRAY) {
|
||||
json_t const* child;
|
||||
for( child = json_getChild( thunk ); child != 0; child = json_getSibling( child ) ) {
|
||||
if (json_getType( child ) == JSON_TEXT) {
|
||||
char const* RootFSLib = json_getValue( child );
|
||||
ThunkOverlays.emplace(RootFSLib, ThunkGuestPath / GuestThunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ThunkOverlays.size()) {
|
||||
LogMan::Msg::I("Thunk Overlays:");
|
||||
for (auto &Thunk: ThunkOverlays) {
|
||||
LogMan::Msg::I("\t%s -> %s", Thunk.first.c_str(), Thunk.second.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileManager::~FileManager() {
|
||||
@@ -40,6 +131,11 @@ std::string FileManager::GetEmulatedPath(const char *pathname) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto thunkOverlay = ThunkOverlays.find(pathname);
|
||||
if (thunkOverlay != ThunkOverlays.end()) {
|
||||
return thunkOverlay->second;
|
||||
}
|
||||
|
||||
return RootFSPath + pathname;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <poll.h>
|
||||
#include <map>
|
||||
|
||||
#include "Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h"
|
||||
|
||||
@@ -49,8 +50,12 @@ private:
|
||||
std::unordered_map<int32_t, std::string> FDToNameMap;
|
||||
std::string PidSelfPath;
|
||||
std::string GetEmulatedPath(const char *pathname);
|
||||
std::map<std::string, std::string> ThunkOverlays;
|
||||
|
||||
FEX_CONFIG_OPT(Filename, APP_FILENAME);
|
||||
FEX_CONFIG_OPT(LDPath, ROOTFSPATH);
|
||||
FEX_CONFIG_OPT(ThunkHostLibs, THUNKHOSTLIBSPATH);
|
||||
FEX_CONFIG_OPT(ThunkGuestLibs, THUNKGUESTLIBSPATH);
|
||||
FEX_CONFIG_OPT(ThunkConfig, THUNKCONFIGPATH);
|
||||
};
|
||||
}
|
||||
@@ -63,7 +63,9 @@ namespace {
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_GDBSERVER, "0");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_EMULATED_CPU_CORES, "1");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_ROOTFSPATH, "");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_THUNKLIBSPATH, "");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_THUNKHOSTLIBSPATH, "");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_THUNKGUESTLIBSPATH, "");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_THUNKCONFIGPATH, "");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_SILENTLOGS, "0");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_ENVIRONMENT, "GALLIUM_THREAD=1");
|
||||
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_ENVIRONMENT, "GALLIUM_HUD=fps");
|
||||
@@ -198,7 +200,9 @@ namespace {
|
||||
|
||||
void FillEmulationConfig() {
|
||||
char RootFS[256]{};
|
||||
char ThunkPath[256]{};
|
||||
char ThunkHostPath[256]{};
|
||||
char ThunkGuestPath[256]{};
|
||||
char ThunkConfigPath[256]{};
|
||||
|
||||
int NumEnvironmentVariables{};
|
||||
|
||||
@@ -212,12 +216,30 @@ namespace {
|
||||
ConfigChanged = true;
|
||||
}
|
||||
|
||||
Value = LoadedConfig->Get(FEXCore::Config::ConfigOption::CONFIG_THUNKLIBSPATH);
|
||||
Value = LoadedConfig->Get(FEXCore::Config::ConfigOption::CONFIG_THUNKHOSTLIBSPATH);
|
||||
if (Value.has_value() && !(*Value)->empty()) {
|
||||
strncpy(ThunkPath, &(*Value)->at(0), 256);
|
||||
strncpy(ThunkHostPath, &(*Value)->at(0), 256);
|
||||
}
|
||||
if (ImGui::InputText("Thunk library folder:", ThunkPath, 256, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_THUNKLIBSPATH, ThunkPath);
|
||||
if (ImGui::InputText("Thunk Host library folder:", ThunkHostPath, 256, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_THUNKHOSTLIBSPATH, ThunkHostPath);
|
||||
ConfigChanged = true;
|
||||
}
|
||||
|
||||
Value = LoadedConfig->Get(FEXCore::Config::ConfigOption::CONFIG_THUNKGUESTLIBSPATH);
|
||||
if (Value.has_value() && !(*Value)->empty()) {
|
||||
strncpy(ThunkGuestPath, &(*Value)->at(0), 256);
|
||||
}
|
||||
if (ImGui::InputText("Thunk Guest library folder:", ThunkGuestPath, 256, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_THUNKGUESTLIBSPATH, ThunkGuestPath);
|
||||
ConfigChanged = true;
|
||||
}
|
||||
|
||||
Value = LoadedConfig->Get(FEXCore::Config::ConfigOption::CONFIG_THUNKCONFIGPATH);
|
||||
if (Value.has_value() && !(*Value)->empty()) {
|
||||
strncpy(ThunkConfigPath, &(*Value)->at(0), 256);
|
||||
}
|
||||
if (ImGui::InputText("Thunk Config file:", ThunkConfigPath, 256, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_THUNKCONFIGPATH, ThunkConfigPath);
|
||||
ConfigChanged = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user