Simplify Launch Process
This commit is contained in:
parent
709de17558
commit
b5974f3f46
@ -41,7 +41,6 @@ endif()
|
|||||||
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
|
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
|
||||||
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
|
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
|
||||||
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
|
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
|
||||||
set(MCPI_FALLBACK_LIB_DIR "${MCPI_INSTALL_DIR}/fallback-lib")
|
|
||||||
|
|
||||||
# Build Mode
|
# Build Mode
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
@ -2,7 +2,7 @@ project(launcher)
|
|||||||
|
|
||||||
# Launcher
|
# Launcher
|
||||||
if(BUILD_NATIVE_COMPONENTS)
|
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)
|
if(MCPI_SERVER_MODE)
|
||||||
target_sources(launcher PRIVATE src/server/launcher.c)
|
target_sources(launcher PRIVATE src/server/launcher.c)
|
||||||
else()
|
else()
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "bootstrap.h"
|
#include "bootstrap.h"
|
||||||
#include "ldconfig.h"
|
#include "patchelf.h"
|
||||||
|
|
||||||
// Set Environmental Variable
|
// Set Environmental Variable
|
||||||
#define PRESERVE_ENVIRONMENTAL_VARIABLE(name) \
|
#define PRESERVE_ENVIRONMENTAL_VARIABLE(name) \
|
||||||
@ -34,7 +34,7 @@ static void trim(char **value) {
|
|||||||
void set_and_print_env(const char *name, char *value) {
|
void set_and_print_env(const char *name, char *value) {
|
||||||
// Set Variable With No Trailing Colon
|
// Set Variable With No Trailing Colon
|
||||||
static const char *unmodified_name_prefix = "MCPI_";
|
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);
|
trim(&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,8 +194,57 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
usr_prefix = "";
|
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
|
// Configure LD_LIBRARY_PATH
|
||||||
{
|
{
|
||||||
|
// Log
|
||||||
|
DEBUG("%s", "Setting Linker Search Paths...");
|
||||||
|
|
||||||
// Preserve
|
// Preserve
|
||||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
||||||
char *new_ld_path = NULL;
|
char *new_ld_path = NULL;
|
||||||
@ -203,38 +252,16 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
// Add Library Directory
|
// Add Library Directory
|
||||||
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
|
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
|
||||||
|
|
||||||
// Add MCPI_LD_LIBRARY_PATH
|
// 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);
|
||||||
char *value = get_env_safe("MCPI_LD_LIBRARY_PATH");
|
|
||||||
if (strlen(value) > 0) {
|
|
||||||
string_append(&new_ld_path, ":%s", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add LD_LIBRARY_PATH (ARM32 Only)
|
// Add LD_LIBRARY_PATH (ARM32 Only)
|
||||||
#ifdef __arm__
|
|
||||||
{
|
{
|
||||||
char *value = get_env_safe("LD_LIBRARY_PATH");
|
char *value = get_env_safe("LD_LIBRARY_PATH");
|
||||||
if (strlen(value) > 0) {
|
if (strlen(value) > 0) {
|
||||||
string_append(&new_ld_path, ":%s", value);
|
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 Free
|
||||||
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
||||||
@ -243,6 +270,9 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// Configure LD_PRELOAD
|
// Configure LD_PRELOAD
|
||||||
{
|
{
|
||||||
|
// Log
|
||||||
|
DEBUG("%s", "Locating Mods...");
|
||||||
|
|
||||||
// Preserve
|
// Preserve
|
||||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
||||||
char *new_ld_preload = NULL;
|
char *new_ld_preload = NULL;
|
||||||
@ -292,24 +322,6 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
free(new_ld_preload);
|
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
|
||||||
free(binary_directory);
|
free(binary_directory);
|
||||||
|
|
||||||
@ -317,8 +329,8 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
INFO("%s", "Starting Game...");
|
INFO("%s", "Starting Game...");
|
||||||
|
|
||||||
// Arguments
|
// Arguments
|
||||||
int argv_start = 2; // argv = &new_args[argv_start]
|
int argv_start = 1; // argv = &new_args[argv_start]
|
||||||
const char *new_args[argv_start /* 2 Potential Prefix Arguments (QEMU And Linker) */ + argc + 1 /* NULL-Terminator */]; //
|
const char *new_args[argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; //
|
||||||
|
|
||||||
// Copy Existing Arguments
|
// Copy Existing Arguments
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
@ -330,13 +342,6 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
// Set Executable Argument
|
// Set Executable Argument
|
||||||
new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH");
|
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
|
// Non-ARM Systems Need QEMU
|
||||||
#ifndef __ARM_ARCH
|
#ifndef __ARM_ARCH
|
||||||
argv_start--;
|
argv_start--;
|
||||||
@ -345,7 +350,6 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
// Prevent QEMU From Being Modded
|
// Prevent QEMU From Being Modded
|
||||||
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH");
|
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH");
|
||||||
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD");
|
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD");
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
|
@ -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;
|
|
||||||
}
|
|
87
launcher/src/patchelf.c
Normal file
87
launcher/src/patchelf.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *get_full_library_search_path(); // Remember To free()
|
void patch_mcpi_elf_dependencies(const char *linker);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
@ -33,6 +33,9 @@ extern "C" {
|
|||||||
// Sanitize String
|
// Sanitize String
|
||||||
void sanitize_string(char **str, int max_length, unsigned int allow_newlines);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -115,7 +115,7 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) {
|
|||||||
data.replacement = code_block;
|
data.replacement = code_block;
|
||||||
data.found = 0;
|
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 Position
|
||||||
increment_code_block();
|
increment_code_block();
|
||||||
|
@ -7,7 +7,7 @@ void iterate_text_sections(const char *exe, text_section_callback_t callback, vo
|
|||||||
|
|
||||||
// Verify Binary
|
// Verify Binary
|
||||||
if (!file_obj) {
|
if (!file_obj) {
|
||||||
ERR("%s", "Unable To Open Current Binary");
|
ERR("%s", "Unable To Open Binary");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get File Size
|
// Get File Size
|
||||||
|
@ -97,7 +97,7 @@ char *run_command(const char *const command[], int *return_code) {
|
|||||||
char *output = NULL;
|
char *output = NULL;
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
char buf[BUFFER_SIZE];
|
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) {
|
while ((bytes_read = read(output_pipe[0], (void *) buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */)) > 0) {
|
||||||
buf[bytes_read] = '\0';
|
buf[bytes_read] = '\0';
|
||||||
string_append(&output, "%s", buf);
|
string_append(&output, "%s", buf);
|
||||||
@ -107,7 +107,7 @@ char *run_command(const char *const command[], int *return_code) {
|
|||||||
// Get Return Code
|
// Get Return Code
|
||||||
int status;
|
int status;
|
||||||
waitpid(ret, &status, 0);
|
waitpid(ret, &status, 0);
|
||||||
*return_code = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
|
*return_code = WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE;
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return output;
|
return output;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -7,31 +7,8 @@ set_target_properties(GLESv1_CM PROPERTIES SOVERSION "1")
|
|||||||
|
|
||||||
# Stubs Only Needed For ARM
|
# Stubs Only Needed For ARM
|
||||||
if(BUILD_ARM_COMPONENTS)
|
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
|
# Install Fake GLESv1_CM Stubs In Server Mode
|
||||||
if(MCPI_HEADLESS_MODE)
|
if(MCPI_HEADLESS_MODE)
|
||||||
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Redirect MCPI To Correct Libraries
|
|
||||||
add_subdirectory(redirect)
|
|
||||||
endif()
|
endif()
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
|
|||||||
|
|
||||||
## Mods
|
## 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)
|
target_link_libraries(compat reborn-patch media-layer-core)
|
||||||
|
|
||||||
add_library(readdir SHARED src/readdir/readdir.c)
|
add_library(readdir SHARED src/readdir/readdir.c)
|
||||||
|
18
mods/src/compat/bcm_host.c
Normal file
18
mods/src/compat/bcm_host.c
Normal file
@ -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
|
||||||
|
}
|
@ -28,6 +28,25 @@ HOOK(SDL_ShowCursor, int, (int toggle)) {
|
|||||||
return (*real_SDL_ShowCursor)(toggle == SDL_QUERY ? SDL_QUERY : SDL_DISABLE);
|
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
|
// Intercept SDL Events
|
||||||
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||||
// In Server Mode, Exit Requests Are Handled In src/server/server.cpp
|
// In Server Mode, Exit Requests Are Handled In src/server/server.cpp
|
||||||
|
@ -10,11 +10,6 @@
|
|||||||
|
|
||||||
#include "../home/home.h"
|
#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)
|
// Get Override Path For File (If It Exists)
|
||||||
char *override_get_path(const char *filename) {
|
char *override_get_path(const char *filename) {
|
||||||
// Get MCPI Home Path
|
// Get MCPI Home Path
|
||||||
|
@ -23,7 +23,8 @@ const version = fs.readFileSync('VERSION', 'utf8').trim();
|
|||||||
// Packages/Dependencies
|
// Packages/Dependencies
|
||||||
const packages = [
|
const packages = [
|
||||||
'libc6',
|
'libc6',
|
||||||
'libstdc++6'
|
'libstdc++6',
|
||||||
|
'patchelf'
|
||||||
];
|
];
|
||||||
if (mode === 'client') {
|
if (mode === 'client') {
|
||||||
// GLFW's Dependencies Aren't Included As They Should Be Provided By The Host System
|
// GLFW's Dependencies Aren't Included As They Should Be Provided By The Host System
|
||||||
|
@ -37,7 +37,8 @@ queue_pkg \
|
|||||||
queue_pkg \
|
queue_pkg \
|
||||||
libfreeimage3 libfreeimage-dev \
|
libfreeimage3 libfreeimage-dev \
|
||||||
libopenal-dev \
|
libopenal-dev \
|
||||||
qemu-user
|
qemu-user \
|
||||||
|
patchelf
|
||||||
|
|
||||||
# GLFW Dependencies
|
# GLFW Dependencies
|
||||||
queue_pkg \
|
queue_pkg \
|
||||||
|
Loading…
Reference in New Issue
Block a user