1#include <stdio.h>2#include <stdlib.h>3#include <string.h>45#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>1213#include "objdump.h"1415enum 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};2930enum phdrflags {31 FLAG_X = 0,32 FLAG_W = 1,33 FLAG_R = 2,34 NR_RIGHTS = 3,35};3637int38elfhasrelloc(Obj *obj, Section *sec)39{40 size_t i;41 Elf *elf = obj->data;42 Elfsec *shdr;4344 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 }5152 return 0;53}5455static void56printents(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;6566 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 };9192 for (i = 0; i < elf->nsym; i++) {93 ent = &elf->syms[i];9495 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;100101 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";110111 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 }124125 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}146147static void148printstbl(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;159160 if (elf->nsym == 0) {161 puts("no symbols");162 return;163 }164165 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);172173 info = ent->info;174 bind = ELF64_ST_BIND(info);175 type = ELF64_ST_TYPE(info);176177 cbind = (bind == STB_LOCAL) ? 'l' : 'g';178 cweak = (bind == STB_WEAK) ? 'w' : ' ';179 cctor = ' ';180 cwarn = ' ';181 cindir = ' ';182183 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 }195196 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 }211212 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}227228void229elfsyms(Obj *obj)230{231 printstbl(obj);232233 if (pflag)234 printents(obj);235}236237void238elfscns(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 };279280 for (i = 0; i < elf->nsec; i++) {281 long type;282 char *stype;283 shdr = &elf->secs[i];284285 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 }315316 if (!stype)317 stype = "Unknown";318319 f.flags = shdr->flags;320321 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);343344 putchar('\t');345 printflags(&f);346 putchar('\n');347 }348}349350static void351printfhdr(Elfhdr *hdr)352{353 unsigned long version;354 unsigned class, data, abi, type, mach;355 char *sclass, *sdata, *sabi, *stype, *smach, *sversion;356357 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 };584585 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;591592 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";599600 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 }610611 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}650651static void652printphdr(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 };676677 if ((map = loadmap(obj, NULL)) == NULL) {678 error("getting the object memory map");679 return;680 }681682 for (i = 0; i < n; i++) {683 char *stype;684 unsigned long type;685686 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 }709710 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);728729 putchar('\t');730 printflags(&f);731732 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');738739 ++phdr;740 }741742 puts("Section to Segment mapping:\nSegment\tSections");743 for (i = 0; i < n; ++i) {744 printf(" %02lu\t", i);745746 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');752753 delmap(map);754}755756void757elffhdr(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;764765 *start = hdr->entry;766767 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 }776777 setflag(f, hdr->type == ET_EXEC, EXEC_P);778 setflag(f, hdr->type == ET_DYN, DYNAMIC);779 setflag(f, elf->nsym > 0, HAS_SYMS);780781 if (!pflag)782 return;783784 printfhdr(hdr);785 printphdr(obj, elf->phdr, hdr->phnum);786}