From 5bcff694f7c69306e9cdc3c2b575b2a212bc2aa2 Mon Sep 17 00:00:00 2001 From: Kasper Sauramo Date: Thu, 20 Mar 2025 19:00:36 +0200 Subject: [PATCH] use sc_arrays for data --- src/hiload.c | 153 +++++++++++++++++++------------------------------- src/symbols.c | 8 +-- src/symbols.h | 8 ++- 3 files changed, 68 insertions(+), 101 deletions(-) diff --git a/src/hiload.c b/src/hiload.c index a3bf3d2..d3f0146 100644 --- a/src/hiload.c +++ b/src/hiload.c @@ -14,11 +14,10 @@ #include typedef struct { - char **names; // Array of library names - void **handles; // Array of library handles - SymbolInfos *symbols; // Symbol info for modules + struct sc_array_str names; // Array of library names + struct sc_array_ptr handles; // Array of library handles + struct sc_array_syms symbols; // Symbol info for modules size_t count; // Number of libraries - size_t capacity; // Allocated capacity } ModuleInfos; typedef struct { @@ -26,7 +25,6 @@ typedef struct { } HiloadContext; static HiloadContext context = {0}; - static ModuleInfos *module_infos = 0; // Callback function for dl_iterate_phdr @@ -34,50 +32,29 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, void *data) { ModuleInfos *infos = (ModuleInfos *)data; - { - // Resize arrays if needed - if (infos->count >= infos->capacity) { - infos->capacity *= 2; - char **new_names = - realloc(infos->names, infos->capacity * sizeof(char *)); - void **new_handles = - realloc(infos->handles, infos->capacity * sizeof(void *)); - SymbolInfos *new_symbols = - realloc(infos->symbols, infos->capacity * sizeof(SymbolInfos)); - - if (!new_names || !new_handles || !new_symbols) { - return 1; // Stop iteration on error - } - - infos->names = new_names; - infos->handles = new_handles; - infos->symbols = new_symbols; - } - } // Store the module name - infos->names[infos->count] = strdup(info->dlpi_name); - if (!infos->names[infos->count]) { - return 1; // Stop iteration on error - } + sc_array_add(&infos->names, strdup(info->dlpi_name)); - sc_log_info("Processing: %s\n", info->dlpi_name); + sc_log_info("Processing: '%s'\n", info->dlpi_name); // Try to get the handle - infos->handles[infos->count] = - dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); + void *handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); + sc_array_add(&infos->handles, handle); sc_log_debug(" size: %u\n", size); - sc_log_debug(" handle: %p\n", infos->handles[infos->count]); + sc_log_debug(" handle: %p\n", sc_array_last(&infos->handles)); sc_log_debug(" dlpi_addr: %p\n", info->dlpi_addr); sc_log_debug(" dlpi_tls_modid: %zu\n", info->dlpi_tls_modid); sc_log_debug(" dlpi_tls_data: %p\n", info->dlpi_tls_data); - if (hi_create_symbol_info(&infos->symbols[infos->count], - &context.memory_regions, info) != CREATE_SUCCESS) { - fprintf(stderr, "Failed to create symbol info for %s\n", - infos->names[infos->count]); + SymbolInfos symbol_info = {0}; + sc_array_add(&infos->symbols, symbol_info); + if (hi_create_symbol_info(&(sc_array_last(&infos->symbols)), + &context.memory_regions, info) != HILOAD_OK) { + sc_log_error("Failed to create symbol info for %s\n", + info->dlpi_name); } infos->count++; return 0; // Continue iteration @@ -88,18 +65,24 @@ static void free_module_infos(ModuleInfos *modules) { return; for (size_t i = 0; i < modules->count; i++) { - if (modules->names[i]) - free(modules->names[i]); - hi_free_symbol_info(&modules->symbols[i]); + // Free char* before clearing the array + const char *n = 0; + sc_array_foreach(&modules->names, n) { + free((void*)n); + } + sc_array_term(&modules->names); + + // Use a destructor for the symbolinfos + hi_free_symbol_info(&(sc_array_at(&modules->symbols, i))); } - free(modules->names); - free(modules->handles); - free(modules->symbols); + sc_array_term(&modules->names); + sc_array_term(&modules->handles); + sc_array_term(&modules->symbols); free(modules); } -static ModuleInfos *gather_shared_libraries(void) { +static ModuleInfos *gather_module_infos(void) { ModuleInfos *result = NULL; // Allocate the result structure @@ -108,24 +91,7 @@ static ModuleInfos *gather_shared_libraries(void) { return NULL; } - // Initial capacity - result->capacity = 16; - result->names = calloc(result->capacity, sizeof(char *)); - result->handles = calloc(result->capacity, sizeof(void *)); - result->symbols = calloc(result->capacity, sizeof(SymbolInfos)); - - if (!result->names || !result->handles || !result->symbols) { - if (result->names) - free(result->names); - if (result->handles) - free(result->handles); - if (result->symbols) - free(result->symbols); - free(result); - return NULL; - } - - // Iterate over all shared objects + // Iterate over all loaded shared objects if (dl_iterate_phdr(gather_module_infos_callback, result) != 0) { // Error occurred in callback free_module_infos(result); @@ -135,14 +101,6 @@ static ModuleInfos *gather_shared_libraries(void) { return result; } -/** - * Reloads a shared library module - * - * @param modules The ModuleInfos structure containing loaded modules - * @param filename The name of the module to reload - * @param updated_handle Pointer to store the new handle (can be NULL) - * @return ReloadResult indicating success or failure - */ static ReloadResult reload_module(ModuleInfos *modules, const char *filename, void **updated_handle) { if (!modules || !filename) { @@ -155,15 +113,17 @@ static ReloadResult reload_module(ModuleInfos *modules, const char *filename, for (size_t i = 0; i < modules->count; i++) { // Check if this is the module we're looking for - if (modules->names[i] && strcmp(modules->names[i], filename) == 0) { + const char *pathname = sc_array_at(&modules->names, i); + + if (pathname && strcmp(pathname, filename) == 0) { found = 1; index = i; break; } // Also check if the filename is at the end of the path - if (modules->names[i]) { - const char *basename = strrchr(modules->names[i], '/'); + if (pathname) { + const char *basename = strrchr(pathname, '/'); if (basename && strcmp(basename + 1, filename) == 0) { found = 1; index = i; @@ -177,15 +137,15 @@ static ReloadResult reload_module(ModuleInfos *modules, const char *filename, } // Save the full path - char *fullpath = strdup(modules->names[index]); + const char *fullpath = sc_array_at(&modules->names, index); if (!fullpath) { return HI_RELOAD_OPEN_ERROR; } // Close the old handle - if (modules->handles[index]) { - if (dlclose(modules->handles[index]) != 0) { - free(fullpath); + void *handle = sc_array_at(&modules->handles, index); + if (handle) { + if (dlclose(handle) != 0) { return HI_RELOAD_CLOSE_ERROR; } } @@ -193,20 +153,18 @@ static ReloadResult reload_module(ModuleInfos *modules, const char *filename, // Open the module again with RTLD_NOW void *new_handle = dlopen(fullpath, RTLD_NOW); if (!new_handle) { - fprintf(stderr, "Error reloading module: %s\n", dlerror()); - free(fullpath); + sc_log_error("Error reloading module: %s\n", dlerror()); return HI_RELOAD_OPEN_ERROR; } // Update the handle in our structure - modules->handles[index] = new_handle; + modules->handles.elems[index] = new_handle; // If the caller wants the new handle, provide it if (updated_handle) { *updated_handle = new_handle; } - free(fullpath); return HI_RELOAD_SUCCESS; } /** @@ -246,27 +204,29 @@ void hi_print_module_infos() { const ModuleInfos *modules = module_infos; if (!modules) { - printf("No module information available.\n"); + sc_log_error("No module information available.\n"); return; } - printf("Found %zu loaded modules:\n\n", modules->count); + sc_log_info("Found %zu loaded modules:\n\n", modules->count); for (size_t i = 0; i < modules->count; i++) { // Get handle information where possible Dl_info info = {0}; int has_info = 0; - printf("%s: %p\n", modules->names[i], modules->handles[i]); - if (modules->symbols) { - for (int j = 0; j < modules->symbols->names.size; j++) { - const void *addr = modules->symbols->addresses.elems[j]; - const char *name = modules->symbols->names.elems[j]; - printf(" %p: %s\n", addr, name); - } - } + sc_log_debug("%s: %p\n", sc_array_at(&modules->names, i), sc_array_at(&modules->handles, i)); - printf("\n"); + + const SymbolInfos *symbols = &sc_array_at(&modules->symbols, i); + for (int j = 0; j < sc_array_size(&symbols->names); j++) { + const void *addr = sc_array_at(&symbols->addresses, j); + const char *name = sc_array_at(&symbols->names, j); + sc_log_debug(" %p: %s\n", addr, name); + } + + + sc_log_debug("\n"); } } @@ -284,15 +244,20 @@ int hi_init() { return HILOAD_FAIL; } - ModuleInfos *infos = gather_shared_libraries(); + ModuleInfos *infos = gather_module_infos(); if (!infos) { - fprintf(stderr, "Failed to gather module infos.\n"); + sc_log_error("Failed to gather module infos.\n"); return 1; } + + // Override existing if (module_infos) { free_module_infos(module_infos); } + module_infos = infos; + hi_print_module_infos(); + return 0; } diff --git a/src/symbols.c b/src/symbols.c index 39bb5cd..47fd822 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -26,12 +26,12 @@ add_ptr_offset_if_invalid(uptr p, uptr offset, * Will clear and free the given SymbolInfo struct. Allocates enough memory to * hold found symbols. */ -CreateResult hi_create_symbol_info(SymbolInfos *symbols, +HiloadResult hi_create_symbol_info(SymbolInfos *symbols, struct sc_array_memreg *const regions, struct dl_phdr_info *info) { if (!symbols) - return CREATE_FAILED; + return HILOAD_FAIL; hi_free_symbol_info(symbols); @@ -86,7 +86,7 @@ CreateResult hi_create_symbol_info(SymbolInfos *symbols, if (!strtab || !symtab || strtab_size == 0 || symtab_size == 0) { sc_log_error("Failed to find symbol or string table in %s\n", info->dlpi_name); - return CREATE_FAILED; + return HILOAD_FAIL; } // Iterate over the symbol table @@ -104,7 +104,7 @@ CreateResult hi_create_symbol_info(SymbolInfos *symbols, } } - return CREATE_SUCCESS; + return HILOAD_OK; } void hi_free_symbol_info(SymbolInfos *symbols) { diff --git a/src/symbols.h b/src/symbols.h index 29dd567..8aaeca5 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -2,22 +2,24 @@ #define SYMBOLS_H_ #include "memory.h" +#include "types.h" #include #include #include + typedef struct { struct sc_array_str names; struct sc_array_ptr addresses; } SymbolInfos; -typedef enum { CREATE_SUCCESS = 0, CREATE_FAILED } CreateResult; +sc_array_def(SymbolInfos, syms); + struct dl_phdr_info; struct sc_array_memreg; - -CreateResult hi_create_symbol_info(SymbolInfos *, +HiloadResult hi_create_symbol_info(SymbolInfos *, struct sc_array_memreg *const regions, struct dl_phdr_info *); void hi_free_symbol_info(SymbolInfos *);