summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-09-27 21:07:56 +0300
committerJari Vetoniemi <mailroxas@gmail.com>2018-09-27 21:07:56 +0300
commit77c5ffe6fcb761c9440e01ed67a797ff011a35dc (patch)
treec9fffe29384e0009ec25ef6ae6feefd62be0affd
parent6a62cdb73eee6dc989baebc91e679a3a9bfd1104 (diff)
elf.fspec: more complete version
-rw-r--r--spec/elf.fspec187
1 files changed, 174 insertions, 13 deletions
diff --git a/spec/elf.fspec b/spec/elf.fspec
index 2776c65..3b8f9f7 100644
--- a/spec/elf.fspec
+++ b/spec/elf.fspec
@@ -1,36 +1,193 @@
struct elf {
struct {
u8 ei_magic[4] | matches('\x7fELF') str;
+
enum {
CLASS_32 = 1,
CLASS_64
- } u8 ei_class hex; // word size
+ } u8 ei_class;
+
enum {
ENDIANESS_LE = 1,
ENDIANESS_BE
- } u8 ei_data hex; // endianess
+ } u8 ei_data;
+
u8 ei_version;
- u8 ei_osabi;
+
+ enum {
+ OSABI_SYSTEM_V,
+ OSABI_HP_UX,
+ OSABI_NETBSD,
+ OSABI_LINUX,
+ OSABI_GNU_HURD,
+ OSABI_SOLARIS,
+ OSABI_AIX,
+ OSABI_IRIX,
+ OSABI_FREEBSD,
+ OSABI_TRU64,
+ OSABI_NOVELL_MODESTO,
+ OSABI_OPENBSD,
+ OSABI_OPENVMS,
+ OSABI_NONSTOP_KERNEL,
+ OSABI_AROS,
+ OSABI_FENIX_OS,
+ OSABI_CLOUD_ABI
+ } u8 ei_osabi;
+
u8 ei_abi_version;
- u8 padding[7] nul;
- } header;
+ u8 ei_pad[7] nul;
+ } e_ident;
+
+ struct program_header {
+ enum {
+ PT_NULL,
+ PT_LOAD,
+ PT_DYNAMIC,
+ PT_INTERP,
+ PT_NOTE,
+ PT_SHLIB,
+ PT_PHDR,
+ PT_LOOS,
+ PT_HIOS,
+ PT_LOPROC,
+ PT_HIPROC
+ } u32 p_type;
+
+ select (e_ident.ei_class) {
+ header.CLASS_32)
+ struct {
+ u32 p_offset hex;
+ u32 p_vaddr hex;
+ u32 p_paddr hex;
+ u32 p_filesz;
+ u32 p_memsz;
+ u32 p_flags hex;
+ u32 p_align;
+ } elf32;
+ header.CLASS_64)
+ struct {
+ u32 p_flags hex;
+ u64 p_offset hex;
+ u64 p_vaddr hex;
+ u64 p_paddr hex;
+ u64 p_filesz;
+ u64 p_memsz;
+ u64 p_align;
+ } elf64;
+ } arch;
+ };
+
+ struct section_header {
+ enum sh_flags {
+ SHF_WRITE = 0x1,
+ SHF_ALLOC = 0x2,
+ SHF_EXECINSTR = 0x4,
+ SHF_MERGE = 0x10,
+ SHF_STRINGS = 0x20,
+ SHF_INFO_LINK = 0x40,
+ SHF_LINK_ORDER = 0x80,
+ SHF_OS_NONCONFORMING = 0x100,
+ SHF_GROUP = 0x200,
+ SHF_TLS = 0x400,
+ SHF_MASKOS = 0x0ff00000,
+ SHF_MASKPROC = 0xf0000000,
+ SHF_ORDERED = 0x40000000,
+ SHF_EXCLUDE = 0x80000000
+ };
+
+ select (e_ident.ei_class) {
+ header.CLASS_32)
+ struct {
+ u32 sh_name hex;
+
+ enum sh_type {
+ SHT_NULL,
+ SHT_PROGBITS,
+ SHT_SYMTAB,
+ SHT_STRTAB,
+ SHT_RELA,
+ SHT_HASH,
+ SHT_DYNAMIC,
+ SHT_NOTE,
+ SHT_NOBITS,
+ SHT_REL,
+ SHT_SHLIB,
+ SHT_DYNSYM,
+ SHT_INIT_ARRAY,
+ SHT_FINI_ARRAY,
+ SHT_PREINIT_ARRAY,
+ SHT_GROUP,
+ SHT_SYMTAB_INDEX,
+ SHT_NUM,
+ SHT_LOOS = 0x60000000
+ } u32 sh_type;
+
+ enum sh_flags u32 sh_flags;
+ u32 sh_addr hex;
+ u32 sh_offset hex;
+ u32 sh_size;
+ u32 sh_link;
+ u32 sh_info;
+ u32 sh_addralign;
+ u32 sh_entsize;
+ } elf32;
+ header.CLASS_64)
+ struct {
+ enum sh_flags u64 sh_flags;
+ u64 sh_addr hex;
+ u64 sh_offset hex;
+ u64 sh_size;
+ u64 sh_addralign;
+ u64 sh_entsize;
+ } elf64;
+ } arch;
+ };
struct body {
- u16 e_type hex;
- u16 e_machine hex;
+ enum {
+ ET_NONE,
+ ET_REL,
+ ET_EXEC,
+ ET_DYN,
+ ET_CORE,
+ ET_LOOS = 0xfe00,
+ ET_HIOS = 0xfeff,
+ ET_LOPROC = 0xff00,
+ ET_HIPROC = 0xffff
+ } u16 e_type hex;
+
+ enum {
+ MACHINE_NONE,
+ MACHINE_SPARC = 0x02,
+ MACHINE_X86 = 0x03,
+ MACHINE_MIPS = 0x08,
+ MACHINE_POWERPC = 0x14,
+ MACHINE_S390 = 0x16,
+ MACHINE_ARM = 0x28,
+ MACHINE_SUPERH = 0x2A,
+ MACHINE_IA_64 = 0x32,
+ MACHINE_X86_64 = 0x3E,
+ MACHINE_AARCH64 = 0xB7,
+ MACHINE_RISCV = 0xF3
+ } u16 e_machine hex;
+
u32 e_version;
- select (header.ei_class) {
- header.CLASS_32) struct {
+
+ select (e_ident.ei_class) {
+ header.CLASS_32)
+ struct {
u32 e_entry hex;
u32 e_phoff;
u32 e_shoff;
} elf32;
- header.CLASS_64) struct {
+ header.CLASS_64)
+ struct {
u64 e_entry hex;
u64 e_phoff;
u64 e_shoff;
} elf64;
} arch;
+
u32 e_flags hex;
u16 e_ehsz;
u16 e_phentsize;
@@ -38,10 +195,14 @@ struct elf {
u16 e_shentsize;
u16 e_shnum;
u16 e_shstrndx;
+
+ // TODO: need to handle offsets
+ struct program_header e_ph[e_phnum:e_phentsize];
+ struct section_header e_sh[e_shnum:e_shentsize];
};
- select (header.ei_class) {
- 1) struct body le | endianess('le');
- 2) struct body be | endianess('be');
+ select (e_ident.ei_class) {
+ e_ident.ENDIANESS_LE) struct body le | endianess('le');
+ e_ident.ENDIANESS_BE) struct body be | endianess('be');
} body;
};