diff --git a/CMakeLists.txt b/CMakeLists.txt index c41a8d8..6d35964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,6 @@ endif() set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}") set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib") set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin") -set(MCPI_FALLBACK_LIB_DIR "${MCPI_INSTALL_DIR}/fallback-lib") # Build Mode if(NOT CMAKE_BUILD_TYPE) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 452545e..7346701 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -2,7 +2,7 @@ project(launcher) # Launcher if(BUILD_NATIVE_COMPONENTS) - add_executable(launcher src/bootstrap.c src/ldconfig.cpp) + add_executable(launcher src/bootstrap.c src/patchelf.c) if(MCPI_SERVER_MODE) target_sources(launcher PRIVATE src/server/launcher.c) else() diff --git a/launcher/src/bootstrap.c b/launcher/src/bootstrap.c index 76b60df..c14fc65 100644 --- a/launcher/src/bootstrap.c +++ b/launcher/src/bootstrap.c @@ -11,7 +11,7 @@ #include #include "bootstrap.h" -#include "ldconfig.h" +#include "patchelf.h" // Set Environmental Variable #define PRESERVE_ENVIRONMENTAL_VARIABLE(name) \ @@ -34,7 +34,7 @@ static void trim(char **value) { void set_and_print_env(const char *name, char *value) { // Set Variable With No Trailing Colon static const char *unmodified_name_prefix = "MCPI_"; - if (strncmp(unmodified_name_prefix, name, strlen(unmodified_name_prefix)) != 0) { + if (!starts_with(name, unmodified_name_prefix)) { trim(&value); } @@ -194,8 +194,57 @@ void bootstrap(int argc, char *argv[]) { usr_prefix = ""; } + // Resolve Binary Path & Set MCPI_DIRECTORY + { + // Log + DEBUG("%s", "Resolving File Paths..."); + + // Resolve Full Binary Path + char *full_path = NULL; + safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory); + char *resolved_path = realpath(full_path, NULL); + ALLOC_CHECK(resolved_path); + free(full_path); + + // Set MCPI_EXECUTABLE_PATH + set_and_print_env("MCPI_EXECUTABLE_PATH", resolved_path); + + // Set MCPI_DIRECTORY + chop_last_component(&resolved_path); + set_and_print_env("MCPI_DIRECTORY", resolved_path); + free(resolved_path); + } + + // Fix MCPI Dependencies + { + // Log + DEBUG("%s", "Patching ELF Dependencies..."); + + // Find Linker + char *linker = NULL; +#ifndef __arm__ + safe_asprintf(&linker, "%s/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3", usr_prefix); +#else + safe_asprintf(&linker, "/lib/ld-linux-armhf.so.3"); +#endif + + // Patch + patch_mcpi_elf_dependencies(linker); + + // Free Linker Path + free(linker); + + // Verify + if (!starts_with(getenv("MCPI_EXECUTABLE_PATH"), "/tmp")) { + IMPOSSIBLE(); + } + } + // Configure LD_LIBRARY_PATH { + // Log + DEBUG("%s", "Setting Linker Search Paths..."); + // Preserve PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH"); char *new_ld_path = NULL; @@ -203,38 +252,16 @@ void bootstrap(int argc, char *argv[]) { // Add Library Directory safe_asprintf(&new_ld_path, "%s/lib", binary_directory); - // Add MCPI_LD_LIBRARY_PATH - { - char *value = get_env_safe("MCPI_LD_LIBRARY_PATH"); - if (strlen(value) > 0) { - string_append(&new_ld_path, ":%s", value); - } - } + // Load ARM Libraries (Ensure Priority) + string_append(&new_ld_path, ":%s/usr/lib/arm-linux-gnueabihf:%s/usr/arm-linux-gnueabihf/lib", usr_prefix, usr_prefix); // Add LD_LIBRARY_PATH (ARM32 Only) -#ifdef __arm__ { char *value = get_env_safe("LD_LIBRARY_PATH"); if (strlen(value) > 0) { string_append(&new_ld_path, ":%s", value); } } -#endif - - // Load ARM Libraries (Ensure Priority) - string_append(&new_ld_path, ":%s/usr/lib/arm-linux-gnueabihf:%s/usr/arm-linux-gnueabihf/lib", usr_prefix, usr_prefix); - - // Add Full Library Search Path - { - char *value = get_full_library_search_path(); - if (strlen(value) > 0) { - string_append(&new_ld_path, ":%s", value); - } - free(value); - } - - // Add Fallback Library Directory - string_append(&new_ld_path, ":%s/fallback-lib", binary_directory); // Set And Free set_and_print_env("LD_LIBRARY_PATH", new_ld_path); @@ -243,6 +270,9 @@ void bootstrap(int argc, char *argv[]) { // Configure LD_PRELOAD { + // Log + DEBUG("%s", "Locating Mods..."); + // Preserve PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD"); char *new_ld_preload = NULL; @@ -292,24 +322,6 @@ void bootstrap(int argc, char *argv[]) { free(new_ld_preload); } - // Resolve Binary Path & Set MCPI_DIRECTORY - { - // Resolve Full Binary Path - char *full_path = NULL; - safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory); - char *resolved_path = realpath(full_path, NULL); - ALLOC_CHECK(resolved_path); - free(full_path); - - // Set MCPI_EXECUTABLE_PATH - set_and_print_env("MCPI_EXECUTABLE_PATH", resolved_path); - - // Set MCPI_DIRECTORY - chop_last_component(&resolved_path); - set_and_print_env("MCPI_DIRECTORY", resolved_path); - free(resolved_path); - } - // Free Binary Directory free(binary_directory); @@ -317,8 +329,8 @@ void bootstrap(int argc, char *argv[]) { INFO("%s", "Starting Game..."); // Arguments - int argv_start = 2; // argv = &new_args[argv_start] - const char *new_args[argv_start /* 2 Potential Prefix Arguments (QEMU And Linker) */ + argc + 1 /* NULL-Terminator */]; // + int argv_start = 1; // argv = &new_args[argv_start] + const char *new_args[argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; // // Copy Existing Arguments for (int i = 1; i < argc; i++) { @@ -330,13 +342,6 @@ void bootstrap(int argc, char *argv[]) { // Set Executable Argument new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH"); - // Non-ARM32 Systems Need Manually Specified Linker -#ifndef __arm__ - argv_start--; - char *linker = NULL; - safe_asprintf(&linker, "%s/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3", usr_prefix); - new_args[argv_start] = linker; - // Non-ARM Systems Need QEMU #ifndef __ARM_ARCH argv_start--; @@ -345,7 +350,6 @@ void bootstrap(int argc, char *argv[]) { // Prevent QEMU From Being Modded PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH"); PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD"); -#endif #endif // Run diff --git a/launcher/src/ldconfig.cpp b/launcher/src/ldconfig.cpp deleted file mode 100644 index 9fade84..0000000 --- a/launcher/src/ldconfig.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include - -#include - -#include - -#include "ldconfig.h" - -char *get_full_library_search_path() { - std::string processed_output; - // Run - int return_code; - const char *ldconfig_argv[] = {"/sbin/ldconfig", "-NXv", NULL}; - char *output = run_command(ldconfig_argv, &return_code); - std::stringstream output_stream((std::string(output))); - // Check Exit Code - if (return_code != 0) { - ERR("ldconfig Failed: Exit Code: %i", return_code); - } - - // Read - int running = 1; - while (running) { - std::string line; - if (std::getline(output_stream, line)) { - // Remove Newline - if (line.size() > 0 && line[line.size() - 1] == '\n') { - line.pop_back(); - } - // Interpret - if (line.size() >= 2 && line[0] != '\t' && line[line.size() - 1] == ':') { - // Blacklist RPI Legacy GL Drivers -#define RPI_LEGACY_GL_PATH "/opt/vc" - if (line.rfind(RPI_LEGACY_GL_PATH ":", 0) != 0 && line.rfind(RPI_LEGACY_GL_PATH "/", 0) != 0) { - processed_output.append(line); - } - } - } else { - running = 0; - } - } - // Free Output - free(output); - - // Remove Colon - if (processed_output.size() > 0 && processed_output[processed_output.size() - 1] == ':') { - processed_output.pop_back(); - } - - // Return - char *output_str = strdup(processed_output.c_str()); - ALLOC_CHECK(output_str); - return output_str; -} diff --git a/launcher/src/patchelf.c b/launcher/src/patchelf.c new file mode 100644 index 0000000..8b64b32 --- /dev/null +++ b/launcher/src/patchelf.c @@ -0,0 +1,87 @@ +#include +#include +#include + +#include + +#include "bootstrap.h" +#include "patchelf.h" + +// Duplicate MCPI Executable Into /tmp +static void duplicate_mcpi_executable() { + // Get Original Path + const char *original_path = getenv("MCPI_EXECUTABLE_PATH"); + + // Generate New File + char new_path[] = "/tmp/.minecraft-pi-XXXXXX"; + int new_file_fd = mkstemp(new_path); + if (new_file_fd == -1) { + ERR("Unable To Create Temporary File: %s", strerror(errno)); + } + FILE *new_file = fdopen(new_file_fd, "wb"); + if (new_file == NULL) { + ERR("Unable To Open Temporary File: %s", strerror(errno)); + } + set_and_print_env("MCPI_EXECUTABLE_PATH", new_path); + + // Copy Original File + { + // Open Original File + FILE *original_file = fopen(original_path, "rb"); + if (original_file == NULL) { + ERR("Unable To Open File: %s", original_path); + } + + // Copy +#define BUFFER_SIZE 1024 + char buf[BUFFER_SIZE]; + size_t bytes_read = 0; + while ((bytes_read = fread((void *) buf, 1, BUFFER_SIZE, original_file)) > 0) { + fwrite((void *) buf, 1, bytes_read, new_file); + if (ferror(new_file) != 0) { + ERR("Unable To Write File: %s", new_path); + } + } + if (ferror(original_file) != 0) { + ERR("Unable To Read File: %s", original_path); + } + + // Close Original File + fclose(original_file); + } + + // Fix Permissions + if (fchmod(new_file_fd, S_IRUSR | S_IWUSR | S_IXUSR) != 0) { + ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno)); + } + + // Close New File + fclose(new_file); + close(new_file_fd); +} + +// Fix MCPI Dependencies +void patch_mcpi_elf_dependencies(const char *linker) { + // Duplicate MCPI executable into /tmp so it can be modified. + duplicate_mcpi_executable(); + + // Run patchelf + const char *const command[] = { + "patchelf", + "--set-interpreter", linker, + "--remove-needed", "libbcm_host.so", + "--remove-needed", "libX11.so.6", + "--remove-needed", "libEGL.so", + "--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", + getenv("MCPI_EXECUTABLE_PATH"), + NULL + }; + int return_code = 0; + char *output = run_command(command, &return_code); + if (output != NULL) { + free(output); + } + if (return_code != 0) { + ERR("patchelf Failed: Exit Code: %i", return_code); + } +} diff --git a/launcher/src/ldconfig.h b/launcher/src/patchelf.h similarity index 58% rename from launcher/src/ldconfig.h rename to launcher/src/patchelf.h index 1d08daa..b065391 100644 --- a/launcher/src/ldconfig.h +++ b/launcher/src/patchelf.h @@ -4,7 +4,7 @@ extern "C" { #endif -char *get_full_library_search_path(); // Remember To free() +void patch_mcpi_elf_dependencies(const char *linker); #ifdef __cplusplus } diff --git a/libreborn/include/libreborn/string.h b/libreborn/include/libreborn/string.h index 5679ef1..0ac9ba9 100644 --- a/libreborn/include/libreborn/string.h +++ b/libreborn/include/libreborn/string.h @@ -33,6 +33,9 @@ extern "C" { // Sanitize String void sanitize_string(char **str, int max_length, unsigned int allow_newlines); +// Starts With +int starts_with(const char *str, const char *prefix); + #ifdef __cplusplus } #endif diff --git a/libreborn/src/patch/patch.c b/libreborn/src/patch/patch.c index d41d0ac..27ac2b4 100644 --- a/libreborn/src/patch/patch.c +++ b/libreborn/src/patch/patch.c @@ -115,7 +115,7 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) { data.replacement = code_block; data.found = 0; - iterate_text_sections(getenv("MCPI_EXECUTABLE_PATH"), overwrite_calls_callback, &data); + iterate_text_sections("/proc/self/exe", overwrite_calls_callback, &data); // Increment Code Block Position increment_code_block(); diff --git a/libreborn/src/util/elf.c b/libreborn/src/util/elf.c index 0b3546c..97d7c75 100644 --- a/libreborn/src/util/elf.c +++ b/libreborn/src/util/elf.c @@ -7,7 +7,7 @@ void iterate_text_sections(const char *exe, text_section_callback_t callback, vo // Verify Binary if (!file_obj) { - ERR("%s", "Unable To Open Current Binary"); + ERR("%s", "Unable To Open Binary"); } // Get File Size diff --git a/libreborn/src/util/exec.c b/libreborn/src/util/exec.c index 3083fd1..6612712 100644 --- a/libreborn/src/util/exec.c +++ b/libreborn/src/util/exec.c @@ -97,7 +97,7 @@ char *run_command(const char *const command[], int *return_code) { char *output = NULL; #define BUFFER_SIZE 1024 char buf[BUFFER_SIZE]; - int bytes_read = 0; + size_t bytes_read = 0; while ((bytes_read = read(output_pipe[0], (void *) buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */)) > 0) { buf[bytes_read] = '\0'; string_append(&output, "%s", buf); @@ -107,7 +107,7 @@ char *run_command(const char *const command[], int *return_code) { // Get Return Code int status; waitpid(ret, &status, 0); - *return_code = WIFEXITED(status) ? WEXITSTATUS(status) : -1; + *return_code = WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE; // Return return output; diff --git a/libreborn/src/util/string.c b/libreborn/src/util/string.c index 55f2d63..cb4ed2e 100644 --- a/libreborn/src/util/string.c +++ b/libreborn/src/util/string.c @@ -23,3 +23,8 @@ void sanitize_string(char **str, int max_length, unsigned int allow_newlines) { } } } + +// Starts With +int starts_with(const char *str, const char *prefix) { + return strncmp(prefix, str, strlen(prefix)) == 0; +} diff --git a/media-layer/stubs/CMakeLists.txt b/media-layer/stubs/CMakeLists.txt index 10ac05c..7f563f2 100644 --- a/media-layer/stubs/CMakeLists.txt +++ b/media-layer/stubs/CMakeLists.txt @@ -7,31 +7,8 @@ set_target_properties(GLESv1_CM PROPERTIES SOVERSION "1") # Stubs Only Needed For ARM if(BUILD_ARM_COMPONENTS) - # Stub RPI-Specific Graphics - add_library(bcm_host SHARED src/bcm_host.c) - # Install - install(TARGETS bcm_host DESTINATION "${MCPI_LIB_DIR}") - - # Stub EGL - add_library(EGL SHARED src/EGL.c) - target_link_libraries(EGL reborn-util media-layer-headers) - set_target_properties(EGL PROPERTIES SOVERSION "1") - # Stub X11 - add_library(X11 SHARED src/X11.c) - target_link_libraries(X11 reborn-util media-layer-headers) - set_target_properties(X11 PROPERTIES SOVERSION "6") - # Install - if(MCPI_HEADLESS_MODE OR MCPI_USE_MEDIA_LAYER_PROXY) - install(TARGETS EGL X11 DESTINATION "${MCPI_LIB_DIR}") - else() - install(TARGETS EGL X11 DESTINATION "${MCPI_FALLBACK_LIB_DIR}") # Place At The End Of LD_LIBRARY_PATH - endif() - # Install Fake GLESv1_CM Stubs In Server Mode if(MCPI_HEADLESS_MODE) install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}") endif() - - # Redirect MCPI To Correct Libraries - add_subdirectory(redirect) endif() diff --git a/media-layer/stubs/redirect/CMakeLists.txt b/media-layer/stubs/redirect/CMakeLists.txt deleted file mode 100644 index f793c64..0000000 --- a/media-layer/stubs/redirect/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -project(media-layer-stubs-redirect) - -# MCPI Depends On GLESv2, But Uses GLESv1_CM -add_library(GLESv2_redirect SHARED src/nop.c) -target_link_libraries(GLESv2_redirect GLESv1_CM) -target_link_options(GLESv2_redirect PRIVATE "-Wl,--no-as-needed") -set_target_properties(GLESv2_redirect PROPERTIES OUTPUT_NAME "GLESv2") -install(TARGETS GLESv2_redirect DESTINATION "${MCPI_LIB_DIR}") - -# MCPI links to libEGL.so instead of libEGL.so.1, this creates a fake libEGL.so which redirects it to the correct libEGL.so.1. -# This is only needed on configurations that don't generate their own libEGL.so. -if(NOT MCPI_HEADLESS_MODE AND NOT MCPI_USE_MEDIA_LAYER_PROXY) - add_library(EGL_redirect SHARED src/nop.c) - target_link_libraries(EGL_redirect EGL) - target_link_options(EGL_redirect PRIVATE "-Wl,--no-as-needed") - set_target_properties(EGL_redirect PROPERTIES OUTPUT_NAME "EGL") - install(TARGETS EGL_redirect DESTINATION "${MCPI_LIB_DIR}") -endif() diff --git a/media-layer/stubs/redirect/src/nop.c b/media-layer/stubs/redirect/src/nop.c deleted file mode 100644 index 7733603..0000000 --- a/media-layer/stubs/redirect/src/nop.c +++ /dev/null @@ -1 +0,0 @@ -// NOP \ No newline at end of file diff --git a/media-layer/stubs/src/EGL.c b/media-layer/stubs/src/EGL.c deleted file mode 100644 index 41b7821..0000000 --- a/media-layer/stubs/src/EGL.c +++ /dev/null @@ -1,39 +0,0 @@ -#include - -#include - -// EGL Is Replaced With GLFW - -EGLDisplay eglGetDisplay(__attribute__((unused)) NativeDisplayType native_display) { - IMPOSSIBLE(); -} -EGLBoolean eglInitialize(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLint *major, __attribute__((unused)) EGLint *minor) { - IMPOSSIBLE(); -} -EGLBoolean eglChooseConfig(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLint const *attrib_list, __attribute__((unused)) EGLConfig *configs, __attribute__((unused)) EGLint config_size, __attribute__((unused)) EGLint *num_config) { - IMPOSSIBLE(); -} -EGLBoolean eglBindAPI(__attribute__((unused)) EGLenum api) { - IMPOSSIBLE(); -} -EGLContext eglCreateContext(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) EGLContext share_context, __attribute__((unused)) EGLint const *attrib_list) { - IMPOSSIBLE(); -} -EGLSurface eglCreateWindowSurface(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list) { - IMPOSSIBLE(); -} -EGLBoolean eglMakeCurrent(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface draw, __attribute__((unused)) EGLSurface read, __attribute__((unused)) EGLContext context) { - IMPOSSIBLE(); -} -EGLBoolean eglDestroySurface(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface) { - IMPOSSIBLE(); -} -EGLBoolean eglDestroyContext(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLContext context) { - IMPOSSIBLE(); -} -EGLBoolean eglTerminate(__attribute__((unused)) EGLDisplay display) { - IMPOSSIBLE(); -} -EGLBoolean eglSwapBuffers(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface) { - IMPOSSIBLE(); -} diff --git a/media-layer/stubs/src/X11.c b/media-layer/stubs/src/X11.c deleted file mode 100644 index e478897..0000000 --- a/media-layer/stubs/src/X11.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include - -// Raw X11 Is Replaced With GLFW - -int XTranslateCoordinates(__attribute__((unused)) void *display, __attribute__((unused)) XID src_w, __attribute__((unused)) XID dest_w, __attribute__((unused)) int src_x, __attribute__((unused)) int src_y, __attribute__((unused)) int *dest_x_return, __attribute__((unused)) int *dest_y_return, __attribute__((unused)) XID *child_return) { - IMPOSSIBLE(); -} -int XGetWindowAttributes(__attribute__((unused)) void *display, __attribute__((unused)) XID w, __attribute__((unused)) XWindowAttributes *window_attributes_return) { - IMPOSSIBLE(); -} diff --git a/media-layer/stubs/src/bcm_host.c b/media-layer/stubs/src/bcm_host.c deleted file mode 100644 index 2962d6e..0000000 --- a/media-layer/stubs/src/bcm_host.c +++ /dev/null @@ -1,27 +0,0 @@ -#include - -void bcm_host_init(void) { -} - -void bcm_host_deinit(void) { -} - -int32_t graphics_get_display_size(__attribute__((unused)) const uint16_t display_number, __attribute__((unused)) uint32_t *width, __attribute__((unused)) uint32_t *height) { - return -1; -} - -uint32_t vc_dispmanx_display_open(__attribute__((unused)) uint32_t device) { - return 0; -} - -uint32_t vc_dispmanx_element_add(__attribute__((unused)) uint32_t update, __attribute__((unused)) uint32_t display, __attribute__((unused)) int32_t layer, __attribute__((unused)) const void *dest_rect, __attribute__((unused)) uint32_t src, __attribute__((unused)) const void *src_rect, __attribute__((unused)) uint32_t protection, __attribute__((unused)) void *alpha, __attribute__((unused)) void *clamp, __attribute__((unused)) uint32_t transform) { - return 0; -} - -uint32_t vc_dispmanx_update_start(__attribute__((unused)) int32_t priority) { - return 0; -} - -int vc_dispmanx_update_submit_sync(__attribute__((unused)) uint32_t update) { - return 0; -} diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 1c36731..6fb757a 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -7,7 +7,7 @@ add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) ## Mods -add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c) +add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c src/compat/bcm_host.c) target_link_libraries(compat reborn-patch media-layer-core) add_library(readdir SHARED src/readdir/readdir.c) diff --git a/mods/src/compat/bcm_host.c b/mods/src/compat/bcm_host.c new file mode 100644 index 0000000..954c427 --- /dev/null +++ b/mods/src/compat/bcm_host.c @@ -0,0 +1,18 @@ +#include + +// Do Nothing Function +static void do_nothing() { + // NOP +} + +// Patch bcm_host Calls +__attribute__((constructor)) static void patch_bcm_host_calls() { + // Disable bcm_host Calls + overwrite_call((void *) 0xdfec, (void *) do_nothing); // bcm_host_init + overwrite_call((void *) 0x12418, (void *) do_nothing); // bcm_host_deinit + overwrite_call((void *) 0x125a8, (void *) do_nothing); // graphics_get_display_size + overwrite_call((void *) 0x125dc, (void *) do_nothing); // vc_dispmanx_display_open + overwrite_call((void *) 0x125e8, (void *) do_nothing); // vc_dispmanx_update_start + overwrite_call((void *) 0x12618, (void *) do_nothing); // vc_dispmanx_element_add + overwrite_call((void *) 0x12624, (void *) do_nothing); // vc_dispmanx_update_submit_sync +} diff --git a/mods/src/compat/compat.c b/mods/src/compat/compat.c index 4ed17dd..31ec8e3 100644 --- a/mods/src/compat/compat.c +++ b/mods/src/compat/compat.c @@ -28,6 +28,25 @@ HOOK(SDL_ShowCursor, int, (int toggle)) { return (*real_SDL_ShowCursor)(toggle == SDL_QUERY ? SDL_QUERY : SDL_DISABLE); } +// Hook SDL_Quit +HOOK(SDL_Quit, __attribute__((noreturn)) void, ()) { + // Cleanup Executable + { + const char *exe = getenv("MCPI_EXECUTABLE_PATH"); + // Check If Executable Is Temporary + if (exe != NULL && starts_with(exe, "/tmp")) { + // Cleanup Temporary File + if (unlink(exe) != 0) { + ERR("Unable To Cleanup Temporary File: %s", strerror(errno)); + } + } + } + + // Call Original Method + ensure_SDL_Quit(); + (*real_SDL_Quit)(); +} + // Intercept SDL Events HOOK(SDL_PollEvent, int, (SDL_Event *event)) { // In Server Mode, Exit Requests Are Handled In src/server/server.cpp diff --git a/mods/src/override/override.c b/mods/src/override/override.c index 0e3a0fd..d4d567a 100644 --- a/mods/src/override/override.c +++ b/mods/src/override/override.c @@ -10,11 +10,6 @@ #include "../home/home.h" -// Check If String Starts With Prefix -static int starts_with(const char *s, const char *t) { - return strncmp(s, t, strlen(t)) == 0; -} - // Get Override Path For File (If It Exists) char *override_get_path(const char *filename) { // Get MCPI Home Path diff --git a/scripts/generate-appimage-builder-yaml.js b/scripts/generate-appimage-builder-yaml.js index 7c780af..e2c1aa8 100755 --- a/scripts/generate-appimage-builder-yaml.js +++ b/scripts/generate-appimage-builder-yaml.js @@ -23,7 +23,8 @@ const version = fs.readFileSync('VERSION', 'utf8').trim(); // Packages/Dependencies const packages = [ 'libc6', - 'libstdc++6' + 'libstdc++6', + 'patchelf' ]; if (mode === 'client') { // GLFW's Dependencies Aren't Included As They Should Be Provided By The Host System diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh index 29f43ff..b80c52c 100755 --- a/scripts/install-dependencies.sh +++ b/scripts/install-dependencies.sh @@ -37,7 +37,8 @@ queue_pkg \ queue_pkg \ libfreeimage3 libfreeimage-dev \ libopenal-dev \ - qemu-user + qemu-user \ + patchelf # GLFW Dependencies queue_pkg \