From 97e0d75bcbdde4ba166de8cd9e36b87b4823f30a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 18 Oct 2018 15:38:04 +0200 Subject: [PATCH] ELFLoader works inside the kernel! We load /_hello.o which just prints out a simple message. It executes inside the kernel itself, so no fancy userspace process or anything, but this is still so cool! --- ELFLoader/ELFImage.cpp | 8 ++++---- ELFLoader/ELFImage.h | 4 ++-- ELFLoader/ELFLoader.cpp | 8 ++++++-- ELFLoader/ELFLoader.h | 4 ++++ ELFLoader/ExecSpace.cpp | 28 ++++++++++++++++++++++------ ELFLoader/ExecSpace.h | 4 ++++ Kernel/_fs_contents | Bin 1024000 -> 1024000 bytes Kernel/_hello.cpp | 7 +++++++ Kernel/_test.cpp | 2 +- Kernel/init.cpp | 22 ++++++++++++++++++++++ 10 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 Kernel/_hello.cpp diff --git a/ELFLoader/ELFImage.cpp b/ELFLoader/ELFImage.cpp index 58a0798071..092ff94e1c 100644 --- a/ELFLoader/ELFImage.cpp +++ b/ELFLoader/ELFImage.cpp @@ -2,8 +2,8 @@ #include #ifdef SERENITY_KERNEL -ELFImage::ELFImage(const byte* data) - : m_data(data) +ELFImage::ELFImage(ByteBuffer&& buffer) + : m_buffer(buffer) { m_isValid = parse(); } @@ -137,7 +137,7 @@ const char* ELFImage::tableString(unsigned offset) const const char* ELFImage::rawData(unsigned offset) const { #ifdef SERENITY_KERNEL - return reinterpret_cast(m_data) + offset; + return reinterpret_cast(m_buffer.pointer()) + offset; #else return reinterpret_cast(m_file.pointer()) + offset; #endif @@ -178,7 +178,7 @@ const ELFImage::RelocationSection ELFImage::Section::relocations() const { // FIXME: This is ugly. char relocationSectionName[128]; - ksprintf(relocationSectionName, ".rel%s", name()); + int x = ksprintf(relocationSectionName, ".rel%s", name()); kprintf("looking for '%s'\n", relocationSectionName); auto relocationSection = m_image.lookupSection(relocationSectionName); diff --git a/ELFLoader/ELFImage.h b/ELFLoader/ELFImage.h index dc83410c92..78f1c28621 100644 --- a/ELFLoader/ELFImage.h +++ b/ELFLoader/ELFImage.h @@ -12,7 +12,7 @@ class ELFImage { public: #ifdef SERENITY_KERNEL - explicit ELFImage(const byte* data); + explicit ELFImage(ByteBuffer&&); #else explicit ELFImage(MappedFile&&); #endif @@ -132,7 +132,7 @@ private: const char* sectionIndexToString(unsigned index); #ifdef SERENITY_KERNEL - const byte* m_data; + ByteBuffer m_buffer; #else MappedFile m_file; #endif diff --git a/ELFLoader/ELFLoader.cpp b/ELFLoader/ELFLoader.cpp index 60e91937c5..6b5b0c928b 100644 --- a/ELFLoader/ELFLoader.cpp +++ b/ELFLoader/ELFLoader.cpp @@ -1,7 +1,11 @@ #include "ELFLoader.h" #include +#ifdef SERENITY_KERNEL +ELFLoader::ELFLoader(ExecSpace& execSpace, ByteBuffer&& file) +#else ELFLoader::ELFLoader(ExecSpace& execSpace, MappedFile&& file) +#endif : m_execSpace(execSpace) { m_image = make(move(file)); @@ -104,9 +108,9 @@ void ELFLoader::performRelocations() void ELFLoader::exportSymbols() { m_image->forEachSymbol([&] (const ELFImage::Symbol symbol) { - kprintf("symbol: %u, type=%u, name=%s\n", symbol.index(), symbol.type(), symbol.name()); + kprintf("symbol: %u, type=%u, name=%s, section=%u\n", symbol.index(), symbol.type(), symbol.name(), symbol.sectionIndex()); if (symbol.type() == STT_FUNC) - m_execSpace.addSymbol(symbol.name(), areaForSectionName(".text") + symbol.value(), symbol.size()); + m_execSpace.addSymbol(symbol.name(), areaForSection(symbol.section()) + symbol.value(), symbol.size()); // FIXME: What about other symbol types? }); } diff --git a/ELFLoader/ELFLoader.h b/ELFLoader/ELFLoader.h index f62745484a..e7249ee8c7 100644 --- a/ELFLoader/ELFLoader.h +++ b/ELFLoader/ELFLoader.h @@ -9,7 +9,11 @@ class ELFLoader { public: +#ifdef SERENITY_KERNEL + ELFLoader(ExecSpace&, ByteBuffer&&); +#else ELFLoader(ExecSpace&, MappedFile&&); +#endif ~ELFLoader(); bool load(); diff --git a/ELFLoader/ExecSpace.cpp b/ELFLoader/ExecSpace.cpp index ca625b4311..8fe97a76ce 100644 --- a/ELFLoader/ExecSpace.cpp +++ b/ELFLoader/ExecSpace.cpp @@ -12,19 +12,31 @@ ExecSpace::~ExecSpace() { } +#ifdef SERENITY_KERNEL +int puts(const char* str) +{ + kprintf("%s\n", str); + return 0; +} +#endif + void ExecSpace::initializeBuiltins() { m_symbols.set("puts", { (char*)puts, 0 }); } +#ifdef SERENITY_KERNEL +bool ExecSpace::loadELF(ByteBuffer&& file) +#else bool ExecSpace::loadELF(MappedFile&& file) +#endif { ELFLoader loader(*this, move(file)); if (!loader.load()) return false; - printf("[ExecSpace] ELF loaded, symbol map now:\n"); + kprintf("[ExecSpace] ELF loaded, symbol map now:\n"); for (auto& s : m_symbols) { - printf("> %p: %s (%u)\n", + kprintf("> %p: %s (%u)\n", s.value.ptr, s.key.characters(), s.value.size); @@ -34,11 +46,15 @@ bool ExecSpace::loadELF(MappedFile&& file) static void disassemble(const char* data, size_t length) { -#ifdef SERENITY_KERNEL -#else if (!length) return; +#ifdef SERENITY_KERNEL + for (unsigned i = 0; i < length; ++i) { + kprintf("%b ", (unsigned char)data[i]); + } + kprintf("\n"); +#else TemporaryFile temp; if (!temp.isValid()) { fprintf(stderr, "Unable to create temp file for disassembly.\n"); @@ -52,7 +68,7 @@ static void disassemble(const char* data, size_t length) temp.sync(); char cmdbuf[128]; - sprintf(cmdbuf, "nasm -f bin -o /dev/stdout %s | ndisasm -b32 -", temp.fileName().characters()); + ksprintf(cmdbuf, "nasm -f bin -o /dev/stdout %s | ndisasm -b32 -", temp.fileName().characters()); system(cmdbuf); #endif } @@ -60,7 +76,7 @@ static void disassemble(const char* data, size_t length) char* ExecSpace::symbolPtr(const char* name) { if (auto it = m_symbols.find(name); it != m_symbols.end()) { - printf("[ELFLoader] symbolPtr(%s) dump:\n", name); + kprintf("[ELFLoader] symbolPtr(%s) dump:\n", name); auto& symbol = (*it).value; disassemble(symbol.ptr, symbol.size); return symbol.ptr; diff --git a/ELFLoader/ExecSpace.h b/ELFLoader/ExecSpace.h index 1086ac17f2..2b175d473a 100644 --- a/ELFLoader/ExecSpace.h +++ b/ELFLoader/ExecSpace.h @@ -37,7 +37,11 @@ public: ExecSpace(); ~ExecSpace(); +#ifdef SERENITY_KERNEL + bool loadELF(ByteBuffer&&); +#else bool loadELF(MappedFile&&); +#endif char* symbolPtr(const char* name); diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents index 53da2581e1b1535107805fd3abd73f613fced14e..e477e526b93abf23e44644000936533dc3e3e541 100644 GIT binary patch delta 876 zcmZoTVApWKZUYYs>ndgjhPcUsEYh4My(gk8drw4jY&K-IzBBK?HeqCMV=0XDr{YeQAWCR%48RJV*i%azK z8I%|p7(|#k7~?Zib8_3i69nQxr<_6_Qf*^z;~- z-|*}JX?pSJ|NsAn2bz!Y9G=K1JUM}tXY!8=DPBAvIR*v>VFm^UAqG|kF(@BI34jQw z3zG{97*cc6;#2cViYgfjN=u3v7+4q>7#LX@7&sXi7??OGcU{)kF3L|yEJ@UZtJEtl zDKgYEWY8;0&Cx4KttdfAP5ykva`NB9?2`?y)|eWBtb+Pa4ax>lAa8@PC&(%W26)^= zft)<~;RRt!R|bd!96-t$7#MUI85lqg=U`x9U}bjJz5 z3=9klpr&w4{&-!QRe+I!L3*;_4P{mvMh1q=$qz4xPY$>-XVL`)rXMVul`c3jbHaVN zx$trrqY9jh$HSXHUlC+vEZEF?Eu4`tU~=qrbxj{eRL55^LmV%}z`($duP2OhWN>XEYh4JStp|Fvrj~`Z8l|bW@L=s$k@&_iGzoEHFNxC zeva?_jP?^5EkT6!<{F6(W*$Zc1lTMn^PYL~fB8Q5ACn3V8< zTZNgOF}@_VxI{01BcmvDQ%YM3V_OPSTMBbq3QJoGYg-E2vK00miwyM#2 #include #include "MemoryManager.h" +#include #if 0 /* Keyboard LED disco task ;^) */ @@ -82,6 +83,8 @@ static void user_kprintf_main() DO_SYSCALL_A1(0x4000, 0); kprintf("This should not work!\n"); HANG; + for (;;) { + } } system_t system; @@ -179,6 +182,25 @@ void init() } #endif + { + auto testExecutable = vfs->open("/_hello.o"); + ASSERT(testExecutable); + auto testExecutableData = testExecutable->readEntireFile(); + ASSERT(testExecutableData); + + ExecSpace space; + space.loadELF(move(testExecutableData)); + auto* elf_entry = space.symbolPtr("elf_entry"); + ASSERT(elf_entry); + + typedef int (*MainFunctionPtr)(void); + kprintf("elf_entry: %p\n", elf_entry); + int rc = reinterpret_cast(elf_entry)(); + kprintf("it returned %d\n", rc); + + HANG; + } + // The idle task will spend its eternity here for now. for (;;) { asm("hlt");