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 // Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX"; char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
std::string linker;
{ {
// Log // Log
DEBUG("Patching ELF Dependencies..."); DEBUG("Patching ELF Dependencies...");
// Find Linker // Find Linker
char *linker = nullptr; linker = "/lib/ld-linux-armhf.so.3";
// Select Linker
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN #ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker // Use ARM Sysroot Linker
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory.c_str()); linker = binary_directory + "/sysroot" + linker;
#else
// Use Current Linker
linker = patch_get_interpreter();
#endif #endif
// Patch // Patch
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker); patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path);
// Free Linker Path
if (linker != nullptr) {
free(linker);
}
// Verify // Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) { if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
@ -146,13 +138,11 @@ void bootstrap() {
free(resolved_path); free(resolved_path);
// Configure Library Search Path // Configure Library Search Path
std::string mcpi_ld_path = "";
{ {
// Log // Log
DEBUG("Setting Linker Search Paths..."); DEBUG("Setting Linker Search Paths...");
// Prepare
std::string mcpi_ld_path = "";
// Library Search Path For ARM Components // Library Search Path For ARM Components
{ {
// Add ARM Library Directory // Add ARM Library Directory
@ -173,19 +163,17 @@ void bootstrap() {
mcpi_ld_path += value; mcpi_ld_path += value;
} }
} }
// Set
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_LIBRARY_PATH", mcpi_ld_path.c_str());
} }
} }
// Configure Preloaded Objects // Configure Preloaded Objects
std::string mcpi_ld_preload;
{ {
// Log // Log
DEBUG("Locating Mods..."); DEBUG("Locating Mods...");
// ARM Components // ARM Components
bootstrap_mods(binary_directory); mcpi_ld_preload = bootstrap_mods(binary_directory);
} }
// Start Game // Start Game
@ -195,23 +183,18 @@ void bootstrap() {
std::vector<std::string> args; std::vector<std::string> args;
// Non-ARM Systems Need QEMU // Non-ARM Systems Need QEMU
#ifdef MCPI_USE_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 #endif
// Preserve Existing LD_* Variables // Setup Linker
#define preserve_variable(name) set_and_print_env(MCPI_ORIGINAL_LD_VARIABLE_PREFIX name, getenv(name)) args.push_back(linker);
for_each_special_environmental_variable(preserve_variable); args.push_back("--library-path");
set_and_print_env(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV, "1"); args.push_back(mcpi_ld_path);
// Setup Environment args.push_back("--preload");
setup_exec_environment(1); args.push_back(mcpi_ld_preload);
// 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
// Specify MCPI Binary // Specify MCPI Binary
args.push_back(new_mcpi_exe_path); args.push_back(new_mcpi_exe_path);

View File

@ -4,4 +4,4 @@
void bootstrap(); void bootstrap();
void copy_sdk(const std::string &binary_directory, bool log_with_debug); 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 // Bootstrap Mods
#define SUBDIRECTORY_FOR_MODS "/mods/" #define SUBDIRECTORY_FOR_MODS "/mods/"
void bootstrap_mods(const std::string &binary_directory) { std::string bootstrap_mods(const std::string &binary_directory) {
// Prepare // Prepare
std::string preload = ""; std::string preload = "";
@ -81,6 +81,6 @@ void bootstrap_mods(const std::string &binary_directory) {
} }
} }
// Set // Return
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_PRELOAD", preload.c_str()); return preload;
} }

View File

@ -15,7 +15,7 @@ static void duplicate_mcpi_executable(char *new_path) {
// Ensure Temporary Directory // Ensure Temporary Directory
{ {
// Check If It Exists // 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); int exists = stat(MCPI_PATCHED_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
if (!exists) { if (!exists) {
// Doesn't Exist // Doesn't Exist
@ -44,16 +44,13 @@ static const char *libraries_to_remove[] = {
static const char *libraries_to_add[] = { static const char *libraries_to_add[] = {
"libmedia-layer-core.so" "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 into /tmp so it can be modified.
duplicate_mcpi_executable(new_path); duplicate_mcpi_executable(new_path);
// Patch File // Patch File
{ {
std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path); 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++) { for (size_t i = 0; i < (sizeof (libraries_to_remove) / sizeof (const char *)); i++) {
binary->remove_library(libraries_to_remove[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)); 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" #define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
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);
char *patch_get_interpreter();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -20,13 +20,6 @@ extern "C" {
void set_and_print_env(const char *name, const char *value); void set_and_print_env(const char *name, const char *value);
// Safe execvpe() // 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[]); __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
// Debug Tag // Debug Tag

View File

@ -19,17 +19,6 @@ void set_and_print_env(const char *name, const char *value) {
} }
// Safe execvpe() // 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[]) { __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
// Log // Log
DEBUG("Running Command:"); 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 reborn_lock_debug(); // Lock Released On Process Exit
dup2(reborn_get_debug_fd(), STDERR_FILENO); dup2(reborn_get_debug_fd(), STDERR_FILENO);
// Setup Environment
setup_exec_environment(0);
// Run // Run
safe_execvpe(command, (const char *const *) environ); safe_execvpe(command, (const char *const *) environ);
} else { } else {