#pragma once #include #include /* * ELF format according to * https://en.wikipedia.org/wiki/Executable_and_Linkable_Format */ #define EI_MAG_SIZE 4 #define PT_NULL 0x00000000 #define PT_LOAD 0x00000001 #define PT_DYNAMIC 0x00000002 #define PT_INTERP 0x00000003 #define PT_NOTE 0x00000004 #define PT_SHLIB 0x00000005 #define PT_PHDR 0x00000006 #define PT_LOOS 0x60000000 #define PT_HIOS 0x6fffffff #define PT_LOPROC 0x70000000 #define PT_HIRPOC 0x7fffffff #define PF_ALL 0x7 #define PF_X 0x1 #define PF_W 0x2 #define PF_R 0x4 /* * This part of ELF header is endianness-independent. */ struct elf_indent { u8 ei_magic[4]; u8 ei_class; u8 ei_data; u8 ei_version; u8 ei_osabi; u8 ei_abiversion; u8 ei_pad[7]; }; /* * ELF header format. One should check the `e_indent` to decide the endianness. */ struct elf_header { struct elf_indent e_indent; u16 e_type; u16 e_machine; u32 e_version; u64 e_entry; u64 e_phoff; u64 e_shoff; u32 e_flags; u16 e_ehsize; u16 e_phentsize; u16 e_phnum; u16 e_shentsize; u16 e_shnum; u16 e_shstrndx; }; /* * 32-Bit of the elf_header. Check the `e_indent` first to decide. */ struct elf_header_32 { struct elf_indent e_indent; u16 e_type; u16 e_machine; u32 e_version; u32 e_entry; u32 e_phoff; u32 e_shoff; u32 e_flags; u16 e_ehsize; u16 e_phentsize; u16 e_phnum; u16 e_shentsize; u16 e_shnum; u16 e_shstrndx; }; struct elf_program_header { u32 p_type; u32 p_flags; u64 p_offset; u64 p_vaddr; u64 p_paddr; u64 p_filesz; u64 p_memsz; u64 p_align; }; struct elf_program_header_32 { u32 p_type; u32 p_offset; u32 p_vaddr; u32 p_paddr; u32 p_filesz; u32 p_memsz; u32 p_flags; u32 p_align; }; struct elf_section_header { u32 sh_name; u32 sh_type; u64 sh_flags; u64 sh_addr; u64 sh_offset; u64 sh_size; u32 sh_link; u32 sh_info; u64 sh_addralign; u64 sh_entsize; }; struct elf_section_header_32 { u32 sh_name; u32 sh_type; u32 sh_flags; u32 sh_addr; u32 sh_offset; u32 sh_size; u32 sh_link; u32 sh_info; u32 sh_addralign; u32 sh_entsize; }; #define MAX_P_HEADERS 128 #define MAX_S_HEADERS 128 struct elf_file { struct elf_header header; struct elf_program_header p_headers[MAX_P_HEADERS]; struct elf_section_header s_headers[MAX_S_HEADERS]; }; struct elf_file *elf_parse_file(const char *code, struct elf_file *elf);