diff options
author | Marvin Borner | 2023-01-28 22:29:48 +0100 |
---|---|---|
committer | Marvin Borner | 2023-01-28 22:29:48 +0100 |
commit | de450bfb4354f716fb43fae69d90ed513068d10b (patch) | |
tree | b474219ae3baaeb8a075e6fbb5c57c3857faa588 /src/load.c | |
parent | 75bb42663294b388377178b7257c6f8c0f787032 (diff) |
Rewrite, bootstrap
Rewriting without KVM, huge goals, won't finish, just for fun.
Diffstat (limited to 'src/load.c')
-rw-r--r-- | src/load.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/load.c b/src/load.c new file mode 100644 index 0000000..ddcd54d --- /dev/null +++ b/src/load.c @@ -0,0 +1,59 @@ +#include <elf.h> +#include <stdio.h> +#include <string.h> + +#include <load.h> +#include <log.h> + +vaddr load(const char *path) +{ + FILE *file = fopen(path, "rb"); + if (!file) { + errln("can't read file %s.", path); + return 0; + } + + Elf64_Ehdr header = { 0 }; + fread(&header, sizeof(header), 1, file); + if (memcmp(header.e_ident, ELFMAG, SELFMAG)) { + errln("invalid ELF %s.", path); + return 0; + } + + for (int i = 0; i < header.e_phnum; i++) { + int offset = header.e_phoff + header.e_phentsize * i; + if (fseek(file, offset, SEEK_SET)) { + errln("can't seek program to %x", offset); + return 0; + } + + Elf64_Phdr program = { 0 }; + if (fread(&program, sizeof(program), 1, file) != 1) { + errln("invalid program size %d", i); + return 0; + } + + if (!program.p_vaddr || program.p_type != PT_LOAD) + continue; + + void *addr = mem_alloc(program.p_memsz, program.p_vaddr); + if (!addr) { + errln("can't allocate %dB at %x", program.p_memsz, + program.p_vaddr); + return 0; + } + if (fseek(file, program.p_offset, SEEK_SET)) { + errln("can't seek program to %x", offset); + return 0; + } + if (fread(addr, program.p_filesz, 1, file) != 1) { + errln("invalid program size %d", i); + return 0; + } + + logln("loaded program %d", i); + } + + fclose(file); + return header.e_entry; +} |