only do local object copy for the local module

This commit is contained in:
2025-04-28 00:07:45 +03:00
parent b0d3c57615
commit 7d2ac662d0
4 changed files with 49 additions and 38 deletions

View File

@@ -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);

View File

@@ -16,11 +16,11 @@
#include <gelf.h>
#include <libelf.h>
#include <link.h>
#include <stdalign.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <unistd.h>
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);

View File

@@ -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;

View File

@@ -4,7 +4,7 @@ namespace minimal_lib {
int getNewValue(int x) {
static int value = 0;
value = value + 1;
value = value + 5;
return value;
}