Tweak Loading

This commit is contained in:
TheBrokenRail 2024-05-20 16:37:55 -04:00
parent 56d93f0150
commit 3088a13725
7 changed files with 24 additions and 88 deletions

View File

@ -103,28 +103,20 @@ void bootstrap() {
// Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
std::string linker;
{
// Log
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = nullptr;
// Select Linker
linker = "/lib/ld-linux-armhf.so.3";
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory.c_str());
#else
// Use Current Linker
linker = patch_get_interpreter();
linker = binary_directory + "/sysroot" + linker;
#endif
// Patch
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
// Free Linker Path
if (linker != nullptr) {
free(linker);
}
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path);
// Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
@ -146,13 +138,11 @@ void bootstrap() {
free(resolved_path);
// Configure Library Search Path
std::string mcpi_ld_path = "";
{
// Log
DEBUG("Setting Linker Search Paths...");
// Prepare
std::string mcpi_ld_path = "";
// Library Search Path For ARM Components
{
// Add ARM Library Directory
@ -173,19 +163,17 @@ void bootstrap() {
mcpi_ld_path += value;
}
}
// Set
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_LIBRARY_PATH", mcpi_ld_path.c_str());
}
}
// Configure Preloaded Objects
std::string mcpi_ld_preload;
{
// Log
DEBUG("Locating Mods...");
// ARM Components
bootstrap_mods(binary_directory);
mcpi_ld_preload = bootstrap_mods(binary_directory);
}
// Start Game
@ -195,23 +183,18 @@ void bootstrap() {
std::vector<std::string> args;
// Non-ARM Systems Need QEMU
#ifdef MCPI_USE_QEMU
args.insert(args.begin(), QEMU_BINARY);
args.push_back(QEMU_BINARY);
// Fix Bug
args.push_back("-B");
args.push_back("0x40000"); // Arbitary Value That Works On My System
#endif
// Preserve Existing LD_* Variables
#define preserve_variable(name) set_and_print_env(MCPI_ORIGINAL_LD_VARIABLE_PREFIX name, getenv(name))
for_each_special_environmental_variable(preserve_variable);
set_and_print_env(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV, "1");
// Setup Environment
setup_exec_environment(1);
// Pass LD_* Variables Through QEMU
#ifdef MCPI_USE_QEMU
#define pass_variable_through_qemu(name) args.push_back("-E"); args.push_back(std::string(name) + "=" + getenv(name))
for_each_special_environmental_variable(pass_variable_through_qemu);
// Treat QEMU Itself As A Native Component
setup_exec_environment(0);
#endif
// Setup Linker
args.push_back(linker);
args.push_back("--library-path");
args.push_back(mcpi_ld_path);
args.push_back("--preload");
args.push_back(mcpi_ld_preload);
// Specify MCPI Binary
args.push_back(new_mcpi_exe_path);

View File

@ -4,4 +4,4 @@
void bootstrap();
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
void bootstrap_mods(const std::string &binary_directory);
std::string bootstrap_mods(const std::string &binary_directory);

View File

@ -53,7 +53,7 @@ static void load(std::string &ld_preload, const std::string &folder) {
// Bootstrap Mods
#define SUBDIRECTORY_FOR_MODS "/mods/"
void bootstrap_mods(const std::string &binary_directory) {
std::string bootstrap_mods(const std::string &binary_directory) {
// Prepare
std::string preload = "";
@ -81,6 +81,6 @@ void bootstrap_mods(const std::string &binary_directory) {
}
}
// Set
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_PRELOAD", preload.c_str());
// Return
return preload;
}

View File

@ -15,7 +15,7 @@ static void duplicate_mcpi_executable(char *new_path) {
// Ensure Temporary Directory
{
// Check If It Exists
struct stat tmp_stat;
struct stat tmp_stat = {};
int exists = stat(MCPI_PATCHED_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
if (!exists) {
// Doesn't Exist
@ -44,16 +44,13 @@ static const char *libraries_to_remove[] = {
static const char *libraries_to_add[] = {
"libmedia-layer-core.so"
};
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker) {
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path) {
// Duplicate MCPI executable into /tmp so it can be modified.
duplicate_mcpi_executable(new_path);
// Patch File
{
std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
if (linker != NULL) {
binary->interpreter(linker);
}
for (size_t i = 0; i < (sizeof (libraries_to_remove) / sizeof (const char *)); i++) {
binary->remove_library(libraries_to_remove[i]);
}
@ -70,25 +67,3 @@ void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, cons
ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));
}
}
// Get Interpreter
static int dl_iterate_callback(struct dl_phdr_info *info, __attribute__((unused)) size_t size, void *data) {
// Only Search Current Program
if (strcmp(info->dlpi_name, "") == 0) {
for (int i = 0; i < info->dlpi_phnum; i++) {
if (info->dlpi_phdr[i].p_type == PT_INTERP) {
// Callback
*(char **) data = (char *) (info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
}
}
}
return 0;
}
char *patch_get_interpreter() {
char *interpreter = NULL;
dl_iterate_phdr(dl_iterate_callback, &interpreter);
if (interpreter != NULL) {
interpreter = strdup(interpreter);
}
return interpreter;
}

View File

@ -6,8 +6,7 @@ extern "C" {
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker);
char *patch_get_interpreter();
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path);
#ifdef __cplusplus
}

View File

@ -20,13 +20,6 @@ extern "C" {
void set_and_print_env(const char *name, const char *value);
// Safe execvpe()
#define MCPI_LD_VARIABLE_PREFIX "_MCPI_"
#define MCPI_ORIGINAL_LD_VARIABLE_PREFIX MCPI_LD_VARIABLE_PREFIX "ORIGINAL_"
#define MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV MCPI_ORIGINAL_LD_VARIABLE_PREFIX "PRESERVED"
#define for_each_special_environmental_variable(handle) \
handle("LD_LIBRARY_PATH"); \
handle("LD_PRELOAD")
void setup_exec_environment(int is_arm_component);
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
// Debug Tag

View File

@ -19,17 +19,6 @@ void set_and_print_env(const char *name, const char *value) {
}
// Safe execvpe()
#define handle_environmental_variable(var) \
{ \
const char *full_var = is_arm_component ? MCPI_LD_VARIABLE_PREFIX var : MCPI_ORIGINAL_LD_VARIABLE_PREFIX var; \
const char *var_value = getenv(full_var); \
set_and_print_env(var, var_value); \
}
void setup_exec_environment(int is_arm_component) {
if (is_arm_component || getenv(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV) != NULL) {
for_each_special_environmental_variable(handle_environmental_variable);
}
}
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
// Log
DEBUG("Running Command:");
@ -69,9 +58,6 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_
reborn_lock_debug(); // Lock Released On Process Exit
dup2(reborn_get_debug_fd(), STDERR_FILENO);
// Setup Environment
setup_exec_environment(0);
// Run
safe_execvpe(command, (const char *const *) environ);
} else {