feature (symbol tables): upgraded symbol tables from static lists to hashmaps
This commit is contained in:
parent
ae0ef5c85d
commit
d7c79e1bdf
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue