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 53da2581e1..e477e526b9 100644 Binary files a/Kernel/_fs_contents and b/Kernel/_fs_contents differ diff --git a/Kernel/_hello.cpp b/Kernel/_hello.cpp new file mode 100644 index 0000000000..36be71125f --- /dev/null +++ b/Kernel/_hello.cpp @@ -0,0 +1,7 @@ +extern "C" int puts(const char*); + +extern "C" int elf_entry() +{ + puts("Home, where you are supposed to be..."); + return 0; +} diff --git a/Kernel/_test.cpp b/Kernel/_test.cpp index 125020cb8c..467b29db62 100644 --- a/Kernel/_test.cpp +++ b/Kernel/_test.cpp @@ -2,7 +2,7 @@ using namespace Userspace; -int elf_entry() +extern "C" int elf_entry() { int fd = open("/Banner.txt"); char buf[2048]; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 70e4ad2426..85f6dbb537 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -23,6 +23,7 @@ #include #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");