only do local object copy for the local module
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user