mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 10:00:16 +02:00
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:
17 files changed
+51
-309
No files matched your search
@@ -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"
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
|
||||
Reference in new issue
Block a user