#include #include #include #include #include #include #include #include "bootstrap.h" // Duplicate MCPI Executable Into /tmp static void duplicate_mcpi_executable(char *new_path) { // Ensure Temporary Directory ensure_directory(MCPI_PATCHED_DIR); // Generate New File const int new_file_fd = mkstemp(new_path); if (new_file_fd == -1) { ERR("Unable To Create Temporary File: %s", strerror(errno)); } close(new_file_fd); } // Fix MCPI Dependencies static std::vector needed_libraries = { "libmedia-layer-core.so", "libpng12.so.0", "libstdc++.so.6", "libm.so.6", "libgcc_s.so.1", "libc.so.6", "libpthread.so.0" }; static std::vector function_prefixes_to_patch = { "SDL_", "gl" }; void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector &rpath, const std::vector &mods) { // Duplicate MCPI executable into /tmp so it can be modified. duplicate_mcpi_executable(new_path); // Load Binary const std::unique_ptr binary = LIEF::ELF::Parser::parse(original_path); // Set Interpreter binary->interpreter(interpreter); // Remove Existing Needed Libraries std::vector to_remove; for (const LIEF::ELF::DynamicEntry &entry : binary->dynamic_entries()) { const LIEF::ELF::DynamicEntryLibrary *library = dynamic_cast(&entry); if (library) { to_remove.push_back(library->name()); } } for (const std::string &library : to_remove) { binary->remove_library(library); } // Setup RPath binary->add(LIEF::ELF::DynamicEntryRpath(rpath)); // Add Libraries std::vector all_libraries; for (const std::vector &list : {mods, needed_libraries}) { all_libraries.insert(all_libraries.end(), list.begin(), list.end()); } for (const std::string &library : all_libraries | std::views::reverse) { binary->add_library(library); } // Fix Symbol Names for (LIEF::ELF::Symbol &symbol : binary->dynamic_symbols()) { if (symbol.is_function()) { for (const std::string &prefix : function_prefixes_to_patch) { if (symbol.name().rfind(prefix, 0) == 0) { symbol.name("media_" + symbol.name()); break; } } } } // Write Binary LIEF::ELF::Builder builder{*binary}; builder.build(); builder.write(new_path); // Fix Permissions if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) { ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno)); } } // Linker std::string get_new_linker(const std::string &binary_directory) { std::string linker = "/lib/ld-linux-armhf.so.3"; #ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN linker = binary_directory + "/sysroot" + linker; #else (void) binary_directory; #endif return linker; } std::vector get_ld_path(const std::string &binary_directory) { std::vector mcpi_ld_path = { // ARM Sysroot #ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN "sysroot/lib", "sysroot/lib/arm-linux-gnueabihf", "sysroot/usr/lib", "sysroot/usr/lib/arm-linux-gnueabihf", #endif // Libraries "lib/arm" }; // Fix Paths for (std::string &path : mcpi_ld_path) { path.insert(0, 1, '/'); path.insert(0, binary_directory); } // Return return mcpi_ld_path; }