]> git.corax.cc Git - corax/commitdiff
kernel/core: Add simple ELF file support
authorMatthias Kruk <m@m10k.eu>
Mon, 4 May 2020 08:27:43 +0000 (17:27 +0900)
committerMatthias Kruk <m@m10k.eu>
Mon, 4 May 2020 08:27:43 +0000 (17:27 +0900)
kernel/core/Makefile
kernel/core/elf.c [new file with mode: 0644]
kernel/core/elf.h [new file with mode: 0644]

index 6ef7ddd338bde96ac6c7a78affd2d28b7f1cb03c..d359f39fc46cb4ea4707d5b4278bbcefc2b6468a 100644 (file)
@@ -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 (file)
index 0000000..b25b7ca
--- /dev/null
@@ -0,0 +1,82 @@
+#include <config.h>
+#include <sys/types.h>
+#include <corax/errno.h>
+#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 (file)
index 0000000..3ed2fd3
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef __ELF_H
+#define __ELF_H
+
+#include <config.h>
+#include <corax/types.h>
+#include <sys/types.h>
+
+#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 */