scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | 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 }