elf.c (20676B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include <scc/mach.h> 6 #include <scc/elf/elftypes.h> 7 #include <scc/elf/elfhdr.h> 8 #include <scc/elf/elfphdr.h> 9 #include <scc/elf/elfshdr.h> 10 #include <scc/elf/elfent.h> 11 #include <scc/elf.h> 12 13 #include "objdump.h" 14 15 enum elfsecflags { 16 ELF_WRITE = 0, 17 ELF_ALLOC = 1, 18 ELF_EXEC = 2, 19 ELF_MERGE = 3, 20 ELF_STRINGS = 4, 21 ELF_INFO_LINK = 5, 22 ELF_LINK_ORDER = 6, 23 ELF_OS_NONCONFOR = 7, 24 ELF_GROUP = 8, 25 ELF_TLS = 9, 26 ELF_COMPRESSED = 10, 27 ELF_NR_FLAGS = 11, 28 }; 29 30 enum phdrflags { 31 FLAG_X = 0, 32 FLAG_W = 1, 33 FLAG_R = 2, 34 NR_RIGHTS = 3, 35 }; 36 37 int 38 elfhasrelloc(Obj *obj, Section *sec) 39 { 40 size_t i; 41 Elf *elf = obj->data; 42 Elfsec *shdr; 43 44 for (i = 0; i < elf->nsec; i++) { 45 shdr = &elf->secs[i]; 46 if (shdr->type != SHT_RELA && shdr->type != SHT_REL) 47 continue; 48 if (shdr->info == sec->index) 49 return 1; 50 } 51 52 return 0; 53 } 54 55 static void 56 printents(Obj *obj) 57 { 58 int n; 59 size_t i; 60 Section sec; 61 Elfsym *ent; 62 Elf *elf = obj->data; 63 char *sbind, *stype, *svis, *ssec; 64 unsigned info, bind, type, vis, nsec; 65 66 static char *binds[] = { 67 [STB_LOCAL] = "Local symbol", 68 [STB_GLOBAL] = "Global symbol", 69 [STB_WEAK] = "like global - lower precedence", 70 [STB_NUM] = "number of symbol bindings", 71 [STB_LOPROC] = "reserved range for processor", 72 [STB_HIPROC] = " specific symbol bindings", 73 }; 74 static char *types[] = { 75 [STT_NOTYPE] = "not specified", 76 [STT_OBJECT] = "data object", 77 [STT_FUNC] = "function", 78 [STT_SECTION] = "section", 79 [STT_FILE] = "file", 80 [STT_COMMON] = "common symbol", 81 [STT_TLS] = "thread local storage", 82 [STT_LOPROC] = "reserved range for processor", 83 [STT_HIPROC] = " specific symbol types", 84 }; 85 static char *visibilities[] = { 86 [STV_DEFAULT] = "Visibility set by binding type", 87 [STV_INTERNAL] = "OS specific version of STV_HIDDEN", 88 [STV_HIDDEN] = "can only be seen inside own .so", 89 [STV_PROTECTED] = "HIDDEN inside, DEFAULT outside", 90 }; 91 92 for (i = 0; i < elf->nsym; i++) { 93 ent = &elf->syms[i]; 94 95 info = ent->info; 96 bind = ELF_ST_BIND(info); 97 type = ELF_ST_TYPE(info); 98 vis = ELF_ST_VISIBILITY(ent->other); 99 nsec = ent->shndx; 100 101 sbind = (bind <= STB_HIPROC) ? binds[bind] : "Unknown"; 102 stype = (type <= STT_HIPROC) ? types[type] : "Unknown"; 103 svis = (vis <= STV_PROTECTED) ? visibilities[vis] : "Unknown"; 104 if (!sbind) 105 sbind = "Unknown"; 106 if (!stype) 107 stype = "Unknown"; 108 if (!svis) 109 svis = "Unknown"; 110 111 switch (nsec) { 112 case SHN_ABS: 113 ssec = "*ABS*"; 114 break; 115 case SHN_COMMON: 116 ssec = "*COM*"; 117 break; 118 default: 119 n = nsec; 120 ssec = "*UNK*"; 121 if (getsec(obj, &n, &sec)) 122 ssec = sec.name; 123 } 124 125 printf("Symbol %zu:\n" 126 "\tst_name: %lu '%s'\n" 127 "\tst_info: %u\n" 128 "\t\tst_bind: %u %s\n" 129 "\t\tst_type: %u %s\n" 130 "\tst_other: %u %s\n" 131 "\tst_shndx: %u %s\n" 132 "\tst_value: %#llx\n" 133 "\tst_size: %llu\n" 134 "\n", 135 i, 136 (long) ent->st_name, ent->name, 137 info, 138 bind, sbind, 139 type, stype, 140 vis, svis, 141 nsec, ssec, 142 (unsigned long long) ent->value, 143 (unsigned long long) ent->size); 144 } 145 } 146 147 static void 148 printstbl(Obj *obj) 149 { 150 int n; 151 size_t i; 152 Symbol sym; 153 Section sec; 154 Elfsym *ent; 155 Elfsec *shdr; 156 Elf *elf = obj->data; 157 unsigned info, bind, type; 158 char cbind, cweak, cctor, cwarn, cindir, cdebug, ctype; 159 160 if (elf->nsym == 0) { 161 puts("no symbols"); 162 return; 163 } 164 165 for (i = 1; i < elf->nsym; i++) { 166 ent = &elf->syms[i]; 167 shdr =&elf->secs[ent->shndx]; 168 n = i; 169 getsym(obj, &n, &sym); 170 n = ent->shndx; 171 getsec(obj, &n, &sec); 172 173 info = ent->info; 174 bind = ELF64_ST_BIND(info); 175 type = ELF64_ST_TYPE(info); 176 177 cbind = (bind == STB_LOCAL) ? 'l' : 'g'; 178 cweak = (bind == STB_WEAK) ? 'w' : ' '; 179 cctor = ' '; 180 cwarn = ' '; 181 cindir = ' '; 182 183 switch (sym.type) { 184 case 'N': 185 case 'n': 186 cdebug = 'd'; 187 break; 188 case 'U': 189 cdebug = ' '; 190 cbind = ' '; 191 break; 192 default: 193 cdebug = (ent->symsec->type == SHT_DYNAMIC) ? 'D' : ' '; 194 } 195 196 switch (type) { 197 case STT_OBJECT: 198 ctype = 'O'; 199 break; 200 case STT_FUNC: 201 ctype = 'F'; 202 break; 203 case STT_FILE: 204 ctype = 'f'; 205 cdebug = 'd'; 206 break; 207 default: 208 ctype = ' '; 209 break; 210 } 211 212 printf("%016llx %c%c%c%c%c%c%c %-15s %08llu %-20s [%4zu]\n", 213 (long long) ent->value, 214 cbind, 215 cweak, 216 cctor, 217 cwarn, 218 cindir, 219 cdebug, 220 ctype, 221 sec.name, 222 (long long) ent->size, 223 sym.name, 224 i); 225 } 226 } 227 228 void 229 elfsyms(Obj *obj) 230 { 231 printstbl(obj); 232 233 if (pflag) 234 printents(obj); 235 } 236 237 void 238 elfscns(Obj *obj) 239 { 240 size_t i; 241 Elf *elf = obj->data; 242 Elfsec *shdr; 243 static char *types[] = { 244 [SHT_NULL] = "inactive", 245 [SHT_PROGBITS] = "program defined information", 246 [SHT_SYMTAB] = "symbol table section", 247 [SHT_STRTAB] = "string table section", 248 [SHT_RELA] = "relocation section with addends", 249 [SHT_HASH] = "symbol hash table section", 250 [SHT_DYNAMIC] = "dynamic section", 251 [SHT_NOTE] = "note section", 252 [SHT_NOBITS] = "no space section", 253 [SHT_REL] = "relation section without addends", 254 [SHT_SHLIB] = "reserved - purpose unknown", 255 [SHT_DYNSYM] = "dynamic symbol table section", 256 [SHT_NUM] = "number of section types", 257 [SHT_INIT_ARRAY] = "pointers to init functions", 258 [SHT_FINI_ARRAY] = "pointers to termination functions", 259 [SHT_PREINIT_ARRAY] = "ptrs to funcs called before init", 260 [SHT_GROUP] = "defines a section group", 261 [SHT_SYMTAB_SHNDX] = "Section indexes (see SHN_XINDEX).", 262 }; 263 static Flags f = { 264 .nr = ELF_NR_FLAGS, 265 .text = { 266 [ELF_WRITE] = "WRITE", 267 [ELF_ALLOC] = "ALLOC", 268 [ELF_EXEC] = "EXEC", 269 [ELF_MERGE] = "MERGE", 270 [ELF_STRINGS] = "STRINGS", 271 [ELF_INFO_LINK] = "INFO_LINK", 272 [ELF_LINK_ORDER] = "LINK_ORDER", 273 [ELF_OS_NONCONFOR] = "OS_NONCONFORMING", 274 [ELF_GROUP] = "GROUP", 275 [ELF_TLS] = "TLS", 276 [ELF_COMPRESSED] = "COMPRESSED", 277 } 278 }; 279 280 for (i = 0; i < elf->nsec; i++) { 281 long type; 282 char *stype; 283 shdr = &elf->secs[i]; 284 285 type = shdr->type; 286 if (type <= SHT_SYMTAB_SHNDX) { 287 stype = types[type]; 288 } else { 289 switch (type) { 290 case SHT_SUNW_dof: 291 stype = "SHT_SUNW_dof"; 292 break; 293 case SHT_GNU_LIBLIST: 294 stype = "SHT_GNU_LIBLIST"; 295 break; 296 case SHT_SUNW_move: 297 stype = "SHT_SUNW_move"; 298 break; 299 case SHT_SUNW_syminfo: 300 stype = "SHT_SUNW_syminfo"; 301 break; 302 case SHT_GNU_VERDEF: 303 stype = "SHT_GNU_VERDEF"; 304 break; 305 case SHT_GNU_VERNEED: 306 stype = "SHT_GNU_VERNEED"; 307 break; 308 case SHT_GNU_VERSYM: 309 stype = "SHT_GNU_VERSYM"; 310 break; 311 default: 312 stype = NULL; 313 } 314 } 315 316 if (!stype) 317 stype = "Unknown"; 318 319 f.flags = shdr->flags; 320 321 printf("Section %zu:\n" 322 "\tsh_name: %lu %s\n" 323 "\tsh_type: %lu %s\n" 324 "\tsh_flags: %#llx\n" 325 "\tsh_addr: %#llx\n" 326 "\tsh_offset: %#llx\n" 327 "\tsh_size: %#llx\n" 328 "\tsh_link: %lu\n" 329 "\tsh_info: %lu\n" 330 "\tsh_addralign: %llu\n" 331 "\tsh_entsize: %llu\n", 332 i, 333 (long) shdr->sh_name, shdr->name, 334 type, stype, 335 (long long) shdr->flags, 336 (long long) shdr->addr, 337 (long long) shdr->offset, 338 (long long) shdr->size, 339 (long) shdr->link, 340 (long) shdr->info, 341 (long long) shdr->addralign, 342 (long long) shdr->entsize); 343 344 putchar('\t'); 345 printflags(&f); 346 putchar('\n'); 347 } 348 } 349 350 static void 351 printfhdr(Elfhdr *hdr) 352 { 353 unsigned long version; 354 unsigned class, data, abi, type, mach; 355 char *sclass, *sdata, *sabi, *stype, *smach, *sversion; 356 357 static char *abis[] = { 358 [ELFOSABI_SYSV] = "UNIX System V ABI", 359 [ELFOSABI_HPUX] = "HP-UX operating system", 360 [ELFOSABI_NETBSD] = "NetBSD", 361 [ELFOSABI_LINUX] = "GNU/Linux", 362 [ELFOSABI_HURD] = "GNU/Hurd", 363 [ELFOSABI_86OPEN] = "86Open common IA32 ABI", 364 [ELFOSABI_SOLARIS] = "Solaris", 365 [ELFOSABI_MONTEREY] = "Monterey", 366 [ELFOSABI_IRIX] = "IRIX", 367 [ELFOSABI_FREEBSD] = "FreeBSD", 368 [ELFOSABI_TRU64] = "TRU64 UNIX", 369 [ELFOSABI_MODESTO] = "Novell Modesto", 370 [ELFOSABI_OPENBSD] = "OpenBSD", 371 [ELFOSABI_OPENVMS] = "Open VMS", 372 [ELFOSABI_NSK] = "Hewlett-Packard Non-Stop Kernel", 373 [ELFOSABI_AROS] = "Amiga Research OS", 374 [ELFOSABI_FENIXOS] = "The FenixOS multi-core OS", 375 [ELFOSABI_CLOUDABI] = "Nuxi CloudABI", 376 [ELFOSABI_OPENVOS] = "Stratus Technologies OpenVOS", 377 [ELFOSABI_ARM] = "ARM", 378 [ELFOSABI_STANDALONE] = "Standalone (embedded) application", 379 }; 380 static char *classes[] = { 381 [ELFCLASSNONE] = "invalid", 382 [ELFCLASS32] = "32-bit objs", 383 [ELFCLASS64] = "64-bit objs", 384 }; 385 static char *datas[] = { 386 [ELFDATANONE] = "invalid", 387 [ELFDATA2LSB] = "Little-Endian", 388 [ELFDATA2MSB] = "Big-Endian", 389 }; 390 static char *types[] = { 391 [ET_NONE] = "No file type", 392 [ET_REL] = "Relocatable file", 393 [ET_EXEC] = "Executable file", 394 [ET_DYN] = "Shared object file", 395 [ET_CORE] = "Core file", 396 }; 397 static char *machs[] = { 398 [EM_NONE] = "No machine", 399 [EM_M32] = "AT&T WE 32100", 400 [EM_SPARC] = "SPARC", 401 [EM_386] = "Intel 80386", 402 [EM_68K] = "Motorola 68000", 403 [EM_88K] = "Motorola 88000", 404 [EM_IAMCU] = "Intel MCU", 405 [EM_860] = "Intel 80860", 406 [EM_MIPS] = "MIPS I Architecture", 407 [EM_S370] = "IBM System/370 Processor", 408 [EM_MIPS_RS3_LE] = "MIPS RS3000 Little-endian", 409 [EM_PARISC] = "Hewlett-Packard PA-RISC", 410 [EM_VPP500] = "Fujitsu VPP500", 411 [EM_SPARC32PLUS] = "Enhanced instruction set SPARC", 412 [EM_960] = "Intel 80960", 413 [EM_PPC] = "PowerPC", 414 [EM_PPC64] = "64-bit PowerPC", 415 [EM_S390] = "IBM System/390", 416 [EM_SPU] = "IBM SPU/SPC", 417 [EM_V800] = "NEC V800", 418 [EM_FR20] = "Fujitsu FR20", 419 [EM_RH32] = "TRW RH-32", 420 [EM_RCE] = "Motorola RCE", 421 [EM_ARM] = "ARM AARCH32", 422 [EM_ALPHA] = "Digital Alpha", 423 [EM_SH] = "Hitachi SH", 424 [EM_SPARCV9] = "SPARC Version 9", 425 [EM_TRICORE] = "Siemens TriCore", 426 [EM_ARC] = "Argonaut RISC Core", 427 [EM_H8_300] = "Hitachi H8/300", 428 [EM_H8_300H] = "Hitachi H8/300H", 429 [EM_H8S] = "Hitachi H8S", 430 [EM_H8_500] = "Hitachi H8/500", 431 [EM_IA_64] = "Intel IA-64", 432 [EM_MIPS_X] = "Stanford MIPS-X", 433 [EM_COLDFIRE] = "Motorola ColdFire", 434 [EM_68HC12] = "Motorola M68HC12", 435 [EM_MMA] = "Fujitsu MMA", 436 [EM_PCP] = "Siemens PCP", 437 [EM_NCPU] = "Sony nCPU", 438 [EM_NDR1] = "Denso NDR1", 439 [EM_STARCORE] = "Motorola Star*Core", 440 [EM_ME16] = "Toyota ME16", 441 [EM_ST100] = "STMicroelectronics ST100", 442 [EM_TINYJ] = "Advanced Logic Corp. TinyJ", 443 [EM_X86_64] = "AMD x86-64", 444 [EM_PDSP] = "Sony DSP Processor", 445 [EM_PDP10] = "DEC PDP-10", 446 [EM_PDP11] = "DEC PDP-11", 447 [EM_FX66] = "Siemens FX66", 448 [EM_ST9PLUS] = "STMicroelectronics ST9+", 449 [EM_ST7] = "STMicroelectronics ST7", 450 [EM_68HC16] = "Motorola MC68HC16", 451 [EM_68HC11] = "Motorola MC68HC11", 452 [EM_68HC08] = "Motorola MC68HC08", 453 [EM_68HC05] = "Motorola MC68HC05", 454 [EM_SVX] = "Silicon Graphics SVx", 455 [EM_ST19] = "STMicroelectronics ST19", 456 [EM_VAX] = "Digital VAX", 457 [EM_CRIS] = "Axis Communications 32-bit", 458 [EM_JAVELIN] = "Infineon Technologies 32-bit", 459 [EM_FIREPATH] = "Element 14 64-bit DSP Processor", 460 [EM_ZSP] = "LSI Logic 16-bit DSP Processor", 461 [EM_MMIX] = "Donald Knuth's educational 64-bit", 462 [EM_HUANY] = "Harvard machine-independent", 463 [EM_PRISM] = "SiTera Prism", 464 [EM_AVR] = "Atmel AVR 8-bit", 465 [EM_FR30] = "Fujitsu FR30", 466 [EM_D10V] = "Mitsubishi D10V", 467 [EM_D30V] = "Mitsubishi D30V", 468 [EM_V850] = "NEC v850", 469 [EM_M32R] = "Mitsubishi M32R", 470 [EM_MN10300] = "Matsushita MN10300", 471 [EM_MN10200] = "Matsushita MN10200", 472 [EM_PJ] = "picoJava", 473 [EM_OPENRISC] = "OpenRISC 32-bit", 474 [EM_ARC_A5] = "ARC ARCompact", 475 [EM_ARC_COMPACT] = "ARC ARCompact", 476 [EM_XTENSA] = "Tensilica Xtensa", 477 [EM_VIDEOCORE] = "Alphamosaic VideoCore", 478 [EM_TMM_GPP] = "Thompson Multimedia GPP", 479 [EM_NS32K] = "National 32000 series", 480 [EM_TPC] = "Tenor Network TPC", 481 [EM_SNP1K] = "Trebia SNP 1000", 482 [EM_ST200] = "STMicroelectronics ST200", 483 [EM_IP2K] = "Ubicom IP2xxx", 484 [EM_MAX] = "MAX Processor", 485 [EM_CR] = "National CompactRISC", 486 [EM_F2MC16] = "Fujitsu F2MC16", 487 [EM_MSP430] = "Texas msp430", 488 [EM_BLACKFIN] = "Analog Devices Blackfin", 489 [EM_SE_C33] = "S1C33 of Seiko Epson", 490 [EM_SEP] = "Sharp embedded", 491 [EM_ARCA] = "Arca RISC", 492 [EM_UNICORE] = "PKU-Unity Ltd. and MPRC", 493 [EM_EXCESS] = "eXcess CPU", 494 [EM_DXP] = "Deep Execution Processor", 495 [EM_ALTERA_NIOS2] = "Altera Nios II", 496 [EM_CRX] = "National CompactRISC CRX", 497 [EM_XGATE] = "Motorola XGATE", 498 [EM_C166] = "Infineon C16x/XC16x", 499 [EM_M16C] = "Renesas M16C", 500 [EM_DSPIC30F] = "Microchip dsPIC30F", 501 [EM_CE] = "Freescale Communication Engine", 502 [EM_M32C] = "Renesas M32C", 503 [EM_TSK3000] = "Altium TSK3000 core", 504 [EM_RS08] = "Freescale RS08", 505 [EM_SHARC] = "Analog Devices SHARC", 506 [EM_ECOG2] = "Cyan Technology eCOG2", 507 [EM_SCORE7] = "Sunplus S+core7", 508 [EM_DSP24] = "NJR 24-bit DSP", 509 [EM_VIDEOCORE3] = "Broadcom VideoCore III", 510 [EM_LATTICEMICO3] = "RISC processor for Lattice FPGA", 511 [EM_SE_C17] = "Seiko Epson C17", 512 [EM_TI_C6000] = "TMS320C6000 DSP family", 513 [EM_TI_C2000] = "TMS320C2000 DSP family", 514 [EM_TI_C5500] = "TMS320C55x DSP family", 515 [EM_TI_ARP32] = "Texas Application Specific RISC", 516 [EM_TI_PRU] = "Texas Programmable Realtime Unit", 517 [EM_MMDSP_PLUS] = "STMicroelectronics 64bit VLIW", 518 [EM_CYPRESS_M8C] = "Cypress M8C microprocessor", 519 [EM_R32C] = "Renesas R32C series", 520 [EM_TRIMEDIA] = "NXP Semiconductors TriMedia", 521 [EM_QDSP6] = "QUALCOMM DSP6 Processor", 522 [EM_8051] = "Intel 8051 and variants", 523 [EM_STXP7X] = "STMicroelectronics STxP7x", 524 [EM_NDS32] = "Andes Technology embedded RISC", 525 [EM_ECOG1] = "Cyan Technology eCOG1X family", 526 [EM_ECOG1X] = "Cyan Technology eCOG1X family", 527 [EM_MAXQ30] = "MAXQ30 Core Micro-controllers", 528 [EM_XIMO16] = "NJR 16-bit DSP Processor", 529 [EM_MANIK] = "M2000 Reconfigurable RISC", 530 [EM_CRAYNV2] = "Cray Inc. NV2 vector architecture", 531 [EM_RX] = "Renesas RX family", 532 [EM_METAG] = "Imagination Technologies META", 533 [EM_MCST_ELBRUS] = "MCST Elbrus", 534 [EM_ECOG16] = "Cyan Technology eCOG16 family", 535 [EM_CR16] = "National CompactRISC CR16", 536 [EM_ETPU] = "Freescale Extended Time Unit", 537 [EM_SLE9X] = "Infineon Technologies SLE9X core", 538 [EM_L10M] = "Intel L10M", 539 [EM_K10M] = "Intel K10M", 540 [EM_AARCH64] = "ARM AARCH64", 541 [EM_AVR32] = "Atmel 32-bit", 542 [EM_STM8] = "STMicroeletronics STM8 ", 543 [EM_TILE64] = "Tilera TILE64", 544 [EM_TILEPRO] = "Tilera TILEPro", 545 [EM_MICROBLAZE] = "Xilinx MicroBlaze 32-bit", 546 [EM_CUDA] = "NVIDIA CUDA architecture", 547 [EM_TILEGX] = "Tilera TILE-Gx family", 548 [EM_CLOUDSHIELD] = "CloudShield architecture family", 549 [EM_COREA_1ST] = "KIPO-KAIST Core-A 1st gen family", 550 [EM_COREA_2ND] = "KIPO-KAIST Core-A 2nd gen family", 551 [EM_ARC_COMPACT2] = "Synopsys ARCompact V2", 552 [EM_OPEN8] = "Open8 8-bit RISC soft processor core", 553 [EM_RL78] = "Renesas RL78 family", 554 [EM_VIDEOCORE5] = "Broadcom VideoCore V processor", 555 [EM_78KOR] = "Renesas 78KOR family", 556 [EM_56800EX] = "Freescale 56800EX (DSC)", 557 [EM_BA1] = "Beyond BA1 CPU architecture", 558 [EM_BA2] = "Beyond BA2 CPU architecture", 559 [EM_XCORE] = "XMOS xCORE processor family", 560 [EM_MCHP_PIC] = "Microchip 8-bit PIC(r) family", 561 [EM_KM32] = "KM211 KM32 32-bit processor", 562 [EM_KMX32] = "KM211 KMX32 32-bit processor", 563 [EM_KMX16] = "KM211 KMX16 16-bit processor", 564 [EM_KMX8] = "KM211 KMX8 8-bit processor", 565 [EM_KVARC] = "KM211 KVARC processor", 566 [EM_CDP] = "Paneve CDP architecture family", 567 [EM_COGE] = "Cognitive Smart Memory Processor", 568 [EM_COOL] = "Bluechip Systems CoolEngine", 569 [EM_NORC] = "Nanoradio Optimized RISC", 570 [EM_CSR_KALIMBA] = "CSR Kalimba architecture family", 571 [EM_Z80] = "Zilog Z80", 572 [EM_VISIUM] = "VISIUMcore processor", 573 [EM_FT32] = "FTDI Chip FT32", 574 [EM_MOXIE] = "Moxie processor family", 575 [EM_AMDGPU] = "AMD GPU architecture", 576 [EM_RISCV] = "RISC-V", 577 [EM_BPF] = "Linux BPF", 578 [EM_CSKY] = "C-SKY", 579 }; 580 static char *versions[] = { 581 [EV_NONE] = "Invalid", 582 [EV_CURRENT] = "Current", 583 }; 584 585 class = hdr->ident[EI_CLASS]; 586 data = hdr->ident[EI_DATA]; 587 abi = hdr->ident[EI_OSABI]; 588 type = hdr->type; 589 mach = hdr->machine; 590 version = hdr->version; 591 592 sclass = (class <= ELFCLASS64) ? classes[class] : "Unknown"; 593 sdata = (data <= ELFDATA2MSB) ? datas[data] : "Unknown"; 594 stype = (type <= ET_CORE) ? types[type] : "Unknown"; 595 smach = (mach <= EM_CSKY) ? machs[mach] : "Unknown"; 596 if (!smach) 597 smach = "Unknown"; 598 sversion = (version <= EV_CURRENT) ? versions[version] : "Unknown"; 599 600 switch (abi) { 601 case ELFOSABI_ARM: 602 sabi = "ARM"; 603 break; 604 case ELFOSABI_STANDALONE: 605 sabi = "Standalone (embedded) application"; 606 break; 607 default: 608 sabi = (abi <= ELFOSABI_OPENVOS) ? abis[abi] : "Unknown"; 609 } 610 611 printf("elfhdr:\n" 612 "\tei_class: %u, %s\n" 613 "\tei_data: %u, %s\n" 614 "\tei_version: %u\n" 615 "\tei_osabi: %u, %s\n" 616 "\tei_abiversion: %u\n" 617 "\te_type: %u, %s\n" 618 "\te_machine: %u, %s\n" 619 "\te_version: %lu, %s\n" 620 "\te_entry: 0x%08llx\n" 621 "\te_phoff: %llu\n" 622 "\te_shoff: %llu\n" 623 "\te_flags: %#lx\n" 624 "\te_ehsize: %lu\n" 625 "\te_phentsize: %lu\n" 626 "\te_phnum: %lu\n" 627 "\te_shentsize: %lu\n" 628 "\te_shnum: %lu\n" 629 "\te_shstrndx: %lu\n" 630 "\n", 631 class, sclass, 632 data, sdata, 633 hdr->ident[EI_VERSION], 634 abi, sabi, 635 hdr->ident[EI_ABIVERSION], 636 type, stype, 637 mach, smach, 638 version, sversion, 639 (long long) hdr->entry, 640 (long long) hdr->phoff, 641 (long long) hdr->shoff, 642 (long) hdr->flags, 643 (long) hdr->ehsize, 644 (long) hdr->phentsize, 645 (long) hdr->phnum, 646 (long) hdr->shentsize, 647 (long) hdr->shnum, 648 (long) hdr->shstrndx); 649 } 650 651 static void 652 printphdr(Obj *obj, Elfphdr *phdr, unsigned long n) 653 { 654 int j; 655 Map *map; 656 Mapsec *seg; 657 unsigned long i; 658 static char *types[] = { 659 [PT_NULL] = "unused", 660 [PT_LOAD] = "loadable segment", 661 [PT_DYNAMIC] = "dynamic linking section", 662 [PT_INTERP] = "the RTLD", 663 [PT_NOTE] = "note information", 664 [PT_SHLIB] = "reserved - purpose undefined", 665 [PT_PHDR] = "program header", 666 [PT_TLS] = "thread local storage", 667 }; 668 static Flags f ={ 669 .nr = NR_RIGHTS, 670 .text = { 671 [FLAG_X] = "Executable", 672 [FLAG_W] = "Writable", 673 [FLAG_R] = "Readable", 674 } 675 }; 676 677 if ((map = loadmap(obj, NULL)) == NULL) { 678 error("getting the object memory map"); 679 return; 680 } 681 682 for (i = 0; i < n; i++) { 683 char *stype; 684 unsigned long type; 685 686 f.flags = phdr->flags; 687 type = phdr->type; 688 if (type <= PT_TLS) { 689 stype = types[type]; 690 } else { 691 switch (type) { 692 case PT_GNU_EH_FRAME: 693 stype = "Frame unwind information"; 694 break; 695 case PT_GNU_STACK: 696 stype = "Stack flags"; 697 break; 698 case PT_GNU_RELRO: 699 stype = "Read-only after relocation"; 700 break; 701 case PT_GNU_PROPERTY: 702 stype = "GNU property"; 703 break; 704 default: 705 stype = "Unknown"; 706 break; 707 } 708 } 709 710 printf("Program header %ld\n" 711 "\tp_type: %#lx, %s\n" 712 "\tp_flags: %#lx\n" 713 "\tp_offset: %#08llx\n" 714 "\tp_vaddr: %#08llx\n" 715 "\tp_paddr: %#08llx\n" 716 "\tp_filesz: %#08llx\n" 717 "\tp_memsz: %#08llx\n" 718 "\tp_align: %#08llx\n", 719 i, 720 type, stype, 721 (long) phdr->flags, 722 (long long) phdr->offset, 723 (long long) phdr->vaddr, 724 (long long) phdr->paddr, 725 (long long) phdr->filesz, 726 (long long) phdr->memsz, 727 (long long) phdr->align); 728 729 putchar('\t'); 730 printflags(&f); 731 732 seg = &map->seg[i]; 733 printf("\tSections:"); 734 for (j = 0; j < seg->nchild; ++j) 735 printf(" %d", seg->child[j]->sec.index); 736 putchar('\n'); 737 putchar('\n'); 738 739 ++phdr; 740 } 741 742 puts("Section to Segment mapping:\nSegment\tSections"); 743 for (i = 0; i < n; ++i) { 744 printf(" %02lu\t", i); 745 746 seg = &map->seg[i]; 747 for (j = 0; j < seg->nchild; ++j) 748 printf(" %s", seg->child[j]->sec.name); 749 putchar('\n'); 750 } 751 putchar('\n'); 752 753 delmap(map); 754 } 755 756 void 757 elffhdr(Obj *obj, unsigned long long *start, Flags *f) 758 { 759 size_t i; 760 char *name; 761 Elf *elf = obj->data; 762 Elfhdr *hdr = &elf->hdr; 763 Elfsec *shdr; 764 765 *start = hdr->entry; 766 767 for (i = 0; i < elf->nsec; i++) { 768 shdr = &elf->secs[i]; 769 name = shdr->name; 770 setflag(f, strncmp(name, ".debug", 6) == 0, HAS_DEBUG); 771 setflag(f, strncmp(name, ".line", 5) == 0, HAS_LINENO); 772 setflag(f, strcmp(name, ".debug_line") == 0, HAS_LINENO); 773 setflag(f, shdr->type == SHT_RELA, HAS_RELOC); 774 setflag(f, shdr->type == SHT_REL, HAS_RELOC); 775 } 776 777 setflag(f, hdr->type == ET_EXEC, EXEC_P); 778 setflag(f, hdr->type == ET_DYN, DYNAMIC); 779 setflag(f, elf->nsym > 0, HAS_SYMS); 780 781 if (!pflag) 782 return; 783 784 printfhdr(hdr); 785 printphdr(obj, elf->phdr, hdr->phnum); 786 }