summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-28 21:30:20 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-28 21:30:20 +0100
commit4ef6be82123ef7c1788db4725ad9f3c0d5a86746 (patch)
tree0b5d775b39c239c54ba93629dc7db5ecbc7f36db
parent1f34e16ec646bc0e76240fea21ca51e37d871122 (diff)
downloadserenity-4ef6be82123ef7c1788db4725ad9f3c0d5a86746.zip
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!
-rw-r--r--Kernel/KSyms.cpp9
-rw-r--r--Kernel/KSyms.h1
-rw-r--r--Kernel/Process.cpp29
-rw-r--r--Kernel/TestModule.cpp6
-rw-r--r--Kernel/mkmap.sh2
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 <Kernel/kstdio.h>
+#include <Kernel/Process.h>
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