#ifndef MR4TH_ELF_H #define MR4TH_ELF_H /* ** ELF total layout summary: ** ** TODO */ //////////////////////////////// // Types: ELF // identification #define ELF_NUM_IDENT 16 #define ELF_IdentificationIdx_XList(X)\ X(MAG0, 0)\ X(MAG1, 1)\ X(MAG2, 2)\ X(MAG3, 3)\ X(CLASS, 4)\ X(DATA, 5)\ X(VERSION, 6)\ X(OSABI, 7)\ X(ABIVERSION, 8)\ X(PAD0, 9)\ X(PAD1, 10)\ X(PAD2, 11)\ X(PAD3, 12)\ X(PAD4, 13)\ X(PAD5, 14)\ X(PAD6, 15) typedef enum ELF_IdentificationIdx{ #define X(N,C) ELF_IdentificationIdx_##N = C, ELF_IdentificationIdx_XList(X) #undef X } ELF_IdentificationIdx; #define ELF_Magic_Byte0 0x7F #define ELF_Magic_Byte1 'E' #define ELF_Magic_Byte2 'L' #define ELF_Magic_Byte3 'F' // elf class #define ELF_Class_XList(X)\ X(NONE, 0)\ X(32, 1)\ X(64, 2) typedef enum ELF_Class{ #define X(N,C) ELF_Class_##N = C, ELF_Class_XList(X) #undef X } ELF_Class; // elf encoding #define ELF_Encoding_XList(X)\ X(NONE, 0)\ X(2LSB, 1)\ X(2MSB, 2) typedef enum ELF_Encoding{ #define X(N,C) ELF_Encoding_##N = C, ELF_Encoding_XList(X) #undef X } ELF_Encoding; // elf os/abi extension #define ELF_OsAbiExtension_XList(X)\ X(NONE, 0)\ X(HPUX, 1)\ X(NETBSD, 2)\ X(GNU, 3)\ X(SOLARIS, 6)\ X(AIX, 7)\ X(IRIX, 8)\ X(FREEBSD, 9)\ X(TRU64, 10)\ X(MODESTO, 11)\ X(OPENBSD, 12)\ X(OPENVMS, 13)\ X(NSK, 14)\ X(AROS, 15)\ X(FENIXOS, 16)\ X(CLOUDABI, 17)\ X(OPENVOS, 18) typedef enum ELF_OsAbiExtension{ #define X(N,C) ELF_OsAbiExtension_##N = C, ELF_OsAbiExtension_XList(X) #undef X } ELF_OsAbiExtension; // file type #define ELF_FileType_XList(X)\ X(NONE, 0)\ X(REL, 1)\ X(EXEC, 2)\ X(DYN, 3)\ X(CORE, 4)\ X(LOOS, 0xfe00)\ X(HIOS, 0xfeff)\ X(LOPROC, 0xff00)\ X(HIPROC, 0xffff) typedef U16 ELF_FileType; enum{ #define X(N,C) ELF_FileType_##N = C, ELF_FileType_XList(X) #undef X }; // machine type #define ELF_MachineType_XList(X)\ X(NONE, 0)\ X(M32, 1)\ X(SPARC, 2)\ X(386, 3)\ X(68K, 4)\ X(88K, 5)\ X(IAMCU, 6)\ X(860, 7)\ X(MIPS, 8)\ X(S370, 9)\ X(MIPS_RS3_LE, 10)\ X(PARISC, 15)\ X(VPP500, 17)\ X(SPARC32PLUS, 18)\ X(960, 19)\ X(PPC, 20)\ X(PPC64, 21)\ X(S390, 22)\ X(SPU, 23)\ X(V800, 36)\ X(FR20, 37)\ X(RH32, 38)\ X(RCE, 39)\ X(ARM, 40)\ X(ALPHA, 41)\ X(SH, 42)\ X(SPARCV9, 43)\ X(TRICORE, 44)\ X(ARC, 45)\ X(H8_300, 300)\ X(H8S, 48)\ X(H8_500, 49)\ X(IA_64, 50)\ X(MIPS_X, 51)\ X(COLDFIRE, 52)\ X(68HC12, 53)\ X(MMA, 54)\ X(PCP, 55)\ X(NCPU, 56)\ X(NDR1, 57)\ X(STARCORE, 58)\ X(ME16, 59)\ X(ST100, 60)\ X(TINYJ, 61)\ X(X86_64, 62)\ X(PDSP, 63)\ X(PDP10, 64)\ X(PDP11, 65)\ X(FX66, 66)\ X(ST9PLUS, 67)\ X(ST7, 68)\ X(68HC16, 69)\ X(68HC11, 70)\ X(68HC08, 71)\ X(68HC05, 72)\ X(SVX, 73)\ X(ST19, 74)\ X(VAX, 75)\ X(CRIS, 76)\ X(JAVELIN, 77)\ X(FIREPATH, 78)\ X(ZSP, 79)\ X(MMIX, 80)\ X(HUANY, 81)\ X(PRISM, 82)\ X(AVR, 83)\ X(FR30, 84)\ X(D10V, 85)\ X(D30V, 86)\ X(V850, 87)\ X(M32R, 88)\ X(MN10300, 89)\ X(MN10200, 90)\ X(PJ, 91)\ X(OPENRISC, 92)\ X(ARC_COMPACT, 93)\ X(XTENSA, 94)\ X(VIDEOCORE, 95)\ X(TMM_GPP, 96)\ X(NS32K, 97)\ X(TPC, 98)\ X(SNP1K, 99)\ X(ST200, 100)\ X(IP2K, 101)\ X(MAX, 102)\ X(CR, 103)\ X(F2MC16, 104)\ X(MSP430, 105)\ X(BLACKFIN, 106)\ X(SE_C33, 107)\ X(SEP, 108)\ X(ARCA, 109)\ X(UNICORE, 110)\ X(EXCESS, 111)\ X(DXP, 112)\ X(ALTERA_NIOS2, 113)\ X(CRX, 114)\ X(XGATE, 115)\ X(C166, 116)\ X(M16C, 117)\ X(DSPIC30F, 118)\ X(CE, 119)\ X(M32C, 120)\ X(TSK3000, 131)\ X(RS08, 132)\ X(SHARC, 133)\ X(ECOG2, 134)\ X(SCORE7, 135)\ X(DSP24, 136)\ X(VIDEOCORE3, 137)\ X(LATTICEMICO32, 138)\ X(SE_C17, 139)\ X(TI_C6000, 140)\ X(TI_C2000, 141)\ X(TI_C5500, 142)\ X(TI_ARP32, 143)\ X(TI_PRU, 144)\ X(MMDSP_PLUS, 160)\ X(CYPRESS_M8C, 161)\ X(R32C, 162)\ X(TRIMEDIA, 163)\ X(QDSP6, 164)\ X(8051, 165)\ X(STXP7X, 166)\ X(NDS32, 167)\ X(ECOG1, 168)\ X(MAXQ30, 169)\ X(XIMO16, 170)\ X(MANIK, 171)\ X(CRAYNV2, 172)\ X(RX, 173)\ X(METAG, 174)\ X(MCST_ELBRUS, 175)\ X(ECOG16, 176)\ X(CR16, 177)\ X(ETPU, 178)\ X(SLE9X, 179)\ X(L10M, 180)\ X(K10M, 181)\ X(AARCH64, 183)\ X(AVR32, 185)\ X(STM8, 186)\ X(TILE64, 187)\ X(TILEPRO, 188)\ X(MICROBLAZE, 189)\ X(CUDA, 190)\ X(TILEGX, 191)\ X(CLOUDSHIELD, 192)\ X(COREA_1ST, 193)\ X(COREA_2ND, 194)\ X(ARC_COMPACT2, 195)\ X(OPEN8, 196)\ X(RL78, 197)\ X(VIDEOCORE5, 198)\ X(78KOR, 199)\ X(56800EX, 200)\ X(BA1, 201)\ X(BA2, 202)\ X(XCORE, 203)\ X(MCHP_PIC, 204)\ X(INTEL205, 205)\ X(INTEL206, 206)\ X(INTEL207, 207)\ X(INTEL208, 208)\ X(INTEL209, 209)\ X(KM32, 210)\ X(KMX32, 211)\ X(KMX16, 212)\ X(KMX8, 213)\ X(KVARC, 214)\ X(CDP, 215)\ X(COGE, 216)\ X(COOL, 217)\ X(NORC, 218)\ X(CSR_KALIMBA, 219)\ X(Z80, 220)\ X(VISIUM, 221)\ X(FT32, 222)\ X(MOXIE, 223)\ X(AMDGPU, 224)\ X(RISCV, 243) typedef U16 ELF_MachineType; enum{ #define X(N,C) ELF_MachineType_##N = C, ELF_MachineType_XList(X) #undef X }; // elf header typedef struct ELF_Header32{ U8 ident[ELF_NUM_IDENT]; ELF_FileType type; ELF_MachineType machine; U32 version; U32 entry; U32 segment_table_foff; U32 section_table_foff; U32 flags; U16 header_size; U16 segment_size; U16 segment_count; U16 section_size; U16 section_count; U16 string_section_index; } ELF_Header32; typedef struct ELF_Header64{ U8 ident[ELF_NUM_IDENT]; ELF_FileType type; ELF_MachineType machine; U32 version; U64 entry; U64 segment_table_foff; U64 section_table_foff; U32 flags; U16 header_size; U16 segment_size; U16 segment_count; U16 section_size; U16 section_count; U16 string_section_index; } ELF_Header64; // elf section type #define ELF_SectionType_XList(X)\ X(NULL, 0)\ X(PROGBITS, 1)\ X(SYMTAB, 2)\ X(STRTAB, 3)\ X(RELA, 4)\ X(HASH, 5)\ X(DYNAMIC, 6)\ X(NOTE, 7)\ X(NOBITS, 8)\ X(REL, 9)\ X(SHLIB, 10)\ X(DYNSYM, 11)\ X(INIT_ARRAY, 14)\ X(FINI_ARRAY, 15)\ X(PREINIT_ARRAY, 16)\ X(GROUP, 17)\ X(SYMTAB_SHNDX, 18)\ X(LOOS, 0x60000000)\ X(HIOS, 0x6fffffff)\ X(LOPROC, 0x70000000)\ X(HIPROC, 0x7fffffff)\ X(LOUSER, 0x80000000)\ X(HIUSER, 0xffffffff) typedef U32 ELF_SectionType; enum{ #define X(N,C) ELF_SectionType_##N = C, ELF_SectionType_XList(X) #undef X }; // elf section flags #define ELF_SectionFlags_XList(X)\ X(WRITE, 0x1)\ X(ALLOC, 0x2)\ X(EXECINSTR, 0x4)\ X(MERGE, 0x10)\ X(STRINGS, 0x20)\ X(INFO_LINK, 0x40)\ X(LINK_ORDER, 0x80)\ X(OS_NONCONFORMING, 0x100)\ X(GROUP, 0x200)\ X(TLS, 0x400)\ X(COMPRESSED, 0x800)\ X(MASKOS, 0x0ff00000)\ X(MASKPROC, 0xf0000000) enum{ #define X(N,C) ELF_SectionFlag_##N = C, ELF_SectionFlags_XList(X) #undef X }; // elf section indexes #define ELF_SectionIndex_XList(X)\ X(UNDEF, 0)\ X(LORESERVE, 0xff00)\ X(LOPROC, 0xff00)\ X(HIPROC, 0xff1f)\ X(LOOS, 0xff20)\ X(HIOS, 0xff3f)\ X(ABS, 0xfff1)\ X(COMMON, 0xfff2)\ X(XINDEX, 0xffff)\ X(HIRESERVE, 0xffff) typedef enum ELF_SectionIndex{ #define X(N,C) ELF_SectionIndex_##N = C, ELF_SectionIndex_XList(X) #undef X } ELF_SectionIndex; // elf section typedef struct ELF_Section32{ U32 name; ELF_SectionType type; U32 flags; U32 addr; U32 offset; U32 size; U32 link; U32 info; U32 addralign; U32 entsize; } ELF_Section32; typedef struct ELF_Section64{ U32 name; ELF_SectionType type; U64 flags; U64 addr; U64 offset; U64 size; U32 link; U32 info; U64 addralign; U64 entsize; } ELF_Section64; // elf compression type #define ELF_CompressionType_XList(X)\ X(ZLIB, 1)\ X(LOOS, 0x60000000)\ X(HIOS, 0x6fffffff)\ X(LOPROC, 0x70000000)\ X(HIPROC, 0x7fffffff) typedef enum ELF_CompressionType{ #define X(N,C) ELF_CompressionType_##N = C, ELF_CompressionType_XList(X) #undef X } ELF_CompressionType; // elf compression header typedef struct ELF_CompressionHeader32{ ELF_CompressionType type; U32 size; U32 addralign; } ELF_CompressionHeader32; typedef struct ELF_CompressionHeader64{ ELF_CompressionType type; U32 reserved; U64 size; U64 addralign; } ELF_CompressionHeader64; // elf section group flags #define ELF_SectionGroupFlags_XList(X)\ X(COMDAT, 0x1)\ X(MASKOS, 0x0ff00000)\ X(MASKPROC, 0xf0000000) typedef U32 ELF_SectionGroupFlags; enum{ #define X(N,C) ELF_SectionGroupFlag_##N = C, ELF_SectionGroupFlags_XList(X) #undef X }; // elf symbol typedef struct ELF_Symbol32{ U32 name; U32 value; U32 size; U8 info; U8 other; U16 section_index; } ELF_Symbol32; typedef struct ELF_Symbol64{ U32 name; U8 info; U8 other; U16 section_index; U64 value; U64 size; } ELF_Symbol64; #define ELF_Symbol_BindFromInfo(inf) ((inf)>>4) #define ELF_Symbol_TypeFromInfo(inf) ((inf)&0xF) #define ELF_Symbol_InfoFromBindType(bin,typ) (((bin)<<4)|((type)&0xF)) #define ELF_Symbol_VisFromOther(oth) ((oth)&0x3) #define ELF_Symbol_OtherFromVis(vis) (((vis)&0x3)) // elf symbol binding #define ELF_SymbolBinding_XList(X)\ X(LOCAL, 0)\ X(GLOBAL, 1)\ X(WEAK, 2)\ X(LOOS, 10)\ X(HIOS, 12)\ X(LOPROC, 13)\ X(HIPROC, 15) typedef enum ELF_SymbolBinding{ #define X(N,C) ELF_SymbolBinding_##N = C, ELF_SymbolBinding_XList(X) #undef X } ELF_SymbolBinding; // elf symbol types #define ELF_SymbolType_XList(X)\ X(NOTYPE, 0)\ X(OBJECT, 1)\ X(FUNC, 2)\ X(SECTION, 3)\ X(FILE, 4)\ X(COMMON, 5)\ X(TLS, 6)\ X(LOOS, 10)\ X(HIOS, 12)\ X(LOPROC, 13)\ X(HIPROC, 15) typedef enum ELF_SymbolType{ #define X(N,C) ELF_SymbolType_##N = C, ELF_SymbolType_XList(X) #undef X } ELF_SymbolType; // elf symbol visibility #define ELF_SymbolVis_XList(X)\ X(DEFAULT, 0)\ X(INTERNAL, 1)\ X(HIDDEN, 2)\ X(PROTECTED, 3) typedef enum ELF_SymbolVis{ #define X(N,C) ELF_SymbolVis_##N = C, ELF_SymbolVis_XList(X) #undef X } ELF_SymbolVis; // elf relocations typedef struct ELF_Relocation32{ U32 offset; U32 info; } ELF_Relocation32; typedef struct ELF_RelocationAdd32{ U32 offset; U32 info; S32 addend; } ELF_RelocationAdd32; typedef struct ELF_Relocation64{ U64 offset; U64 info; } ELF_Relocation64; typedef struct ELF_RelocationAdd64{ U64 offset; U64 info; S64 addend; } ELF_RelocationAdd64; // elf segment type #define ELF_SegmentType_XList(X)\ X(NULL, 0)\ X(LOAD, 1)\ X(DYNAMIC, 2)\ X(INTERP, 3)\ X(NOTE, 4)\ X(SHLIB, 5)\ X(PHDR, 6)\ X(TLS, 7)\ X(LOOS, 0x60000000)\ X(HIOS, 0x6fffffff)\ X(LOPROC, 0x70000000)\ X(HIPROC, 0x7fffffff) typedef U32 ELF_SegmentType; enum{ #define X(N,C) ELF_SegmentType_##N = C, ELF_SegmentType_XList(X) #undef X }; // elf segment flags #define ELF_SegmentFlags_XList(X)\ X(X, 0x1)\ X(W, 0x2)\ X(R, 0x4)\ X(MASKOS, 0x0ff00000)\ X(MASKPROC, 0xf0000000)\ typedef U32 ELF_SegmentFlags; enum{ #define X(N,C) ELF_SegmentFlag_##N = C, ELF_SegmentFlags_XList(X) #undef X }; // elf segment typedef struct ELF_Segment32{ ELF_SegmentType type; U32 offset; U32 vaddr; U32 paddr; U32 file_size; U32 memory_size; ELF_SegmentFlags flags; U32 align; } ELF_Segment32; typedef struct ELF_Segment64{ ELF_SegmentType type; ELF_SegmentFlags flags; U64 offset; U64 vaddr; U64 paddr; U64 file_size; U64 memory_size; U64 align; } ELF_Segment64; //////////////////////////////// // Functions: ELF // normalizing MR4TH_SYMBOL_STATIC U16 elf_u16_decode(void *ptr, B32 flip); MR4TH_SYMBOL_STATIC U32 elf_u32_decode(void *ptr, B32 flip); MR4TH_SYMBOL_STATIC U64 elf_u64_decode(void *ptr, B32 flip); MR4TH_SYMBOL_STATIC void elf_header64_from_header32(ELF_Header64 *dst, ELF_Header32 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_header64_from_header64(ELF_Header64 *dst, ELF_Header64 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_section64_from_section32(ELF_Section64 *dst, ELF_Section32 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_section64_from_section64(ELF_Section64 *dst, ELF_Section64 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_segment64_from_segment32(ELF_Segment64 *dst, ELF_Segment32 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_segment64_from_segment64(ELF_Segment64 *dst, ELF_Segment64 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_symbol64_from_symbol32(ELF_Symbol64 *dst, ELF_Symbol32 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_symbol64_from_symbol64(ELF_Symbol64 *dst, ELF_Symbol64 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloc32(ELF_RelocationAdd64 *dst, ELF_Relocation32 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloc64(ELF_RelocationAdd64 *dst, ELF_Relocation64 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloca32(ELF_RelocationAdd64 *dst, ELF_RelocationAdd32 *src, ELF_Encoding src_encoding); MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloca64(ELF_RelocationAdd64 *dst, ELF_RelocationAdd64 *src, ELF_Encoding src_encoding); // strings MR4TH_SYMBOL_STATIC String8 elf_str8_from_identification_idx(ELF_IdentificationIdx idx); MR4TH_SYMBOL_STATIC String8 elf_str8_from_class(ELF_Class elf_class); MR4TH_SYMBOL_STATIC String8 elf_str8_from_encoding(ELF_Encoding elf_encoding); MR4TH_SYMBOL_STATIC String8 elf_str8_from_osabi(ELF_OsAbiExtension elf_osabi); MR4TH_SYMBOL_STATIC String8 elf_str8_from_file_type(ELF_FileType file_type); MR4TH_SYMBOL_STATIC String8 elf_str8_from_machine_type(ELF_FileType machine_type); MR4TH_SYMBOL_STATIC String8 elf_str8_from_section_type(ELF_SectionType section_type); MR4TH_SYMBOL_STATIC void elf_str8list_from_section_flags(Arena *arena, String8List *out, U32 flags); MR4TH_SYMBOL_STATIC String8 elf_str8_from_section_flags(Arena *arena, U32 flags); MR4TH_SYMBOL_STATIC String8 elf_str8_from_segment_type(ELF_SegmentType segment_type); MR4TH_SYMBOL_STATIC void elf_str8list_from_segment_flags(Arena *arena, String8List *out, ELF_SegmentFlags flags); MR4TH_SYMBOL_STATIC String8 elf_str8_from_segment_flags(Arena *arena, ELF_SegmentFlags flags); MR4TH_SYMBOL_STATIC String8 elf_str8_from_symbol_binding(ELF_SymbolBinding bind); MR4TH_SYMBOL_STATIC String8 elf_str8_from_symbol_type(ELF_SymbolType type); MR4TH_SYMBOL_STATIC String8 elf_str8_from_symbol_vis(ELF_SymbolVis vis); #endif //MR4TH_ELF_H