Files
Espresso/drivers/elf.c
2025-06-27 14:48:06 -05:00

64 lines
1.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <mm/pmm.h>
#include <mm/paging.h>
#include <drivers/elf.h>
#define PAGE_SIZE 4096
#define ALIGN_DOWN(x) ((x) & ~(PAGE_SIZE - 1))
#define ALIGN_UP(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
elf_executable_t* load_elf32(void* elf_data)
{
Elf32_Ehdr* ehdr = (Elf32_Ehdr*)elf_data;
/* Check ELF magic */
if (memcmp(ehdr->e_ident, (uint8_t*)("\x7F""ELF"), 4) != 0)
{
printf("Invalid ELF file\n");
return NULL;
}
if (ehdr->e_machine != 3 || ehdr->e_type != 2)
{
printf("Unsupported ELF type or architecture\n");
return NULL;
}
Elf32_Phdr* phdrs = (Elf32_Phdr*)((uint8_t*)elf_data + ehdr->e_phoff);
for (int i = 0; i < ehdr->e_phnum; i++) {
Elf32_Phdr* phdr = &phdrs[i];
if (phdr->p_type != PT_LOAD)
{
continue;
}
uint32_t vaddr_start = ALIGN_DOWN(phdr->p_vaddr);
uint32_t vaddr_end = ALIGN_UP(phdr->p_vaddr + phdr->p_memsz);
uint32_t segment_pages = (vaddr_end - vaddr_start) / PAGE_SIZE;
for (uint32_t page = 0; page < segment_pages; page++)
{
void* phys = alloc_page();
void* virt = (void*)(vaddr_start + page * PAGE_SIZE);
map_page(phys, virt);
memset(virt, 0, PAGE_SIZE);
}
void* dest = (void*)(uintptr_t)phdr->p_vaddr;
void* src = (uint8_t*)elf_data + phdr->p_offset;
memcpy(dest, src, phdr->p_filesz);
printf("Mapped segment %d: 0x%08x0x%08x (memsz: %u, filesz: %u)\n", i, phdr->p_vaddr, phdr->p_vaddr + phdr->p_memsz, phdr->p_memsz, phdr->p_filesz);
}
elf_executable_t* result = malloc(sizeof(elf_executable_t));
result->entry_point = (void*)(uintptr_t)ehdr->e_entry;
return result;
}