From 7d2ac662d0e9cc362ecdfea0edbe8476064f7d4d Mon Sep 17 00:00:00 2001 From: Kasper Date: Mon, 28 Apr 2025 00:07:45 +0300 Subject: [PATCH] only do local object copy for the local module --- src/hiload.c | 2 +- src/moduler/moduler.c | 81 +++++++++++++++++++++---------------- test/manual/minimal.cpp | 2 +- test/manual/minimal_lib.cpp | 2 +- 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/hiload.c b/src/hiload.c index af05801..0f15d87 100644 --- a/src/hiload.c +++ b/src/hiload.c @@ -36,7 +36,7 @@ static int gather_module_data_callback(struct dl_phdr_info *info, size_t size, // '' for executable, fname for rest const char *modname = info->dlpi_name; - log_info("Processing: '%s'\n", info->dlpi_name); + log_info("Found: '%s'\n", info->dlpi_name); // Try to get the handle void *handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); diff --git a/src/moduler/moduler.c b/src/moduler/moduler.c index 3528cc1..28100d4 100644 --- a/src/moduler/moduler.c +++ b/src/moduler/moduler.c @@ -16,11 +16,11 @@ #include #include #include +#include #include #include #include - static void *adjust_if_relative(void *ptr, void *module_base) { uptr p = (uptr)ptr; if (p && (p < (uptr)module_base)) { @@ -119,7 +119,9 @@ static HiloadResult gather_patchable_symbols(struct sc_array_sym *symbols, // Assumption: Only symbols with size are defined here, and those // without are safely ignored. Linker will handle them. - if (sym.st_size == 0) { + // Assumption: completed.0 seems to be size 1 and appears locally, lets + // assume its useless + if (sym.st_size <= 1) { continue; } @@ -160,7 +162,7 @@ cleanup: return ret; } -static HiloadResult moduler_apply_module_patch(HiSymbols *psymbols, HiSymbols *msymbols, +static HiloadResult moduler_apply_module_patch(HiSymbols *psymbols, MemoryRegionSpan module_memory) { void *module_base = (void *)module_memory.region_start; @@ -255,29 +257,13 @@ static HiloadResult moduler_apply_module_patch(HiSymbols *psymbols, HiSymbols *m *got_entry = sym->address; log_debug("Found GOT entry for '%s' at %p (points to %p)\n", name, - got_entry, *got_entry); + got_entry, *got_entry); found_count++; } } } - // Copy old data to new data. Breaks with layout changes. - for (size_t i = 0; i < sc_array_size(msymbols); ++i) { - HiSymbol *sym = &sc_array_at(msymbols, i); - if (sym->type == HI_SYMBOL_TYPE_OBJECT) { - HiSymbol *ps = symbol_find(psymbols, sym); - if (ps) { - if (ps->size >= sym->size) { - memcpy(ps->address, sym->address, sym->size); - } else { - memcpy(ps->address, sym->address, ps->size); - } - log_debug("Copied data for symbol: %s\n", sym->name); - } - } - } - elf_end(elf); return HILOAD_OK; } @@ -295,8 +281,8 @@ HiloadResult moduler_reload(HiModuleArray *modules, HiModuleData *module, dlerror(); // clear old errors char patch_filename[512]; - size_t written = - hi_strncat_buf(sizeof(patch_filename), patch_filename, module->name, ".patch"); + size_t written = hi_strncat_buf(sizeof(patch_filename), patch_filename, + module->name, ".patch"); if (written == 0) { log_error("Failed to concat %s and %s\n", module->name, ".patch"); return HILOAD_FAIL; @@ -313,16 +299,18 @@ HiloadResult moduler_reload(HiModuleArray *modules, HiModuleData *module, return HILOAD_FAIL; } - // refresh before using + // refresh cache read_memory_maps_self(memregs); - MemoryRegionSpan patch_memory = memory_get_module_span(memregs, patch_filename); + MemoryRegionSpan patch_memory = + memory_get_module_span(memregs, patch_filename); void *patch_base = (void *)patch_memory.region_start; HiSymbols patch_symbols; symbol_init_symbols(&patch_symbols); - HiloadResult ret = gather_patchable_symbols(&patch_symbols, patch_filename, patch_base); + HiloadResult ret = + gather_patchable_symbols(&patch_symbols, patch_filename, patch_base); if (!HIOK(ret)) { log_error("Failed to gather symbols for %s\n", patch_filename); return HILOAD_FAIL; @@ -334,19 +322,42 @@ HiloadResult moduler_reload(HiModuleArray *modules, HiModuleData *module, if (!hi_modinfo_has(mod.info, HI_MODULE_STATE_PATCHABLE)) continue; - HiSymbols module_symbols; - symbol_init_symbols(&module_symbols); - ret = gather_patchable_symbols(&module_symbols, mod.name, (void*)mod.address); - if (!HIOK(ret)) { - log_error("Failed to gather symbols for %s\n", mod.name); - symbol_term_symbols(&module_symbols); - continue; - } MemoryRegionSpan module_memory = memory_get_module_span(memregs, mod.name); - moduler_apply_module_patch(&patch_symbols, &module_symbols, module_memory); + moduler_apply_module_patch(&patch_symbols, module_memory); + + // If patch is for the same module, also collect local object symbols for + // coping those over + if (strncmp(mod.name, patch_filename, strlen(mod.name)) == 0) { + + HiSymbols module_symbols; + symbol_init_symbols(&module_symbols); + ret = gather_patchable_symbols(&module_symbols, mod.name, + (void *)mod.address); + if (!HIOK(ret)) { + log_error("Failed to gather symbols for %s\n", mod.name); + symbol_term_symbols(&module_symbols); + continue; + } + + // Copy old data to new data. Breaks with layout changes. + for (size_t i = 0; i < sc_array_size(&module_symbols); ++i) { + HiSymbol *sym = &sc_array_at(&module_symbols, i); + if (sym->type == HI_SYMBOL_TYPE_OBJECT) { + HiSymbol *ps = symbol_find(&patch_symbols, sym); + if (ps) { + if (ps->size >= sym->size) { + memcpy(ps->address, sym->address, sym->size); + } else { + memcpy(ps->address, sym->address, ps->size); + } + log_debug("Copied data for symbol: %s\n", sym->name); + } + } + } + symbol_term_symbols(&module_symbols); + } module->info = hi_modinfo_clear(module->info, HI_MODULE_STATE_DIRTY); - symbol_term_symbols(&module_symbols); } symbol_term_symbols(&patch_symbols); diff --git a/test/manual/minimal.cpp b/test/manual/minimal.cpp index d624bfe..f2f23c0 100644 --- a/test/manual/minimal.cpp +++ b/test/manual/minimal.cpp @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) { - const char *reloadable_modules[] = {"", "libmini.so", "libhiload.so"}; + const char *reloadable_modules[] = {"", "libmini.so"}; hi_init(ARRLEN(reloadable_modules), reloadable_modules); int modified = -1; diff --git a/test/manual/minimal_lib.cpp b/test/manual/minimal_lib.cpp index 670bd34..a0fccf0 100644 --- a/test/manual/minimal_lib.cpp +++ b/test/manual/minimal_lib.cpp @@ -4,7 +4,7 @@ namespace minimal_lib { int getNewValue(int x) { static int value = 0; - value = value + 1; + value = value + 5; return value; }