From 77c5ffe6fcb761c9440e01ed67a797ff011a35dc Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Thu, 27 Sep 2018 21:07:56 +0300 Subject: elf.fspec: more complete version --- spec/elf.fspec | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 174 insertions(+), 13 deletions(-) (limited to 'spec') 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; }; -- cgit v1.2.3