c-scripting/mr4th/mr4th_elf.h

706 lines
14 KiB
C

#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;
// 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