remove the symbol-table walking
it wasn't feasible without knowledge of the size which I couldn't find without reading the elf file. Moreover, it wasn't really required and was halting progress
This commit is contained in:
22
src/hiload.c
22
src/hiload.c
@@ -43,7 +43,8 @@ static inline int if_load_symbols_for_module(struct dl_phdr_info *info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Callback function for dl_iterate_phdr
|
// Callback function for dl_iterate_phdr
|
||||||
static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
static
|
||||||
|
int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
||||||
void *data) {
|
void *data) {
|
||||||
|
|
||||||
ModuleInfos *infos = (ModuleInfos *)data;
|
ModuleInfos *infos = (ModuleInfos *)data;
|
||||||
@@ -68,20 +69,11 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
|||||||
SymbolInfos symbol_info = {0};
|
SymbolInfos symbol_info = {0};
|
||||||
sc_array_add(&infos->symbols, symbol_info);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; // Continue iteration
|
return 0; // Continue iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_module_infos(ModuleInfos *modules) {
|
static
|
||||||
|
void free_module_infos(ModuleInfos *modules) {
|
||||||
if (!modules)
|
if (!modules)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -101,7 +93,8 @@ static void free_module_infos(ModuleInfos *modules) {
|
|||||||
free(modules);
|
free(modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ModuleInfos *gather_module_infos(void) {
|
static
|
||||||
|
ModuleInfos *gather_module_infos(void) {
|
||||||
ModuleInfos *result = NULL;
|
ModuleInfos *result = NULL;
|
||||||
|
|
||||||
// Allocate the result structure
|
// Allocate the result structure
|
||||||
@@ -120,7 +113,8 @@ static ModuleInfos *gather_module_infos(void) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReloadResult reload_module(ModuleInfos *modules, const char *filename,
|
static
|
||||||
|
ReloadResult reload_module(ModuleInfos *modules, const char *filename,
|
||||||
void **updated_handle) {
|
void **updated_handle) {
|
||||||
if (!modules || !filename) {
|
if (!modules || !filename) {
|
||||||
return HI_RELOAD_NOT_FOUND;
|
return HI_RELOAD_NOT_FOUND;
|
||||||
|
|||||||
102
src/symbols.c
102
src/symbols.c
@@ -4,13 +4,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <elf.h>
|
|
||||||
#include <link.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static inline uptr
|
static inline uptr
|
||||||
add_ptr_offset_if_invalid(uptr p, uptr offset,
|
add_ptr_offset_if_invalid(uptr p, uptr offset,
|
||||||
@@ -20,102 +14,6 @@ add_ptr_offset_if_invalid(uptr p, uptr offset,
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gathers and populates symbols, given a dynamic module info
|
|
||||||
*/
|
|
||||||
HiloadResult hi_create_symbol_info(SymbolInfos *symbols,
|
|
||||||
struct sc_array_memreg *const regions,
|
|
||||||
struct dl_phdr_info *info) {
|
|
||||||
|
|
||||||
if (!symbols)
|
|
||||||
return HILOAD_FAIL;
|
|
||||||
|
|
||||||
hi_free_symbol_info(symbols);
|
|
||||||
|
|
||||||
for (int i = 0; i < info->dlpi_phnum; i++) {
|
|
||||||
const ElfW(Phdr) *phdr = &info->dlpi_phdr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < info->dlpi_phnum; i++) {
|
|
||||||
const ElfW(Phdr) *phdr = &info->dlpi_phdr[i];
|
|
||||||
|
|
||||||
// Look for the dynamic segment
|
|
||||||
if (phdr->p_type != PT_DYNAMIC)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sc_log_debug("Dynamic Header:\n");
|
|
||||||
sc_log_debug("p_type: %u\n", phdr->p_type);
|
|
||||||
sc_log_debug("p_flags: %u\n", phdr->p_flags);
|
|
||||||
sc_log_debug("p_offset: %#06lx\n", phdr->p_offset);
|
|
||||||
sc_log_debug("p_vaddr: %#06lx\n", phdr->p_vaddr);
|
|
||||||
sc_log_debug("p_paddr: %#06lx\n", phdr->p_paddr);
|
|
||||||
sc_log_debug("p_filesz: %zu\n", phdr->p_filesz);
|
|
||||||
sc_log_debug("p_memsz: %zu\n", phdr->p_memsz);
|
|
||||||
sc_log_debug("p_align: %zu\n", phdr->p_align);
|
|
||||||
|
|
||||||
const ElfW(Dyn) *dyn = (const ElfW(Dyn) *)(info->dlpi_addr + phdr->p_vaddr);
|
|
||||||
const char *strtab = NULL;
|
|
||||||
const ElfW(Sym) *symtab = NULL;
|
|
||||||
size_t strtab_size = 0;
|
|
||||||
|
|
||||||
uptr off = info->dlpi_addr;
|
|
||||||
// Parse the dynamic table. Add offset if address is not in executable
|
|
||||||
// memory. NOTE: Haven't found a better way to differentiate with items that
|
|
||||||
// have relative address, and items that don't.
|
|
||||||
for (; dyn->d_tag != DT_NULL; dyn++) {
|
|
||||||
|
|
||||||
if (dyn->d_tag == DT_STRTAB) {
|
|
||||||
uptr p = dyn->d_un.d_ptr;
|
|
||||||
p = add_ptr_offset_if_invalid(p, off, regions);
|
|
||||||
strtab = (const char *)p;
|
|
||||||
|
|
||||||
} else if (dyn->d_tag == DT_STRSZ) {
|
|
||||||
strtab_size = dyn->d_un.d_val;
|
|
||||||
|
|
||||||
} else if (dyn->d_tag == DT_SYMTAB) {
|
|
||||||
uptr p = dyn->d_un.d_ptr;
|
|
||||||
p = add_ptr_offset_if_invalid(p, off, regions);
|
|
||||||
symtab = (const ElfW(Sym) *)(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we found the symbol and string tables
|
|
||||||
if (!strtab || !symtab || strtab_size == 0) {
|
|
||||||
sc_log_error("Failed to find symbol or string table in %s\n",
|
|
||||||
info->dlpi_name);
|
|
||||||
return HILOAD_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate over the symbol table
|
|
||||||
// We assume the dynsym and dynstr are linked
|
|
||||||
const char *strptr = strtab;
|
|
||||||
|
|
||||||
for (const ElfW(Sym) *sym = symtab;; sym++) {
|
|
||||||
|
|
||||||
// escape if we'd hit the end of string table
|
|
||||||
strptr = strtab + sym->st_name;
|
|
||||||
if (strptr + strlen(strptr) + 1 >= strtab + strtab_size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ELF64_ST_TYPE(sym->st_info) == STT_FUNC ||
|
|
||||||
ELF64_ST_TYPE(sym->st_info) == STT_OBJECT) {
|
|
||||||
const char *name = strdup(strtab + sym->st_name);
|
|
||||||
void *address = (void *)(info->dlpi_addr + sym->st_value);
|
|
||||||
|
|
||||||
// Store the symbol information in the arrays
|
|
||||||
sc_array_add(&symbols->names, name);
|
|
||||||
sc_array_add(&symbols->addresses, address);
|
|
||||||
|
|
||||||
sc_log_debug("%s: %p\n", name, address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log_debug("Symbols for %s gathered...\n", info->dlpi_name);
|
|
||||||
|
|
||||||
return HILOAD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hi_free_symbol_info(SymbolInfos *symbols) {
|
void hi_free_symbol_info(SymbolInfos *symbols) {
|
||||||
for (size_t i = 0; i < symbols->names.size; i++) {
|
for (size_t i = 0; i < symbols->names.size; i++) {
|
||||||
free((void *)symbols->names.elems[i]);
|
free((void *)symbols->names.elems[i]);
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ typedef struct {
|
|||||||
|
|
||||||
sc_array_def(SymbolInfos, syms);
|
sc_array_def(SymbolInfos, syms);
|
||||||
|
|
||||||
struct dl_phdr_info;
|
|
||||||
struct sc_array_memreg;
|
|
||||||
HiloadResult hi_create_symbol_info(SymbolInfos *,
|
|
||||||
struct sc_array_memreg *const regions,
|
|
||||||
struct dl_phdr_info *);
|
|
||||||
void hi_free_symbol_info(SymbolInfos *);
|
void hi_free_symbol_info(SymbolInfos *);
|
||||||
|
|
||||||
#endif // SYMBOLS_H_
|
#endif // SYMBOLS_H_
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
project(Minimal)
|
project(Minimal)
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
|
add_compile_options(-g -ffunction-sections -fdata-sections)
|
||||||
|
|
||||||
add_executable(minimal
|
add_executable(minimal
|
||||||
minimal.cpp
|
minimal.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user