parent
709de17558
commit
b5974f3f46
@ -1,57 +0,0 @@
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
@ -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()
|
@ -1 +0,0 @@
|
||||
// NOP
|
@ -1,39 +0,0 @@
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
// 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();
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
// 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();
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
// 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
|
||||
}
|
Loading…
Reference in new issue