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 }