feature (symbol tables): upgraded symbol tables from static lists to hashmaps

This commit is contained in:
antifallobst 2023-06-06 22:28:47 +02:00
parent ae0ef5c85d
commit d7c79e1bdf
8 changed files with 68 additions and 34 deletions

View File

@ -10,8 +10,7 @@
typedef struct { typedef struct {
elf_header_T header; elf_header_T header;
uint64_t num_symbols; symbol_table_T symbol_table;
symbol_T* symbols;
uint64_t num_mappings; uint64_t num_mappings;
elf_mapping_T* mappings; elf_mapping_T* mappings;
void* string_table; void* string_table;

View File

@ -4,6 +4,7 @@
#define NOX_SYMBOLS_H #define NOX_SYMBOLS_H
#include "utils/string.h" #include "utils/string.h"
#include "utils/hashmap.h"
typedef enum { typedef enum {
SYMBOL_FUNCTION, SYMBOL_FUNCTION,
@ -17,7 +18,17 @@ typedef struct {
uint64_t address; uint64_t address;
} symbol_T; } symbol_T;
symbol_T* symbol_resolve_from_name (symbol_T* symbols, uint64_t num_symbols, string_t name); typedef struct {
symbol_T* symbol_resolve_from_rip (symbol_T* symbols, uint64_t num_symbols, uint64_t rip); hashmap_T hashmap;
uint64_t num_symbols;
symbol_T* symbols;
uint64_t symbols_index;
} symbol_table_T;
symbol_table_T symbol_table_init (uint64_t num_symbols);
void symbol_table_destruct (symbol_table_T* symbol_table);
void symbol_table_insert (symbol_table_T* symbol_table, symbol_T symbol);
symbol_T* symbol_resolve_from_name (symbol_table_T* symbol_table, string_t name);
symbol_T* symbol_resolve_from_rip (symbol_table_T* symbol_table, uint64_t rip);
#endif //NOX_SYMBOLS_H #endif //NOX_SYMBOLS_H

View File

@ -36,31 +36,33 @@ bool elf_executable_validate(elf_executable_T* executable) {
} }
void elf_executable_extract_symbols(elf_executable_temp_T* executable_temp) { void elf_executable_extract_symbols(elf_executable_temp_T* executable_temp) {
executable_temp->executable->num_symbols = executable_temp->symbol_table->length / executable_temp->symbol_table->entry_size; uint64_t num_symbols = executable_temp->symbol_table->length / executable_temp->symbol_table->entry_size;
executable_temp->executable->symbols = memory_allocate(executable_temp->executable->num_symbols * sizeof(symbol_T)); executable_temp->executable->symbol_table = symbol_table_init(num_symbols);
for (int i = 0; i < executable_temp->executable->num_symbols; i++) { for (int i = 0; i < num_symbols; i++) {
symbol_T* symbol = &executable_temp->executable->symbols[i]; symbol_T symbol;
elf_symbol_T* symbol_elf = &((elf_symbol_T*)&executable_temp->buffer[executable_temp->symbol_table->offset])[i]; elf_symbol_T* symbol_elf = &((elf_symbol_T*)&executable_temp->buffer[executable_temp->symbol_table->offset])[i];
elf_symbol_type_E type = ELF_SYMBOL_TYPE(symbol_elf->info); elf_symbol_type_E type = ELF_SYMBOL_TYPE(symbol_elf->info);
symbol->name = &executable_temp->executable->string_table[symbol_elf->name_offset]; symbol.name = &executable_temp->executable->string_table[symbol_elf->name_offset];
symbol->address = symbol_elf->value; symbol.address = symbol_elf->value;
switch (type) { switch (type) {
case ELF_SYMBOL_FUNC: { case ELF_SYMBOL_FUNC: {
symbol->type = SYMBOL_FUNCTION; symbol.type = SYMBOL_FUNCTION;
break; break;
} }
case ELF_SYMBOL_OBJECT: { case ELF_SYMBOL_OBJECT: {
symbol->type = SYMBOL_VARIABLE; symbol.type = SYMBOL_VARIABLE;
break; break;
} }
default: { default: {
symbol->type = SYMBOL_UNKNOWN; symbol.type = SYMBOL_UNKNOWN;
break; break;
} }
} }
symbol_table_insert(&executable_temp->executable->symbol_table, symbol);
} }
} }
@ -153,7 +155,7 @@ elf_executable_T* elf_executable_create(uint8_t* buffer) {
void elf_executable_destruct(elf_executable_T* executable) { void elf_executable_destruct(elf_executable_T* executable) {
memory_free(executable->string_table); memory_free(executable->string_table);
memory_free(executable->symbols); symbol_table_destruct(&executable->symbol_table);
memory_free(executable->mappings); memory_free(executable->mappings);
memory_free(executable); memory_free(executable);
} }

View File

@ -77,9 +77,9 @@ bool elf_relocate_driver(elf_executable_T* executable, uint8_t* buffer, void* lo
for (uint32_t i = 0; i < executable->header.num_section_header_entries; i++) { for (uint32_t i = 0; i < executable->header.num_section_header_entries; i++) {
if (sections[i].type != ELF_SECTION_RELOCATION_A) continue; if (sections[i].type != ELF_SECTION_RELOCATION_A) continue;
symbol_T* symbols = scheduler_get_process(PROCESS_KERNEL)->executable->symbols; process_T* kernel_process = scheduler_get_process(PROCESS_KERNEL);
uint64_t num_symbols = scheduler_get_process(PROCESS_KERNEL)->executable->num_symbols; symbol_table_T* symbol_table = &kernel_process->executable->symbol_table;
uint32_t num_relocations = sections[i].length / sections[i].entry_size; uint32_t num_relocations = sections[i].length / sections[i].entry_size;
log(LOG_INFO, "Found RELA section with %d relocations", num_relocations); log(LOG_INFO, "Found RELA section with %d relocations", num_relocations);
for (int j = 0; j < num_relocations; j++) { for (int j = 0; j < num_relocations; j++) {
@ -88,7 +88,7 @@ bool elf_relocate_driver(elf_executable_T* executable, uint8_t* buffer, void* lo
elf_relocation_type_E relocation_type = ELF_RELOCATION_TYPE(relocation->info); elf_relocation_type_E relocation_type = ELF_RELOCATION_TYPE(relocation->info);
elf_symbol_T* drv_symbol = &((elf_symbol_T*)&buffer[section_dynsym->offset])[ELF_RELOCATION_SYMBOL(relocation->info)]; elf_symbol_T* drv_symbol = &((elf_symbol_T*)&buffer[section_dynsym->offset])[ELF_RELOCATION_SYMBOL(relocation->info)];
string_t drv_symbol_name = (string_t)&buffer[section_dynstr->offset + drv_symbol->name_offset]; string_t drv_symbol_name = (string_t)&buffer[section_dynstr->offset + drv_symbol->name_offset];
symbol_T* k_symbol = symbol_resolve_from_name(symbols, num_symbols, drv_symbol_name); symbol_T* k_symbol = symbol_resolve_from_name(symbol_table, drv_symbol_name);
if (k_symbol == NULL) { if (k_symbol == NULL) {
log(LOG_ERROR, "Failed to relocate driver (symbol '%s' not found in kernel)", drv_symbol_name); log(LOG_ERROR, "Failed to relocate driver (symbol '%s' not found in kernel)", drv_symbol_name);
return false; return false;

View File

@ -16,7 +16,7 @@ void stack_trace_call_stack(uint64_t rbp) {
log(LOG_NONE, " 0x%x -> <failed to resolve symbol> (process NULL reference)", rip); log(LOG_NONE, " 0x%x -> <failed to resolve symbol> (process NULL reference)", rip);
return; return;
} }
symbol_T* symbol = symbol_resolve_from_rip(process->executable->symbols, process->executable->num_symbols, rip); symbol_T* symbol = symbol_resolve_from_rip(&process->executable->symbol_table, rip);
if (symbol == NULL) { if (symbol == NULL) {
log(LOG_NONE, " 0x%x -> <failed to resolve symbol> (symbol NULL reference)", rip); log(LOG_NONE, " 0x%x -> <failed to resolve symbol> (symbol NULL reference)", rip);

View File

@ -240,7 +240,7 @@ void syscall_handle_nx_proc_create(cpu_state_T* state) {
state->rax = STATUS_GENERIC_ERROR; state->rax = STATUS_GENERIC_ERROR;
return; return;
} }
void* entry = (void*)(symbol_resolve_from_name(exec->symbols, exec->num_symbols, "_start")->address + MEM_REGION_PROCESS_EXEC); void* entry = (void*)(symbol_resolve_from_name(&exec->symbol_table, "_start")->address + MEM_REGION_PROCESS_EXEC);
thread_spawn(*pid, entry); thread_spawn(*pid, entry);
@ -297,7 +297,7 @@ void syscall_handle_nx_drv_register(cpu_state_T* state) {
return; return;
} }
void (*drv_init)() = drv->base + symbol_resolve_from_name(exec->symbols, exec->num_symbols, "_init")->address;; void (*drv_init)() = drv->base + symbol_resolve_from_name(&exec->symbol_table, "_init")->address;;
drv_init(); drv_init();
*id_ptr = drv->id; *id_ptr = drv->id;

View File

@ -68,7 +68,7 @@ void panic_log_call_stack(cpu_state_T* state) {
log(LOG_NONE, "Call Stack:"); log(LOG_NONE, "Call Stack:");
stack_trace_call_stack(state->rbp); stack_trace_call_stack(state->rbp);
symbol_T* symbol = symbol_resolve_from_rip(process->executable->symbols, process->executable->num_symbols,state->rip); symbol_T* symbol = symbol_resolve_from_rip(&process->executable->symbol_table, state->rip);
if (symbol == NULL) { if (symbol == NULL) {
log(LOG_NONE, " 0x%x -> <failed to resolve symbol> (symbol NULL reference)", state->rip); log(LOG_NONE, " 0x%x -> <failed to resolve symbol> (symbol NULL reference)", state->rip);
return; return;

View File

@ -1,25 +1,47 @@
// This file is part of noxos and licensed under the MIT open source license // This file is part of noxos and licensed under the MIT open source license
#include "utils/symbol.h" #include "utils/symbol.h"
#include "utils/memory.h"
symbol_T* symbol_resolve_from_name(symbol_T* symbols, uint64_t num_symbols, string_t name) { #include "utils/logger.h"
for (uint64_t i = 0; i < num_symbols; i++) {
if (string_compare(name, symbols[i].name)) {
return &symbols[i];
}
}
return NULL; symbol_table_T symbol_table_init(uint64_t num_symbols) {
symbol_table_T symbol_table;
DEBUG("symbol_table_init -> num_symbols: %d", num_symbols);
symbol_table.symbols = memory_allocate(num_symbols * sizeof(symbol_T));
symbol_table.hashmap = hashmap_create(num_symbols);
symbol_table.num_symbols = num_symbols;
symbol_table.symbols_index = 0;
return symbol_table;
} }
symbol_T* symbol_resolve_from_rip(symbol_T* symbols, uint64_t num_symbols, uint64_t rip) { void symbol_table_destruct(symbol_table_T* symbol_table) {
hashmap_destruct(&symbol_table->hashmap);
memory_free(symbol_table->symbols);
}
void symbol_table_insert(symbol_table_T* symbol_table, symbol_T symbol) {
// DEBUG("symbol_table_insert -> SYMTAB[0x%x] || %s (0x%x)", symbol_table, symbol.name, symbol.address);
symbol_table->symbols[symbol_table->symbols_index] = symbol;
hashmap_insert(&symbol_table->hashmap, string_hash_djb(symbol.name), &symbol_table->symbols[symbol_table->symbols_index]);
symbol_table->symbols_index++;
}
symbol_T* symbol_resolve_from_name(symbol_table_T* symbol_table, string_t name) {
return hashmap_lookup(&symbol_table->hashmap, string_hash_djb(name));
}
symbol_T* symbol_resolve_from_rip(symbol_table_T* symbol_table, uint64_t rip) {
symbol_T* symbol = NULL; symbol_T* symbol = NULL;
for (uint64_t i = 0; i < num_symbols; i++) { for (uint64_t i = 0; i < symbol_table->num_symbols; i++) {
if (symbols[i].address <= rip && if (symbol_table->symbols[i].address <= rip &&
(symbol == NULL || symbols[i].address > symbol->address)) (symbol == NULL || symbol_table->symbols[i].address > symbol->address))
{ {
symbol = &symbols[i]; symbol = &symbol_table->symbols[i];
} }
} }