preload symbol names for each loaded, non library module
This commit is contained in:
@@ -22,9 +22,6 @@ add_ptr_offset_if_invalid(uptr p, uptr offset,
|
||||
|
||||
/**
|
||||
* Gathers and populates symbols, given a dynamic module info
|
||||
*
|
||||
* Will clear and free the given SymbolInfo struct. Allocates enough memory to
|
||||
* hold found symbols.
|
||||
*/
|
||||
HiloadResult hi_create_symbol_info(SymbolInfos *symbols,
|
||||
struct sc_array_memreg *const regions,
|
||||
@@ -35,6 +32,10 @@ HiloadResult hi_create_symbol_info(SymbolInfos *symbols,
|
||||
|
||||
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];
|
||||
|
||||
@@ -55,13 +56,12 @@ HiloadResult hi_create_symbol_info(SymbolInfos *symbols,
|
||||
const ElfW(Dyn) *dyn = (const ElfW(Dyn) *)(info->dlpi_addr + phdr->p_vaddr);
|
||||
const char *strtab = NULL;
|
||||
const ElfW(Sym) *symtab = NULL;
|
||||
size_t symtab_size = 0;
|
||||
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.
|
||||
// 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) {
|
||||
@@ -76,34 +76,43 @@ HiloadResult hi_create_symbol_info(SymbolInfos *symbols,
|
||||
uptr p = dyn->d_un.d_ptr;
|
||||
p = add_ptr_offset_if_invalid(p, off, regions);
|
||||
symtab = (const ElfW(Sym) *)(p);
|
||||
|
||||
} else if (dyn->d_tag == DT_SYMENT) {
|
||||
symtab_size = dyn->d_un.d_val;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we found the symbol and string tables
|
||||
if (!strtab || !symtab || strtab_size == 0 || symtab_size == 0) {
|
||||
if (!strtab || !symtab || strtab_size == 0) {
|
||||
sc_log_error("Failed to find symbol or string table in %s\n",
|
||||
info->dlpi_name);
|
||||
info->dlpi_name);
|
||||
return HILOAD_FAIL;
|
||||
}
|
||||
|
||||
// Iterate over the symbol table
|
||||
for (const ElfW(Sym) *sym = symtab;
|
||||
(const char *)sym < (const char *)symtab + symtab_size; sym++) {
|
||||
// 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]);
|
||||
const char *name = strdup(strtab + sym->st_name);
|
||||
void *address = (void *)(info->dlpi_addr + sym->st_value);
|
||||
|
||||
// Store the symbol information in the arrays
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user