From 4ef6be82123ef7c1788db4725ad9f3c0d5a86746 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 28 Nov 2019 21:30:20 +0100 Subject: [PATCH] Kernel: Allow modules to link against anything in kernel.map :^) We now use the symbols from kernel.map to link modules as they are loaded into the kernel. This is pretty fricken cool! --- Kernel/KSyms.cpp | 9 +++++++++ Kernel/KSyms.h | 1 + Kernel/Process.cpp | 29 +++++++++++------------------ Kernel/TestModule.cpp | 6 +++++- Kernel/mkmap.sh | 2 +- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp index 949e11c143..6580fb0570 100644 --- a/Kernel/KSyms.cpp +++ b/Kernel/KSyms.cpp @@ -19,6 +19,15 @@ static u8 parse_hex_digit(char nibble) return 10 + (nibble - 'a'); } +u32 address_for_kernel_symbol(const char* name) +{ + for (unsigned i = 0; i < ksym_count; ++i) { + if (!strcmp(name, s_ksyms[i].name)) + return s_ksyms[i].address; + } + return 0; +} + const KSym* ksymbolicate(u32 address) { if (address < ksym_lowest_address || address > ksym_highest_address) diff --git a/Kernel/KSyms.h b/Kernel/KSyms.h index 2b18f5a52f..1b1d76732f 100644 --- a/Kernel/KSyms.h +++ b/Kernel/KSyms.h @@ -8,6 +8,7 @@ struct KSym { const char* name; }; +u32 address_for_kernel_symbol(const char* name); const KSym* ksymbolicate(u32 address); void load_ksyms(); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index f7990af921..5a8159acd3 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -3382,20 +3382,6 @@ int Process::sys$beep() return 0; } -extern "C" void outside_func() -{ - kprintf("I'm the outside func!\n"); -} - -static u32 find_kernel_symbol(const StringView& name) -{ - if (name == "kprintf") - return (u32)kprintf; - if (name == "outside_func") - return (u32)outside_func; - ASSERT_NOT_REACHED(); -} - int Process::sys$module_load(const char* path, size_t path_length) { #if 0 @@ -3439,7 +3425,7 @@ int Process::sys$module_load(const char* path, size_t path_length) case R_386_PC32: { // PC-relative relocation dbg() << "PC-relative relocation: " << relocation.symbol().name(); - u32 symbol_address = find_kernel_symbol(relocation.symbol().name()); + u32 symbol_address = address_for_kernel_symbol(relocation.symbol().name()); dbg() << " Symbol address: " << (void*)symbol_address; ptrdiff_t relative_offset = (char*)symbol_address - ((char*)&patch_ptr + 4); patch_ptr = relative_offset; @@ -3447,9 +3433,16 @@ int Process::sys$module_load(const char* path, size_t path_length) } case R_386_32: // Absolute relocation dbg() << "Absolute relocation: '" << relocation.symbol().name() << "' value:" << relocation.symbol().value() << ", index:" << relocation.symbol_index(); - auto* section_storage_containing_symbol = section_storage_by_name.get(relocation.symbol().section().name()).value_or(nullptr); - ASSERT(section_storage_containing_symbol); - patch_ptr += (ptrdiff_t)(section_storage_containing_symbol + relocation.symbol().value()); + + if (relocation.symbol().bind() == STB_LOCAL) { + auto* section_storage_containing_symbol = section_storage_by_name.get(relocation.symbol().section().name()).value_or(nullptr); + ASSERT(section_storage_containing_symbol); + patch_ptr += (ptrdiff_t)(section_storage_containing_symbol + relocation.symbol().value()); + } else if (relocation.symbol().bind() == STB_GLOBAL) { + patch_ptr += address_for_kernel_symbol(relocation.symbol().name()); + } else { + ASSERT_NOT_REACHED(); + } break; } return IterationDecision::Continue; diff --git a/Kernel/TestModule.cpp b/Kernel/TestModule.cpp index 20603c2028..ab4dfa84e9 100644 --- a/Kernel/TestModule.cpp +++ b/Kernel/TestModule.cpp @@ -1,12 +1,16 @@ #include +#include extern "C" void module_init() { kprintf("TestModule has booted!\n"); - for (int i = 0; i < 99; ++i) { + for (int i = 0; i < 3; ++i) { kprintf("i is now %d\n", i); } + + kprintf("current pid: %d\n", current->process().sys$getpid()); + kprintf("current process name: %s\n", current->process().name().characters()); } extern "C" void module_fini() diff --git a/Kernel/mkmap.sh b/Kernel/mkmap.sh index 3c2d7b5cff..2f1b7aa872 100644 --- a/Kernel/mkmap.sh +++ b/Kernel/mkmap.sh @@ -1,6 +1,6 @@ #!/bin/sh tmp=$(mktemp) -nm -nC kernel | awk '{ if ($2 != "a") print; }' | uniq > $tmp +nm -n kernel | awk '{ if ($2 != "a") print; }' | uniq > $tmp printf "%08x\n" $(wc -l $tmp | cut -f1 -d' ') > kernel.map cat $tmp >> kernel.map rm -f $tmp