From 09d5020494f28c9bec06390817fbb18b8e59e128 Mon Sep 17 00:00:00 2001 From: Kasper Date: Fri, 18 Apr 2025 14:39:09 +0300 Subject: [PATCH] Use AoS for modules instead of SoA --- src/hiload.c | 120 +++++++++++++++++------------------------- src/logger/logger.c | 2 +- src/moduler/elf.h | 1 + src/moduler/moduler.c | 16 +++--- src/moduler/moduler.h | 22 ++++---- 5 files changed, 70 insertions(+), 91 deletions(-) diff --git a/src/hiload.c b/src/hiload.c index bb802b5..09063f5 100644 --- a/src/hiload.c +++ b/src/hiload.c @@ -23,17 +23,16 @@ typedef struct { struct sc_array_memreg memory_regions; struct sc_array_str enabled_modules; struct hiFileWatcher *filewatcher; - ModuleInfos *loaded_modules; + HiModuleArray modules; } HiloadContext; static HiloadContext context = {0}; // Callback function for dl_iterate_phdr -static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, - void *data) { - - ModuleInfos *mod_infos = (ModuleInfos *)data; +static int gather_module_data_callback(struct dl_phdr_info *info, size_t size, + void *data) { + // '' for executable, fname for rest const char *modname = info->dlpi_name; log_info("Processing: '%s'\n", info->dlpi_name); @@ -41,12 +40,11 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, // Try to get the handle void *handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); assert(handle); - mod_infos->count++; - sc_array_add(&mod_infos->handles, handle); - sc_array_add(&mod_infos->addresses, info->dlpi_addr); + HiModuleData module = {0}; + module.address = info->dlpi_addr; + log_debugv(" header size: %u\n", size); - log_debugv(" handle: %p\n", sc_array_last(&mod_infos->handles)); log_debugv(" dlpi_addr: %p\n", info->dlpi_addr); log_debugv(" dlpi_tls_modid: %zu\n", info->dlpi_tls_modid); log_debugv(" dlpi_tls_data: %p\n", info->dlpi_tls_data); @@ -57,7 +55,7 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, // Store the full name. Differs from dlpi_name for the executable only, // afaik const char *modpath = dl_info.dli_fname; - sc_array_add(&mod_infos->names, strdup(modpath)); + module.name = strdup(modpath); log_debugv("dli_fname: %s\n", dl_info.dli_fname); log_debugv("dli_sname: %s\n", dl_info.dli_sname); @@ -69,8 +67,7 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, sc_array_at(&context.enabled_modules, i))) { // Replace shortform with str pointer from module info - sc_array_at(&context.enabled_modules, i) = - sc_array_last(&mod_infos->names); + sc_array_at(&context.enabled_modules, i) = module.name; // Add filewatcher if (!HILOADRES(hi_file_watcher_add(context.filewatcher, modpath, @@ -82,62 +79,51 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, } } } else { - sc_array_add(&mod_infos->names, strdup(modname)); - log_error("Couldn't load dlinfo for %s: %s\n", - (sc_array_last(&mod_infos->names)), dlerror()); + module.name = strdup(modname); + log_error("Couldn't load dlinfo for %s: %s\n", module.name, dlerror()); } + HiModuleArray *modules = (HiModuleArray *)data; + sc_array_add(modules, module); + return 0; // Continue iteration } -static void module_infos_free(ModuleInfos *modules) { +static void module_infos_free(HiModuleArray *modules) { if (!modules) return; - for (size_t i = 0; i < modules->count; i++) { - // Free char* before clearing the array - const char *n = 0; - sc_array_foreach(&modules->names, n) { free((char *)n); } - sc_array_term(&modules->names); - - // Use a destructor for the symbolinfos - hi_free_symbol_info(&(sc_array_at(&modules->symbols, i))); + for (size_t i = 0; i < sc_array_size(modules); i++) { + free((char*)sc_array_at(modules, i).name); } - sc_array_term(&modules->names); - sc_array_term(&modules->handles); - sc_array_term(&modules->symbols); free(modules); } -static ModuleInfos *gather_module_infos(void) { - ModuleInfos *result = NULL; +HiloadResult gather_module_infos(HiModuleArray *modules) { - // Allocate the result structure - result = calloc(1, sizeof(ModuleInfos)); - if (!result) { - return NULL; - } + sc_array_init(modules); // Iterate over all loaded shared objects - if (dl_iterate_phdr(gather_module_infos_callback, result) != 0) { + if (dl_iterate_phdr(gather_module_data_callback, modules) != 0) { // Error occurred in callback - module_infos_free(result); - return NULL; + module_infos_free(modules); + return HILOAD_FAIL; } - return result; + return HILOAD_OK; } -static i32 get_module_index_by_path(const char *path, ModuleInfos *modinfos) { +static HiModuleData *get_module_by_path(const char *path, HiModuleArray *modules) { - for (size_t i = 0; i < modinfos->count; i++) { - const char *name = sc_array_at(&modinfos->names, i); + for (size_t i = 0; i < sc_array_size(modules); i++) { + HiModuleData *module = &sc_array_at(modules, i); + const char *name = module->name; if (strcmp(name, path) == 0) { - return i; + return module; } } - return -1; + return NULL; } /** @@ -145,56 +131,54 @@ static i32 get_module_index_by_path(const char *path, ModuleInfos *modinfos) { * * Marks a module dirty if there has been any event. */ -static void handle_events(struct hiFileWatcher *fw, ModuleInfos *modinfos) { +static void handle_events(struct hiFileWatcher *fw, HiModuleArray *modules) { hiFileEvent event = hi_file_event_pop(fw); while (event.type != HI_FILE_NONE) { log_debug("Event pop: %s – %s\n", event.pathname, hi_file_watch_type_to_str(event.type)); - i32 index = get_module_index_by_path(event.pathname, modinfos); - if (index < 0) { + HiModuleData *module = get_module_by_path(event.pathname, modules); + if (!module) { log_warn("Watched module: %s not found.\n", event.pathname); } else { - context.loaded_modules->state[index] = HI_MODULE_STATE_DIRTY; + module->state = HI_MODULE_STATE_DIRTY; } event = hi_file_event_pop(context.filewatcher); } } -static i32 get_string_index(const char *needle, +static const char* find_string_from_array(const char *needle, const struct sc_array_str *haystack) { - i32 index = -1; + for (size_t i = 0; i < sc_array_size(haystack); i++) { if (strcmp(needle, sc_array_at(haystack, i)) == 0) { - index = i; - break; + return sc_array_at(haystack, i); } } - return index; + return NULL; } static HiloadResult reload_dirty_modules(HiloadContext *context) { HiloadResult ret = HILOAD_OK; - for (u8 i = 0; i < context->loaded_modules->count; i++) { - const char *module_name = sc_array_at(&context->loaded_modules->names, i); + for (u8 i = 0; i < sc_array_size(&context->modules); i++) { + HiModuleData *module = &sc_array_at(&context->modules, i); // Operate on dirty modules only - if (context->loaded_modules->state[i] == HI_MODULE_STATE_DIRTY) { + if (module->state == HI_MODULE_STATE_DIRTY) { // Operate only if the module is marked as operatable - i32 module_index = - get_string_index(module_name, &context->enabled_modules); - if (module_index != -1) { + const char *module_name = find_string_from_array(module->name, &context->enabled_modules); + if (module_name) { log_info("Reloading %s...\n", module_name); - if (moduler_reload(context->loaded_modules, &context->memory_regions, - i) != HILOAD_OK) { + if (moduler_reload(module, &context->memory_regions) != HILOAD_OK) { ret = HILOAD_FAIL; - log_error("Failed loading: %s\n", module_name); + log_error("Failed loading: %s\n", module->name); } + log_info("Reloaded\n"); } } } @@ -203,7 +187,7 @@ static HiloadResult reload_dirty_modules(HiloadContext *context) { HiloadResult hi_reload() { - handle_events(context.filewatcher, context.loaded_modules); + handle_events(context.filewatcher, &context.modules); reload_dirty_modules(&context); return HILOAD_OK; } @@ -231,23 +215,17 @@ int hi_init(unsigned n, const char **enabled_modules) { return HILOAD_FAIL; } - ModuleInfos *infos = gather_module_infos(); - if (!infos) { + HiloadResult re = gather_module_infos(&context.modules); + if (re == HILOAD_OK) { log_error("Failed to gather module infos.\n"); return 1; } - // Override existing - if (context.loaded_modules) { - module_infos_free(context.loaded_modules); - } - - context.loaded_modules = infos; return 0; } void hi_deinit() { - module_infos_free(context.loaded_modules); + module_infos_free(&context.modules); hi_file_watcher_destroy(context.filewatcher); log_term(); memset(&context, 0, sizeof(context)); diff --git a/src/logger/logger.c b/src/logger/logger.c index 6ad72bf..2f90021 100644 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -2,7 +2,7 @@ #include -_Atomic bool hiload_verbose_log = true; +_Atomic bool hiload_verbose_log = false; void log_set_verbose(bool value) { atomic_store_explicit(&hiload_verbose_log, value, memory_order_relaxed); diff --git a/src/moduler/elf.h b/src/moduler/elf.h index 679bb5d..9af8937 100644 --- a/src/moduler/elf.h +++ b/src/moduler/elf.h @@ -2,6 +2,7 @@ #define ELF_H_ #include +#include const char *dyn_type_to_str(unsigned type); const char *segment_type_to_str(unsigned type); diff --git a/src/moduler/moduler.c b/src/moduler/moduler.c index 1db5556..99208c0 100644 --- a/src/moduler/moduler.c +++ b/src/moduler/moduler.c @@ -4,11 +4,12 @@ #include "memory.h" #include "moduler/elf.h" #include "types.h" +#include -HiloadResult moduler_reload(ModuleInfos *modinfos, - const struct sc_array_memreg *const memregs, - int modindex) { - const char *modname = sc_array_at(&modinfos->names, modindex); +HiloadResult moduler_reload(HiModuleData *module, + const struct sc_array_memreg *const memregs) { + + const char *modname = module->name; MemoryRegionSpan memspan = memory_get_module_span(memregs, modname); log_debugv("Module: %s - [%p, %p]\n", modname, memspan.region_start, memspan.region_end); @@ -18,9 +19,10 @@ HiloadResult moduler_reload(ModuleInfos *modinfos, int err = elf_errno(); if (err) { log_error("%s\n", elf_errmsg(err)); + return HILOAD_FAIL; } - void *module_address = (void *)sc_array_at(&modinfos->addresses, modindex); + void *module_address = (void *)module->address; size_t phdrnum = 0; err = elf_getphdrnum(elf, &phdrnum); @@ -76,7 +78,7 @@ HiloadResult moduler_reload(ModuleInfos *modinfos, } ++dyn; } - printf("strtab: %p\n" + log_debugv("\nstrtab: %p\n" "symtab: %p\n" "strsz: %zu\n" "syment: %zu\n" @@ -94,6 +96,6 @@ HiloadResult moduler_reload(ModuleInfos *modinfos, } - modinfos->state[modindex] = HI_MODULE_STATE_CLEAN; + module->state = HI_MODULE_STATE_CLEAN; return HILOAD_OK; } diff --git a/src/moduler/moduler.h b/src/moduler/moduler.h index be491dc..26fd2f5 100644 --- a/src/moduler/moduler.h +++ b/src/moduler/moduler.h @@ -8,24 +8,22 @@ struct HiloadContext; -sc_array_def(uptr, uptr); - enum HiModuleState { HI_MODULE_STATE_CLEAN = 0, HI_MODULE_STATE_DIRTY, }; typedef struct { - struct sc_array_str names; // Array of library names - struct sc_array_ptr handles; // Array of library handles - struct sc_array_uptr addresses; // Array of library base addresses - struct sc_array_syms symbols; // Symbol info for modules - u8 state[256]; // Flag for when module needs to be changed - size_t count; // Number of modules -} ModuleInfos; + const char *name; // Filename if found + uptr address; + u8 state; +} HiModuleData; +sc_array_def(HiModuleData, module); + +typedef struct sc_array_module HiModuleArray; + +HiloadResult moduler_reload(HiModuleData *module, + const struct sc_array_memreg *const memregs); -HiloadResult moduler_reload(ModuleInfos *modinfos, - const struct sc_array_memreg *const memregs, - int modindex); #endif // MODULER_H_