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 }