preload symbol names for each loaded, non library module
This commit is contained in:
80
src/hiload.c
80
src/hiload.c
@@ -1,7 +1,6 @@
|
||||
#include "hiload/hiload.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include "logger/sc_log.h"
|
||||
#include "memory.h"
|
||||
#include "symbols.h"
|
||||
#include "types.h"
|
||||
@@ -14,10 +13,10 @@
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
struct sc_array_str names; // Array of library names
|
||||
struct sc_array_ptr handles; // Array of library handles
|
||||
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 count; // Number of modules
|
||||
} ModuleInfos;
|
||||
|
||||
typedef struct {
|
||||
@@ -27,6 +26,22 @@ typedef struct {
|
||||
static HiloadContext context = {0};
|
||||
static ModuleInfos *module_infos = 0;
|
||||
|
||||
// if the pathname contains these, skip them from early gathering
|
||||
// as they are unlikely to be changed, and would bloat our memory
|
||||
const char *path_filter_list[] = {"libstdc++.", "libc++.", "libc.", "libm.",
|
||||
"libgcc", "ld-linux-", NULL};
|
||||
|
||||
static inline int if_load_symbols_for_module(struct dl_phdr_info *info) {
|
||||
const char *name = info->dlpi_name;
|
||||
|
||||
for (int i = 0; path_filter_list[i] != NULL; i++) {
|
||||
if (strstr(name, path_filter_list[i]) != NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Callback function for dl_iterate_phdr
|
||||
static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
||||
void *data) {
|
||||
@@ -40,23 +55,29 @@ 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);
|
||||
sc_array_add(&infos->handles, handle);
|
||||
assert(handle);
|
||||
infos->count++;
|
||||
|
||||
sc_array_add(&infos->handles, handle);
|
||||
sc_log_debug(" size: %u\n", size);
|
||||
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);
|
||||
|
||||
|
||||
SymbolInfos symbol_info = {0};
|
||||
sc_array_add(&infos->symbols, symbol_info);
|
||||
|
||||
if (!if_load_symbols_for_module(info)) {
|
||||
sc_log_info("Skipping symbol preload for: %s\n", info->dlpi_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
sc_log_error("Failed to create symbol info for %s\n", info->dlpi_name);
|
||||
}
|
||||
infos->count++;
|
||||
|
||||
return 0; // Continue iteration
|
||||
}
|
||||
|
||||
@@ -67,9 +88,7 @@ static void free_module_infos(ModuleInfos *modules) {
|
||||
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((void*)n);
|
||||
}
|
||||
sc_array_foreach(&modules->names, n) { free((void *)n); }
|
||||
sc_array_term(&modules->names);
|
||||
|
||||
// Use a destructor for the symbolinfos
|
||||
@@ -167,34 +186,12 @@ static ReloadResult reload_module(ModuleInfos *modules, const char *filename,
|
||||
|
||||
return HI_RELOAD_SUCCESS;
|
||||
}
|
||||
/**
|
||||
* Helper function to print the result of a module reload
|
||||
*/
|
||||
static void print_reload_result(ReloadResult result, const char *filename) {
|
||||
switch (result) {
|
||||
case HI_RELOAD_SUCCESS:
|
||||
printf("Successfully reloaded module: %s\n", filename);
|
||||
break;
|
||||
case HI_RELOAD_NOT_FOUND:
|
||||
printf("Module not found: %s\n", filename);
|
||||
break;
|
||||
case HI_RELOAD_CLOSE_ERROR:
|
||||
printf("Error closing module: %s\n", filename);
|
||||
break;
|
||||
case HI_RELOAD_OPEN_ERROR:
|
||||
printf("Error reopening module: %s\n", filename);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown error reloading module: %s\n", filename);
|
||||
}
|
||||
}
|
||||
|
||||
ReloadResult hi_reload_module(const char *module_name) {
|
||||
assert(module_infos);
|
||||
|
||||
void *new_handle = NULL;
|
||||
ReloadResult result = reload_module(module_infos, module_name, &new_handle);
|
||||
print_reload_result(result, module_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -215,16 +212,15 @@ void hi_print_module_infos() {
|
||||
Dl_info info = {0};
|
||||
int has_info = 0;
|
||||
|
||||
sc_log_debug("%s: %p\n", sc_array_at(&modules->names, i), sc_array_at(&modules->handles, i));
|
||||
|
||||
sc_log_debug("'%s': %p\n", sc_array_at(&modules->names, i),
|
||||
sc_array_at(&modules->handles, i));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user