1 /* 2 * Copyright (c) 2015 Travis Geiselbrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #pragma once 9 10 #include <inttypes.h> 11 12 /* elf defines */ 13 #define ELF_MAGIC "\x7f""ELF" 14 15 /* e_ident */ 16 #define EI_MAG0 0 17 #define EI_MAG1 1 18 #define EI_MAG2 2 19 #define EI_MAG3 3 20 #define EI_CLASS 4 21 #define EI_DATA 5 22 #define EI_VERSION 6 23 #define EI_OSABI 7 24 #define EI_ABIVERSION 8 25 #define EI_PAD 9 26 #define EI_NIDENT 16 27 28 /* e_machine */ 29 #define EM_NONE 0 30 #define EM_SPARC 2 31 #define EM_386 3 32 #define EM_68K 4 33 #define EM_MIPS 8 34 #define EM_SPARC32PLUS 18 35 #define EM_PPC 20 36 #define EM_PPC64 21 37 #define EM_ARM 40 38 #define EM_SH 42 39 #define EM_SPARCV9 43 40 #define EM_IA_64 50 41 #define EM_X86_64 62 42 #define EM_OR1K 92 43 #define EM_VC4 137 44 #define EM_AARCH64 183 45 #define EM_MICROBLAZE 189 46 #define EM_RISCV 243 47 #define EM_ALPHA 0x9026 48 49 /* e_ident[EI_CLASS] */ 50 #define ELFCLASS32 1 51 #define ELFCLASS64 2 52 53 /* e_ident[EI_DATA] */ 54 #define ELFDATA2LSB 1 55 #define ELFDATA2MSB 2 56 57 /* e_ident[EI_VERSION] */ 58 #define EV_CURRENT 1 59 60 /* e_type */ 61 #define ET_REL 1 62 #define ET_EXEC 2 63 #define ET_DYN 3 64 #define ET_CORE 4 65 66 /* e_flags */ 67 #define EF_ARM_RELEXEC 0x1 68 #define EF_ARM_HASENTRY 0x2 69 #define EF_ARM_SYMSARESORTED 0x4 70 #define EF_ARM_DYNSYMSUSESEGIDX 0x8 71 #define EF_ARM_MAPSYMSFIRST 0x10 72 #define EF_ARM_LE8 0x00400000 73 #define EF_ARM_BE8 0x00800000 74 #define EF_ARM_EABIMASK 0xFF000000 75 #define EF_ARM_EABI_UNKNOWN 0x00000000 76 #define EF_ARM_EABI_VER1 0x01000000 77 #define EF_ARM_EABI_VER2 0x02000000 78 #define EF_ARM_EABI_VER3 0x03000000 79 #define EF_ARM_EABI_VER4 0x04000000 80 #define EF_ARM_EABI_VER5 0x05000000 81 #define EF_ARM_INTERWORK 0x00000004 82 #define EF_ARM_APCS_26 0x00000008 83 #define EF_ARM_APCS_FLOAT 0x00000010 84 #define EF_ARM_PIC 0x00000020 85 #define EF_ARM_ALIGN8 0x00000040 86 #define EF_ARM_NEW_ABI 0x00000080 87 #define EF_ARM_OLD_ABI 0x00000100 88 #define EF_ARM_SOFT_FLOAT 0x00000200 89 #define EF_ARM_VFP_FLOAT 0x00000400 90 #define EF_ARM_MAVERICK_FLOAT 0x00000800 91 92 #define EF_RISCV_RVC 0x1 93 #define EF_RISCV_FLOAT_ABI_SOFT 0x0 94 #define EF_RISCV_FLOAT_ABI_SINGLE 0x2 95 #define EF_RISCV_FLOAT_ABI_DOUBLE 0x4 96 #define EF_RISCV_FLOAT_ABI_QUAD 0x6 97 #define EF_RISCV_FLOAT_ABI 0x6 98 #define EF_RISCV_RVE 0x8 99 #define EF_RISCV_TSO 0x10 100 101 #define SHT_NULL 0 102 #define SHT_PROGBITS 1 103 #define SHT_SYMTAB 2 104 #define SHT_STRTAB 3 105 #define SHT_RELA 4 106 #define SHT_HASH 5 107 #define SHT_DYNAMIC 6 108 #define SHT_NOTE 7 109 #define SHT_NOBITS 8 110 #define SHT_REL 9 111 #define SHT_SHLIB 10 112 #define SHT_DYNSYM 11 113 #define SHT_INIT_ARRAY 14 114 #define SHT_FINI_ARRAY 15 115 #define SHT_PREINIT_ARRAY 16 116 #define SHT_GROUP 17 117 #define SHT_SYMTAB_SHNDX 18 118 #define SHT_LOOS 0x60000000 119 #define SHT_HIOS 0x6fffffff 120 #define SHT_LOPROC 0x70000000 121 #define SHT_HIPROC 0x7fffffff 122 #define SHT_LOUSER 0x80000000 123 #define SHT_HIUSER 0xffffffff 124 125 #define SHF_WRITE 0x1 126 #define SHF_ALLOC 0x2 127 #define SHF_EXECINSTR 0x4 128 #define SHF_TLS 0x400 129 #define SHF_MASKPROC 0xf0000000 130 131 #define PF_X 0x1 132 #define PF_W 0x2 133 #define PF_R 0x4 134 #define PF_MASKPROC 0xf0000000 135 136 #define PT_NULL 0 137 #define PT_LOAD 1 138 #define PT_DYNAMIC 2 139 #define PT_INTERP 3 140 #define PT_NOTE 4 141 #define PT_SHLIB 5 142 #define PT_PHDR 6 143 #define PT_TLS 7 144 #define PT_LOOS 0x60000000 145 #define PT_HIOS 0x6fffffff 146 #define PT_LOPROC 0x70000000 147 #define PT_HIPROC 0x7fffffff 148 149 #define SHN_UNDEF 0 150 #define SHN_LORESERVE 0xff00 151 #define SHN_LOPROC 0xff00 152 #define SHN_HIPROC 0xff1f 153 #define SHN_ABS 0xfff1 154 #define SHN_COMMON 0xfff2 155 #define SHN_HIRESERVE 0xffff 156 157 #define STT_NOTYPE 0 158 #define STT_OBJECT 1 159 #define STT_FUNC 2 160 #define STT_SECTION 3 161 #define STT_FILE 4 162 #define STT_TLS 6 163 #define STT_LOPROC 13 164 #define STT_HIPROC 15 165 166 #define STB_LOCAL 0 167 #define STB_GLOBAL 1 168 #define STB_WEAK 2 169 #define STB_LOPROC 13 170 #define STB_HIPROC 15 171 172 #define STN_UNDEF 0 173 174 /* d_tag */ 175 #define DT_NULL 0 176 #define DT_NEEDED 1 177 #define DT_PLTRELSZ 2 178 #define DT_PLTGOT 3 179 #define DT_HASH 4 180 #define DT_STRTAB 5 181 #define DT_SYMTAB 6 182 #define DT_RELA 7 183 #define DT_RELASZ 8 184 #define DT_RELAENT 9 185 #define DT_STRSZ 10 186 #define DT_SYMENT 11 187 #define DT_INIT 12 188 #define DT_FINI 13 189 #define DT_SONAME 14 190 #define DT_RPATH 15 191 #define DT_SYMBOLIC 16 192 #define DT_REL 17 193 #define DT_RELSZ 18 194 #define DT_RELENT 19 195 #define DT_PLTREL 20 196 #define DT_DEBUG 21 197 #define DT_TEXTREL 22 198 #define DT_JMPREL 23 199 #define DT_BIND_NOW 24 200 #define DT_INIT_ARRAY 25 201 #define DT_FINI_ARRAY 26 202 #define DT_INIT_ARRAYSZ 27 203 #define DT_FINI_ARRAYSZ 28 204 #define DT_RUNPATH 29 205 #define DT_FLAGS 30 206 #define DT_ENCODING 32 207 #define DT_PREINIT_ARRAY 32 208 #define DT_PREINIT_ARRAYSZ 33 209 #define DT_LOOS 0x6000000d 210 #define DT_HIOS 0x6fff0000 211 #define DT_LOPROC 0x70000000 212 #define DT_HIPROC 0x7fffffff 213 214 /* 215 * i386 relocation types 216 */ 217 #define R_386_NONE 0 218 #define R_386_32 1 219 #define R_386_PC32 2 220 #define R_386_GOT32 3 221 #define R_386_PLT32 4 222 #define R_386_COPY 5 223 #define R_386_GLOB_DAT 6 224 #define R_386_JMP_SLOT 7 225 #define R_386_RELATIVE 8 226 #define R_386_GOTOFF 9 227 #define R_386_GOTPC 10 228 229 /* 230 * x86-64 relocation types 231 */ 232 #define R_X86_64_NONE 0 233 #define R_X86_64_64 1 234 #define R_X86_64_PC32 2 235 #define R_X86_64_GOT32 3 236 #define R_X86_64_PLT32 4 237 #define R_X86_64_COPY 5 238 #define R_X86_64_GLOB_DAT 6 239 #define R_X86_64_JUMP_SLOT 7 240 #define R_X86_64_RELATIVE 8 241 #define R_X86_64_GOTPCREL 9 242 #define R_X86_64_32 10 243 #define R_X86_64_32S 11 244 #define R_X86_64_16 12 245 #define R_X86_64_PC16 13 246 #define R_X86_64_8 14 247 #define R_X86_64_PC8 15 248 #define R_X86_64_DPTMOD64 16 249 #define R_X86_64_DTPOFF64 17 250 #define R_X86_64_TPOFF64 18 251 #define R_X86_64_TLSGD 19 252 #define R_X86_64_TLSLD 20 253 #define R_X86_64_DTPOFF32 21 254 #define R_X86_64_GOTTPOFF 22 255 #define R_X86_64_TPOFF32 23 256 257 /* 258 * sh4 relocation types 259 */ 260 #define R_SH_NONE 0 261 #define R_SH_DIR32 1 262 #define R_SH_REL32 2 263 #define R_SH_DIR8WPN 3 264 #define R_SH_IND12W 4 265 #define R_SH_DIR8WPL 5 266 #define R_SH_DIR8WPZ 6 267 #define R_SH_DIR8BP 7 268 #define R_SH_DIR8W 8 269 #define R_SH_DIR8L 9 270 #define R_SH_SWITCH16 25 271 #define R_SH_SWITCH32 26 272 #define R_SH_USES 27 273 #define R_SH_COUNT 28 274 #define R_SH_ALIGN 29 275 276 #define R_SH_CODE 30 277 #define R_SH_DATA 31 278 #define R_SH_LABEL 32 279 #define R_SH_SWITCH8 33 280 #define R_SH_GNU_VTINHERIT 34 281 #define R_SH_GNU_VTENTRY 35 282 #define R_SH_LOOP_START 36 283 #define R_SH_LOOP_END 37 284 #define R_SH_DIR5U 45 285 #define R_SH_DIR6U 46 286 #define R_SH_DIR6S 47 287 #define R_SH_DIR10S 48 288 #define R_SH_DIR10SW 49 289 #define R_SH_DIR10SL 50 290 #define R_SH_DIR10SQ 51 291 #define R_SH_GOT32 160 292 #define R_SH_PLT32 161 293 #define R_SH_COPY 162 294 #define R_SH_GLOB_DAT 163 295 #define R_SH_JMP_SLOT 164 296 #define R_SH_RELATIVE 165 297 #define R_SH_GOTOFF 166 298 #define R_SH_GOTPC 167 299 #define R_SH_GOTPLT32 168 300 #define R_SH_GOT_LOW16 169 301 #define R_SH_GOT_MEDLOW16 170 302 #define R_SH_GOT_MEDHI16 171 303 #define R_SH_GOT_HI16 172 304 #define R_SH_GOTPLT_LOW16 173 305 #define R_SH_GOTPLT_MEDLOW16 174 306 #define R_SH_GOTPLT_MEDHI16 175 307 #define R_SH_GOTPLT_HI16 176 308 #define R_SH_PLT_LOW16 177 309 #define R_SH_PLT_MEDLOW16 178 310 #define R_SH_PLT_MEDHI16 179 311 #define R_SH_PLT_HI16 180 312 #define R_SH_GOTOFF_LOW16 181 313 #define R_SH_GOTOFF_MEDLOW16 182 314 #define R_SH_GOTOFF_MEDHI16 183 315 #define R_SH_GOTOFF_HI16 184 316 #define R_SH_GOTPC_LOW16 185 317 #define R_SH_GOTPC_MEDLOW16 186 318 #define R_SH_GOTPC_MEDHI16 187 319 #define R_SH_GOTPC_HI16 188 320 #define R_SH_GOT10BY4 189 321 #define R_SH_GOTPLT10BY4 190 322 #define R_SH_GOT10BY8 191 323 #define R_SH_GOTPLT10BY8 192 324 #define R_SH_COPY64 193 325 #define R_SH_GLOB_DAT64 194 326 #define R_SH_JMP_SLOT64 195 327 #define R_SH_RELATIVE64 196 328 #define R_SH_SHMEDIA_CODE 242 329 #define R_SH_PT_16 243 330 #define R_SH_IMMS16 244 331 #define R_SH_IMMU16 245 332 #define R_SH_IMM_LOW16 246 333 #define R_SH_IMM_LOW16_PCREL 247 334 #define R_SH_IMM_MEDLOW16 248 335 #define R_SH_IMM_MEDLOW16_PCREL 249 336 #define R_SH_IMM_MEDHI16 250 337 #define R_SH_IMM_MEDHI16_PCREL 251 338 #define R_SH_IMM_HI16 252 339 #define R_SH_IMM_HI16_PCREL 253 340 #define R_SH_64 254 341 #define R_SH_64_PCREL 255 342 343 /* 344 * ppc relocation types 345 */ 346 #define R_PPC_NONE 0 347 #define R_PPC_ADDR32 1 /* 32bit absolute address */ 348 #define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ 349 #define R_PPC_ADDR16 3 /* 16bit absolute address */ 350 #define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ 351 #define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ 352 #define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ 353 #define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ 354 #define R_PPC_ADDR14_BRTAKEN 8 355 #define R_PPC_ADDR14_BRNTAKEN 9 356 #define R_PPC_REL24 10 /* PC relative 26 bit */ 357 #define R_PPC_REL14 11 /* PC relative 16 bit */ 358 #define R_PPC_REL14_BRTAKEN 12 359 #define R_PPC_REL14_BRNTAKEN 13 360 #define R_PPC_GOT16 14 361 #define R_PPC_GOT16_LO 15 362 #define R_PPC_GOT16_HI 16 363 #define R_PPC_GOT16_HA 17 364 #define R_PPC_PLTREL24 18 365 #define R_PPC_COPY 19 366 #define R_PPC_GLOB_DAT 20 367 #define R_PPC_JMP_SLOT 21 368 #define R_PPC_RELATIVE 22 369 #define R_PPC_LOCAL24PC 23 370 #define R_PPC_UADDR32 24 371 #define R_PPC_UADDR16 25 372 #define R_PPC_REL32 26 373 #define R_PPC_PLT32 27 374 #define R_PPC_PLTREL32 28 375 #define R_PPC_PLT16_LO 29 376 #define R_PPC_PLT16_HI 30 377 #define R_PPC_PLT16_HA 31 378 #define R_PPC_SDAREL16 32 379 #define R_PPC_SECTOFF 33 380 #define R_PPC_SECTOFF_LO 34 381 #define R_PPC_SECTOFF_HI 35 382 #define R_PPC_SECTOFF_HA 36 383 #define R_PPC_NUM 37 384 385 /* 386 * ARM relocation types 387 */ 388 #define R_ARM_NONE 0 389 #define R_ARM_PC24 1 390 #define R_ARM_ABS32 2 391 #define R_ARM_REL32 3 392 #define R_ARM_PC13 4 393 #define R_ARM_ABS16 5 394 #define R_ARM_ABS12 6 395 #define R_ARM_THM_ABS5 7 396 #define R_ARM_ABS8 8 397 #define R_ARM_SBREL32 9 398 #define R_ARM_THM_PC22 10 399 #define R_ARM_THM_PC8 11 400 #define R_ARM_AMP_VCALL9 12 401 #define R_ARM_SWI24 13 402 #define R_ARM_THM_SWI8 14 403 #define R_ARM_XPC25 15 404 #define R_ARM_THM_XPC22 16 405 #define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ 406 #define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ 407 #define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ 408 #define R_ARM_COPY 20 /* Copy data from shared object. */ 409 #define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ 410 #define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ 411 #define R_ARM_RELATIVE 23 /* Add load address of shared object. */ 412 #define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ 413 #define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ 414 #define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ 415 #define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ 416 #define R_ARM_GNU_VTENTRY 100 417 #define R_ARM_GNU_VTINHERIT 101 418 #define R_ARM_RSBREL32 250 419 #define R_ARM_THM_RPC22 251 420 #define R_ARM_RREL32 252 421 #define R_ARM_RABS32 253 422 #define R_ARM_RPC24 254 423 #define R_ARM_RBASE 255 424 425 /* elf32 stuff */ 426 typedef uint32_t Elf32_Addr; 427 typedef uint16_t Elf32_Half; 428 typedef uint32_t Elf32_Off; 429 typedef int32_t Elf32_Sword; 430 typedef uint32_t Elf32_Word; 431 432 struct Elf32_Ehdr { 433 unsigned char e_ident[EI_NIDENT]; 434 Elf32_Half e_type; 435 Elf32_Half e_machine; 436 Elf32_Word e_version; 437 Elf32_Addr e_entry; 438 Elf32_Off e_phoff; 439 Elf32_Off e_shoff; 440 Elf32_Word e_flags; 441 Elf32_Half e_ehsize; 442 Elf32_Half e_phentsize; 443 Elf32_Half e_phnum; 444 Elf32_Half e_shentsize; 445 Elf32_Half e_shnum; 446 Elf32_Half e_shstrndx; 447 }; 448 449 struct Elf32_Shdr { 450 Elf32_Word sh_name; 451 Elf32_Word sh_type; 452 Elf32_Word sh_flags; 453 Elf32_Addr sh_addr; 454 Elf32_Off sh_offset; 455 Elf32_Word sh_size; 456 Elf32_Word sh_link; 457 Elf32_Word sh_info; 458 Elf32_Word sh_addralign; 459 Elf32_Word sh_entsize; 460 }; 461 462 struct Elf32_Phdr { 463 Elf32_Word p_type; 464 Elf32_Off p_offset; 465 Elf32_Addr p_vaddr; 466 Elf32_Addr p_paddr; 467 Elf32_Word p_filesz; 468 Elf32_Word p_memsz; 469 Elf32_Word p_flags; 470 Elf32_Word p_align; 471 }; 472 473 struct Elf32_Sym { 474 Elf32_Word st_name; 475 Elf32_Addr st_value; 476 Elf32_Word st_size; 477 unsigned char st_info; 478 unsigned char st_other; 479 Elf32_Half st_shndx; 480 }; 481 482 #define ELF32_ST_BIND(i) ((i) >> 4) 483 #define ELF32_ST_TYPE(i) ((i) & 0xf) 484 #define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) 485 486 struct Elf32_Rel { 487 Elf32_Addr r_offset; 488 Elf32_Word r_info; 489 }; 490 491 struct Elf32_Rela { 492 Elf32_Addr r_offset; 493 Elf32_Word r_info; 494 Elf32_Sword r_addend; 495 }; 496 497 #define ELF32_R_SYM(i) ((i) >> 8) 498 #define ELF32_R_TYPE(i) ((unsigned char)(i)) 499 #define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) 500 501 struct Elf32_Dyn { 502 Elf32_Sword d_tag; 503 union { 504 Elf32_Word d_val; 505 Elf32_Addr d_ptr; 506 } d_un; 507 }; 508 509 /* elf64 stuff */ 510 typedef uint64_t Elf64_Addr; 511 typedef uint16_t Elf64_Half; 512 typedef uint64_t Elf64_Off; 513 typedef int32_t Elf64_Sword; 514 typedef int64_t Elf64_Sxword; 515 typedef uint32_t Elf64_Word; 516 typedef uint64_t Elf64_Lword; 517 typedef uint64_t Elf64_Xword; 518 519 520 struct Elf64_Ehdr { 521 unsigned char e_ident[EI_NIDENT]; 522 Elf64_Half e_type; 523 Elf64_Half e_machine; 524 Elf64_Word e_version; 525 Elf64_Addr e_entry; 526 Elf64_Off e_phoff; 527 Elf64_Off e_shoff; 528 Elf64_Word e_flags; 529 Elf64_Half e_ehsize; 530 Elf64_Half e_phentsize; 531 Elf64_Half e_phnum; 532 Elf64_Half e_shentsize; 533 Elf64_Half e_shnum; 534 Elf64_Half e_shstrndx; 535 }; 536 537 struct Elf64_Shdr { 538 Elf64_Word sh_name; 539 Elf64_Word sh_type; 540 Elf64_Xword sh_flags; 541 Elf64_Addr sh_addr; 542 Elf64_Off sh_offset; 543 Elf64_Xword sh_size; 544 Elf64_Word sh_link; 545 Elf64_Word sh_info; 546 Elf64_Xword sh_addralign; 547 Elf64_Xword sh_entsize; 548 }; 549 550 struct Elf64_Phdr { 551 Elf64_Word p_type; 552 Elf64_Word p_flags; 553 Elf64_Off p_offset; 554 Elf64_Addr p_vaddr; 555 Elf64_Addr p_paddr; 556 Elf64_Xword p_filesz; 557 Elf64_Xword p_memsz; 558 Elf64_Xword p_align; 559 }; 560 561 #define ELF64_ST_BIND(info) ((info) >> 4) 562 #define ELF64_ST_TYPE(info) ((info) & 0xf) 563 #define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) 564 565 struct Elf64_Rel { 566 Elf64_Addr r_offset; 567 Elf64_Xword r_info; 568 }; 569 570 struct Elf64_Rela { 571 Elf64_Addr r_offset; 572 Elf64_Xword r_info; 573 Elf64_Sxword r_addend; 574 }; 575 576 #define ELF64_R_SYM(info) ((info) >> 32) 577 #define ELF64_R_TYPE(info) ((info) & 0xffffffffL) 578 579 #define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL)) 580 581 #define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) 582 #define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) 583 #define ELF64_R_TYPE_INFO(data, type) (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type)) 584 585