From afd06491886bd7004f950ca37dd17b14d09e6436 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Wed, 26 Aug 2026 23:10:16 +0200 Subject: [PATCH] feat(loader): add static x86_64 ELF loader --- include/elf.h | 36 ++++++++++++++++++++++++++++++++++++ src/elf.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 include/elf.h create mode 100644 src/elf.c diff --git a/include/elf.h b/include/elf.h new file mode 100644 index 0000000..97fdc25 --- /dev/null +++ b/include/elf.h @@ -0,0 +1,36 @@ +#ifndef FROSTBYTE_ELF_H +#define FROSTBYTE_ELF_H + +#include "types.h" + +typedef struct Elf64Header { + uint8 ident[16]; + uint16 type; + uint16 machine; + uint32 version; + uint64 entry; + uint64 programHeaderOffset; + uint64 sectionHeaderOffset; + uint32 flags; + uint16 headerSize; + uint16 programHeaderEntrySize; + uint16 programHeaderCount; + uint16 sectionHeaderEntrySize; + uint16 sectionHeaderCount; + uint16 sectionNameIndex; +} __attribute__((packed)) Elf64Header; + +typedef struct Elf64ProgramHeader { + uint32 type; + uint32 flags; + uint64 offset; + uint64 virtualAddr; + uint64 physicalAddr; + uint64 fileSize; + uint64 memorySize; + uint64 align; +} __attribute__((packed)) Elf64ProgramHeader; + +uint64 elfLoad(const void* image, uint64 imageSize); + +#endif diff --git a/src/elf.c b/src/elf.c new file mode 100644 index 0000000..450b1fe --- /dev/null +++ b/src/elf.c @@ -0,0 +1,51 @@ +#include "elf.h" +#include "paging.h" +#include "string.h" +#include "console.h" + +#define programTypeLoad 1 +#define elfTypeExec 2 +#define elfMachineX8664 62 + +static bool validHeader(const Elf64Header* header) +{ + if (header->ident[0] != 0x7F || header->ident[1] != 'E' || + header->ident[2] != 'L' || header->ident[3] != 'F') + return false; + if (header->ident[4] != 2) + return false; + if (header->type != elfTypeExec) + return false; + if (header->machine != elfMachineX8664) + return false; + return true; +} + +uint64 elfLoad(const void* image, uint64 imageSize) +{ + const Elf64Header* header = (const Elf64Header*)image; + + if (imageSize < sizeof(Elf64Header) || !validHeader(header)) { + kprintf("[elf] rejected image: not a static x86_64 ELF\n"); + return 0; + } + + const uint8* base = (const uint8*)image; + + for (uint16 i = 0; i < header->programHeaderCount; i++) { + const Elf64ProgramHeader* segment = (const Elf64ProgramHeader*) + (base + header->programHeaderOffset + (uint64)i * header->programHeaderEntrySize); + + if (segment->type != programTypeLoad) + continue; + + if (!pagingMapUserRange(segment->virtualAddr, segment->memorySize)) { + kprintf("[elf] failed to map segment at %p\n", (void*)segment->virtualAddr); + return 0; + } + + memcpy((void*)segment->virtualAddr, base + segment->offset, segment->fileSize); + } + + return header->entry; +}