1 2 /** 3 * Declarations for ELF file format 4 * 5 * Compiler implementation of the 6 * $(LINK2 https://www.dlang.org, D programming language). 7 * 8 * Translation to D of Linux's melf.h 9 * 10 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/melf.d, backend/melf.d) 11 */ 12 13 module dmd.backend.melf; 14 15 /* ELF file format */ 16 17 alias Elf32_Half = ushort; 18 alias Elf32_Word = uint; 19 alias Elf32_Sword = int; 20 alias Elf32_Addr = uint; 21 alias Elf32_Off = uint; 22 alias elf_u8_f32 = uint; 23 24 enum EI_NIDENT = 16; 25 26 nothrow: 27 @safe: 28 29 // EHident 30 enum EI_MAG0 = 0; /* Identification byte offset 0*/ 31 enum EI_MAG1 = 1; /* Identification byte offset 1*/ 32 enum EI_MAG2 = 2; /* Identification byte offset 2*/ 33 enum EI_MAG3 = 3; /* Identification byte offset 3*/ 34 enum ELFMAG0 = 0x7f; /* Magic number byte 0 */ 35 enum ELFMAG1 = 'E'; /* Magic number byte 1 */ 36 enum ELFMAG2 = 'L'; /* Magic number byte 2 */ 37 enum ELFMAG3 = 'F'; /* Magic number byte 3 */ 38 39 enum EI_CLASS = 4; /* File class byte offset 4 */ 40 enum ELFCLASSNONE = 0; // invalid 41 enum ELFCLASS32 = 1; /* 32-bit objects */ 42 enum ELFCLASS64 = 2; /* 64-bit objects */ 43 44 enum EI_DATA = 5; /* Data encoding byte offset 5 */ 45 enum ELFDATANONE = 0; // invalid 46 enum ELFDATA2LSB = 1; /* 2's comp,lsb low address */ 47 enum ELFDATA2MSB = 2; /* 2's comp,msb low address */ 48 49 enum EI_VERSION = 6; /* Header version byte offset 6 */ 50 //enum EV_CURRENT = 1; /* Current header format */ 51 52 enum EI_OSABI = 7; /* OS ABI byte offset 7 */ 53 enum ELFOSABI_SYSV = 0; /* UNIX System V ABI */ 54 enum ELFOSABI_HPUX = 1; /* HP-UX */ 55 enum ELFOSABI_NETBSD = 2; 56 enum ELFOSABI_LINUX = 3; 57 enum ELFOSABI_FREEBSD = 9; 58 enum ELFOSABI_OPENBSD = 12; 59 enum ELFOSABI_ARM = 97; /* ARM */ 60 enum ELFOSABI_STANDALONE = 255; /* Standalone/embedded */ 61 62 enum EI_ABIVERSION = 8; /* ABI version byte offset 8 */ 63 64 enum EI_PAD = 9; /* Byte to start of padding */ 65 66 // e_type 67 enum ET_NONE = 0; /* No specified file type */ 68 enum ET_REL = 1; /* Relocatable object file */ 69 enum ET_EXEC = 2; /* Executable file */ 70 enum ET_DYN = 3; /* Dynamic link object file */ 71 enum ET_CORE = 4; /* Core file */ 72 enum ET_LOPROC = 0xff00; /* Processor low index */ 73 enum ET_HIPROC = 0xffff; /* Processor hi index */ 74 75 // e_machine 76 enum EM_386 = 3; /* Intel 80386 */ 77 enum EM_486 = 6; /* Intel 80486 */ 78 enum EM_X86_64 = 62; // Advanced Micro Devices X86-64 processor 79 80 // e_version 81 enum EV_NONE = 0; // invalid version 82 enum EV_CURRENT = 1; // Current file format 83 84 // e_ehsize 85 enum EH_HEADER_SIZE = 0x34; 86 87 // e_phentsize 88 enum EH_PHTENT_SIZE = 0x20; 89 90 // e_shentsize 91 enum EH_SHTENT_SIZE = 0x28; 92 93 struct Elf32_Ehdr 94 { 95 ubyte[EI_NIDENT] EHident; /* Header identification info */ 96 Elf32_Half e_type; /* Object file type */ 97 Elf32_Half e_machine; /* Machine architecture */ 98 Elf32_Word e_version; /* File format version */ 99 Elf32_Addr e_entry; /* Entry point virtual address */ 100 Elf32_Off e_phoff; /* Program header table(PHT)offset */ 101 Elf32_Off e_shoff; /* Section header table(SHT)offset */ 102 Elf32_Word e_flags; /* Processor-specific flags */ 103 Elf32_Half e_ehsize; /* Size of ELF header (bytes) */ 104 Elf32_Half e_phentsize; /* Size of PHT (bytes) */ 105 Elf32_Half e_phnum; /* Number of PHT entries */ 106 Elf32_Half e_shentsize; /* Size of SHT entry in bytes */ 107 Elf32_Half e_shnum; /* Number of SHT entries */ 108 Elf32_Half e_shstrndx; /* SHT index for string table */ 109 } 110 111 112 /* Section header. */ 113 114 // sh_type 115 enum SHT_NULL = 0; /* SHT entry unused */ 116 enum SHT_PROGBITS = 1; /* Program defined data */ 117 enum SHT_SYMTAB = 2; /* Symbol table */ 118 enum SHT_STRTAB = 3; /* String table */ 119 enum SHT_RELA = 4; /* Relocations with addends */ 120 enum SHT_HASHTAB = 5; /* Symbol hash table */ 121 enum SHT_DYNAMIC = 6; /* String table for dynamic symbols */ 122 enum SHT_NOTE = 7; /* Notes */ 123 enum SHT_RESDATA = 8; /* Reserved data space */ 124 enum SHT_NOBITS = SHT_RESDATA; 125 enum SHT_REL = 9; /* Relocations no addends */ 126 enum SHT_RESTYPE = 10; /* Reserved section type*/ 127 enum SHT_DYNTAB = 11; /* Dynamic linker symbol table */ 128 enum SHT_INIT_ARRAY = 14; /* Array of constructors */ 129 enum SHT_FINI_ARRAY = 15; /* Array of destructors */ 130 enum SHT_GROUP = 17; /* Section group (COMDAT) */ 131 enum SHT_SYMTAB_SHNDX = 18; /* Extended section indices */ 132 133 // sh_flags 134 enum SHF_WRITE = (1 << 0); /* Writable during execution */ 135 enum SHF_ALLOC = (1 << 1); /* In memory during execution */ 136 enum SHF_EXECINSTR = (1 << 2); /* Executable machine instructions*/ 137 enum SHF_MERGE = 0x10; 138 enum SHF_STRINGS = 0x20; 139 enum SHF_INFO_LINK = 0x40; 140 enum SHF_LINK_ORDER = 0x80; 141 enum SHF_OS_NONCONFORMING = 0x100; 142 enum SHF_GROUP = 0x200; // Member of a section group 143 enum SHF_TLS = 0x400; /* Thread local */ 144 enum SHF_MASKPROC = 0xf0000000; /* Mask for processor-specific */ 145 146 struct Elf32_Shdr 147 { 148 Elf32_Word sh_name; /* String table offset for section name */ 149 Elf32_Word sh_type; /* Section type */ 150 Elf32_Word sh_flags; /* Section attribute flags */ 151 Elf32_Addr sh_addr; /* Starting virtual memory address */ 152 Elf32_Off sh_offset; /* Offset to section in file */ 153 Elf32_Word sh_size; /* Size of section */ 154 Elf32_Word sh_link; /* Index to optional related section */ 155 Elf32_Word sh_info; /* Optional extra section information */ 156 Elf32_Word sh_addralign; /* Required section alignment */ 157 Elf32_Word sh_entsize; /* Size of fixed size section entries */ 158 } 159 160 // Special Section Header Table Indices 161 enum SHN_UNDEF = 0; /* Undefined section */ 162 enum SHN_LORESERVE = 0xff00; /* Start of reserved indices */ 163 enum SHN_LOPROC = 0xff00; /* Start of processor-specific */ 164 enum SHN_HIPROC = 0xff1f; /* End of processor-specific */ 165 enum SHN_LOOS = 0xff20; /* Start of OS-specific */ 166 enum SHN_HIOS = 0xff3f; /* End of OS-specific */ 167 enum SHN_ABS = 0xfff1; /* Absolute value for symbol references */ 168 enum SHN_COMMON = 0xfff2; /* Symbol defined in common section */ 169 enum SHN_XINDEX = 0xffff; /* Index is in extra table. */ 170 enum SHN_HIRESERVE = 0xffff; /* End of reserved indices */ 171 172 173 /* Symbol Table */ 174 175 // st_info 176 177 ubyte ELF32_ST_BIND(ubyte s) { return s >> 4; } 178 ubyte ELF32_ST_TYPE(ubyte s) { return s & 0xf; } 179 ubyte ELF32_ST_INFO(ubyte b, ubyte t) { return cast(ubyte)((b << 4) + (t & 0xf)); } 180 181 enum STB_LOCAL = 0; /* Local symbol */ 182 enum STB_GLOBAL = 1; /* Global symbol */ 183 enum STB_WEAK = 2; /* Weak symbol */ 184 enum ST_NUM_BINDINGS = 3; /* Number of defined types. */ 185 enum STB_LOOS = 10; /* Start of OS-specific */ 186 enum STB_HIOS = 12; /* End of OS-specific */ 187 enum STB_LOPROC = 13; /* Start of processor-specific */ 188 enum STB_HIPROC = 15; /* End of processor-specific */ 189 190 enum STT_NOTYPE = 0; /* Symbol type is unspecified */ 191 enum STT_OBJECT = 1; /* Symbol is a data object */ 192 enum STT_FUNC = 2; /* Symbol is a code object */ 193 enum STT_SECTION = 3; /* Symbol associated with a section */ 194 enum STT_FILE = 4; /* Symbol's name is file name */ 195 enum STT_COMMON = 5; 196 enum STT_TLS = 6; 197 enum STT_NUM = 5; /* Number of defined types. */ 198 enum STT_LOOS = 11; /* Start of OS-specific */ 199 enum STT_HIOS = 12; /* End of OS-specific */ 200 enum STT_LOPROC = 13; /* Start of processor-specific */ 201 enum STT_HIPROC = 15; /* End of processor-specific */ 202 203 enum STV_DEFAULT = 0; /* Default symbol visibility rules */ 204 enum STV_INTERNAL = 1; /* Processor specific hidden class */ 205 enum STV_HIDDEN = 2; /* Sym unavailable in other modules */ 206 enum STV_PROTECTED = 3; /* Not preemptible, not exported */ 207 208 209 struct Elf32_Sym 210 { 211 Elf32_Word st_name; /* string table index for symbol name */ 212 Elf32_Addr st_value; /* Associated symbol value */ 213 Elf32_Word st_size; /* Symbol size */ 214 ubyte st_info; /* Symbol type and binding */ 215 ubyte st_other; /* Currently not defined */ 216 Elf32_Half st_shndx; /* SHT index for symbol definition */ 217 } 218 219 220 /* Relocation table entry without addend (in section of type SHT_REL). */ 221 222 223 // r_info 224 225 // 386 Relocation types 226 227 uint ELF32_R_SYM(uint i) { return i >> 8; } /* Symbol idx */ 228 uint ELF32_R_TYPE(uint i) { return i & 0xff; } /* Type of relocation */ 229 uint ELF32_R_INFO(uint i, uint t) { return ((i << 8) + (t & 0xff)); } 230 231 enum R_386_NONE = 0; /* No reloc */ 232 enum R_386_32 = 1; /* Symbol value 32 bit */ 233 enum R_386_PC32 = 2; /* PC relative 32 bit */ 234 enum R_386_GOT32 = 3; /* 32 bit GOT entry */ 235 enum R_386_PLT32 = 4; /* 32 bit PLT address */ 236 enum R_386_COPY = 5; /* Copy symbol at runtime */ 237 enum R_386_GLOB_DAT = 6; /* Create GOT entry */ 238 enum R_386_JMP_SLOT = 7; /* Create PLT entry */ 239 enum R_386_RELATIVE = 8; /* Adjust by program base */ 240 enum R_386_GOTOFF = 9; /* 32 bit offset to GOT */ 241 enum R_386_GOTPC = 10; /* 32 bit PC relative offset to GOT */ 242 enum R_386_TLS_TPOFF = 14; 243 enum R_386_TLS_IE = 15; 244 enum R_386_TLS_GOTIE = 16; 245 enum R_386_TLS_LE = 17; /* negative offset relative to static TLS */ 246 enum R_386_TLS_GD = 18; 247 enum R_386_TLS_LDM = 19; 248 enum R_386_TLS_GD_32 = 24; 249 enum R_386_TLS_GD_PUSH = 25; 250 enum R_386_TLS_GD_CALL = 26; 251 enum R_386_TLS_GD_POP = 27; 252 enum R_386_TLS_LDM_32 = 28; 253 enum R_386_TLS_LDM_PUSH = 29; 254 enum R_386_TLS_LDM_CALL = 30; 255 enum R_386_TLS_LDM_POP = 31; 256 enum R_386_TLS_LDO_32 = 32; 257 enum R_386_TLS_IE_32 = 33; 258 enum R_386_TLS_LE_32 = 34; 259 enum R_386_TLS_DTPMOD32 = 35; 260 enum R_386_TLS_DTPOFF32 = 36; 261 enum R_386_TLS_TPOFF32 = 37; 262 263 struct Elf32_Rel 264 { 265 Elf32_Addr r_offset; /* Address */ 266 Elf32_Word r_info; /* Relocation type and symbol index */ 267 } 268 269 /* stabs debug records */ 270 271 // DBtype 272 enum DBT_UNDEF = 0x00; /* undefined symbol */ 273 enum DBT_EXT = 0x01; /* exernal modifier */ 274 enum DBT_ABS = 0x02; /* absolute */ 275 enum DBT_TEXT = 0x04; /* code text */ 276 enum DBT_DATA = 0x06; /* data */ 277 enum DBT_BSS = 0x08; /* BSS */ 278 enum DBT_INDR = 0x0a; /* indirect to another symbol */ 279 enum DBT_COMM = 0x12; /* common -visible after shr'd lib link */ 280 enum DBT_SETA = 0x14; /* Absolue set element */ 281 enum DBT_SETT = 0x16; /* code text segment set element */ 282 enum DBT_SETD = 0x18; /* data segment set element */ 283 enum DBT_SETB = 0x1a; /* BSS segment set element */ 284 enum DBT_SETV = 0x1c; /* Pointer to set vector */ 285 enum DBT_WARNING = 0x1e; /* print warning during link */ 286 enum DBT_FN = 0x1f; /* name of object file */ 287 288 enum DBT_GSYM = 0x20; /* global symbol */ 289 enum DBT_FUN = 0x24; /* function name */ 290 enum DBT_STSYM = 0x26; /* static data */ 291 enum DBT_LCSYM = 0x28; /* static bss */ 292 enum DBT_MAIN = 0x2a; /* main routine */ 293 enum DBT_RO = 0x2c; /* read only */ 294 enum DBT_OPT = 0x3c; /* target option? */ 295 enum DBT_REG = 0x40; /* register variable */ 296 enum DBT_TLINE = 0x44; /* text line number */ 297 enum DBT_DLINE = 0x46; /* dat line number */ 298 enum DBT_BLINE = 0x48; /* bss line number */ 299 enum DBT_STUN = 0x62; /* structure or union */ 300 enum DBT_SRCF = 0x64; /* source file */ 301 enum DBT_AUTO = 0x80; /* stack variable */ 302 enum DBT_TYPE = 0x80; /* type definition */ 303 enum DBT_INCS = 0x84; /* include file start */ 304 enum DBT_PARAM = 0xa0; /* parameter */ 305 enum DBT_INCE = 0xa2; /* include file end */ 306 307 308 struct elf_stab 309 { 310 Elf32_Word DBstring; /* string table index for the symbol */ 311 elf_u8_f32 DBtype; /* type of the symbol */ 312 elf_u8_f32 DBmisc; /* misc. info */ 313 Elf32_Half DBdesc; /* description field */ 314 Elf32_Word DBvalu; /* symbol value */ 315 } 316 317 318 /* Program header. */ 319 320 // PHtype 321 enum PHT_NULL = 0; /* SHT entry unused */ 322 323 struct Elf32_Phdr 324 { 325 Elf32_Word PHtype; /* Program type */ 326 Elf32_Off PHoff; /* Offset to segment in file */ 327 Elf32_Addr PHvaddr; /* Starting virtual memory address */ 328 Elf32_Addr PHpaddr; /* Starting absolute memory address */ 329 Elf32_Word PHfilesz; /* Size of file image */ 330 Elf32_Word PHmemsz; /* Size of memory image */ 331 Elf32_Word PHflags; /* Program attribute flags */ 332 Elf32_Word PHalign; /* Program loading alignment */ 333 } 334 335 336 337 /* Legal values for sh_flags (section flags). */ 338 339 /***************************** 64 bit Elf *****************************************/ 340 341 alias Elf64_Addr = ulong; 342 alias Elf64_Off = ulong; 343 alias Elf64_Xword = ulong; 344 alias Elf64_Sxword = long; 345 alias Elf64_Sword = int; 346 alias Elf64_Word = uint; 347 alias Elf64_Half = ushort; 348 349 struct Elf64_Ehdr 350 { 351 ubyte[EI_NIDENT] EHident; /* Header identification info */ 352 Elf64_Half e_type; 353 Elf64_Half e_machine; 354 Elf64_Word e_version; 355 Elf64_Addr e_entry; 356 Elf64_Off e_phoff; 357 Elf64_Off e_shoff; 358 Elf64_Word e_flags; 359 Elf64_Half e_ehsize; 360 Elf64_Half e_phentsize; 361 Elf64_Half e_phnum; 362 Elf64_Half e_shentsize; 363 Elf64_Half e_shnum; 364 Elf64_Half e_shstrndx; 365 } 366 367 struct Elf64_Shdr 368 { 369 Elf64_Word sh_name; 370 Elf64_Word sh_type; 371 Elf64_Xword sh_flags; 372 Elf64_Addr sh_addr; 373 Elf64_Off sh_offset; 374 Elf64_Xword sh_size; 375 Elf64_Word sh_link; 376 Elf64_Word sh_info; 377 Elf64_Xword sh_addralign; 378 Elf64_Xword sh_entsize; 379 } 380 381 struct Elf64_Phdr 382 { 383 Elf64_Word p_type; 384 Elf64_Word p_flags; 385 Elf64_Off p_offset; 386 Elf64_Addr p_vaddr; 387 Elf64_Addr p_paddr; 388 Elf64_Xword p_filesz; 389 Elf64_Xword p_memsz; 390 Elf64_Xword p_align; 391 } 392 393 struct Elf64_Sym 394 { 395 Elf64_Word st_name; 396 ubyte st_info; 397 ubyte st_other; 398 Elf64_Half st_shndx; 399 Elf64_Addr st_value; 400 Elf64_Xword st_size; 401 } 402 403 ubyte ELF64_ST_BIND(ubyte s) { return ELF32_ST_BIND(s); } 404 ubyte ELF64_ST_TYPE(ubyte s) { return ELF32_ST_TYPE(s); } 405 ubyte ELF64_ST_INFO(ubyte b, ubyte t) { return ELF32_ST_INFO(b,t); } 406 407 // r_info 408 uint ELF64_R_SYM(ulong i) { return cast(Elf64_Word)(i>>32); } 409 uint ELF64_R_TYPE(ulong i) { return cast(Elf64_Word)(i & 0xFFFF_FFFF); } 410 ulong ELF64_R_INFO(ulong s, ulong t) { return ((cast(Elf64_Xword)s)<<32)|cast(Elf64_Word)t; } 411 412 // X86-64 Relocation types 413 414 enum R_X86_64_NONE = 0; // -- No relocation 415 enum R_X86_64_64 = 1; // 64 Direct 64 bit 416 enum R_X86_64_PC32 = 2; // 32 PC relative 32 bit signed 417 enum R_X86_64_GOT32 = 3; // 32 32 bit GOT entry 418 enum R_X86_64_PLT32 = 4; // 32 bit PLT address 419 enum R_X86_64_COPY = 5; // -- Copy symbol at runtime 420 enum R_X86_64_GLOB_DAT = 6; // 64 Create GOT entry 421 enum R_X86_64_JUMP_SLOT = 7; // 64 Create PLT entry 422 enum R_X86_64_RELATIVE = 8; // 64 Adjust by program base 423 enum R_X86_64_GOTPCREL = 9; // 32 32 bit signed pc relative offset to GOT 424 enum R_X86_64_32 = 10; // 32 Direct 32 bit zero extended 425 enum R_X86_64_32S = 11; // 32 Direct 32 bit sign extended 426 enum R_X86_64_16 = 12; // 16 Direct 16 bit zero extended 427 enum R_X86_64_PC16 = 13; // 16 16 bit sign extended pc relative 428 enum R_X86_64_8 = 14; // 8 Direct 8 bit sign extended 429 enum R_X86_64_PC8 = 15; // 8 8 bit sign extended pc relative 430 enum R_X86_64_DTPMOD64 = 16; // 64 ID of module containing symbol 431 enum R_X86_64_DTPOFF64 = 17; // 64 Offset in TLS block 432 enum R_X86_64_TPOFF64 = 18; // 64 Offset in initial TLS block 433 enum R_X86_64_TLSGD = 19; // 32 PC relative offset to GD GOT block 434 enum R_X86_64_TLSLD = 20; // 32 PC relative offset to LD GOT block 435 enum R_X86_64_DTPOFF32 = 21; // 32 Offset in TLS block 436 enum R_X86_64_GOTTPOFF = 22; // 32 PC relative offset to IE GOT entry 437 enum R_X86_64_TPOFF32 = 23; // 32 Offset in initial TLS block 438 enum R_X86_64_PC64 = 24; // 64 439 enum R_X86_64_GOTOFF64 = 25; // 64 440 enum R_X86_64_GOTPC32 = 26; // 32 441 enum R_X86_64_GNU_VTINHERIT = 250; // GNU C++ hack 442 enum R_X86_64_GNU_VTENTRY = 251; // GNU C++ hack 443 444 struct Elf64_Rel 445 { 446 Elf64_Addr r_offset; 447 Elf64_Xword r_info; 448 449 } 450 451 struct Elf64_Rela 452 { 453 Elf64_Addr r_offset; 454 Elf64_Xword r_info; 455 Elf64_Sxword r_addend; 456 } 457 458 // Section Group Flags 459 enum GRP_COMDAT = 1; 460 enum GRP_MASKOS = 0x0ff0_0000; 461 enum GRP_MASKPROC = 0xf000_0000;