mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
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!
This commit is contained in:
parent
6ab0649ad6
commit
97e0d75bcb
Notes:
sideshowbarker
2024-07-19 18:46:15 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/97e0d75bcbd
10 changed files with 72 additions and 15 deletions
|
@ -2,8 +2,8 @@
|
|||
#include <AK/kstdio.h>
|
||||
|
||||
#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<const char*>(m_data) + offset;
|
||||
return reinterpret_cast<const char*>(m_buffer.pointer()) + offset;
|
||||
#else
|
||||
return reinterpret_cast<const char*>(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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#include "ELFLoader.h"
|
||||
#include <AK/kstdio.h>
|
||||
|
||||
#ifdef SERENITY_KERNEL
|
||||
ELFLoader::ELFLoader(ExecSpace& execSpace, ByteBuffer&& file)
|
||||
#else
|
||||
ELFLoader::ELFLoader(ExecSpace& execSpace, MappedFile&& file)
|
||||
#endif
|
||||
: m_execSpace(execSpace)
|
||||
{
|
||||
m_image = make<ELFImage>(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?
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,7 +9,11 @@
|
|||
|
||||
class ELFLoader {
|
||||
public:
|
||||
#ifdef SERENITY_KERNEL
|
||||
ELFLoader(ExecSpace&, ByteBuffer&&);
|
||||
#else
|
||||
ELFLoader(ExecSpace&, MappedFile&&);
|
||||
#endif
|
||||
~ELFLoader();
|
||||
|
||||
bool load();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,7 +37,11 @@ public:
|
|||
ExecSpace();
|
||||
~ExecSpace();
|
||||
|
||||
#ifdef SERENITY_KERNEL
|
||||
bool loadELF(ByteBuffer&&);
|
||||
#else
|
||||
bool loadELF(MappedFile&&);
|
||||
#endif
|
||||
|
||||
char* symbolPtr(const char* name);
|
||||
|
||||
|
|
Binary file not shown.
7
Kernel/_hello.cpp
Normal file
7
Kernel/_hello.cpp
Normal file
|
@ -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;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
using namespace Userspace;
|
||||
|
||||
int elf_entry()
|
||||
extern "C" int elf_entry()
|
||||
{
|
||||
int fd = open("/Banner.txt");
|
||||
char buf[2048];
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <VirtualFileSystem/FileHandle.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include "MemoryManager.h"
|
||||
#include <ELFLoader/ELFLoader.h>
|
||||
|
||||
#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<MainFunctionPtr>(elf_entry)();
|
||||
kprintf("it returned %d\n", rc);
|
||||
|
||||
HANG;
|
||||
}
|
||||
|
||||
// The idle task will spend its eternity here for now.
|
||||
for (;;) {
|
||||
asm("hlt");
|
||||
|
|
Loading…
Reference in a new issue