From 054dcba425e8340446395ec861f4fde9ec1dd0ed Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Tue, 10 Nov 2020 15:06:29 -0500 Subject: [PATCH] Improve Error Reporting --- mods/include/libcore/libcore.h | 9 ++++----- mods/src/compat.c | 7 ++----- mods/src/core.c | 28 +++++++++++++++++++++++----- mods/src/cxx11_util.cpp | 6 ++++-- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/mods/include/libcore/libcore.h b/mods/include/libcore/libcore.h index e60100a0..42f43fa8 100644 --- a/mods/include/libcore/libcore.h +++ b/mods/include/libcore/libcore.h @@ -10,6 +10,9 @@ extern "C" { #include #include +#define INFO(msg, ...) fprintf(stderr, "[INFO]: " msg "\n", __VA_ARGS__); +#define ERR(msg, ...) fprintf(stderr, "[ERR]: " msg "\n", __VA_ARGS__); exit(1); + #define HOOK(name, return_type, args) \ typedef return_type (*name##_t)args; \ static name##_t real_##name = NULL; \ @@ -19,17 +22,13 @@ extern "C" { dlerror(); \ real_##name = (name##_t) dlsym(RTLD_NEXT, #name); \ if (!real_##name) { \ - fprintf(stderr, "Error Resolving Symbol: "#name": %s\n", dlerror()); \ - exit(1); \ + ERR("Error Resolving Symbol: "#name": %s", dlerror()); \ } \ } \ }; \ \ __attribute__((__used__)) return_type name args -#define INFO(msg, ...) fprintf(stderr, "[INFO]: " msg "\n", __VA_ARGS__); -#define ERR(msg, ...) fprintf(stderr, "[ERR]: " msg "\n", __VA_ARGS__); exit(1); - void _overwrite_calls(const char *file, int line, void *start, void *target); #define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target); diff --git a/mods/src/compat.c b/mods/src/compat.c index 43ada034..46afe87f 100644 --- a/mods/src/compat.c +++ b/mods/src/compat.c @@ -41,7 +41,6 @@ static void store_x11_window() { // Handle GLFW Error static void glfw_error(__attribute__((unused)) int error, const char *description) { ERR("GLFW Error: %s", description); - exit(1); } // Convert GLFW Key To SDL Key @@ -191,8 +190,7 @@ HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const glfwSetErrorCallback(glfw_error); if (!glfwInit()) { - fprintf(stderr, "Unable To Initialize GLFW\n"); - exit(1); + ERR("%s", "Unable To Initialize GLFW"); } // Create OpenGL ES 1.1 Context @@ -203,8 +201,7 @@ HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const glfw_window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, title, NULL, NULL); if (!glfw_window) { - fprintf(stderr, "Unable To Create GLFW Window\n"); - exit(1); + ERR("%s", "Unable To Create GLFW Window"); } // Don't Process Events In Server Mode diff --git a/mods/src/core.c b/mods/src/core.c index b4c684eb..82d5ab68 100644 --- a/mods/src/core.c +++ b/mods/src/core.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -75,18 +76,20 @@ struct overwrite_data { int line; void *target; void *replacement; + int found; }; static void overwrite_calls_callback(void *section, Elf32_Word size, void *data) { - struct overwrite_data args = *(struct overwrite_data *) data; + struct overwrite_data *args = (struct overwrite_data *) data; for (uint32_t i = 0; i < size; i = i + 4) { unsigned char *addr = ((unsigned char *) section) + i; if (addr[3] == BL_INSTRUCTION) { - uint32_t check_instruction = generate_bl_instruction(addr, args.target); + uint32_t check_instruction = generate_bl_instruction(addr, args->target); unsigned char *check_instruction_array = (unsigned char *) &check_instruction; if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) { - uint32_t new_instruction = generate_bl_instruction(addr, args.replacement); - _patch(args.file, args.line, addr, (unsigned char *) &new_instruction); + uint32_t new_instruction = generate_bl_instruction(addr, args->replacement); + _patch(args->file, args->line, addr, (unsigned char *) &new_instruction); + args->found++; } } } @@ -95,14 +98,22 @@ static void overwrite_calls_callback(void *section, Elf32_Word size, void *data) // Limit To 512 overwrite_calls() Uses #define CODE_BLOCK_SIZE 4096 static unsigned char *code_block = NULL; +#define CODE_SIZE 8 +static int code_block_remaining = CODE_BLOCK_SIZE; // Overwrite Function Calls void _overwrite_calls(const char *file, int line, void *start, void *target) { // BL Instructions Can Only Access A Limited Portion of Memory, So This Allocates Memory Closer To The Original Instruction, That When Run, Will Jump Into The Actual Target if (code_block == NULL) { code_block = mmap((void *) 0x200000, CODE_BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (code_block == MAP_FAILED) { + ERR("Unable To Allocate Code Block: %s", strerror(errno)); + } INFO("Code Block Allocated At: 0x%08x", (uint32_t) code_block); } + if (code_block_remaining < CODE_SIZE) { + ERR("%s", "Maximum Amount Of overwrite_calls() Uses Reached"); + } _overwrite(NULL, -1, code_block, target); struct overwrite_data data; @@ -110,9 +121,16 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) { data.line = line; data.target = start; data.replacement = code_block; + data.found = 0; + iterate_text_section(overwrite_calls_callback, &data); - code_block = code_block + 8; + code_block = code_block + CODE_SIZE; + code_block_remaining = code_block_remaining - CODE_SIZE; + + if (data.found < 1) { + ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) start); + } } // Overwrite Function diff --git a/mods/src/cxx11_util.cpp b/mods/src/cxx11_util.cpp index 180cc1b3..aff0c55e 100644 --- a/mods/src/cxx11_util.cpp +++ b/mods/src/cxx11_util.cpp @@ -4,15 +4,17 @@ #include +#include + #include "cxx11_util.h" // Convert A C-String into A C++11 String That Can be Acessed In C++03 Code cxx11_string create_cxx11_string(const char *str) { std::string *new_str = new std::string(str); int32_t new_size = sizeof (cxx11_string); - int32_t old_size = sizeof *new_str; + int32_t old_size = sizeof (*new_str); if (new_size != old_size) { - fprintf(stderr, "Mismatched String Size: Expected: %i Real: %i\n", new_size, old_size); + ERR("Mismatched String Size: Expected: %i Real: %i", new_size, old_size); } return *reinterpret_cast(new_str); }