Tweak Loading
This commit is contained in:
parent
56d93f0150
commit
3088a13725
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user