From d7c79e1bdf389b385bb0fff730413b15b59124e7 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Tue, 6 Jun 2023 22:28:47 +0200 Subject: [PATCH] feature (symbol tables): upgraded symbol tables from static lists to hashmaps --- inc/drivers/builtin/elf/elf.h | 3 +- inc/utils/symbol.h | 15 +++++++-- src/drivers/builtin/elf/elf.c | 22 +++++++------ src/drivers/builtin/elf/relocation.c | 8 ++--- src/mm/stack.c | 2 +- src/platform/syscall.c | 4 +-- src/utils/panic.c | 2 +- src/utils/symbol.c | 46 ++++++++++++++++++++-------- 8 files changed, 68 insertions(+), 34 deletions(-) diff --git a/inc/drivers/builtin/elf/elf.h b/inc/drivers/builtin/elf/elf.h index f571c26..c54a86d 100644 --- a/inc/drivers/builtin/elf/elf.h +++ b/inc/drivers/builtin/elf/elf.h @@ -10,8 +10,7 @@ typedef struct { elf_header_T header; - uint64_t num_symbols; - symbol_T* symbols; + symbol_table_T symbol_table; uint64_t num_mappings; elf_mapping_T* mappings; void* string_table; diff --git a/inc/utils/symbol.h b/inc/utils/symbol.h index c442f95..153bf61 100644 --- a/inc/utils/symbol.h +++ b/inc/utils/symbol.h @@ -4,6 +4,7 @@ #define NOX_SYMBOLS_H #include "utils/string.h" +#include "utils/hashmap.h" typedef enum { SYMBOL_FUNCTION, @@ -17,7 +18,17 @@ typedef struct { uint64_t address; } symbol_T; -symbol_T* symbol_resolve_from_name (symbol_T* symbols, uint64_t num_symbols, string_t name); -symbol_T* symbol_resolve_from_rip (symbol_T* symbols, uint64_t num_symbols, uint64_t rip); +typedef struct { + 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 diff --git a/src/drivers/builtin/elf/elf.c b/src/drivers/builtin/elf/elf.c index 20d25f9..3fbcb26 100644 --- a/src/drivers/builtin/elf/elf.c +++ b/src/drivers/builtin/elf/elf.c @@ -36,31 +36,33 @@ bool elf_executable_validate(elf_executable_T* executable) { } 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; - executable_temp->executable->symbols = memory_allocate(executable_temp->executable->num_symbols * sizeof(symbol_T)); + uint64_t num_symbols = executable_temp->symbol_table->length / executable_temp->symbol_table->entry_size; + executable_temp->executable->symbol_table = symbol_table_init(num_symbols); - for (int i = 0; i < executable_temp->executable->num_symbols; i++) { - symbol_T* symbol = &executable_temp->executable->symbols[i]; + for (int i = 0; i < num_symbols; i++) { + symbol_T symbol; 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); - symbol->name = &executable_temp->executable->string_table[symbol_elf->name_offset]; - symbol->address = symbol_elf->value; + symbol.name = &executable_temp->executable->string_table[symbol_elf->name_offset]; + symbol.address = symbol_elf->value; switch (type) { case ELF_SYMBOL_FUNC: { - symbol->type = SYMBOL_FUNCTION; + symbol.type = SYMBOL_FUNCTION; break; } case ELF_SYMBOL_OBJECT: { - symbol->type = SYMBOL_VARIABLE; + symbol.type = SYMBOL_VARIABLE; break; } default: { - symbol->type = SYMBOL_UNKNOWN; + symbol.type = SYMBOL_UNKNOWN; 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) { memory_free(executable->string_table); - memory_free(executable->symbols); + symbol_table_destruct(&executable->symbol_table); memory_free(executable->mappings); memory_free(executable); } \ No newline at end of file diff --git a/src/drivers/builtin/elf/relocation.c b/src/drivers/builtin/elf/relocation.c index 361b07d..1aee9ac 100644 --- a/src/drivers/builtin/elf/relocation.c +++ b/src/drivers/builtin/elf/relocation.c @@ -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++) { if (sections[i].type != ELF_SECTION_RELOCATION_A) continue; - symbol_T* symbols = scheduler_get_process(PROCESS_KERNEL)->executable->symbols; - uint64_t num_symbols = scheduler_get_process(PROCESS_KERNEL)->executable->num_symbols; - uint32_t num_relocations = sections[i].length / sections[i].entry_size; + process_T* kernel_process = scheduler_get_process(PROCESS_KERNEL); + symbol_table_T* symbol_table = &kernel_process->executable->symbol_table; + uint32_t num_relocations = sections[i].length / sections[i].entry_size; log(LOG_INFO, "Found RELA section with %d relocations", num_relocations); 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_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]; - 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) { log(LOG_ERROR, "Failed to relocate driver (symbol '%s' not found in kernel)", drv_symbol_name); return false; diff --git a/src/mm/stack.c b/src/mm/stack.c index 611b18a..777fff3 100644 --- a/src/mm/stack.c +++ b/src/mm/stack.c @@ -16,7 +16,7 @@ void stack_trace_call_stack(uint64_t rbp) { log(LOG_NONE, " 0x%x -> (process NULL reference)", rip); 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) { log(LOG_NONE, " 0x%x -> (symbol NULL reference)", rip); diff --git a/src/platform/syscall.c b/src/platform/syscall.c index 36a1999..2f3dbcf 100644 --- a/src/platform/syscall.c +++ b/src/platform/syscall.c @@ -240,7 +240,7 @@ void syscall_handle_nx_proc_create(cpu_state_T* state) { state->rax = STATUS_GENERIC_ERROR; 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); @@ -297,7 +297,7 @@ void syscall_handle_nx_drv_register(cpu_state_T* state) { 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(); *id_ptr = drv->id; diff --git a/src/utils/panic.c b/src/utils/panic.c index 239a19c..d29f772 100644 --- a/src/utils/panic.c +++ b/src/utils/panic.c @@ -68,7 +68,7 @@ void panic_log_call_stack(cpu_state_T* state) { log(LOG_NONE, "Call Stack:"); 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) { log(LOG_NONE, " 0x%x -> (symbol NULL reference)", state->rip); return; diff --git a/src/utils/symbol.c b/src/utils/symbol.c index 4261d2b..bfa7870 100644 --- a/src/utils/symbol.c +++ b/src/utils/symbol.c @@ -1,25 +1,47 @@ // This file is part of noxos and licensed under the MIT open source license #include "utils/symbol.h" +#include "utils/memory.h" -symbol_T* symbol_resolve_from_name(symbol_T* symbols, uint64_t num_symbols, string_t name) { - for (uint64_t i = 0; i < num_symbols; i++) { - if (string_compare(name, symbols[i].name)) { - return &symbols[i]; - } - } +#include "utils/logger.h" - 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; - for (uint64_t i = 0; i < num_symbols; i++) { - if (symbols[i].address <= rip && - (symbol == NULL || symbols[i].address > symbol->address)) + for (uint64_t i = 0; i < symbol_table->num_symbols; i++) { + if (symbol_table->symbols[i].address <= rip && + (symbol == NULL || symbol_table->symbols[i].address > symbol->address)) { - symbol = &symbols[i]; + symbol = &symbol_table->symbols[i]; } }