FEXInterpreter: Remove FEXLoader

Doesn't /quite/ remove the ArgumentLoader because it is intertwined with
LinuxEmulation in an annoying way that will take another step to remove.
This commit is contained in:
Ryan Houdek committed 2025-09-12 10:24:58 -07:00
1 parent 997d041a84
commit 7273041314
17 files changed
+51 -309

No files matched your search

+1 -160
View File
@@ -118,41 +118,6 @@ def print_man_env_option(name, desc, default, no_json_key):
output_man.write("\\fBdefault:\\fR {0}\n".format(default))
output_man.write(".Pp\n\n")
def print_man_options(options):
output_man.write(".Sh OPTIONS\n")
output_man.write(".Bl -tag -width -indent\n")
for op_group, group_vals in options.items():
for op_key, op_vals in group_vals.items():
short = None
long = op_key.lower()
if ("ShortArg" in op_vals):
short = op_vals["ShortArg"]
default = op_vals["Default"]
value_type = op_vals["Type"]
# Textual default rather than enum based
if ("TextDefault" in op_vals):
default = op_vals["TextDefault"]
if (value_type == "str" or value_type == "strarray" or value_type == "strenum"):
# Wrap the string argument in quotes
default = "'" + default + "'"
print_man_option(
short,
long,
op_vals["Desc"],
default
)
if (value_type == "strenum"):
Enums = op_vals["Enums"]
output_man.write("\\fBAvailable Options:\\fR\n")
output_man.write(", ".join(f"{enum_op_val}" for [_, enum_op_val] in Enums.items()))
output_man.write("\n.sp\n")
output_man.write(".El\n")
def print_man_environment(options):
output_man.write(".Sh ENVIRONMENT\n")
output_man.write(".Bl -tag -width -indent\n")
@@ -240,20 +205,12 @@ def print_man_header():
.Dt FEX
.Os Linux
.Sh NAME
.Nm FEXLoader
.Nm FEXInterpreter
.Nm FEXBash
.Nd Fast x86-64 and x86 emulation.
.Sh SYNOPSIS
.Nm
.Op options
.Op Ar --
.Ar Application
<args> ...
.Pp
.Nm FEXInterpreter
.Ar Application
<args> ...
.Ar <args> ...
.Pp
.Nm FEXBash
.Ar <args> ...
@@ -361,82 +318,6 @@ def print_config_option(type, group_name, json_name, default_value, short, choic
output_argloader.write("\n");
def print_argloader_options(options):
output_argloader.write("#ifdef BEFORE_PARSE\n")
output_argloader.write("#undef BEFORE_PARSE\n")
for op_group, group_vals in options.items():
for op_key, op_vals in group_vals.items():
default = op_vals["Default"]
if (op_vals["Type"] == "str" or op_vals["Type"] == "strarray" or op_vals["Type"] == "strenum"):
# Wrap the string argument in quotes
default = "\"" + default + "\""
# Textual default rather than enum based
if ("TextDefault" in op_vals):
default = "\"" + op_vals["TextDefault"] + "\""
short = None
choices = None
if ("ShortArg" in op_vals):
short = op_vals["ShortArg"]
if ("Choices" in op_vals):
choices = op_vals["Choices"]
print_config_option(
op_vals["Type"],
op_group,
op_key,
default,
short,
choices,
op_vals["Desc"])
output_argloader.write("\n")
output_argloader.write("#endif\n")
def print_parse_argloader_options(options):
output_argloader.write("#ifdef AFTER_PARSE\n")
output_argloader.write("#undef AFTER_PARSE\n")
for op_group, group_vals in options.items():
for op_key, op_vals in group_vals.items():
output_argloader.write("if (Options.is_set_by_user(\"{0}\")) {{\n".format(op_key))
value_type = op_vals["Type"]
NeedsString = False
conversion_func = "fextl::fmt::format(\"{}\", "
if ("ArgumentHandler" in op_vals):
NeedsString = True
conversion_func = "FEXCore::Config::Handler::{0}(".format(op_vals["ArgumentHandler"])
if (value_type == "str"):
NeedsString = True
conversion_func = "std::move("
if (value_type == "bool"):
# boolean values need a decimal specifier. Otherwise fmt prints strings.
conversion_func = "fextl::fmt::format(\"{:d}\", "
if (value_type == "strenum"):
output_argloader.write("\tfextl::string UserValue = Options[\"{0}\"];\n".format(op_key))
output_argloader.write("\tSet(FEXCore::Config::ConfigOption::CONFIG_{}, FEXCore::Config::EnumParser<FEXCore::Config::{}ConfigPair>(FEXCore::Config::{}_EnumPairs, UserValue));\n".format(op_key.upper(), op_key, op_key))
elif (value_type == "strarray"):
# these need a bit more help
output_argloader.write("\tauto Array = Options.all(\"{0}\");\n".format(op_key))
output_argloader.write("\tfor (auto iter = Array.begin(); iter != Array.end(); ++iter) {\n")
output_argloader.write("\t\tAppendStrArrayValue(FEXCore::Config::ConfigOption::CONFIG_{0}, *iter);\n".format(op_key.upper()))
output_argloader.write("\t}\n")
else:
if (NeedsString):
output_argloader.write("\tfextl::string UserValue = Options[\"{0}\"];\n".format(op_key))
else:
output_argloader.write("\t{0} UserValue = Options.get(\"{1}\");\n".format(value_type, op_key))
output_argloader.write("\tSet(FEXCore::Config::ConfigOption::CONFIG_{0}, {1}UserValue));\n".format(op_key.upper(), conversion_func))
output_argloader.write("}\n")
output_argloader.write("#endif\n")
def print_parse_envloader_options(options):
output_argloader.write("#ifdef ENVLOADER\n")
output_argloader.write("#undef ENVLOADER\n")
@@ -517,41 +398,6 @@ def print_parse_enum_options(options):
output_argloader.write("#endif\n")
def check_for_duplicate_options(options):
short_map = []
long_map = []
# Spin through all the items and see if we have a duplicate option
for op_group, group_vals in options.items():
for op_key, op_vals in group_vals.items():
short = None
long = op_key.lower()
long_invert = None
if ("ShortArg" in op_vals):
short = op_vals["ShortArg"]
if (op_vals["Type"] == "bool"):
long_invert = "no-" + long
# Check for short key duplication
if (short != None):
if (short in short_map):
raise Exception("Short config '{0}' for option '{1}' has duplicate entry!".format(short, op_key))
else:
short_map.append(short)
# Check for long key duplication
if (long in long_map):
raise Exception("Long config '{0}' has duplicate entry!".format(long))
else:
long_map.append(long)
# Check for long key duplication
if (long_invert != None):
if (long_invert in long_map):
raise Exception("Long config '{0}' has duplicate entry!".format(long_invert))
else:
long_map.append(long_invert)
if (len(sys.argv) < 5):
sys.exit()
@@ -568,8 +414,6 @@ json_object = json.loads(json_text)
options = json_object["Options"]
unnamed_options = json_object["UnnamedOptions"]
check_for_duplicate_options(options)
# Generate config include file
output_file = open(output_filename, "w")
print_header()
@@ -581,7 +425,6 @@ output_file.close()
# Generate man file
output_man = open(output_man_page, "w")
print_man_header()
print_man_options(options)
print_man_environment(options)
print_man_tail()
@@ -589,8 +432,6 @@ output_man.close()
# Generate argument loader code
output_argloader = open(output_argumentloader_filename, "w")
print_argloader_options(options);
print_parse_argloader_options(options);
# Generate environment loader code
print_parse_envloader_options(options);
@@ -4,7 +4,6 @@
"Multiblock": {
"Type": "bool",
"Default": "true",
"ShortArg": "m",
"Desc": [
"Controls multiblock code compilation",
"Can cause long JIT compilation times and stutter"
@@ -13,7 +12,6 @@
"MaxInst": {
"Type": "int32",
"Default": "5000",
"ShortArg": "n",
"Desc": [
"Maximum number of instruction to store in a block"
]
@@ -99,7 +97,6 @@
"RootFS": {
"Type": "str",
"Default": "",
"ShortArg": "R",
"Desc": [
"Which Root filesystem prefix to use",
"This can be a filesystem path",
@@ -114,7 +111,6 @@
"ThunkHostLibs": {
"Type": "str",
"Default": "@CMAKE_INSTALL_FULL_LIBDIR@/fex-emu/HostThunks",
"ShortArg": "t",
"Desc": [
"Folder to find the host-side thunking libraries."
]
@@ -122,7 +118,6 @@
"ThunkGuestLibs": {
"Type": "str",
"Default": "@CMAKE_INSTALL_PREFIX@/share/fex-emu/GuestThunks",
"ShortArg": "j",
"Desc": [
"Folder to find the guest-side thunking libraries."
]
@@ -130,7 +125,6 @@
"ThunkConfig": {
"Type": "str",
"Default": "",
"ShortArg": "k",
"Desc": [
"A json file specifying where to overlay the thunks.",
"This can be a filesystem path",
@@ -145,7 +139,6 @@
"Env": {
"Type": "strarray",
"Default": "",
"ShortArg": "E",
"Desc": [
"Adds an environment variable to the emulated environment."
]
@@ -153,7 +146,6 @@
"HostEnv": {
"Type": "strarray",
"Default": "",
"ShortArg": "H",
"Desc": [
"Adds an environment variable to the host environment.",
"This can be useful for setting environment variables that thunks can pick up.",
@@ -172,7 +164,6 @@
"SingleStep": {
"Type": "bool",
"Default": "false",
"ShortArg": "S",
"Desc": [
"Single stepping configuration."
]
@@ -180,7 +171,6 @@
"GdbServer": {
"Type": "bool",
"Default": "false",
"ShortArg": "G",
"Desc": [
"Enables the GDB server."
]
@@ -214,7 +204,6 @@
"DumpGPRs": {
"Type": "bool",
"Default": "false",
"ShortArg": "g",
"Desc": [
"When the test harness ends, print the GPR state."
]
@@ -222,7 +211,6 @@
"O0": {
"Type": "bool",
"Default": "false",
"ShortArg": "O0",
"Desc": [
"Disables optimizations passes for debugging."
]
@@ -312,7 +300,6 @@
"SilentLog": {
"Type": "bool",
"Default": "true",
"ShortArg": "s",
"Desc": [
"Disables logging"
]
@@ -320,7 +307,6 @@
"OutputLog": {
"Type": "str",
"Default": "server",
"ShortArg": "o",
"Desc": [
"File to write FEX output to.",
"[stdout, stderr, server, <Filename>]"
@@ -506,10 +492,6 @@
},
"UnnamedOptions": {
"Misc": {
"IS_INTERPRETER": {
"Type": "bool",
"Default": "false"
},
"INTERPRETER_INSTALLED": {
"Type": "bool",
"Default": "false"
-37
View File
@@ -5,50 +5,13 @@
#include <FEXCore/fextl/string.h>
#include <FEXCore/fextl/vector.h>
#include "cpp-optparse/OptionParser.h"
#include "git_version.h"
#include <stdint.h>
namespace FEX::ArgLoader {
void FEX::ArgLoader::ArgLoader::PreLoad() {
RemainingArgs.clear();
ProgramArguments.clear();
if (Type == LoadType::WITHOUT_FEXLOADER_PARSER) {
LoadWithoutArguments();
return;
}
optparse::OptionParser Parser {};
Parser.version("FEX-Emu (" GIT_DESCRIBE_STRING ") ");
optparse::OptionGroup CPUGroup(Parser, "CPU Core options");
optparse::OptionGroup EmulationGroup(Parser, "Emulation options");
optparse::OptionGroup DebugGroup(Parser, "Debug options");
optparse::OptionGroup HacksGroup(Parser, "Hacks options");
optparse::OptionGroup MiscGroup(Parser, "Miscellaneous options");
optparse::OptionGroup LoggingGroup(Parser, "Logging options");
#define BEFORE_PARSE
#include <FEXCore/Config/ConfigOptions.inl>
Parser.add_option_group(CPUGroup);
Parser.add_option_group(EmulationGroup);
Parser.add_option_group(DebugGroup);
Parser.add_option_group(HacksGroup);
Parser.add_option_group(MiscGroup);
Parser.add_option_group(LoggingGroup);
optparse::Values Options = Parser.parse_args(argc, argv);
using int32 = int32_t;
using uint32 = uint32_t;
#define AFTER_PARSE
#include <FEXCore/Config/ConfigOptions.inl>
RemainingArgs = Parser.args();
ProgramArguments = Parser.parsed_args();
}
void FEX::ArgLoader::ArgLoader::LoadWithoutArguments() {
// Skip argument 0, which will be the interpreter
for (int i = 1; i < argc; ++i) {
RemainingArgs.emplace_back(argv[i]);
+1 -13
View File
@@ -8,14 +8,8 @@
namespace FEX::ArgLoader {
class ArgLoader final : public FEXCore::Config::Layer {
public:
enum class LoadType {
WITH_FEXLOADER_PARSER,
WITHOUT_FEXLOADER_PARSER,
};
explicit ArgLoader(LoadType Type, int argc, char** argv)
explicit ArgLoader(int argc, char** argv)
: FEXCore::Config::Layer(FEXCore::Config::LayerType::LAYER_ARGUMENTS)
, Type {Type}
, argc {argc}
, argv {argv} {
PreLoad();
@@ -25,7 +19,6 @@ public:
// Intentional no-op.
}
void PreLoad();
void LoadWithoutArguments();
fextl::vector<fextl::string> Get() {
return RemainingArgs;
}
@@ -33,12 +26,7 @@ public:
return ProgramArguments;
}
LoadType GetLoadType() const {
return Type;
}
private:
LoadType Type;
int argc {};
char** argv {};
+1 -6
View File
@@ -448,8 +448,7 @@ ApplicationNames GetApplicationNames(const fextl::vector<fextl::string>& Args, b
return ApplicationNames {std::move(Program), std::move(ProgramName)};
}
void LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoader, fextl::string ProgramName, char** const envp,
const PortableInformation& PortableInfo) {
void LoadConfig(fextl::string ProgramName, char** const envp, const PortableInformation& PortableInfo) {
const bool IsPortable = PortableInfo.IsPortable;
FEX::Config::InitializeConfigs(PortableInfo);
FEXCore::Config::Initialize();
@@ -476,10 +475,6 @@ void LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoader, fextl::
}
}
if (ArgsLoader && ArgsLoader->GetLoadType() == FEX::ArgLoader::ArgLoader::LoadType::WITH_FEXLOADER_PARSER) {
FEXCore::Config::AddLayer(std::move(ArgsLoader));
}
const char* AppConfig = getenv("FEX_APP_CONFIG");
if (AppConfig) {
fextl::string AppConfigStr = AppConfig;
+1 -3
View File
@@ -52,12 +52,10 @@ ApplicationNames GetApplicationNames(const fextl::vector<fextl::string>& Args, b
/**
* @brief Loads the FEX and application configurations for the application that is getting ready to run.
*
* @param ArgLoader Optional argument loader for argument based config options
* @param ProgramName Optional program name, if non-empty application specific configurations will be loaded
* @param envp Optional `envp` passed to main(...)
*/
void LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgLoader = {}, fextl::string ProgramName = {}, char** const envp = nullptr,
const PortableInformation& PortableInfo = {});
void LoadConfig(fextl::string ProgramName = {}, char** const envp = nullptr, const PortableInformation& PortableInfo = {});
const char* GetHomeDirectory();
-2
View File
@@ -175,7 +175,6 @@ static void LoadDefaultSettings() {
#include <FEXCore/Config/ConfigValues.inl>
// Erase unnamed options which shouldn't be set
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_IS_INTERPRETER);
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_INTERPRETER_INSTALLED);
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_APP_FILENAME);
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_APP_CONFIG_NAME);
@@ -384,7 +383,6 @@ static bool OpenFile(fextl::string Filename) {
#include <FEXCore/Config/ConfigValues.inl>
// Erase unnamed options which shouldn't be set
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_IS_INTERPRETER);
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_INTERPRETER_INSTALLED);
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_APP_FILENAME);
LoadedConfig->Erase(FEXCore::Config::ConfigOption::CONFIG_APP_CONFIG_NAME);
+37 -43
View File
@@ -5,55 +5,49 @@ if (ENABLE_VIXL_SIMULATOR)
list(APPEND DEFINES -DVIXL_SIMULATOR=1)
endif()
function(GenerateInterpreter NAME AsInterpreter)
add_executable(${NAME}
FEXInterpreter.cpp
AOT/AOTGenerator.cpp)
add_executable(FEXInterpreter
FEXInterpreter.cpp
AOT/AOTGenerator.cpp)
target_compile_definitions(${NAME} PRIVATE ${DEFINES})
target_compile_definitions(FEXInterpreter PRIVATE ${DEFINES})
# Enable FEX APIs to be used by targets that use target_link_libraries on FEXInterpreter
set_target_properties(${NAME} PROPERTIES
ENABLE_EXPORTS 1
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN TRUE
)
# Enable FEX APIs to be used by targets that use target_link_libraries on FEXInterpreter
set_target_properties(FEXInterpreter PROPERTIES
ENABLE_EXPORTS 1
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN TRUE
)
target_include_directories(${NAME}
target_include_directories(FEXInterpreter
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/
${CMAKE_BINARY_DIR}/generated
)
target_link_libraries(FEXInterpreter
PRIVATE
${LIBS}
LinuxEmulation
CommonTools
${PTHREAD_LIB}
fmt::fmt
)
target_compile_options(FEXInterpreter PRIVATE ${FEX_TUNE_COMPILE_FLAGS})
if (CMAKE_BUILD_TYPE MATCHES "RELEASE")
target_link_options(FEXInterpreter
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/
${CMAKE_BINARY_DIR}/generated
"LINKER:--gc-sections"
"LINKER:--strip-all"
"LINKER:--as-needed"
)
target_link_libraries(${NAME}
PRIVATE
${LIBS}
LinuxEmulation
CommonTools
${PTHREAD_LIB}
fmt::fmt
)
target_compile_options(${NAME} PRIVATE ${FEX_TUNE_COMPILE_FLAGS})
target_compile_definitions(${NAME} PRIVATE -DFEXLOADER_AS_INTERPRETER=${AsInterpreter})
endif()
if (CMAKE_BUILD_TYPE MATCHES "RELEASE")
target_link_options(${NAME}
PRIVATE
"LINKER:--gc-sections"
"LINKER:--strip-all"
"LINKER:--as-needed"
)
endif()
install(TARGETS ${NAME}
RUNTIME
DESTINATION bin
COMPONENT Runtime
)
endfunction()
GenerateInterpreter(FEXLoader 0)
GenerateInterpreter(FEXInterpreter 1)
install(TARGETS FEXInterpreter
RUNTIME
DESTINATION bin
COMPONENT Runtime
)
if (_M_ARM_64)
if (NOT USE_LEGACY_BINFMTMISC)
+2 -10
View File
@@ -138,10 +138,6 @@ bool InterpreterHandler(fextl::string* Filename, const fextl::string& RootFS, fe
return true;
}
bool RanAsInterpreter(bool ExecutedWithFD) {
return ExecutedWithFD || FEXLOADER_AS_INTERPRETER;
}
/**
* @brief Queries if FEX is installed as a binfmt_misc interpreter
*
@@ -283,7 +279,6 @@ int main(int argc, char** argv, char** const envp) {
FEXCore::Allocator::GLIBCScopedFault GLIBFaultScope;
const bool ExecutedWithFD = getauxval(AT_EXECFD) != 0;
const bool IsInterpreter = RanAsInterpreter(ExecutedWithFD);
const auto PortableInfo = FEX::ReadPortabilityInformation();
const bool InterpreterInstalled = QueryInterpreterInstalled(ExecutedWithFD, PortableInfo);
@@ -293,9 +288,7 @@ int main(int argc, char** argv, char** const envp) {
LogMan::Throw::InstallHandler(AssertHandler);
LogMan::Msg::InstallHandler(MsgHandler);
auto ArgsLoader = fextl::make_unique<FEX::ArgLoader::ArgLoader>(
IsInterpreter ? FEX::ArgLoader::ArgLoader::LoadType::WITHOUT_FEXLOADER_PARSER : FEX::ArgLoader::ArgLoader::LoadType::WITH_FEXLOADER_PARSER,
argc, argv);
auto ArgsLoader = fextl::make_unique<FEX::ArgLoader::ArgLoader>(argc, argv);
auto Args = ArgsLoader->Get();
auto ParsedArgs = ArgsLoader->GetParsedArgs();
auto Program = FEX::Config::GetApplicationNames(Args, ExecutedWithFD, FEXFD);
@@ -306,11 +299,10 @@ int main(int argc, char** argv, char** const envp) {
FEX::GCS::CheckForGCS();
FEX::Config::LoadConfig(std::move(ArgsLoader), Program.ProgramName, envp, PortableInfo);
FEX::Config::LoadConfig(Program.ProgramName, envp, PortableInfo);
// Reload the meta layer
FEXCore::Config::ReloadMetaLayer();
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS_INTERPRETER, IsInterpreter ? "1" : "0");
FEXCore::Config::Set(FEXCore::Config::CONFIG_INTERPRETER_INSTALLED, InterpreterInstalled ? "1" : "0");
#ifdef VIXL_SIMULATOR
// If running under the vixl simulator, ensure that indirect runtime calls are enabled.
+1 -2
View File
@@ -7,7 +7,6 @@
#include "Common/JSONPool.h"
#include "XXFileHash.h"
#include "Common/ArgumentLoader.h"
#include "Common/Config.h"
#include <array>
@@ -1108,7 +1107,7 @@ bool ExtractEroFS(const fextl::string& Path, const fextl::string& RootFS, const
} // namespace UnSquash
int main(int argc, char** argv, char** const envp) {
FEX::Config::LoadConfig({}, {}, envp);
FEX::Config::LoadConfig({}, envp);
// Reload the meta layer
FEXCore::Config::ReloadMetaLayer();
+1 -1
View File
@@ -135,7 +135,7 @@ int main(int argc, char** argv, char** const envp) {
DeparentSelf();
}
FEX::Config::LoadConfig({}, {}, envp, FEX::ReadPortabilityInformation());
FEX::Config::LoadConfig({}, envp, FEX::ReadPortabilityInformation());
// Reload the meta layer
FEXCore::Config::ReloadMetaLayer();
@@ -290,8 +290,8 @@ uint64_t ExecveHandler(FEXCore::Core::CpuStateFrame* Frame, const char* pathname
// If the FEX interpreter is installed then just execve the ELF file
// This will stay inside of our emulated environment since binfmt_misc will capture it
const bool IsBinfmtCompatible = SyscallHandler->IsInterpreterInstalled() && SyscallHandler->IsInterpreter() &&
(Type == ELFLoader::ELFContainer::ELFType::TYPE_X86_32 || Type == ELFLoader::ELFContainer::ELFType::TYPE_X86_64);
const bool IsBinfmtCompatible = SyscallHandler->IsInterpreterInstalled() && (Type == ELFLoader::ELFContainer::ELFType::TYPE_X86_32 ||
Type == ELFLoader::ELFContainer::ELFType::TYPE_X86_64);
// We are trying to execute an ELF of a different architecture
// We can't know if we can support this without architecture specific checks and binfmt_misc parsing
@@ -391,10 +391,6 @@ uint64_t ExecveHandler(FEXCore::Core::CpuStateFrame* Frame, const char* pathname
// We now need to munge the arguments
const char NullString[] = "";
fextl::vector<const char*> ExecveArgs = SyscallHandler->GetCodeLoader()->GetExecveArguments();
if (!SyscallHandler->IsInterpreter()) {
// If we were launched from FEXLoader then we need to make sure to split arguments from FEXLoader and guest
ExecveArgs.emplace_back("--");
}
if (argv) {
// Overwrite the filename with the new one we are redirecting to
@@ -199,7 +199,6 @@ public:
return ThunkHandler;
}
FEX_CONFIG_OPT(IsInterpreter, IS_INTERPRETER);
FEX_CONFIG_OPT(IsInterpreterInstalled, INTERPRETER_INSTALLED);
FEX_CONFIG_OPT(Filename, APP_FILENAME);
FEX_CONFIG_OPT(RootFSPath, ROOTFS);
+1 -2
View File
@@ -27,7 +27,6 @@ $end_info$
#include <FEXCore/Utils/TypeDefines.h>
#include <FEXCore/Utils/SignalScopeGuards.h>
#include "Common/ArgumentLoader.h"
#include "Common/CallRetStack.h"
#include "Common/Config.h"
#include "Common/Exception.h"
@@ -635,7 +634,7 @@ NTSTATUS ProcessInit() {
FEX::Windows::InitCRTProcess();
const auto ExecutablePath = FEX::Windows::GetExecutableFilePath();
FEX::Config::LoadConfig(nullptr, ExecutablePath, _environ, FEX::ReadPortabilityInformation());
FEX::Config::LoadConfig(ExecutablePath, _environ, FEX::ReadPortabilityInformation());
FEXCore::Config::ReloadMetaLayer();
FEX::Windows::Logging::Init();
+1 -3
View File
@@ -28,7 +28,6 @@ $end_info$
#include <FEXCore/Utils/TypeDefines.h>
#include <FEXCore/Utils/SignalScopeGuards.h>
#include "Common/ArgumentLoader.h"
#include "Common/CallRetStack.h"
#include "Common/Config.h"
#include "Common/Exception.h"
@@ -510,11 +509,10 @@ public:
void BTCpuProcessInit() {
FEX::Windows::InitCRTProcess();
const auto ExecutablePath = FEX::Windows::GetExecutableFilePath();
FEX::Config::LoadConfig(nullptr, ExecutablePath, _environ, FEX::ReadPortabilityInformation());
FEX::Config::LoadConfig(ExecutablePath, _environ, FEX::ReadPortabilityInformation());
FEXCore::Config::ReloadMetaLayer();
FEX::Windows::Logging::Init();
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS_INTERPRETER, "0");
FEXCore::Config::Set(FEXCore::Config::CONFIG_INTERPRETER_INSTALLED, "0");
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, "0");
+1 -1
View File
@@ -81,7 +81,7 @@ function(add_host_lib NAME GUEST_BITNESS)
target_include_directories(${NAME}-host-${GUEST_BITNESS} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/gen_${GUEST_BITNESS}/")
target_link_libraries(${NAME}-host-${GUEST_BITNESS} PRIVATE dl)
target_link_libraries(${NAME}-host-${GUEST_BITNESS} PRIVATE lib${NAME}-${GUEST_BITNESS}-deps)
target_link_libraries(${NAME}-host-${GUEST_BITNESS} PRIVATE FEXLoader)
target_link_libraries(${NAME}-host-${GUEST_BITNESS} PRIVATE FEXInterpreter)
## Make signed overflow well defined 2's complement overflow
target_compile_options(${NAME}-host-${GUEST_BITNESS} PRIVATE -fwrapv)
+1 -1
View File
@@ -15,7 +15,7 @@ ln -s $BUILDDIR/Guest/libX11-guest.so $ROOTFS/lib/x86_64-linux-gnu/libX11.so.6
```
Finally, FEX needs to be told where to look for the matching host libraries with `-t /Host/Libs/Path`. eg
```FEXLoader -c irjit -n 500 -R $ROOTFS -t $BUILDDIR/Host -- /PATH/TO/ELF```
```FEX_THUNKHOSTLIBS= $BUILDDIR/Host FEXInterpreter /PATH/TO/ELF```
We currently don't have any unit tests for the guest libraries, only for OP_THUNK.