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 {
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;

View File

@ -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

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) {
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);
}

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++) {
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;

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);
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 -> <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;
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;

View File

@ -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 -> <failed to resolve symbol> (symbol NULL reference)", state->rip);
return;

View File

@ -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];
}
}