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