elf.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       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 }