From 2a3e2f54f51088bb8b602de61de143dfada91eb5 Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Mon, 4 May 2020 17:27:43 +0900 Subject: [PATCH] kernel/core: Add simple ELF file support --- kernel/core/Makefile | 3 +- kernel/core/elf.c | 82 ++++++++++++++++++++++++++++++++++ kernel/core/elf.h | 104 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 kernel/core/elf.c create mode 100644 kernel/core/elf.h diff --git a/kernel/core/Makefile b/kernel/core/Makefile index 6ef7ddd..d359f39 100644 --- a/kernel/core/Makefile +++ b/kernel/core/Makefile @@ -1,4 +1,5 @@ -OBJECTS = main.o process.o cxipc.o syscall.o posixcall.o net.o signal.o mailbox.o +OBJECTS = main.o process.o cxipc.o syscall.o posixcall.o net.o signal.o \ + mailbox.o elf.o OUTPUT = core.o INCLUDES = -I../include -I../../include -I../.. CFLAGS += $(INCLUDES) -nostdinc -fno-builtin -fno-builtin-memcpy diff --git a/kernel/core/elf.c b/kernel/core/elf.c new file mode 100644 index 0000000..b25b7ca --- /dev/null +++ b/kernel/core/elf.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include "elf.h" + +int elf_validate(void *elf, size_t size) +{ + int ret_val; + struct elf_hdr *hdr; + + ret_val = -EINVAL; + + /* make sure there is enough space for the header */ + if(size < sizeof(*hdr)) { + goto gtfo; + } + + hdr = (struct elf_hdr*)elf; + + /* check the magic number */ + if(!(hdr->e_ident[EI_MAG0] == ELFMAG0 && + hdr->e_ident[EI_MAG1] == ELFMAG1 && + hdr->e_ident[EI_MAG2] == ELFMAG2 && + hdr->e_ident[EI_MAG3] == ELFMAG3)) { + goto gtfo; + } + + /* make sure the binary is little-endian ELF32 */ + if(hdr->e_ident[EI_CLASS] != ELFCLASS32 || + hdr->e_ident[EI_DATA] != ELFDATA2LSB) { + ret_val = -ENOTSUP; + goto gtfo; + } + + /* TODO: make sure the program header table and sections are valid */ + + ret_val = 0; + +gtfo: + return(ret_val); +} + +int elf_phdr_foreach(void *elf, size_t size, + int (*func)(struct elf_hdr*, struct elf_phdr*, void*), + void *arg2) +{ + int ret_val; + struct elf_hdr *hdr; + + hdr = (struct elf_hdr*)elf; + + if(hdr->e_phoff) { + int i; + + ret_val = 0; + + for(i = 0; i < hdr->e_phnum; i++) { + struct elf_phdr *phdr; + + phdr = (struct elf_phdr*)((char*)elf + i * hdr->e_phentsize); + + ret_val = func(hdr, phdr, arg2); + + if(ret_val < 0) { + break; + } + } + } else { + ret_val = -ENOENT; + } + + return(ret_val); +} + +void *elf_entry(void *elf) +{ + struct elf_hdr *hdr; + + hdr = (struct elf_hdr*)elf; + + return((void*)hdr->e_entry); +} diff --git a/kernel/core/elf.h b/kernel/core/elf.h new file mode 100644 index 0000000..3ed2fd3 --- /dev/null +++ b/kernel/core/elf.h @@ -0,0 +1,104 @@ +#ifndef __ELF_H +#define __ELF_H + +#include +#include +#include + +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 +#define EI_NIDENT 16 + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 +#define EV_CURRENT 1 + +#define ELF_OSABI_NONE 0 +#define ELF_OSABI_NETBSD 2 +#define ELF_OSABI_GNU 3 +#define ELF_OSABI_LINUX ELF_OSABI_GNU +#define ELF_OSABI_SOLARIS 6 +#define ELF_OSABI_FREEBSD 9 +#define ELF_OSABI_OPENBSD 12 +#define ELF_OSABI_CORAX 32 + +struct elf_hdr { + /* magic number, elf type (ELF32/ELF64), byte order, etc. */ + u8_t e_ident[EI_NIDENT]; + /* executable, shared object, ... */ + u16_t e_type; + u16_t e_machine; + u32_t e_version; + u32_t e_entry; + u32_t e_phoff; + u32_t e_shoff; + u32_t e_flags; + u16_t e_ehsize; + u16_t e_phentsize; + u16_t e_phnum; + u16_t e_shentsize; + u16_t e_shnum; + u16_t e_shstrndx; +}; + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 + +struct elf_phdr { + u32_t p_type; + u32_t p_offset; + u32_t p_vaddr; + u32_t p_paddr; + u32_t p_filesz; + u32_t p_memsz; + u32_t p_flags; + u32_t p_align; +}; + +#define ELF_PHDR_R(_phdr_) ((_phdr_)->p_flags & PF_R) +#define ELF_PHDR_W(_phdr_) ((_phdr_)->p_flags & PF_W) +#define ELF_PHDR_X(_phdr_) ((_phdr_)->p_flags & PF_X) + +int elf_validate(void*, size_t); + +int elf_phdr_foreach(void*, size_t, + int (*)(struct elf_hdr*, struct elf_phdr*, void*), + void*); + +void* elf_entry(void*); + +#endif /* __ELF_H */ -- 2.47.3