blob: d606cf5a1dabc3069d0bd4b5b9ccb81b31398540 [file] [log] [blame]
Brian Silverman86497922018-02-10 19:28:39 -05001/* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2017 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1999.
5
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23#include <argp.h>
24#include <assert.h>
25#include <ctype.h>
26#include <dwarf.h>
27#include <errno.h>
28#include <error.h>
29#include <fcntl.h>
30#include <gelf.h>
31#include <inttypes.h>
32#include <langinfo.h>
33#include <libdw.h>
34#include <libdwfl.h>
35#include <libintl.h>
36#include <locale.h>
37#include <stdarg.h>
38#include <stdbool.h>
39#include <stdlib.h>
40#include <string.h>
41#include <strings.h>
42#include <time.h>
43#include <unistd.h>
44#include <sys/stat.h>
45#include <signal.h>
46
47#include <libeu.h>
48#include <system.h>
49#include <printversion.h>
50#include "../libelf/libelfP.h"
51#include "../libelf/common.h"
52#include "../libebl/libeblP.h"
53#include "../libdwelf/libdwelf.h"
54#include "../libdw/libdwP.h"
55#include "../libdwfl/libdwflP.h"
56#include "../libdw/memory-access.h"
57
58#include "../libdw/known-dwarf.h"
59
60#ifdef __linux__
61#define CORE_SIGILL SIGILL
62#define CORE_SIGBUS SIGBUS
63#define CORE_SIGFPE SIGFPE
64#define CORE_SIGSEGV SIGSEGV
65#define CORE_SI_USER SI_USER
66#else
67/* We want the linux version of those as that is what shows up in the core files. */
68#define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
69#define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
70#define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
71#define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
72#define CORE_SI_USER 0 /* Sent by kill, sigsend. */
73#endif
74
75/* Name and version of program. */
76ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
77
78/* Bug report address. */
79ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
80
81/* argp key value for --elf-section, non-ascii. */
82#define ELF_INPUT_SECTION 256
83
84/* Definitions of arguments for argp functions. */
85static const struct argp_option options[] =
86{
87 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
88 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
89 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
90 "input data"), 0 },
91 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
92 { "all", 'a', NULL, 0,
93 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
94 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
95 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
96 { "histogram", 'I', NULL, 0,
97 N_("Display histogram of bucket list lengths"), 0 },
98 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
99 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
100 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
101 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
102 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
103 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
104 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
105 N_("Display the symbol table sections"), 0 },
106 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
107 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
108 { "arch-specific", 'A', NULL, 0,
109 N_("Display architecture specific information, if any"), 0 },
110 { "exception", 'e', NULL, 0,
111 N_("Display sections for exception handling"), 0 },
112
113 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
114 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
115 N_("Display DWARF section content. SECTION can be one of abbrev, "
116 "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
117 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
118 { "hex-dump", 'x', "SECTION", 0,
119 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
120 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
121 N_("Print string contents of sections"), 0 },
122 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
123 { "archive-index", 'c', NULL, 0,
124 N_("Display the symbol index of an archive"), 0 },
125
126 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
127 { "numeric-addresses", 'N', NULL, 0,
128 N_("Do not find symbol names for addresses in DWARF data"), 0 },
129 { "unresolved-address-offsets", 'U', NULL, 0,
130 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
131 { "wide", 'W', NULL, 0,
132 N_("Ignored for compatibility (lines always wide)"), 0 },
133 { "decompress", 'z', NULL, 0,
134 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
135 { NULL, 0, NULL, 0, NULL, 0 }
136};
137
138/* Short description of program. */
139static const char doc[] = N_("\
140Print information from ELF file in human-readable form.");
141
142/* Strings for arguments in help texts. */
143static const char args_doc[] = N_("FILE...");
144
145/* Prototype for option handler. */
146static error_t parse_opt (int key, char *arg, struct argp_state *state);
147
148/* Data structure to communicate with argp functions. */
149static struct argp argp =
150{
151 options, parse_opt, args_doc, doc, NULL, NULL, NULL
152};
153
154/* If non-null, the section from which we should read to (compressed) ELF. */
155static const char *elf_input_section = NULL;
156
157/* Flags set by the option controlling the output. */
158
159/* True if dynamic segment should be printed. */
160static bool print_dynamic_table;
161
162/* True if the file header should be printed. */
163static bool print_file_header;
164
165/* True if the program headers should be printed. */
166static bool print_program_header;
167
168/* True if relocations should be printed. */
169static bool print_relocations;
170
171/* True if the section headers should be printed. */
172static bool print_section_header;
173
174/* True if the symbol table should be printed. */
175static bool print_symbol_table;
176
177/* A specific section name, or NULL to print all symbol tables. */
178static char *symbol_table_section;
179
180/* True if the version information should be printed. */
181static bool print_version_info;
182
183/* True if section groups should be printed. */
184static bool print_section_groups;
185
186/* True if bucket list length histogram should be printed. */
187static bool print_histogram;
188
189/* True if the architecture specific data should be printed. */
190static bool print_arch;
191
192/* True if note section content should be printed. */
193static bool print_notes;
194
195/* True if SHF_STRINGS section content should be printed. */
196static bool print_string_sections;
197
198/* True if archive index should be printed. */
199static bool print_archive_index;
200
201/* True if any of the control options except print_archive_index is set. */
202static bool any_control_option;
203
204/* True if we should print addresses from DWARF in symbolic form. */
205static bool print_address_names = true;
206
207/* True if we should print raw values instead of relativized addresses. */
208static bool print_unresolved_addresses = false;
209
210/* True if we should print the .debug_aranges section using libdw. */
211static bool decodedaranges = false;
212
213/* True if we should print the .debug_aranges section using libdw. */
214static bool decodedline = false;
215
216/* True if we want to show more information about compressed sections. */
217static bool print_decompress = false;
218
219/* Select printing of debugging sections. */
220static enum section_e
221{
222 section_abbrev = 1, /* .debug_abbrev */
223 section_aranges = 2, /* .debug_aranges */
224 section_frame = 4, /* .debug_frame or .eh_frame & al. */
225 section_info = 8, /* .debug_info, .debug_types */
226 section_types = section_info,
227 section_line = 16, /* .debug_line */
228 section_loc = 32, /* .debug_loc */
229 section_pubnames = 64, /* .debug_pubnames */
230 section_str = 128, /* .debug_str */
231 section_macinfo = 256, /* .debug_macinfo */
232 section_ranges = 512, /* .debug_ranges */
233 section_exception = 1024, /* .eh_frame & al. */
234 section_gdb_index = 2048, /* .gdb_index */
235 section_macro = 4096, /* .debug_macro */
236 section_all = (section_abbrev | section_aranges | section_frame
237 | section_info | section_line | section_loc
238 | section_pubnames | section_str | section_macinfo
239 | section_ranges | section_exception | section_gdb_index
240 | section_macro)
241} print_debug_sections, implicit_debug_sections;
242
243/* Select hex dumping of sections. */
244static struct section_argument *dump_data_sections;
245static struct section_argument **dump_data_sections_tail = &dump_data_sections;
246
247/* Select string dumping of sections. */
248static struct section_argument *string_sections;
249static struct section_argument **string_sections_tail = &string_sections;
250
251struct section_argument
252{
253 struct section_argument *next;
254 const char *arg;
255 bool implicit;
256};
257
258/* Numbers of sections and program headers in the file. */
259static size_t shnum;
260static size_t phnum;
261
262
263/* Declarations of local functions. */
264static void process_file (int fd, const char *fname, bool only_one);
265static void process_elf_file (Dwfl_Module *dwflmod, int fd);
266static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
267static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
268static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
269static void print_scngrp (Ebl *ebl);
270static void print_dynamic (Ebl *ebl);
271static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
272static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
273 GElf_Shdr *shdr);
274static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
275 GElf_Shdr *shdr);
276static void print_symtab (Ebl *ebl, int type);
277static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
278static void print_verinfo (Ebl *ebl);
279static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
280static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
281static void handle_versym (Ebl *ebl, Elf_Scn *scn,
282 GElf_Shdr *shdr);
283static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
284static void handle_hash (Ebl *ebl);
285static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
286static void print_liblist (Ebl *ebl);
287static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
288static void dump_data (Ebl *ebl);
289static void dump_strings (Ebl *ebl);
290static void print_strings (Ebl *ebl);
291static void dump_archive_index (Elf *, const char *);
292
293
294int
295main (int argc, char *argv[])
296{
297 /* Set locale. */
298 setlocale (LC_ALL, "");
299
300 /* Initialize the message catalog. */
301 textdomain (PACKAGE_TARNAME);
302
303 /* Parse and process arguments. */
304 int remaining;
305 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
306
307 /* Before we start tell the ELF library which version we are using. */
308 elf_version (EV_CURRENT);
309
310 /* Now process all the files given at the command line. */
311 bool only_one = remaining + 1 == argc;
312 do
313 {
314 /* Open the file. */
315 int fd = open (argv[remaining], O_RDONLY);
316 if (fd == -1)
317 {
318 error (0, errno, gettext ("cannot open input file"));
319 continue;
320 }
321
322 process_file (fd, argv[remaining], only_one);
323
324 close (fd);
325 }
326 while (++remaining < argc);
327
328 return error_message_count != 0;
329}
330
331
332/* Handle program arguments. */
333static error_t
334parse_opt (int key, char *arg,
335 struct argp_state *state __attribute__ ((unused)))
336{
337 void add_dump_section (const char *name, bool implicit)
338 {
339 struct section_argument *a = xmalloc (sizeof *a);
340 a->arg = name;
341 a->next = NULL;
342 a->implicit = implicit;
343 struct section_argument ***tailp
344 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
345 **tailp = a;
346 *tailp = &a->next;
347 }
348
349 switch (key)
350 {
351 case 'a':
352 print_file_header = true;
353 print_program_header = true;
354 print_relocations = true;
355 print_section_header = true;
356 print_symbol_table = true;
357 print_version_info = true;
358 print_dynamic_table = true;
359 print_section_groups = true;
360 print_histogram = true;
361 print_arch = true;
362 print_notes = true;
363 implicit_debug_sections |= section_exception;
364 add_dump_section (".strtab", true);
365 add_dump_section (".dynstr", true);
366 add_dump_section (".comment", true);
367 any_control_option = true;
368 break;
369 case 'A':
370 print_arch = true;
371 any_control_option = true;
372 break;
373 case 'd':
374 print_dynamic_table = true;
375 any_control_option = true;
376 break;
377 case 'e':
378 print_debug_sections |= section_exception;
379 any_control_option = true;
380 break;
381 case 'g':
382 print_section_groups = true;
383 any_control_option = true;
384 break;
385 case 'h':
386 print_file_header = true;
387 any_control_option = true;
388 break;
389 case 'I':
390 print_histogram = true;
391 any_control_option = true;
392 break;
393 case 'l':
394 print_program_header = true;
395 any_control_option = true;
396 break;
397 case 'n':
398 print_notes = true;
399 any_control_option = true;
400 break;
401 case 'r':
402 print_relocations = true;
403 any_control_option = true;
404 break;
405 case 'S':
406 print_section_header = true;
407 any_control_option = true;
408 break;
409 case 's':
410 print_symbol_table = true;
411 any_control_option = true;
412 symbol_table_section = arg;
413 break;
414 case 'V':
415 print_version_info = true;
416 any_control_option = true;
417 break;
418 case 'c':
419 print_archive_index = true;
420 break;
421 case 'w':
422 if (arg == NULL)
423 print_debug_sections = section_all;
424 else if (strcmp (arg, "abbrev") == 0)
425 print_debug_sections |= section_abbrev;
426 else if (strcmp (arg, "aranges") == 0)
427 print_debug_sections |= section_aranges;
428 else if (strcmp (arg, "decodedaranges") == 0)
429 {
430 print_debug_sections |= section_aranges;
431 decodedaranges = true;
432 }
433 else if (strcmp (arg, "ranges") == 0)
434 {
435 print_debug_sections |= section_ranges;
436 implicit_debug_sections |= section_info;
437 }
438 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
439 print_debug_sections |= section_frame;
440 else if (strcmp (arg, "info") == 0)
441 print_debug_sections |= section_info;
442 else if (strcmp (arg, "loc") == 0)
443 {
444 print_debug_sections |= section_loc;
445 implicit_debug_sections |= section_info;
446 }
447 else if (strcmp (arg, "line") == 0)
448 print_debug_sections |= section_line;
449 else if (strcmp (arg, "decodedline") == 0)
450 {
451 print_debug_sections |= section_line;
452 decodedline = true;
453 }
454 else if (strcmp (arg, "pubnames") == 0)
455 print_debug_sections |= section_pubnames;
456 else if (strcmp (arg, "str") == 0)
457 print_debug_sections |= section_str;
458 else if (strcmp (arg, "macinfo") == 0)
459 print_debug_sections |= section_macinfo;
460 else if (strcmp (arg, "macro") == 0)
461 print_debug_sections |= section_macro;
462 else if (strcmp (arg, "exception") == 0)
463 print_debug_sections |= section_exception;
464 else if (strcmp (arg, "gdb_index") == 0)
465 print_debug_sections |= section_gdb_index;
466 else
467 {
468 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
469 arg);
470 argp_help (&argp, stderr, ARGP_HELP_SEE,
471 program_invocation_short_name);
472 exit (1);
473 }
474 any_control_option = true;
475 break;
476 case 'p':
477 any_control_option = true;
478 if (arg == NULL)
479 {
480 print_string_sections = true;
481 break;
482 }
483 FALLTHROUGH;
484 case 'x':
485 add_dump_section (arg, false);
486 any_control_option = true;
487 break;
488 case 'N':
489 print_address_names = false;
490 break;
491 case 'U':
492 print_unresolved_addresses = true;
493 break;
494 case ARGP_KEY_NO_ARGS:
495 fputs (gettext ("Missing file name.\n"), stderr);
496 goto do_argp_help;
497 case ARGP_KEY_FINI:
498 if (! any_control_option && ! print_archive_index)
499 {
500 fputs (gettext ("No operation specified.\n"), stderr);
501 do_argp_help:
502 argp_help (&argp, stderr, ARGP_HELP_SEE,
503 program_invocation_short_name);
504 exit (EXIT_FAILURE);
505 }
506 break;
507 case 'W': /* Ignored. */
508 break;
509 case 'z':
510 print_decompress = true;
511 break;
512 case ELF_INPUT_SECTION:
513 if (arg == NULL)
514 elf_input_section = ".gnu_debugdata";
515 else
516 elf_input_section = arg;
517 break;
518 default:
519 return ARGP_ERR_UNKNOWN;
520 }
521 return 0;
522}
523
524
525/* Create a file descriptor to read the data from the
526 elf_input_section given a file descriptor to an ELF file. */
527static int
528open_input_section (int fd)
529{
530 size_t shnums;
531 size_t cnt;
532 size_t shstrndx;
533 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
534 if (elf == NULL)
535 {
536 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
537 elf_errmsg (-1));
538 return -1;
539 }
540
541 if (elf_getshdrnum (elf, &shnums) < 0)
542 {
543 error (0, 0, gettext ("cannot determine number of sections: %s"),
544 elf_errmsg (-1));
545 open_error:
546 elf_end (elf);
547 return -1;
548 }
549
550 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
551 {
552 error (0, 0, gettext ("cannot get section header string table index"));
553 goto open_error;
554 }
555
556 for (cnt = 0; cnt < shnums; ++cnt)
557 {
558 Elf_Scn *scn = elf_getscn (elf, cnt);
559 if (scn == NULL)
560 {
561 error (0, 0, gettext ("cannot get section: %s"),
562 elf_errmsg (-1));
563 goto open_error;
564 }
565
566 GElf_Shdr shdr_mem;
567 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
568 if (unlikely (shdr == NULL))
569 {
570 error (0, 0, gettext ("cannot get section header: %s"),
571 elf_errmsg (-1));
572 goto open_error;
573 }
574
575 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
576 if (sname == NULL)
577 {
578 error (0, 0, gettext ("cannot get section name"));
579 goto open_error;
580 }
581
582 if (strcmp (sname, elf_input_section) == 0)
583 {
584 Elf_Data *data = elf_rawdata (scn, NULL);
585 if (data == NULL)
586 {
587 error (0, 0, gettext ("cannot get %s content: %s"),
588 sname, elf_errmsg (-1));
589 goto open_error;
590 }
591
592 /* Create (and immediately unlink) a temporary file to store
593 section data in to create a file descriptor for it. */
594 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
595 static const char suffix[] = "/readelfXXXXXX";
596 int tmplen = strlen (tmpdir) + sizeof (suffix);
597 char *tempname = alloca (tmplen);
598 sprintf (tempname, "%s%s", tmpdir, suffix);
599
600 int sfd = mkstemp (tempname);
601 if (sfd == -1)
602 {
603 error (0, 0, gettext ("cannot create temp file '%s'"),
604 tempname);
605 goto open_error;
606 }
607 unlink (tempname);
608
609 ssize_t size = data->d_size;
610 if (write_retry (sfd, data->d_buf, size) != size)
611 {
612 error (0, 0, gettext ("cannot write section data"));
613 goto open_error;
614 }
615
616 if (elf_end (elf) != 0)
617 {
618 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
619 elf_errmsg (-1));
620 return -1;
621 }
622
623 if (lseek (sfd, 0, SEEK_SET) == -1)
624 {
625 error (0, 0, gettext ("error while rewinding file descriptor"));
626 return -1;
627 }
628
629 return sfd;
630 }
631 }
632
633 /* Named section not found. */
634 if (elf_end (elf) != 0)
635 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
636 elf_errmsg (-1));
637 return -1;
638}
639
640/* Check if the file is an archive, and if so dump its index. */
641static void
642check_archive_index (int fd, const char *fname, bool only_one)
643{
644 /* Create an `Elf' descriptor. */
645 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
646 if (elf == NULL)
647 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
648 elf_errmsg (-1));
649 else
650 {
651 if (elf_kind (elf) == ELF_K_AR)
652 {
653 if (!only_one)
654 printf ("\n%s:\n\n", fname);
655 dump_archive_index (elf, fname);
656 }
657 else
658 error (0, 0,
659 gettext ("'%s' is not an archive, cannot print archive index"),
660 fname);
661
662 /* Now we can close the descriptor. */
663 if (elf_end (elf) != 0)
664 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
665 elf_errmsg (-1));
666 }
667}
668
669/* Trivial callback used for checking if we opened an archive. */
670static int
671count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
672 void **userdata __attribute__ ((unused)),
673 const char *name __attribute__ ((unused)),
674 Dwarf_Addr base __attribute__ ((unused)),
675 void *arg)
676{
677 if (*(bool *) arg)
678 return DWARF_CB_ABORT;
679 *(bool *) arg = true;
680 return DWARF_CB_OK;
681}
682
683struct process_dwflmod_args
684{
685 int fd;
686 bool only_one;
687};
688
689static int
690process_dwflmod (Dwfl_Module *dwflmod,
691 void **userdata __attribute__ ((unused)),
692 const char *name __attribute__ ((unused)),
693 Dwarf_Addr base __attribute__ ((unused)),
694 void *arg)
695{
696 const struct process_dwflmod_args *a = arg;
697
698 /* Print the file name. */
699 if (!a->only_one)
700 {
701 const char *fname;
702 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
703
704 printf ("\n%s:\n\n", fname);
705 }
706
707 process_elf_file (dwflmod, a->fd);
708
709 return DWARF_CB_OK;
710}
711
712/* Stub libdwfl callback, only the ELF handle already open is ever used.
713 Only used for finding the alternate debug file if the Dwarf comes from
714 the main file. We are not interested in separate debuginfo. */
715static int
716find_no_debuginfo (Dwfl_Module *mod,
717 void **userdata,
718 const char *modname,
719 Dwarf_Addr base,
720 const char *file_name,
721 const char *debuglink_file,
722 GElf_Word debuglink_crc,
723 char **debuginfo_file_name)
724{
725 Dwarf_Addr dwbias;
726 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
727
728 /* We are only interested if the Dwarf has been setup on the main
729 elf file but is only missing the alternate debug link. If dwbias
730 hasn't even been setup, this is searching for separate debuginfo
731 for the main elf. We don't care in that case. */
732 if (dwbias == (Dwarf_Addr) -1)
733 return -1;
734
735 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
736 file_name, debuglink_file,
737 debuglink_crc, debuginfo_file_name);
738}
739
740/* Process one input file. */
741static void
742process_file (int fd, const char *fname, bool only_one)
743{
744 if (print_archive_index)
745 check_archive_index (fd, fname, only_one);
746
747 if (!any_control_option)
748 return;
749
750 if (elf_input_section != NULL)
751 {
752 /* Replace fname and fd with section content. */
753 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
754 sprintf (fnname, "%s:%s", fname, elf_input_section);
755 fd = open_input_section (fd);
756 if (fd == -1)
757 {
758 error (0, 0, gettext ("No such section '%s' in '%s'"),
759 elf_input_section, fname);
760 return;
761 }
762 fname = fnname;
763 }
764
765 /* Duplicate an fd for dwfl_report_offline to swallow. */
766 int dwfl_fd = dup (fd);
767 if (unlikely (dwfl_fd < 0))
768 error (EXIT_FAILURE, errno, "dup");
769
770 /* Use libdwfl in a trivial way to open the libdw handle for us.
771 This takes care of applying relocations to DWARF data in ET_REL files. */
772 static const Dwfl_Callbacks callbacks =
773 {
774 .section_address = dwfl_offline_section_address,
775 .find_debuginfo = find_no_debuginfo
776 };
777 Dwfl *dwfl = dwfl_begin (&callbacks);
778 if (likely (dwfl != NULL))
779 /* Let 0 be the logical address of the file (or first in archive). */
780 dwfl->offline_next_address = 0;
781 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
782 {
783 struct stat st;
784 if (fstat (dwfl_fd, &st) != 0)
785 error (0, errno, gettext ("cannot stat input file"));
786 else if (unlikely (st.st_size == 0))
787 error (0, 0, gettext ("input file is empty"));
788 else
789 error (0, 0, gettext ("failed reading '%s': %s"),
790 fname, dwfl_errmsg (-1));
791 close (dwfl_fd); /* Consumed on success, not on failure. */
792 }
793 else
794 {
795 dwfl_report_end (dwfl, NULL, NULL);
796
797 if (only_one)
798 {
799 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
800 bool seen = false;
801 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
802 }
803
804 /* Process the one or more modules gleaned from this file. */
805 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
806 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
807 }
808 dwfl_end (dwfl);
809
810 /* Need to close the replaced fd if we created it. Caller takes
811 care of original. */
812 if (elf_input_section != NULL)
813 close (fd);
814}
815
816/* Check whether there are any compressed sections in the ELF file. */
817static bool
818elf_contains_chdrs (Elf *elf)
819{
820 Elf_Scn *scn = NULL;
821 while ((scn = elf_nextscn (elf, scn)) != NULL)
822 {
823 GElf_Shdr shdr_mem;
824 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
825 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
826 return true;
827 }
828 return false;
829}
830
831/* Process one ELF file. */
832static void
833process_elf_file (Dwfl_Module *dwflmod, int fd)
834{
835 GElf_Addr dwflbias;
836 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
837
838 GElf_Ehdr ehdr_mem;
839 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
840
841 if (ehdr == NULL)
842 {
843 elf_error:
844 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
845 return;
846 }
847
848 Ebl *ebl = ebl_openbackend (elf);
849 if (unlikely (ebl == NULL))
850 {
851 ebl_error:
852 error (0, errno, gettext ("cannot create EBL handle"));
853 return;
854 }
855
856 /* Determine the number of sections. */
857 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
858 error (EXIT_FAILURE, 0,
859 gettext ("cannot determine number of sections: %s"),
860 elf_errmsg (-1));
861
862 /* Determine the number of phdrs. */
863 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
864 error (EXIT_FAILURE, 0,
865 gettext ("cannot determine number of program headers: %s"),
866 elf_errmsg (-1));
867
868 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
869 may have applied relocation to some sections. If there are any
870 compressed sections, any pass (or libdw/libdwfl) might have
871 uncompressed them. So we need to get a fresh Elf handle on the
872 file to display those. */
873 bool print_unchanged = ((print_section_header
874 || print_relocations
875 || dump_data_sections != NULL
876 || print_notes)
877 && (ehdr->e_type == ET_REL
878 || elf_contains_chdrs (ebl->elf)));
879
880 Elf *pure_elf = NULL;
881 Ebl *pure_ebl = ebl;
882 if (print_unchanged)
883 {
884 /* Read the file afresh. */
885 off_t aroff = elf_getaroff (elf);
886 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
887 if (aroff > 0)
888 {
889 /* Archive member. */
890 (void) elf_rand (pure_elf, aroff);
891 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
892 elf_end (pure_elf);
893 pure_elf = armem;
894 }
895 if (pure_elf == NULL)
896 goto elf_error;
897 pure_ebl = ebl_openbackend (pure_elf);
898 if (pure_ebl == NULL)
899 goto ebl_error;
900 }
901
902 if (print_file_header)
903 print_ehdr (ebl, ehdr);
904 if (print_section_header)
905 print_shdr (pure_ebl, ehdr);
906 if (print_program_header)
907 print_phdr (ebl, ehdr);
908 if (print_section_groups)
909 print_scngrp (ebl);
910 if (print_dynamic_table)
911 print_dynamic (ebl);
912 if (print_relocations)
913 print_relocs (pure_ebl, ehdr);
914 if (print_histogram)
915 handle_hash (ebl);
916 if (print_symbol_table)
917 print_symtab (ebl, SHT_DYNSYM);
918 if (print_version_info)
919 print_verinfo (ebl);
920 if (print_symbol_table)
921 print_symtab (ebl, SHT_SYMTAB);
922 if (print_arch)
923 print_liblist (ebl);
924 if (print_arch)
925 print_attributes (ebl, ehdr);
926 if (dump_data_sections != NULL)
927 dump_data (pure_ebl);
928 if (string_sections != NULL)
929 dump_strings (ebl);
930 if ((print_debug_sections | implicit_debug_sections) != 0)
931 print_debug (dwflmod, ebl, ehdr);
932 if (print_notes)
933 handle_notes (pure_ebl, ehdr);
934 if (print_string_sections)
935 print_strings (ebl);
936
937 ebl_closebackend (ebl);
938
939 if (pure_ebl != ebl)
940 {
941 ebl_closebackend (pure_ebl);
942 elf_end (pure_elf);
943 }
944}
945
946
947/* Print file type. */
948static void
949print_file_type (unsigned short int e_type)
950{
951 if (likely (e_type <= ET_CORE))
952 {
953 static const char *const knowntypes[] =
954 {
955 N_("NONE (None)"),
956 N_("REL (Relocatable file)"),
957 N_("EXEC (Executable file)"),
958 N_("DYN (Shared object file)"),
959 N_("CORE (Core file)")
960 };
961 puts (gettext (knowntypes[e_type]));
962 }
963 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
964 printf (gettext ("OS Specific: (%x)\n"), e_type);
965 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
966 printf (gettext ("Processor Specific: (%x)\n"), e_type);
967 else
968 puts ("???");
969}
970
971
972/* Print ELF header. */
973static void
974print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
975{
976 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
977 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
978 printf (" %02hhx", ehdr->e_ident[cnt]);
979
980 printf (gettext ("\n Class: %s\n"),
981 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
982 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
983 : "\?\?\?");
984
985 printf (gettext (" Data: %s\n"),
986 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
987 ? "2's complement, little endian"
988 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
989 ? "2's complement, big endian" : "\?\?\?");
990
991 printf (gettext (" Ident Version: %hhd %s\n"),
992 ehdr->e_ident[EI_VERSION],
993 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
994 : "(\?\?\?)");
995
996 char buf[512];
997 printf (gettext (" OS/ABI: %s\n"),
998 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
999
1000 printf (gettext (" ABI Version: %hhd\n"),
1001 ehdr->e_ident[EI_ABIVERSION]);
1002
1003 fputs_unlocked (gettext (" Type: "), stdout);
1004 print_file_type (ehdr->e_type);
1005
1006 printf (gettext (" Machine: %s\n"), ebl->name);
1007
1008 printf (gettext (" Version: %d %s\n"),
1009 ehdr->e_version,
1010 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1011
1012 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
1013 ehdr->e_entry);
1014
1015 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
1016 ehdr->e_phoff, gettext ("(bytes into file)"));
1017
1018 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
1019 ehdr->e_shoff, gettext ("(bytes into file)"));
1020
1021 printf (gettext (" Flags: %s\n"),
1022 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1023
1024 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
1025 ehdr->e_ehsize, gettext ("(bytes)"));
1026
1027 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
1028 ehdr->e_phentsize, gettext ("(bytes)"));
1029
1030 printf (gettext (" Number of program headers entries: %" PRId16),
1031 ehdr->e_phnum);
1032 if (ehdr->e_phnum == PN_XNUM)
1033 {
1034 GElf_Shdr shdr_mem;
1035 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1036 if (shdr != NULL)
1037 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1038 (uint32_t) shdr->sh_info);
1039 else
1040 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1041 }
1042 fputc_unlocked ('\n', stdout);
1043
1044 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1045 ehdr->e_shentsize, gettext ("(bytes)"));
1046
1047 printf (gettext (" Number of section headers entries: %" PRId16),
1048 ehdr->e_shnum);
1049 if (ehdr->e_shnum == 0)
1050 {
1051 GElf_Shdr shdr_mem;
1052 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1053 if (shdr != NULL)
1054 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1055 (uint32_t) shdr->sh_size);
1056 else
1057 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1058 }
1059 fputc_unlocked ('\n', stdout);
1060
1061 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1062 {
1063 GElf_Shdr shdr_mem;
1064 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1065 if (shdr != NULL)
1066 /* We managed to get the zeroth section. */
1067 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1068 (uint32_t) shdr->sh_link);
1069 else
1070 {
1071 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1072 buf[sizeof (buf) - 1] = '\0';
1073 }
1074
1075 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1076 buf);
1077 }
1078 else
1079 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1080 ehdr->e_shstrndx);
1081}
1082
1083
1084static const char *
1085get_visibility_type (int value)
1086{
1087 switch (value)
1088 {
1089 case STV_DEFAULT:
1090 return "DEFAULT";
1091 case STV_INTERNAL:
1092 return "INTERNAL";
1093 case STV_HIDDEN:
1094 return "HIDDEN";
1095 case STV_PROTECTED:
1096 return "PROTECTED";
1097 default:
1098 return "???";
1099 }
1100}
1101
1102static const char *
1103elf_ch_type_name (unsigned int code)
1104{
1105 if (code == 0)
1106 return "NONE";
1107
1108 if (code == ELFCOMPRESS_ZLIB)
1109 return "ZLIB";
1110
1111 return "UNKNOWN";
1112}
1113
1114/* Print the section headers. */
1115static void
1116print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1117{
1118 size_t cnt;
1119 size_t shstrndx;
1120
1121 if (! print_file_header)
1122 printf (gettext ("\
1123There are %d section headers, starting at offset %#" PRIx64 ":\n\
1124\n"),
1125 ehdr->e_shnum, ehdr->e_shoff);
1126
1127 /* Get the section header string table index. */
1128 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1129 error (EXIT_FAILURE, 0,
1130 gettext ("cannot get section header string table index"));
1131
1132 puts (gettext ("Section Headers:"));
1133
1134 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1135 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1136 else
1137 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1138
1139 if (print_decompress)
1140 {
1141 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1142 puts (gettext (" [Compression Size Al]"));
1143 else
1144 puts (gettext (" [Compression Size Al]"));
1145 }
1146
1147 for (cnt = 0; cnt < shnum; ++cnt)
1148 {
1149 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1150
1151 if (unlikely (scn == NULL))
1152 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1153 elf_errmsg (-1));
1154
1155 /* Get the section header. */
1156 GElf_Shdr shdr_mem;
1157 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1158 if (unlikely (shdr == NULL))
1159 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1160 elf_errmsg (-1));
1161
1162 char flagbuf[20];
1163 char *cp = flagbuf;
1164 if (shdr->sh_flags & SHF_WRITE)
1165 *cp++ = 'W';
1166 if (shdr->sh_flags & SHF_ALLOC)
1167 *cp++ = 'A';
1168 if (shdr->sh_flags & SHF_EXECINSTR)
1169 *cp++ = 'X';
1170 if (shdr->sh_flags & SHF_MERGE)
1171 *cp++ = 'M';
1172 if (shdr->sh_flags & SHF_STRINGS)
1173 *cp++ = 'S';
1174 if (shdr->sh_flags & SHF_INFO_LINK)
1175 *cp++ = 'I';
1176 if (shdr->sh_flags & SHF_LINK_ORDER)
1177 *cp++ = 'L';
1178 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1179 *cp++ = 'N';
1180 if (shdr->sh_flags & SHF_GROUP)
1181 *cp++ = 'G';
1182 if (shdr->sh_flags & SHF_TLS)
1183 *cp++ = 'T';
1184 if (shdr->sh_flags & SHF_COMPRESSED)
1185 *cp++ = 'C';
1186 if (shdr->sh_flags & SHF_ORDERED)
1187 *cp++ = 'O';
1188 if (shdr->sh_flags & SHF_EXCLUDE)
1189 *cp++ = 'E';
1190 *cp = '\0';
1191
1192 const char *sname;
1193 char buf[128];
1194 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1195 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1196 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1197 " %2" PRId64 "\n",
1198 cnt, sname,
1199 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1200 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1201 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1202 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1203 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1204 shdr->sh_addralign);
1205
1206 if (print_decompress)
1207 {
1208 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1209 {
1210 GElf_Chdr chdr;
1211 if (gelf_getchdr (scn, &chdr) != NULL)
1212 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1213 " %2" PRId64 "]\n",
1214 elf_ch_type_name (chdr.ch_type),
1215 chdr.ch_type,
1216 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1217 chdr.ch_size, chdr.ch_addralign);
1218 else
1219 error (0, 0,
1220 gettext ("bad compression header for section %zd: %s"),
1221 elf_ndxscn (scn), elf_errmsg (-1));
1222 }
1223 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1224 {
1225 ssize_t size;
1226 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1227 printf (" [GNU ZLIB %0*zx ]\n",
1228 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1229 else
1230 error (0, 0,
1231 gettext ("bad gnu compressed size for section %zd: %s"),
1232 elf_ndxscn (scn), elf_errmsg (-1));
1233 }
1234 }
1235 }
1236
1237 fputc_unlocked ('\n', stdout);
1238}
1239
1240
1241/* Print the program header. */
1242static void
1243print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1244{
1245 if (phnum == 0)
1246 /* No program header, this is OK in relocatable objects. */
1247 return;
1248
1249 puts (gettext ("Program Headers:"));
1250 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1251 puts (gettext ("\
1252 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1253 else
1254 puts (gettext ("\
1255 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1256
1257 /* Process all program headers. */
1258 bool has_relro = false;
1259 GElf_Addr relro_from = 0;
1260 GElf_Addr relro_to = 0;
1261 for (size_t cnt = 0; cnt < phnum; ++cnt)
1262 {
1263 char buf[128];
1264 GElf_Phdr mem;
1265 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1266
1267 /* If for some reason the header cannot be returned show this. */
1268 if (unlikely (phdr == NULL))
1269 {
1270 puts (" ???");
1271 continue;
1272 }
1273
1274 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1275 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1276 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1277 phdr->p_offset,
1278 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1279 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1280 phdr->p_filesz,
1281 phdr->p_memsz,
1282 phdr->p_flags & PF_R ? 'R' : ' ',
1283 phdr->p_flags & PF_W ? 'W' : ' ',
1284 phdr->p_flags & PF_X ? 'E' : ' ',
1285 phdr->p_align);
1286
1287 if (phdr->p_type == PT_INTERP)
1288 {
1289 /* If we are sure the file offset is valid then we can show
1290 the user the name of the interpreter. We check whether
1291 there is a section at the file offset. Normally there
1292 would be a section called ".interp". But in separate
1293 .debug files it is a NOBITS section (and so doesn't match
1294 with gelf_offscn). Which probably means the offset is
1295 not valid another reason could be because the ELF file
1296 just doesn't contain any section headers, in that case
1297 just play it safe and don't display anything. */
1298
1299 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1300 GElf_Shdr shdr_mem;
1301 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1302
1303 size_t maxsize;
1304 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1305
1306 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1307 && filedata != NULL && phdr->p_offset < maxsize
1308 && phdr->p_filesz <= maxsize - phdr->p_offset
1309 && memchr (filedata + phdr->p_offset, '\0',
1310 phdr->p_filesz) != NULL)
1311 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1312 filedata + phdr->p_offset);
1313 }
1314 else if (phdr->p_type == PT_GNU_RELRO)
1315 {
1316 has_relro = true;
1317 relro_from = phdr->p_vaddr;
1318 relro_to = relro_from + phdr->p_memsz;
1319 }
1320 }
1321
1322 if (ehdr->e_shnum == 0)
1323 /* No sections in the file. Punt. */
1324 return;
1325
1326 /* Get the section header string table index. */
1327 size_t shstrndx;
1328 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1329 error (EXIT_FAILURE, 0,
1330 gettext ("cannot get section header string table index"));
1331
1332 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1333
1334 for (size_t cnt = 0; cnt < phnum; ++cnt)
1335 {
1336 /* Print the segment number. */
1337 printf (" %2.2zu ", cnt);
1338
1339 GElf_Phdr phdr_mem;
1340 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1341 /* This must not happen. */
1342 if (unlikely (phdr == NULL))
1343 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1344 elf_errmsg (-1));
1345
1346 /* Iterate over the sections. */
1347 bool in_relro = false;
1348 bool in_ro = false;
1349 for (size_t inner = 1; inner < shnum; ++inner)
1350 {
1351 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1352 /* This should not happen. */
1353 if (unlikely (scn == NULL))
1354 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1355 elf_errmsg (-1));
1356
1357 /* Get the section header. */
1358 GElf_Shdr shdr_mem;
1359 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1360 if (unlikely (shdr == NULL))
1361 error (EXIT_FAILURE, 0,
1362 gettext ("cannot get section header: %s"),
1363 elf_errmsg (-1));
1364
1365 if (shdr->sh_size > 0
1366 /* Compare allocated sections by VMA, unallocated
1367 sections by file offset. */
1368 && (shdr->sh_flags & SHF_ALLOC
1369 ? (shdr->sh_addr >= phdr->p_vaddr
1370 && (shdr->sh_addr + shdr->sh_size
1371 <= phdr->p_vaddr + phdr->p_memsz))
1372 : (shdr->sh_offset >= phdr->p_offset
1373 && (shdr->sh_offset + shdr->sh_size
1374 <= phdr->p_offset + phdr->p_filesz))))
1375 {
1376 if (has_relro && !in_relro
1377 && shdr->sh_addr >= relro_from
1378 && shdr->sh_addr + shdr->sh_size <= relro_to)
1379 {
1380 fputs_unlocked (" [RELRO:", stdout);
1381 in_relro = true;
1382 }
1383 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1384 {
1385 fputs_unlocked ("]", stdout);
1386 in_relro = false;
1387 }
1388 else if (has_relro && in_relro
1389 && shdr->sh_addr + shdr->sh_size > relro_to)
1390 fputs_unlocked ("] <RELRO:", stdout);
1391 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1392 {
1393 if (!in_ro)
1394 {
1395 fputs_unlocked (" [RO:", stdout);
1396 in_ro = true;
1397 }
1398 }
1399 else
1400 {
1401 /* Determine the segment this section is part of. */
1402 size_t cnt2;
1403 GElf_Phdr phdr2_mem;
1404 GElf_Phdr *phdr2 = NULL;
1405 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1406 {
1407 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1408
1409 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1410 && shdr->sh_addr >= phdr2->p_vaddr
1411 && (shdr->sh_addr + shdr->sh_size
1412 <= phdr2->p_vaddr + phdr2->p_memsz))
1413 break;
1414 }
1415
1416 if (cnt2 < phnum)
1417 {
1418 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1419 {
1420 fputs_unlocked (" [RO:", stdout);
1421 in_ro = true;
1422 }
1423 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1424 {
1425 fputs_unlocked ("]", stdout);
1426 in_ro = false;
1427 }
1428 }
1429 }
1430
1431 printf (" %s",
1432 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1433
1434 /* Signal that this sectin is only partially covered. */
1435 if (has_relro && in_relro
1436 && shdr->sh_addr + shdr->sh_size > relro_to)
1437 {
1438 fputs_unlocked (">", stdout);
1439 in_relro = false;
1440 }
1441 }
1442 }
1443 if (in_relro || in_ro)
1444 fputs_unlocked ("]", stdout);
1445
1446 /* Finish the line. */
1447 fputc_unlocked ('\n', stdout);
1448 }
1449}
1450
1451
1452static const char *
1453section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1454{
1455 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1456}
1457
1458
1459static void
1460handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1461{
1462 /* Get the data of the section. */
1463 Elf_Data *data = elf_getdata (scn, NULL);
1464
1465 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1466 GElf_Shdr symshdr_mem;
1467 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1468 Elf_Data *symdata = elf_getdata (symscn, NULL);
1469
1470 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1471 || symdata == NULL)
1472 return;
1473
1474 /* Get the section header string table index. */
1475 size_t shstrndx;
1476 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1477 error (EXIT_FAILURE, 0,
1478 gettext ("cannot get section header string table index"));
1479
1480 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1481
1482 GElf_Sym sym_mem;
1483 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1484
1485 printf ((grpref[0] & GRP_COMDAT)
1486 ? ngettext ("\
1487\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1488 "\
1489\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1490 data->d_size / sizeof (Elf32_Word) - 1)
1491 : ngettext ("\
1492\nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1493\nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1494 data->d_size / sizeof (Elf32_Word) - 1),
1495 elf_ndxscn (scn),
1496 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1497 (sym == NULL ? NULL
1498 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1499 ?: gettext ("<INVALID SYMBOL>"),
1500 data->d_size / sizeof (Elf32_Word) - 1);
1501
1502 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1503 {
1504 GElf_Shdr grpshdr_mem;
1505 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1506 &grpshdr_mem);
1507
1508 const char *str;
1509 printf (" [%2u] %s\n",
1510 grpref[cnt],
1511 grpshdr != NULL
1512 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1513 ? str : gettext ("<INVALID SECTION>"));
1514 }
1515}
1516
1517
1518static void
1519print_scngrp (Ebl *ebl)
1520{
1521 /* Find all relocation sections and handle them. */
1522 Elf_Scn *scn = NULL;
1523
1524 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1525 {
1526 /* Handle the section if it is a symbol table. */
1527 GElf_Shdr shdr_mem;
1528 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1529
1530 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1531 {
1532 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1533 {
1534 if (elf_compress (scn, 0, 0) < 0)
1535 printf ("WARNING: %s [%zd]\n",
1536 gettext ("Couldn't uncompress section"),
1537 elf_ndxscn (scn));
1538 shdr = gelf_getshdr (scn, &shdr_mem);
1539 if (unlikely (shdr == NULL))
1540 error (EXIT_FAILURE, 0,
1541 gettext ("cannot get section [%zd] header: %s"),
1542 elf_ndxscn (scn),
1543 elf_errmsg (-1));
1544 }
1545 handle_scngrp (ebl, scn, shdr);
1546 }
1547 }
1548}
1549
1550
1551static const struct flags
1552{
1553 int mask;
1554 const char *str;
1555} dt_flags[] =
1556 {
1557 { DF_ORIGIN, "ORIGIN" },
1558 { DF_SYMBOLIC, "SYMBOLIC" },
1559 { DF_TEXTREL, "TEXTREL" },
1560 { DF_BIND_NOW, "BIND_NOW" },
1561 { DF_STATIC_TLS, "STATIC_TLS" }
1562 };
1563static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1564
1565static const struct flags dt_flags_1[] =
1566 {
1567 { DF_1_NOW, "NOW" },
1568 { DF_1_GLOBAL, "GLOBAL" },
1569 { DF_1_GROUP, "GROUP" },
1570 { DF_1_NODELETE, "NODELETE" },
1571 { DF_1_LOADFLTR, "LOADFLTR" },
1572 { DF_1_INITFIRST, "INITFIRST" },
1573 { DF_1_NOOPEN, "NOOPEN" },
1574 { DF_1_ORIGIN, "ORIGIN" },
1575 { DF_1_DIRECT, "DIRECT" },
1576 { DF_1_TRANS, "TRANS" },
1577 { DF_1_INTERPOSE, "INTERPOSE" },
1578 { DF_1_NODEFLIB, "NODEFLIB" },
1579 { DF_1_NODUMP, "NODUMP" },
1580 { DF_1_CONFALT, "CONFALT" },
1581 { DF_1_ENDFILTEE, "ENDFILTEE" },
1582 { DF_1_DISPRELDNE, "DISPRELDNE" },
1583 { DF_1_DISPRELPND, "DISPRELPND" },
1584 };
1585static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1586
1587static const struct flags dt_feature_1[] =
1588 {
1589 { DTF_1_PARINIT, "PARINIT" },
1590 { DTF_1_CONFEXP, "CONFEXP" }
1591 };
1592static const int ndt_feature_1 = (sizeof (dt_feature_1)
1593 / sizeof (dt_feature_1[0]));
1594
1595static const struct flags dt_posflag_1[] =
1596 {
1597 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1598 { DF_P1_GROUPPERM, "GROUPPERM" }
1599 };
1600static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1601 / sizeof (dt_posflag_1[0]));
1602
1603
1604static void
1605print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1606 int nflags)
1607{
1608 bool first = true;
1609 int cnt;
1610
1611 for (cnt = 0; cnt < nflags; ++cnt)
1612 if (d_val & flags[cnt].mask)
1613 {
1614 if (!first)
1615 putchar_unlocked (' ');
1616 fputs_unlocked (flags[cnt].str, stdout);
1617 d_val &= ~flags[cnt].mask;
1618 first = false;
1619 }
1620
1621 if (d_val != 0)
1622 {
1623 if (!first)
1624 putchar_unlocked (' ');
1625 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1626 }
1627
1628 putchar_unlocked ('\n');
1629}
1630
1631
1632static void
1633print_dt_flags (int class, GElf_Xword d_val)
1634{
1635 print_flags (class, d_val, dt_flags, ndt_flags);
1636}
1637
1638
1639static void
1640print_dt_flags_1 (int class, GElf_Xword d_val)
1641{
1642 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1643}
1644
1645
1646static void
1647print_dt_feature_1 (int class, GElf_Xword d_val)
1648{
1649 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1650}
1651
1652
1653static void
1654print_dt_posflag_1 (int class, GElf_Xword d_val)
1655{
1656 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1657}
1658
1659
1660static void
1661handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1662{
1663 int class = gelf_getclass (ebl->elf);
1664 GElf_Shdr glink_mem;
1665 GElf_Shdr *glink;
1666 Elf_Data *data;
1667 size_t cnt;
1668 size_t shstrndx;
1669 size_t sh_entsize;
1670
1671 /* Get the data of the section. */
1672 data = elf_getdata (scn, NULL);
1673 if (data == NULL)
1674 return;
1675
1676 /* Get the section header string table index. */
1677 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1678 error (EXIT_FAILURE, 0,
1679 gettext ("cannot get section header string table index"));
1680
1681 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1682
1683 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1684 if (glink == NULL)
1685 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1686 elf_ndxscn (scn));
1687
1688 printf (ngettext ("\
1689\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1690 "\
1691\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1692 shdr->sh_size / sh_entsize),
1693 (unsigned long int) (shdr->sh_size / sh_entsize),
1694 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1695 shdr->sh_offset,
1696 (int) shdr->sh_link,
1697 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1698 fputs_unlocked (gettext (" Type Value\n"), stdout);
1699
1700 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1701 {
1702 GElf_Dyn dynmem;
1703 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1704 if (dyn == NULL)
1705 break;
1706
1707 char buf[64];
1708 printf (" %-17s ",
1709 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1710
1711 switch (dyn->d_tag)
1712 {
1713 case DT_NULL:
1714 case DT_DEBUG:
1715 case DT_BIND_NOW:
1716 case DT_TEXTREL:
1717 /* No further output. */
1718 fputc_unlocked ('\n', stdout);
1719 break;
1720
1721 case DT_NEEDED:
1722 printf (gettext ("Shared library: [%s]\n"),
1723 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1724 break;
1725
1726 case DT_SONAME:
1727 printf (gettext ("Library soname: [%s]\n"),
1728 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1729 break;
1730
1731 case DT_RPATH:
1732 printf (gettext ("Library rpath: [%s]\n"),
1733 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1734 break;
1735
1736 case DT_RUNPATH:
1737 printf (gettext ("Library runpath: [%s]\n"),
1738 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1739 break;
1740
1741 case DT_PLTRELSZ:
1742 case DT_RELASZ:
1743 case DT_STRSZ:
1744 case DT_RELSZ:
1745 case DT_RELAENT:
1746 case DT_SYMENT:
1747 case DT_RELENT:
1748 case DT_PLTPADSZ:
1749 case DT_MOVEENT:
1750 case DT_MOVESZ:
1751 case DT_INIT_ARRAYSZ:
1752 case DT_FINI_ARRAYSZ:
1753 case DT_SYMINSZ:
1754 case DT_SYMINENT:
1755 case DT_GNU_CONFLICTSZ:
1756 case DT_GNU_LIBLISTSZ:
1757 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1758 break;
1759
1760 case DT_VERDEFNUM:
1761 case DT_VERNEEDNUM:
1762 case DT_RELACOUNT:
1763 case DT_RELCOUNT:
1764 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1765 break;
1766
1767 case DT_PLTREL:;
1768 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1769 NULL, 0);
1770 puts (tagname ?: "???");
1771 break;
1772
1773 case DT_FLAGS:
1774 print_dt_flags (class, dyn->d_un.d_val);
1775 break;
1776
1777 case DT_FLAGS_1:
1778 print_dt_flags_1 (class, dyn->d_un.d_val);
1779 break;
1780
1781 case DT_FEATURE_1:
1782 print_dt_feature_1 (class, dyn->d_un.d_val);
1783 break;
1784
1785 case DT_POSFLAG_1:
1786 print_dt_posflag_1 (class, dyn->d_un.d_val);
1787 break;
1788
1789 default:
1790 printf ("%#0*" PRIx64 "\n",
1791 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1792 break;
1793 }
1794 }
1795}
1796
1797
1798/* Print the dynamic segment. */
1799static void
1800print_dynamic (Ebl *ebl)
1801{
1802 for (size_t i = 0; i < phnum; ++i)
1803 {
1804 GElf_Phdr phdr_mem;
1805 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1806
1807 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1808 {
1809 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1810 GElf_Shdr shdr_mem;
1811 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1812 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1813 handle_dynamic (ebl, scn, shdr);
1814 break;
1815 }
1816 }
1817}
1818
1819
1820/* Print relocations. */
1821static void
1822print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1823{
1824 /* Find all relocation sections and handle them. */
1825 Elf_Scn *scn = NULL;
1826
1827 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1828 {
1829 /* Handle the section if it is a symbol table. */
1830 GElf_Shdr shdr_mem;
1831 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1832
1833 if (likely (shdr != NULL))
1834 {
1835 if (shdr->sh_type == SHT_REL)
1836 handle_relocs_rel (ebl, ehdr, scn, shdr);
1837 else if (shdr->sh_type == SHT_RELA)
1838 handle_relocs_rela (ebl, ehdr, scn, shdr);
1839 }
1840 }
1841}
1842
1843
1844/* Handle a relocation section. */
1845static void
1846handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1847{
1848 int class = gelf_getclass (ebl->elf);
1849 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1850 int nentries = shdr->sh_size / sh_entsize;
1851
1852 /* Get the data of the section. */
1853 Elf_Data *data = elf_getdata (scn, NULL);
1854 if (data == NULL)
1855 return;
1856
1857 /* Get the symbol table information. */
1858 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1859 GElf_Shdr symshdr_mem;
1860 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1861 Elf_Data *symdata = elf_getdata (symscn, NULL);
1862
1863 /* Get the section header of the section the relocations are for. */
1864 GElf_Shdr destshdr_mem;
1865 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1866 &destshdr_mem);
1867
1868 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1869 {
1870 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1871 shdr->sh_offset);
1872 return;
1873 }
1874
1875 /* Search for the optional extended section index table. */
1876 Elf_Data *xndxdata = NULL;
1877 int xndxscnidx = elf_scnshndx (scn);
1878 if (unlikely (xndxscnidx > 0))
1879 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1880
1881 /* Get the section header string table index. */
1882 size_t shstrndx;
1883 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1884 error (EXIT_FAILURE, 0,
1885 gettext ("cannot get section header string table index"));
1886
1887 if (shdr->sh_info != 0)
1888 printf (ngettext ("\
1889\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1890 "\
1891\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1892 nentries),
1893 elf_ndxscn (scn),
1894 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1895 (unsigned int) shdr->sh_info,
1896 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1897 shdr->sh_offset,
1898 nentries);
1899 else
1900 /* The .rel.dyn section does not refer to a specific section but
1901 instead of section index zero. Do not try to print a section
1902 name. */
1903 printf (ngettext ("\
1904\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1905 "\
1906\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1907 nentries),
1908 (unsigned int) elf_ndxscn (scn),
1909 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1910 shdr->sh_offset,
1911 nentries);
1912 fputs_unlocked (class == ELFCLASS32
1913 ? gettext ("\
1914 Offset Type Value Name\n")
1915 : gettext ("\
1916 Offset Type Value Name\n"),
1917 stdout);
1918
1919 int is_statically_linked = 0;
1920 for (int cnt = 0; cnt < nentries; ++cnt)
1921 {
1922 GElf_Rel relmem;
1923 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1924 if (likely (rel != NULL))
1925 {
1926 char buf[128];
1927 GElf_Sym symmem;
1928 Elf32_Word xndx;
1929 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1930 GELF_R_SYM (rel->r_info),
1931 &symmem, &xndx);
1932 if (unlikely (sym == NULL))
1933 {
1934 /* As a special case we have to handle relocations in static
1935 executables. This only happens for IRELATIVE relocations
1936 (so far). There is no symbol table. */
1937 if (is_statically_linked == 0)
1938 {
1939 /* Find the program header and look for a PT_INTERP entry. */
1940 is_statically_linked = -1;
1941 if (ehdr->e_type == ET_EXEC)
1942 {
1943 is_statically_linked = 1;
1944
1945 for (size_t inner = 0; inner < phnum; ++inner)
1946 {
1947 GElf_Phdr phdr_mem;
1948 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1949 &phdr_mem);
1950 if (phdr != NULL && phdr->p_type == PT_INTERP)
1951 {
1952 is_statically_linked = -1;
1953 break;
1954 }
1955 }
1956 }
1957 }
1958
1959 if (is_statically_linked > 0 && shdr->sh_link == 0)
1960 printf ("\
1961 %#0*" PRIx64 " %-20s %*s %s\n",
1962 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1963 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1964 /* Avoid the leading R_ which isn't carrying any
1965 information. */
1966 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1967 buf, sizeof (buf)) + 2
1968 : gettext ("<INVALID RELOC>"),
1969 class == ELFCLASS32 ? 10 : 18, "",
1970 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1971 else
1972 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1973 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1974 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1975 /* Avoid the leading R_ which isn't carrying any
1976 information. */
1977 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1978 buf, sizeof (buf)) + 2
1979 : gettext ("<INVALID RELOC>"),
1980 gettext ("INVALID SYMBOL"),
1981 (long int) GELF_R_SYM (rel->r_info));
1982 }
1983 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1984 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1985 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1986 likely (ebl_reloc_type_check (ebl,
1987 GELF_R_TYPE (rel->r_info)))
1988 /* Avoid the leading R_ which isn't carrying any
1989 information. */
1990 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1991 buf, sizeof (buf)) + 2
1992 : gettext ("<INVALID RELOC>"),
1993 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1994 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1995 else
1996 {
1997 /* This is a relocation against a STT_SECTION symbol. */
1998 GElf_Shdr secshdr_mem;
1999 GElf_Shdr *secshdr;
2000 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2001 sym->st_shndx == SHN_XINDEX
2002 ? xndx : sym->st_shndx),
2003 &secshdr_mem);
2004
2005 if (unlikely (secshdr == NULL))
2006 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2007 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2008 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2009 /* Avoid the leading R_ which isn't carrying any
2010 information. */
2011 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2012 buf, sizeof (buf)) + 2
2013 : gettext ("<INVALID RELOC>"),
2014 gettext ("INVALID SECTION"),
2015 (long int) (sym->st_shndx == SHN_XINDEX
2016 ? xndx : sym->st_shndx));
2017 else
2018 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2019 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2020 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2021 /* Avoid the leading R_ which isn't carrying any
2022 information. */
2023 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2024 buf, sizeof (buf)) + 2
2025 : gettext ("<INVALID RELOC>"),
2026 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2027 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2028 }
2029 }
2030 }
2031}
2032
2033
2034/* Handle a relocation section. */
2035static void
2036handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2037{
2038 int class = gelf_getclass (ebl->elf);
2039 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2040 int nentries = shdr->sh_size / sh_entsize;
2041
2042 /* Get the data of the section. */
2043 Elf_Data *data = elf_getdata (scn, NULL);
2044 if (data == NULL)
2045 return;
2046
2047 /* Get the symbol table information. */
2048 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2049 GElf_Shdr symshdr_mem;
2050 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2051 Elf_Data *symdata = elf_getdata (symscn, NULL);
2052
2053 /* Get the section header of the section the relocations are for. */
2054 GElf_Shdr destshdr_mem;
2055 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2056 &destshdr_mem);
2057
2058 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2059 {
2060 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2061 shdr->sh_offset);
2062 return;
2063 }
2064
2065 /* Search for the optional extended section index table. */
2066 Elf_Data *xndxdata = NULL;
2067 int xndxscnidx = elf_scnshndx (scn);
2068 if (unlikely (xndxscnidx > 0))
2069 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2070
2071 /* Get the section header string table index. */
2072 size_t shstrndx;
2073 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2074 error (EXIT_FAILURE, 0,
2075 gettext ("cannot get section header string table index"));
2076
2077 if (shdr->sh_info != 0)
2078 printf (ngettext ("\
2079\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2080 "\
2081\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2082 nentries),
2083 elf_ndxscn (scn),
2084 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2085 (unsigned int) shdr->sh_info,
2086 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2087 shdr->sh_offset,
2088 nentries);
2089 else
2090 /* The .rela.dyn section does not refer to a specific section but
2091 instead of section index zero. Do not try to print a section
2092 name. */
2093 printf (ngettext ("\
2094\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2095 "\
2096\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2097 nentries),
2098 (unsigned int) elf_ndxscn (scn),
2099 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2100 shdr->sh_offset,
2101 nentries);
2102 fputs_unlocked (class == ELFCLASS32
2103 ? gettext ("\
2104 Offset Type Value Addend Name\n")
2105 : gettext ("\
2106 Offset Type Value Addend Name\n"),
2107 stdout);
2108
2109 int is_statically_linked = 0;
2110 for (int cnt = 0; cnt < nentries; ++cnt)
2111 {
2112 GElf_Rela relmem;
2113 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2114 if (likely (rel != NULL))
2115 {
2116 char buf[64];
2117 GElf_Sym symmem;
2118 Elf32_Word xndx;
2119 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2120 GELF_R_SYM (rel->r_info),
2121 &symmem, &xndx);
2122
2123 if (unlikely (sym == NULL))
2124 {
2125 /* As a special case we have to handle relocations in static
2126 executables. This only happens for IRELATIVE relocations
2127 (so far). There is no symbol table. */
2128 if (is_statically_linked == 0)
2129 {
2130 /* Find the program header and look for a PT_INTERP entry. */
2131 is_statically_linked = -1;
2132 if (ehdr->e_type == ET_EXEC)
2133 {
2134 is_statically_linked = 1;
2135
2136 for (size_t inner = 0; inner < phnum; ++inner)
2137 {
2138 GElf_Phdr phdr_mem;
2139 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2140 &phdr_mem);
2141 if (phdr != NULL && phdr->p_type == PT_INTERP)
2142 {
2143 is_statically_linked = -1;
2144 break;
2145 }
2146 }
2147 }
2148 }
2149
2150 if (is_statically_linked > 0 && shdr->sh_link == 0)
2151 printf ("\
2152 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2153 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2154 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2155 /* Avoid the leading R_ which isn't carrying any
2156 information. */
2157 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2158 buf, sizeof (buf)) + 2
2159 : gettext ("<INVALID RELOC>"),
2160 class == ELFCLASS32 ? 10 : 18, "",
2161 rel->r_addend,
2162 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2163 else
2164 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2165 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2166 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2167 /* Avoid the leading R_ which isn't carrying any
2168 information. */
2169 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2170 buf, sizeof (buf)) + 2
2171 : gettext ("<INVALID RELOC>"),
2172 gettext ("INVALID SYMBOL"),
2173 (long int) GELF_R_SYM (rel->r_info));
2174 }
2175 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2176 printf ("\
2177 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2178 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2179 likely (ebl_reloc_type_check (ebl,
2180 GELF_R_TYPE (rel->r_info)))
2181 /* Avoid the leading R_ which isn't carrying any
2182 information. */
2183 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2184 buf, sizeof (buf)) + 2
2185 : gettext ("<INVALID RELOC>"),
2186 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2187 rel->r_addend,
2188 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2189 else
2190 {
2191 /* This is a relocation against a STT_SECTION symbol. */
2192 GElf_Shdr secshdr_mem;
2193 GElf_Shdr *secshdr;
2194 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2195 sym->st_shndx == SHN_XINDEX
2196 ? xndx : sym->st_shndx),
2197 &secshdr_mem);
2198
2199 if (unlikely (secshdr == NULL))
2200 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2201 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2202 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2203 /* Avoid the leading R_ which isn't carrying any
2204 information. */
2205 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2206 buf, sizeof (buf)) + 2
2207 : gettext ("<INVALID RELOC>"),
2208 gettext ("INVALID SECTION"),
2209 (long int) (sym->st_shndx == SHN_XINDEX
2210 ? xndx : sym->st_shndx));
2211 else
2212 printf ("\
2213 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2214 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2215 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2216 /* Avoid the leading R_ which isn't carrying any
2217 information. */
2218 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2219 buf, sizeof (buf)) + 2
2220 : gettext ("<INVALID RELOC>"),
2221 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2222 rel->r_addend,
2223 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2224 }
2225 }
2226 }
2227}
2228
2229
2230/* Print the program header. */
2231static void
2232print_symtab (Ebl *ebl, int type)
2233{
2234 /* Find the symbol table(s). For this we have to search through the
2235 section table. */
2236 Elf_Scn *scn = NULL;
2237
2238 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2239 {
2240 /* Handle the section if it is a symbol table. */
2241 GElf_Shdr shdr_mem;
2242 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2243
2244 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2245 {
2246 if (symbol_table_section != NULL)
2247 {
2248 /* Get the section header string table index. */
2249 size_t shstrndx;
2250 const char *sname;
2251 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2252 error (EXIT_FAILURE, 0,
2253 gettext ("cannot get section header string table index"));
2254 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2255 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2256 continue;
2257 }
2258
2259 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2260 {
2261 if (elf_compress (scn, 0, 0) < 0)
2262 printf ("WARNING: %s [%zd]\n",
2263 gettext ("Couldn't uncompress section"),
2264 elf_ndxscn (scn));
2265 shdr = gelf_getshdr (scn, &shdr_mem);
2266 if (unlikely (shdr == NULL))
2267 error (EXIT_FAILURE, 0,
2268 gettext ("cannot get section [%zd] header: %s"),
2269 elf_ndxscn (scn), elf_errmsg (-1));
2270 }
2271 handle_symtab (ebl, scn, shdr);
2272 }
2273 }
2274}
2275
2276
2277static void
2278handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2279{
2280 Elf_Data *versym_data = NULL;
2281 Elf_Data *verneed_data = NULL;
2282 Elf_Data *verdef_data = NULL;
2283 Elf_Data *xndx_data = NULL;
2284 int class = gelf_getclass (ebl->elf);
2285 Elf32_Word verneed_stridx = 0;
2286 Elf32_Word verdef_stridx = 0;
2287
2288 /* Get the data of the section. */
2289 Elf_Data *data = elf_getdata (scn, NULL);
2290 if (data == NULL)
2291 return;
2292
2293 /* Find out whether we have other sections we might need. */
2294 Elf_Scn *runscn = NULL;
2295 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2296 {
2297 GElf_Shdr runshdr_mem;
2298 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2299
2300 if (likely (runshdr != NULL))
2301 {
2302 if (runshdr->sh_type == SHT_GNU_versym
2303 && runshdr->sh_link == elf_ndxscn (scn))
2304 /* Bingo, found the version information. Now get the data. */
2305 versym_data = elf_getdata (runscn, NULL);
2306 else if (runshdr->sh_type == SHT_GNU_verneed)
2307 {
2308 /* This is the information about the needed versions. */
2309 verneed_data = elf_getdata (runscn, NULL);
2310 verneed_stridx = runshdr->sh_link;
2311 }
2312 else if (runshdr->sh_type == SHT_GNU_verdef)
2313 {
2314 /* This is the information about the defined versions. */
2315 verdef_data = elf_getdata (runscn, NULL);
2316 verdef_stridx = runshdr->sh_link;
2317 }
2318 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2319 && runshdr->sh_link == elf_ndxscn (scn))
2320 /* Extended section index. */
2321 xndx_data = elf_getdata (runscn, NULL);
2322 }
2323 }
2324
2325 /* Get the section header string table index. */
2326 size_t shstrndx;
2327 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2328 error (EXIT_FAILURE, 0,
2329 gettext ("cannot get section header string table index"));
2330
2331 GElf_Shdr glink_mem;
2332 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2333 &glink_mem);
2334 if (glink == NULL)
2335 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2336 elf_ndxscn (scn));
2337
2338 /* Now we can compute the number of entries in the section. */
2339 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2340 ? sizeof (Elf32_Sym)
2341 : sizeof (Elf64_Sym));
2342
2343 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2344 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2345 nsyms),
2346 (unsigned int) elf_ndxscn (scn),
2347 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2348 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2349 " %lu local symbols String table: [%2u] '%s'\n",
2350 shdr->sh_info),
2351 (unsigned long int) shdr->sh_info,
2352 (unsigned int) shdr->sh_link,
2353 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2354
2355 fputs_unlocked (class == ELFCLASS32
2356 ? gettext ("\
2357 Num: Value Size Type Bind Vis Ndx Name\n")
2358 : gettext ("\
2359 Num: Value Size Type Bind Vis Ndx Name\n"),
2360 stdout);
2361
2362 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2363 {
2364 char typebuf[64];
2365 char bindbuf[64];
2366 char scnbuf[64];
2367 Elf32_Word xndx;
2368 GElf_Sym sym_mem;
2369 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2370
2371 if (unlikely (sym == NULL))
2372 continue;
2373
2374 /* Determine the real section index. */
2375 if (likely (sym->st_shndx != SHN_XINDEX))
2376 xndx = sym->st_shndx;
2377
2378 printf (gettext ("\
2379%5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2380 cnt,
2381 class == ELFCLASS32 ? 8 : 16,
2382 sym->st_value,
2383 sym->st_size,
2384 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2385 typebuf, sizeof (typebuf)),
2386 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2387 bindbuf, sizeof (bindbuf)),
2388 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2389 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2390 sizeof (scnbuf), NULL, shnum),
2391 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2392
2393 if (versym_data != NULL)
2394 {
2395 /* Get the version information. */
2396 GElf_Versym versym_mem;
2397 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2398
2399 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2400 {
2401 bool is_nobits = false;
2402 bool check_def = xndx != SHN_UNDEF;
2403
2404 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2405 {
2406 GElf_Shdr symshdr_mem;
2407 GElf_Shdr *symshdr =
2408 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2409
2410 is_nobits = (symshdr != NULL
2411 && symshdr->sh_type == SHT_NOBITS);
2412 }
2413
2414 if (is_nobits || ! check_def)
2415 {
2416 /* We must test both. */
2417 GElf_Vernaux vernaux_mem;
2418 GElf_Vernaux *vernaux = NULL;
2419 size_t vn_offset = 0;
2420
2421 GElf_Verneed verneed_mem;
2422 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2423 &verneed_mem);
2424 while (verneed != NULL)
2425 {
2426 size_t vna_offset = vn_offset;
2427
2428 vernaux = gelf_getvernaux (verneed_data,
2429 vna_offset += verneed->vn_aux,
2430 &vernaux_mem);
2431 while (vernaux != NULL
2432 && vernaux->vna_other != *versym
2433 && vernaux->vna_next != 0)
2434 {
2435 /* Update the offset. */
2436 vna_offset += vernaux->vna_next;
2437
2438 vernaux = (vernaux->vna_next == 0
2439 ? NULL
2440 : gelf_getvernaux (verneed_data,
2441 vna_offset,
2442 &vernaux_mem));
2443 }
2444
2445 /* Check whether we found the version. */
2446 if (vernaux != NULL && vernaux->vna_other == *versym)
2447 /* Found it. */
2448 break;
2449
2450 vn_offset += verneed->vn_next;
2451 verneed = (verneed->vn_next == 0
2452 ? NULL
2453 : gelf_getverneed (verneed_data, vn_offset,
2454 &verneed_mem));
2455 }
2456
2457 if (vernaux != NULL && vernaux->vna_other == *versym)
2458 {
2459 printf ("@%s (%u)",
2460 elf_strptr (ebl->elf, verneed_stridx,
2461 vernaux->vna_name),
2462 (unsigned int) vernaux->vna_other);
2463 check_def = 0;
2464 }
2465 else if (unlikely (! is_nobits))
2466 error (0, 0, gettext ("bad dynamic symbol"));
2467 else
2468 check_def = 1;
2469 }
2470
2471 if (check_def && *versym != 0x8001)
2472 {
2473 /* We must test both. */
2474 size_t vd_offset = 0;
2475
2476 GElf_Verdef verdef_mem;
2477 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2478 &verdef_mem);
2479 while (verdef != NULL)
2480 {
2481 if (verdef->vd_ndx == (*versym & 0x7fff))
2482 /* Found the definition. */
2483 break;
2484
2485 vd_offset += verdef->vd_next;
2486 verdef = (verdef->vd_next == 0
2487 ? NULL
2488 : gelf_getverdef (verdef_data, vd_offset,
2489 &verdef_mem));
2490 }
2491
2492 if (verdef != NULL)
2493 {
2494 GElf_Verdaux verdaux_mem;
2495 GElf_Verdaux *verdaux
2496 = gelf_getverdaux (verdef_data,
2497 vd_offset + verdef->vd_aux,
2498 &verdaux_mem);
2499
2500 if (verdaux != NULL)
2501 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2502 elf_strptr (ebl->elf, verdef_stridx,
2503 verdaux->vda_name));
2504 }
2505 }
2506 }
2507 }
2508
2509 putchar_unlocked ('\n');
2510 }
2511}
2512
2513
2514/* Print version information. */
2515static void
2516print_verinfo (Ebl *ebl)
2517{
2518 /* Find the version information sections. For this we have to
2519 search through the section table. */
2520 Elf_Scn *scn = NULL;
2521
2522 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2523 {
2524 /* Handle the section if it is part of the versioning handling. */
2525 GElf_Shdr shdr_mem;
2526 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2527
2528 if (likely (shdr != NULL))
2529 {
2530 if (shdr->sh_type == SHT_GNU_verneed)
2531 handle_verneed (ebl, scn, shdr);
2532 else if (shdr->sh_type == SHT_GNU_verdef)
2533 handle_verdef (ebl, scn, shdr);
2534 else if (shdr->sh_type == SHT_GNU_versym)
2535 handle_versym (ebl, scn, shdr);
2536 }
2537 }
2538}
2539
2540
2541static const char *
2542get_ver_flags (unsigned int flags)
2543{
2544 static char buf[32];
2545 char *endp;
2546
2547 if (flags == 0)
2548 return gettext ("none");
2549
2550 if (flags & VER_FLG_BASE)
2551 endp = stpcpy (buf, "BASE ");
2552 else
2553 endp = buf;
2554
2555 if (flags & VER_FLG_WEAK)
2556 {
2557 if (endp != buf)
2558 endp = stpcpy (endp, "| ");
2559
2560 endp = stpcpy (endp, "WEAK ");
2561 }
2562
2563 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2564 {
2565 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2566 buf[sizeof (buf) - 1] = '\0';
2567 }
2568
2569 return buf;
2570}
2571
2572
2573static void
2574handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2575{
2576 int class = gelf_getclass (ebl->elf);
2577
2578 /* Get the data of the section. */
2579 Elf_Data *data = elf_getdata (scn, NULL);
2580 if (data == NULL)
2581 return;
2582
2583 /* Get the section header string table index. */
2584 size_t shstrndx;
2585 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2586 error (EXIT_FAILURE, 0,
2587 gettext ("cannot get section header string table index"));
2588
2589 GElf_Shdr glink_mem;
2590 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2591 &glink_mem);
2592 if (glink == NULL)
2593 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2594 elf_ndxscn (scn));
2595
2596 printf (ngettext ("\
2597\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2598 "\
2599\nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2600 shdr->sh_info),
2601 (unsigned int) elf_ndxscn (scn),
2602 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2603 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2604 shdr->sh_offset,
2605 (unsigned int) shdr->sh_link,
2606 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2607
2608 unsigned int offset = 0;
2609 for (int cnt = shdr->sh_info; --cnt >= 0; )
2610 {
2611 /* Get the data at the next offset. */
2612 GElf_Verneed needmem;
2613 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2614 if (unlikely (need == NULL))
2615 break;
2616
2617 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2618 offset, (unsigned short int) need->vn_version,
2619 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2620 (unsigned short int) need->vn_cnt);
2621
2622 unsigned int auxoffset = offset + need->vn_aux;
2623 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2624 {
2625 GElf_Vernaux auxmem;
2626 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2627 if (unlikely (aux == NULL))
2628 break;
2629
2630 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2631 auxoffset,
2632 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2633 get_ver_flags (aux->vna_flags),
2634 (unsigned short int) aux->vna_other);
2635
2636 if (aux->vna_next == 0)
2637 break;
2638
2639 auxoffset += aux->vna_next;
2640 }
2641
2642 /* Find the next offset. */
2643 if (need->vn_next == 0)
2644 break;
2645
2646 offset += need->vn_next;
2647 }
2648}
2649
2650
2651static void
2652handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2653{
2654 /* Get the data of the section. */
2655 Elf_Data *data = elf_getdata (scn, NULL);
2656 if (data == NULL)
2657 return;
2658
2659 /* Get the section header string table index. */
2660 size_t shstrndx;
2661 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2662 error (EXIT_FAILURE, 0,
2663 gettext ("cannot get section header string table index"));
2664
2665 GElf_Shdr glink_mem;
2666 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2667 &glink_mem);
2668 if (glink == NULL)
2669 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2670 elf_ndxscn (scn));
2671
2672 int class = gelf_getclass (ebl->elf);
2673 printf (ngettext ("\
2674\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2675 "\
2676\nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2677 shdr->sh_info),
2678 (unsigned int) elf_ndxscn (scn),
2679 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2680 shdr->sh_info,
2681 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2682 shdr->sh_offset,
2683 (unsigned int) shdr->sh_link,
2684 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2685
2686 unsigned int offset = 0;
2687 for (int cnt = shdr->sh_info; --cnt >= 0; )
2688 {
2689 /* Get the data at the next offset. */
2690 GElf_Verdef defmem;
2691 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2692 if (unlikely (def == NULL))
2693 break;
2694
2695 unsigned int auxoffset = offset + def->vd_aux;
2696 GElf_Verdaux auxmem;
2697 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2698 if (unlikely (aux == NULL))
2699 break;
2700
2701 printf (gettext ("\
2702 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2703 offset, def->vd_version,
2704 get_ver_flags (def->vd_flags),
2705 def->vd_ndx,
2706 def->vd_cnt,
2707 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2708
2709 auxoffset += aux->vda_next;
2710 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2711 {
2712 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2713 if (unlikely (aux == NULL))
2714 break;
2715
2716 printf (gettext (" %#06x: Parent %d: %s\n"),
2717 auxoffset, cnt2,
2718 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2719
2720 if (aux->vda_next == 0)
2721 break;
2722
2723 auxoffset += aux->vda_next;
2724 }
2725
2726 /* Find the next offset. */
2727 if (def->vd_next == 0)
2728 break;
2729 offset += def->vd_next;
2730 }
2731}
2732
2733
2734static void
2735handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2736{
2737 int class = gelf_getclass (ebl->elf);
2738 const char **vername;
2739 const char **filename;
2740
2741 /* Get the data of the section. */
2742 Elf_Data *data = elf_getdata (scn, NULL);
2743 if (data == NULL)
2744 return;
2745
2746 /* Get the section header string table index. */
2747 size_t shstrndx;
2748 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2749 error (EXIT_FAILURE, 0,
2750 gettext ("cannot get section header string table index"));
2751
2752 /* We have to find the version definition section and extract the
2753 version names. */
2754 Elf_Scn *defscn = NULL;
2755 Elf_Scn *needscn = NULL;
2756
2757 Elf_Scn *verscn = NULL;
2758 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2759 {
2760 GElf_Shdr vershdr_mem;
2761 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2762
2763 if (likely (vershdr != NULL))
2764 {
2765 if (vershdr->sh_type == SHT_GNU_verdef)
2766 defscn = verscn;
2767 else if (vershdr->sh_type == SHT_GNU_verneed)
2768 needscn = verscn;
2769 }
2770 }
2771
2772 size_t nvername;
2773 if (defscn != NULL || needscn != NULL)
2774 {
2775 /* We have a version information (better should have). Now get
2776 the version names. First find the maximum version number. */
2777 nvername = 0;
2778 if (defscn != NULL)
2779 {
2780 /* Run through the version definitions and find the highest
2781 index. */
2782 unsigned int offset = 0;
2783 Elf_Data *defdata;
2784 GElf_Shdr defshdrmem;
2785 GElf_Shdr *defshdr;
2786
2787 defdata = elf_getdata (defscn, NULL);
2788 if (unlikely (defdata == NULL))
2789 return;
2790
2791 defshdr = gelf_getshdr (defscn, &defshdrmem);
2792 if (unlikely (defshdr == NULL))
2793 return;
2794
2795 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2796 {
2797 GElf_Verdef defmem;
2798 GElf_Verdef *def;
2799
2800 /* Get the data at the next offset. */
2801 def = gelf_getverdef (defdata, offset, &defmem);
2802 if (unlikely (def == NULL))
2803 break;
2804
2805 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2806
2807 if (def->vd_next == 0)
2808 break;
2809 offset += def->vd_next;
2810 }
2811 }
2812 if (needscn != NULL)
2813 {
2814 unsigned int offset = 0;
2815 Elf_Data *needdata;
2816 GElf_Shdr needshdrmem;
2817 GElf_Shdr *needshdr;
2818
2819 needdata = elf_getdata (needscn, NULL);
2820 if (unlikely (needdata == NULL))
2821 return;
2822
2823 needshdr = gelf_getshdr (needscn, &needshdrmem);
2824 if (unlikely (needshdr == NULL))
2825 return;
2826
2827 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2828 {
2829 GElf_Verneed needmem;
2830 GElf_Verneed *need;
2831 unsigned int auxoffset;
2832 int cnt2;
2833
2834 /* Get the data at the next offset. */
2835 need = gelf_getverneed (needdata, offset, &needmem);
2836 if (unlikely (need == NULL))
2837 break;
2838
2839 /* Run through the auxiliary entries. */
2840 auxoffset = offset + need->vn_aux;
2841 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2842 {
2843 GElf_Vernaux auxmem;
2844 GElf_Vernaux *aux;
2845
2846 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2847 if (unlikely (aux == NULL))
2848 break;
2849
2850 nvername = MAX (nvername,
2851 (size_t) (aux->vna_other & 0x7fff));
2852
2853 if (aux->vna_next == 0)
2854 break;
2855 auxoffset += aux->vna_next;
2856 }
2857
2858 if (need->vn_next == 0)
2859 break;
2860 offset += need->vn_next;
2861 }
2862 }
2863
2864 /* This is the number of versions we know about. */
2865 ++nvername;
2866
2867 /* Allocate the array. */
2868 vername = (const char **) alloca (nvername * sizeof (const char *));
2869 memset(vername, 0, nvername * sizeof (const char *));
2870 filename = (const char **) alloca (nvername * sizeof (const char *));
2871 memset(filename, 0, nvername * sizeof (const char *));
2872
2873 /* Run through the data structures again and collect the strings. */
2874 if (defscn != NULL)
2875 {
2876 /* Run through the version definitions and find the highest
2877 index. */
2878 unsigned int offset = 0;
2879 Elf_Data *defdata;
2880 GElf_Shdr defshdrmem;
2881 GElf_Shdr *defshdr;
2882
2883 defdata = elf_getdata (defscn, NULL);
2884 if (unlikely (defdata == NULL))
2885 return;
2886
2887 defshdr = gelf_getshdr (defscn, &defshdrmem);
2888 if (unlikely (defshdr == NULL))
2889 return;
2890
2891 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2892 {
2893
2894 /* Get the data at the next offset. */
2895 GElf_Verdef defmem;
2896 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2897 if (unlikely (def == NULL))
2898 break;
2899
2900 GElf_Verdaux auxmem;
2901 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2902 offset + def->vd_aux,
2903 &auxmem);
2904 if (unlikely (aux == NULL))
2905 break;
2906
2907 vername[def->vd_ndx & 0x7fff]
2908 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2909 filename[def->vd_ndx & 0x7fff] = NULL;
2910
2911 if (def->vd_next == 0)
2912 break;
2913 offset += def->vd_next;
2914 }
2915 }
2916 if (needscn != NULL)
2917 {
2918 unsigned int offset = 0;
2919
2920 Elf_Data *needdata = elf_getdata (needscn, NULL);
2921 GElf_Shdr needshdrmem;
2922 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2923 if (unlikely (needdata == NULL || needshdr == NULL))
2924 return;
2925
2926 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2927 {
2928 /* Get the data at the next offset. */
2929 GElf_Verneed needmem;
2930 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2931 &needmem);
2932 if (unlikely (need == NULL))
2933 break;
2934
2935 /* Run through the auxiliary entries. */
2936 unsigned int auxoffset = offset + need->vn_aux;
2937 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2938 {
2939 GElf_Vernaux auxmem;
2940 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2941 &auxmem);
2942 if (unlikely (aux == NULL))
2943 break;
2944
2945 vername[aux->vna_other & 0x7fff]
2946 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2947 filename[aux->vna_other & 0x7fff]
2948 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2949
2950 if (aux->vna_next == 0)
2951 break;
2952 auxoffset += aux->vna_next;
2953 }
2954
2955 if (need->vn_next == 0)
2956 break;
2957 offset += need->vn_next;
2958 }
2959 }
2960 }
2961 else
2962 {
2963 vername = NULL;
2964 nvername = 1;
2965 filename = NULL;
2966 }
2967
2968 GElf_Shdr glink_mem;
2969 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2970 &glink_mem);
2971 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2972 if (glink == NULL)
2973 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2974 elf_ndxscn (scn));
2975
2976 /* Print the header. */
2977 printf (ngettext ("\
2978\nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2979 "\
2980\nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2981 shdr->sh_size / sh_entsize),
2982 (unsigned int) elf_ndxscn (scn),
2983 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2984 (int) (shdr->sh_size / sh_entsize),
2985 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2986 shdr->sh_offset,
2987 (unsigned int) shdr->sh_link,
2988 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2989
2990 /* Now we can finally look at the actual contents of this section. */
2991 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2992 {
2993 if (cnt % 2 == 0)
2994 printf ("\n %4d:", cnt);
2995
2996 GElf_Versym symmem;
2997 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2998 if (sym == NULL)
2999 break;
3000
3001 switch (*sym)
3002 {
3003 ssize_t n;
3004 case 0:
3005 fputs_unlocked (gettext (" 0 *local* "),
3006 stdout);
3007 break;
3008
3009 case 1:
3010 fputs_unlocked (gettext (" 1 *global* "),
3011 stdout);
3012 break;
3013
3014 default:
3015 n = printf ("%4d%c%s",
3016 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3017 (vername != NULL
3018 && (unsigned int) (*sym & 0x7fff) < nvername)
3019 ? vername[*sym & 0x7fff] : "???");
3020 if ((unsigned int) (*sym & 0x7fff) < nvername
3021 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3022 n += printf ("(%s)", filename[*sym & 0x7fff]);
3023 printf ("%*s", MAX (0, 33 - (int) n), " ");
3024 break;
3025 }
3026 }
3027 putchar_unlocked ('\n');
3028}
3029
3030
3031static void
3032print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3033 uint_fast32_t maxlength, Elf32_Word nbucket,
3034 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3035{
3036 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3037
3038 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3039 ++counts[lengths[cnt]];
3040
3041 GElf_Shdr glink_mem;
3042 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3043 shdr->sh_link),
3044 &glink_mem);
3045 if (glink == NULL)
3046 {
3047 error (0, 0, gettext ("invalid sh_link value in section %zu"),
3048 elf_ndxscn (scn));
3049 return;
3050 }
3051
3052 printf (ngettext ("\
3053\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3054 "\
3055\nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3056 nbucket),
3057 (unsigned int) elf_ndxscn (scn),
3058 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3059 (int) nbucket,
3060 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3061 shdr->sh_addr,
3062 shdr->sh_offset,
3063 (unsigned int) shdr->sh_link,
3064 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3065
3066 if (extrastr != NULL)
3067 fputs (extrastr, stdout);
3068
3069 if (likely (nbucket > 0))
3070 {
3071 uint64_t success = 0;
3072
3073 /* xgettext:no-c-format */
3074 fputs_unlocked (gettext ("\
3075 Length Number % of total Coverage\n"), stdout);
3076 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
3077 counts[0], (counts[0] * 100.0) / nbucket);
3078
3079 uint64_t nzero_counts = 0;
3080 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3081 {
3082 nzero_counts += counts[cnt] * cnt;
3083 printf (gettext ("\
3084%7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3085 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3086 (nzero_counts * 100.0) / nsyms);
3087 }
3088
3089 Elf32_Word acc = 0;
3090 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3091 {
3092 acc += cnt;
3093 success += counts[cnt] * acc;
3094 }
3095
3096 printf (gettext ("\
3097 Average number of tests: successful lookup: %f\n\
3098 unsuccessful lookup: %f\n"),
3099 (double) success / (double) nzero_counts,
3100 (double) nzero_counts / (double) nbucket);
3101 }
3102
3103 free (counts);
3104}
3105
3106
3107/* This function handles the traditional System V-style hash table format. */
3108static void
3109handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3110{
3111 Elf_Data *data = elf_getdata (scn, NULL);
3112 if (unlikely (data == NULL))
3113 {
3114 error (0, 0, gettext ("cannot get data for section %d: %s"),
3115 (int) elf_ndxscn (scn), elf_errmsg (-1));
3116 return;
3117 }
3118
3119 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3120 {
3121 invalid_data:
3122 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3123 (int) elf_ndxscn (scn));
3124 return;
3125 }
3126
3127 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3128 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3129
3130 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3131 if (used_buf > data->d_size)
3132 goto invalid_data;
3133
3134 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3135 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3136
3137 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3138
3139 uint_fast32_t maxlength = 0;
3140 uint_fast32_t nsyms = 0;
3141 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3142 {
3143 Elf32_Word inner = bucket[cnt];
3144 while (inner > 0 && inner < nchain)
3145 {
3146 ++nsyms;
3147 if (maxlength < ++lengths[cnt])
3148 ++maxlength;
3149
3150 inner = chain[inner];
3151 }
3152 }
3153
3154 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3155 lengths, NULL);
3156
3157 free (lengths);
3158}
3159
3160
3161/* This function handles the incorrect, System V-style hash table
3162 format some 64-bit architectures use. */
3163static void
3164handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3165{
3166 Elf_Data *data = elf_getdata (scn, NULL);
3167 if (unlikely (data == NULL))
3168 {
3169 error (0, 0, gettext ("cannot get data for section %d: %s"),
3170 (int) elf_ndxscn (scn), elf_errmsg (-1));
3171 return;
3172 }
3173
3174 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3175 {
3176 invalid_data:
3177 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3178 (int) elf_ndxscn (scn));
3179 return;
3180 }
3181
3182 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3183 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3184
3185 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3186 if (maxwords < 2
3187 || maxwords - 2 < nbucket
3188 || maxwords - 2 - nbucket < nchain)
3189 goto invalid_data;
3190
3191 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3192 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3193
3194 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3195
3196 uint_fast32_t maxlength = 0;
3197 uint_fast32_t nsyms = 0;
3198 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3199 {
3200 Elf64_Xword inner = bucket[cnt];
3201 while (inner > 0 && inner < nchain)
3202 {
3203 ++nsyms;
3204 if (maxlength < ++lengths[cnt])
3205 ++maxlength;
3206
3207 inner = chain[inner];
3208 }
3209 }
3210
3211 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3212 lengths, NULL);
3213
3214 free (lengths);
3215}
3216
3217
3218/* This function handles the GNU-style hash table format. */
3219static void
3220handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3221{
3222 uint32_t *lengths = NULL;
3223 Elf_Data *data = elf_getdata (scn, NULL);
3224 if (unlikely (data == NULL))
3225 {
3226 error (0, 0, gettext ("cannot get data for section %d: %s"),
3227 (int) elf_ndxscn (scn), elf_errmsg (-1));
3228 return;
3229 }
3230
3231 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3232 {
3233 invalid_data:
3234 free (lengths);
3235 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3236 (int) elf_ndxscn (scn));
3237 return;
3238 }
3239
3240 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3241 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3242
3243 /* Next comes the size of the bitmap. It's measured in words for
3244 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3245 64 bit archs. There is always a bloom filter present, so zero is
3246 an invalid value. */
3247 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3248 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3249 bitmask_words *= 2;
3250
3251 if (bitmask_words == 0)
3252 goto invalid_data;
3253
3254 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3255
3256 /* Is there still room for the sym chain?
3257 Use uint64_t calculation to prevent 32bit overlow. */
3258 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3259 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3260 if (used_buf > data->d_size)
3261 goto invalid_data;
3262
3263 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3264
3265 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3266 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3267 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3268 + nbucket];
3269
3270 /* Compute distribution of chain lengths. */
3271 uint_fast32_t maxlength = 0;
3272 uint_fast32_t nsyms = 0;
3273 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3274 if (bucket[cnt] != 0)
3275 {
3276 Elf32_Word inner = bucket[cnt] - symbias;
3277 do
3278 {
3279 ++nsyms;
3280 if (maxlength < ++lengths[cnt])
3281 ++maxlength;
3282 if (inner >= max_nsyms)
3283 goto invalid_data;
3284 }
3285 while ((chain[inner++] & 1) == 0);
3286 }
3287
3288 /* Count bits in bitmask. */
3289 uint_fast32_t nbits = 0;
3290 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3291 {
3292 uint_fast32_t word = bitmask[cnt];
3293
3294 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3295 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3296 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3297 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3298 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3299 }
3300
3301 char *str;
3302 if (unlikely (asprintf (&str, gettext ("\
3303 Symbol Bias: %u\n\
3304 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3305 (unsigned int) symbias,
3306 bitmask_words * sizeof (Elf32_Word),
3307 ((nbits * 100 + 50)
3308 / (uint_fast32_t) (bitmask_words
3309 * sizeof (Elf32_Word) * 8)),
3310 (unsigned int) shift) == -1))
3311 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3312
3313 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3314 lengths, str);
3315
3316 free (str);
3317 free (lengths);
3318}
3319
3320
3321/* Find the symbol table(s). For this we have to search through the
3322 section table. */
3323static void
3324handle_hash (Ebl *ebl)
3325{
3326 /* Get the section header string table index. */
3327 size_t shstrndx;
3328 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3329 error (EXIT_FAILURE, 0,
3330 gettext ("cannot get section header string table index"));
3331
3332 Elf_Scn *scn = NULL;
3333 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3334 {
3335 /* Handle the section if it is a symbol table. */
3336 GElf_Shdr shdr_mem;
3337 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3338
3339 if (likely (shdr != NULL))
3340 {
3341 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3342 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3343 {
3344 if (elf_compress (scn, 0, 0) < 0)
3345 printf ("WARNING: %s [%zd]\n",
3346 gettext ("Couldn't uncompress section"),
3347 elf_ndxscn (scn));
3348 shdr = gelf_getshdr (scn, &shdr_mem);
3349 if (unlikely (shdr == NULL))
3350 error (EXIT_FAILURE, 0,
3351 gettext ("cannot get section [%zd] header: %s"),
3352 elf_ndxscn (scn), elf_errmsg (-1));
3353 }
3354
3355 if (shdr->sh_type == SHT_HASH)
3356 {
3357 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3358 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3359 else
3360 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3361 }
3362 else if (shdr->sh_type == SHT_GNU_HASH)
3363 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3364 }
3365 }
3366}
3367
3368
3369static void
3370print_liblist (Ebl *ebl)
3371{
3372 /* Find the library list sections. For this we have to search
3373 through the section table. */
3374 Elf_Scn *scn = NULL;
3375
3376 /* Get the section header string table index. */
3377 size_t shstrndx;
3378 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3379 error (EXIT_FAILURE, 0,
3380 gettext ("cannot get section header string table index"));
3381
3382 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3383 {
3384 GElf_Shdr shdr_mem;
3385 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3386
3387 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3388 {
3389 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3390 int nentries = shdr->sh_size / sh_entsize;
3391 printf (ngettext ("\
3392\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3393 "\
3394\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3395 nentries),
3396 elf_ndxscn (scn),
3397 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3398 shdr->sh_offset,
3399 nentries);
3400
3401 Elf_Data *data = elf_getdata (scn, NULL);
3402 if (data == NULL)
3403 return;
3404
3405 puts (gettext ("\
3406 Library Time Stamp Checksum Version Flags"));
3407
3408 for (int cnt = 0; cnt < nentries; ++cnt)
3409 {
3410 GElf_Lib lib_mem;
3411 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3412 if (unlikely (lib == NULL))
3413 continue;
3414
3415 time_t t = (time_t) lib->l_time_stamp;
3416 struct tm *tm = gmtime (&t);
3417 if (unlikely (tm == NULL))
3418 continue;
3419
3420 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3421 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3422 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3423 tm->tm_hour, tm->tm_min, tm->tm_sec,
3424 (unsigned int) lib->l_checksum,
3425 (unsigned int) lib->l_version,
3426 (unsigned int) lib->l_flags);
3427 }
3428 }
3429 }
3430}
3431
3432static void
3433print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3434{
3435 /* Find the object attributes sections. For this we have to search
3436 through the section table. */
3437 Elf_Scn *scn = NULL;
3438
3439 /* Get the section header string table index. */
3440 size_t shstrndx;
3441 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3442 error (EXIT_FAILURE, 0,
3443 gettext ("cannot get section header string table index"));
3444
3445 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3446 {
3447 GElf_Shdr shdr_mem;
3448 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3449
3450 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3451 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3452 || ehdr->e_machine != EM_ARM)))
3453 continue;
3454
3455 printf (gettext ("\
3456\nObject attributes section [%2zu] '%s' of %" PRIu64
3457 " bytes at offset %#0" PRIx64 ":\n"),
3458 elf_ndxscn (scn),
3459 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3460 shdr->sh_size, shdr->sh_offset);
3461
3462 Elf_Data *data = elf_rawdata (scn, NULL);
3463 if (unlikely (data == NULL || data->d_size == 0))
3464 return;
3465
3466 const unsigned char *p = data->d_buf;
3467
3468 /* There is only one 'version', A. */
3469 if (unlikely (*p++ != 'A'))
3470 return;
3471
3472 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3473
3474 inline size_t left (void)
3475 {
3476 return (const unsigned char *) data->d_buf + data->d_size - p;
3477 }
3478
3479 /* Loop over the sections. */
3480 while (left () >= 4)
3481 {
3482 /* Section length. */
3483 uint32_t len;
3484 memcpy (&len, p, sizeof len);
3485
3486 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3487 CONVERT (len);
3488
3489 if (unlikely (len > left ()))
3490 break;
3491
3492 /* Section vendor name. */
3493 const unsigned char *name = p + sizeof len;
3494 p += len;
3495
3496 unsigned const char *q = memchr (name, '\0', len);
3497 if (unlikely (q == NULL))
3498 break;
3499 ++q;
3500
3501 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3502
3503 bool gnu_vendor = (q - name == sizeof "gnu"
3504 && !memcmp (name, "gnu", sizeof "gnu"));
3505
3506 /* Loop over subsections. */
3507 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3508 || gnu_vendor)
3509 while (q < p)
3510 {
3511 const unsigned char *const sub = q;
3512
3513 unsigned int subsection_tag;
3514 get_uleb128 (subsection_tag, q, p);
3515 if (unlikely (q >= p))
3516 break;
3517
3518 uint32_t subsection_len;
3519 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3520 break;
3521
3522 memcpy (&subsection_len, q, sizeof subsection_len);
3523
3524 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3525 CONVERT (subsection_len);
3526
3527 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3528 if (unlikely (subsection_len == 0
3529 || subsection_len >= (uint32_t) PTRDIFF_MAX
3530 || p - sub < (ptrdiff_t) subsection_len))
3531 break;
3532
3533 const unsigned char *r = q + sizeof subsection_len;
3534 q = sub + subsection_len;
3535
3536 switch (subsection_tag)
3537 {
3538 default:
3539 /* Unknown subsection, print and skip. */
3540 printf (gettext (" %-4u %12" PRIu32 "\n"),
3541 subsection_tag, subsection_len);
3542 break;
3543
3544 case 1: /* Tag_File */
3545 printf (gettext (" File: %11" PRIu32 "\n"),
3546 subsection_len);
3547
3548 while (r < q)
3549 {
3550 unsigned int tag;
3551 get_uleb128 (tag, r, q);
3552 if (unlikely (r >= q))
3553 break;
3554
3555 /* GNU style tags have either a uleb128 value,
3556 when lowest bit is not set, or a string
3557 when the lowest bit is set.
3558 "compatibility" (32) is special. It has
3559 both a string and a uleb128 value. For
3560 non-gnu we assume 6 till 31 only take ints.
3561 XXX see arm backend, do we need a separate
3562 hook? */
3563 uint64_t value = 0;
3564 const char *string = NULL;
3565 if (tag == 32 || (tag & 1) == 0
3566 || (! gnu_vendor && (tag > 5 && tag < 32)))
3567 {
3568 get_uleb128 (value, r, q);
3569 if (r > q)
3570 break;
3571 }
3572 if (tag == 32
3573 || ((tag & 1) != 0
3574 && (gnu_vendor
3575 || (! gnu_vendor && tag > 32)))
3576 || (! gnu_vendor && tag > 3 && tag < 6))
3577 {
3578 string = (const char *) r;
3579 r = memchr (r, '\0', q - r);
3580 if (r == NULL)
3581 break;
3582 ++r;
3583 }
3584
3585 const char *tag_name = NULL;
3586 const char *value_name = NULL;
3587 ebl_check_object_attribute (ebl, (const char *) name,
3588 tag, value,
3589 &tag_name, &value_name);
3590
3591 if (tag_name != NULL)
3592 {
3593 if (tag == 32)
3594 printf (gettext (" %s: %" PRId64 ", %s\n"),
3595 tag_name, value, string);
3596 else if (string == NULL && value_name == NULL)
3597 printf (gettext (" %s: %" PRId64 "\n"),
3598 tag_name, value);
3599 else
3600 printf (gettext (" %s: %s\n"),
3601 tag_name, string ?: value_name);
3602 }
3603 else
3604 {
3605 /* For "gnu" vendor 32 "compatibility" has
3606 already been handled above. */
3607 assert (tag != 32
3608 || strcmp ((const char *) name, "gnu"));
3609 if (string == NULL)
3610 printf (gettext (" %u: %" PRId64 "\n"),
3611 tag, value);
3612 else
3613 printf (gettext (" %u: %s\n"),
3614 tag, string);
3615 }
3616 }
3617 }
3618 }
3619 }
3620 }
3621}
3622
3623
3624static char *
3625format_dwarf_addr (Dwfl_Module *dwflmod,
3626 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3627{
3628 /* See if there is a name we can give for this address. */
3629 GElf_Sym sym;
3630 GElf_Off off = 0;
3631 const char *name = (print_address_names && ! print_unresolved_addresses)
3632 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3633 : NULL;
3634
3635 const char *scn;
3636 if (print_unresolved_addresses)
3637 {
3638 address = raw;
3639 scn = NULL;
3640 }
3641 else
3642 {
3643 /* Relativize the address. */
3644 int n = dwfl_module_relocations (dwflmod);
3645 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3646
3647 /* In an ET_REL file there is a section name to refer to. */
3648 scn = (i < 0 ? NULL
3649 : dwfl_module_relocation_info (dwflmod, i, NULL));
3650 }
3651
3652 char *result;
3653 if ((name != NULL
3654 ? (off != 0
3655 ? (scn != NULL
3656 ? (address_size == 0
3657 ? asprintf (&result,
3658 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3659 scn, address, name, off)
3660 : asprintf (&result,
3661 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3662 scn, 2 + address_size * 2, address,
3663 name, off))
3664 : (address_size == 0
3665 ? asprintf (&result,
3666 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3667 address, name, off)
3668 : asprintf (&result,
3669 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3670 2 + address_size * 2, address,
3671 name, off)))
3672 : (scn != NULL
3673 ? (address_size == 0
3674 ? asprintf (&result,
3675 gettext ("%s+%#" PRIx64 " <%s>"),
3676 scn, address, name)
3677 : asprintf (&result,
3678 gettext ("%s+%#0*" PRIx64 " <%s>"),
3679 scn, 2 + address_size * 2, address, name))
3680 : (address_size == 0
3681 ? asprintf (&result,
3682 gettext ("%#" PRIx64 " <%s>"),
3683 address, name)
3684 : asprintf (&result,
3685 gettext ("%#0*" PRIx64 " <%s>"),
3686 2 + address_size * 2, address, name))))
3687 : (scn != NULL
3688 ? (address_size == 0
3689 ? asprintf (&result,
3690 gettext ("%s+%#" PRIx64),
3691 scn, address)
3692 : asprintf (&result,
3693 gettext ("%s+%#0*" PRIx64),
3694 scn, 2 + address_size * 2, address))
3695 : (address_size == 0
3696 ? asprintf (&result,
3697 "%#" PRIx64,
3698 address)
3699 : asprintf (&result,
3700 "%#0*" PRIx64,
3701 2 + address_size * 2, address)))) < 0)
3702 error (EXIT_FAILURE, 0, _("memory exhausted"));
3703
3704 return result;
3705}
3706
3707static const char *
3708dwarf_tag_string (unsigned int tag)
3709{
3710 switch (tag)
3711 {
3712#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3713 DWARF_ALL_KNOWN_DW_TAG
3714#undef DWARF_ONE_KNOWN_DW_TAG
3715 default:
3716 return NULL;
3717 }
3718}
3719
3720
3721static const char *
3722dwarf_attr_string (unsigned int attrnum)
3723{
3724 switch (attrnum)
3725 {
3726#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3727 DWARF_ALL_KNOWN_DW_AT
3728#undef DWARF_ONE_KNOWN_DW_AT
3729 default:
3730 return NULL;
3731 }
3732}
3733
3734
3735static const char *
3736dwarf_form_string (unsigned int form)
3737{
3738 switch (form)
3739 {
3740#define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3741 DWARF_ALL_KNOWN_DW_FORM
3742#undef DWARF_ONE_KNOWN_DW_FORM
3743 default:
3744 return NULL;
3745 }
3746}
3747
3748
3749static const char *
3750dwarf_lang_string (unsigned int lang)
3751{
3752 switch (lang)
3753 {
3754#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3755 DWARF_ALL_KNOWN_DW_LANG
3756#undef DWARF_ONE_KNOWN_DW_LANG
3757 default:
3758 return NULL;
3759 }
3760}
3761
3762
3763static const char *
3764dwarf_inline_string (unsigned int code)
3765{
3766 static const char *const known[] =
3767 {
3768#define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3769 DWARF_ALL_KNOWN_DW_INL
3770#undef DWARF_ONE_KNOWN_DW_INL
3771 };
3772
3773 if (likely (code < sizeof (known) / sizeof (known[0])))
3774 return known[code];
3775
3776 return NULL;
3777}
3778
3779
3780static const char *
3781dwarf_encoding_string (unsigned int code)
3782{
3783 static const char *const known[] =
3784 {
3785#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3786 DWARF_ALL_KNOWN_DW_ATE
3787#undef DWARF_ONE_KNOWN_DW_ATE
3788 };
3789
3790 if (likely (code < sizeof (known) / sizeof (known[0])))
3791 return known[code];
3792
3793 return NULL;
3794}
3795
3796
3797static const char *
3798dwarf_access_string (unsigned int code)
3799{
3800 static const char *const known[] =
3801 {
3802#define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3803 DWARF_ALL_KNOWN_DW_ACCESS
3804#undef DWARF_ONE_KNOWN_DW_ACCESS
3805 };
3806
3807 if (likely (code < sizeof (known) / sizeof (known[0])))
3808 return known[code];
3809
3810 return NULL;
3811}
3812
3813
3814static const char *
3815dwarf_defaulted_string (unsigned int code)
3816{
3817 static const char *const known[] =
3818 {
3819#define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3820 DWARF_ALL_KNOWN_DW_DEFAULTED
3821#undef DWARF_ONE_KNOWN_DW_DEFAULTED
3822 };
3823
3824 if (likely (code < sizeof (known) / sizeof (known[0])))
3825 return known[code];
3826
3827 return NULL;
3828}
3829
3830
3831static const char *
3832dwarf_visibility_string (unsigned int code)
3833{
3834 static const char *const known[] =
3835 {
3836#define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3837 DWARF_ALL_KNOWN_DW_VIS
3838#undef DWARF_ONE_KNOWN_DW_VIS
3839 };
3840
3841 if (likely (code < sizeof (known) / sizeof (known[0])))
3842 return known[code];
3843
3844 return NULL;
3845}
3846
3847
3848static const char *
3849dwarf_virtuality_string (unsigned int code)
3850{
3851 static const char *const known[] =
3852 {
3853#define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3854 DWARF_ALL_KNOWN_DW_VIRTUALITY
3855#undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3856 };
3857
3858 if (likely (code < sizeof (known) / sizeof (known[0])))
3859 return known[code];
3860
3861 return NULL;
3862}
3863
3864
3865static const char *
3866dwarf_identifier_case_string (unsigned int code)
3867{
3868 static const char *const known[] =
3869 {
3870#define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3871 DWARF_ALL_KNOWN_DW_ID
3872#undef DWARF_ONE_KNOWN_DW_ID
3873 };
3874
3875 if (likely (code < sizeof (known) / sizeof (known[0])))
3876 return known[code];
3877
3878 return NULL;
3879}
3880
3881
3882static const char *
3883dwarf_calling_convention_string (unsigned int code)
3884{
3885 static const char *const known[] =
3886 {
3887#define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3888 DWARF_ALL_KNOWN_DW_CC
3889#undef DWARF_ONE_KNOWN_DW_CC
3890 };
3891
3892 if (likely (code < sizeof (known) / sizeof (known[0])))
3893 return known[code];
3894
3895 return NULL;
3896}
3897
3898
3899static const char *
3900dwarf_ordering_string (unsigned int code)
3901{
3902 static const char *const known[] =
3903 {
3904#define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3905 DWARF_ALL_KNOWN_DW_ORD
3906#undef DWARF_ONE_KNOWN_DW_ORD
3907 };
3908
3909 if (likely (code < sizeof (known) / sizeof (known[0])))
3910 return known[code];
3911
3912 return NULL;
3913}
3914
3915
3916static const char *
3917dwarf_discr_list_string (unsigned int code)
3918{
3919 static const char *const known[] =
3920 {
3921#define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3922 DWARF_ALL_KNOWN_DW_DSC
3923#undef DWARF_ONE_KNOWN_DW_DSC
3924 };
3925
3926 if (likely (code < sizeof (known) / sizeof (known[0])))
3927 return known[code];
3928
3929 return NULL;
3930}
3931
3932
3933static const char *
3934dwarf_locexpr_opcode_string (unsigned int code)
3935{
3936 static const char *const known[] =
3937 {
3938 /* Normally we can't affort building huge table of 64K entries,
3939 most of them zero, just because there are a couple defined
3940 values at the far end. In case of opcodes, it's OK. */
3941#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3942 DWARF_ALL_KNOWN_DW_OP
3943#undef DWARF_ONE_KNOWN_DW_OP
3944 };
3945
3946 if (likely (code < sizeof (known) / sizeof (known[0])))
3947 return known[code];
3948
3949 return NULL;
3950}
3951
3952
3953/* Used by all dwarf_foo_name functions. */
3954static const char *
3955string_or_unknown (const char *known, unsigned int code,
3956 unsigned int lo_user, unsigned int hi_user,
3957 bool print_unknown_num)
3958{
3959 static char unknown_buf[20];
3960
3961 if (likely (known != NULL))
3962 return known;
3963
3964 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3965 {
3966 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3967 code - lo_user);
3968 return unknown_buf;
3969 }
3970
3971 if (print_unknown_num)
3972 {
3973 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3974 return unknown_buf;
3975 }
3976
3977 return "???";
3978}
3979
3980
3981static const char *
3982dwarf_tag_name (unsigned int tag)
3983{
3984 const char *ret = dwarf_tag_string (tag);
3985 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3986}
3987
3988static const char *
3989dwarf_attr_name (unsigned int attr)
3990{
3991 const char *ret = dwarf_attr_string (attr);
3992 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3993}
3994
3995
3996static const char *
3997dwarf_form_name (unsigned int form)
3998{
3999 const char *ret = dwarf_form_string (form);
4000 return string_or_unknown (ret, form, 0, 0, true);
4001}
4002
4003
4004static const char *
4005dwarf_lang_name (unsigned int lang)
4006{
4007 const char *ret = dwarf_lang_string (lang);
4008 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4009}
4010
4011
4012static const char *
4013dwarf_inline_name (unsigned int code)
4014{
4015 const char *ret = dwarf_inline_string (code);
4016 return string_or_unknown (ret, code, 0, 0, false);
4017}
4018
4019
4020static const char *
4021dwarf_encoding_name (unsigned int code)
4022{
4023 const char *ret = dwarf_encoding_string (code);
4024 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4025}
4026
4027
4028static const char *
4029dwarf_access_name (unsigned int code)
4030{
4031 const char *ret = dwarf_access_string (code);
4032 return string_or_unknown (ret, code, 0, 0, false);
4033}
4034
4035
4036static const char *
4037dwarf_defaulted_name (unsigned int code)
4038{
4039 const char *ret = dwarf_defaulted_string (code);
4040 return string_or_unknown (ret, code, 0, 0, false);
4041}
4042
4043
4044static const char *
4045dwarf_visibility_name (unsigned int code)
4046{
4047 const char *ret = dwarf_visibility_string (code);
4048 return string_or_unknown (ret, code, 0, 0, false);
4049}
4050
4051
4052static const char *
4053dwarf_virtuality_name (unsigned int code)
4054{
4055 const char *ret = dwarf_virtuality_string (code);
4056 return string_or_unknown (ret, code, 0, 0, false);
4057}
4058
4059
4060static const char *
4061dwarf_identifier_case_name (unsigned int code)
4062{
4063 const char *ret = dwarf_identifier_case_string (code);
4064 return string_or_unknown (ret, code, 0, 0, false);
4065}
4066
4067
4068static const char *
4069dwarf_calling_convention_name (unsigned int code)
4070{
4071 const char *ret = dwarf_calling_convention_string (code);
4072 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4073}
4074
4075
4076static const char *
4077dwarf_ordering_name (unsigned int code)
4078{
4079 const char *ret = dwarf_ordering_string (code);
4080 return string_or_unknown (ret, code, 0, 0, false);
4081}
4082
4083
4084static const char *
4085dwarf_discr_list_name (unsigned int code)
4086{
4087 const char *ret = dwarf_discr_list_string (code);
4088 return string_or_unknown (ret, code, 0, 0, false);
4089}
4090
4091
4092static void
4093print_block (size_t n, const void *block)
4094{
4095 if (n == 0)
4096 puts (_("empty block"));
4097 else
4098 {
4099 printf (_("%zu byte block:"), n);
4100 const unsigned char *data = block;
4101 do
4102 printf (" %02x", *data++);
4103 while (--n > 0);
4104 putchar ('\n');
4105 }
4106}
4107
4108static void
4109print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4110 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4111 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4112{
4113 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4114
4115 if (len == 0)
4116 {
4117 printf ("%*s(empty)\n", indent, "");
4118 return;
4119 }
4120
4121#define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4122#define CONSUME(n) NEED (n); else len -= (n)
4123
4124 Dwarf_Word offset = 0;
4125 while (len-- > 0)
4126 {
4127 uint_fast8_t op = *data++;
4128
4129 const char *op_name = dwarf_locexpr_opcode_string (op);
4130 if (unlikely (op_name == NULL))
4131 {
4132 static char buf[20];
4133 if (op >= DW_OP_lo_user)
4134 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4135 else
4136 snprintf (buf, sizeof buf, "??? (%#x)", op);
4137 op_name = buf;
4138 }
4139
4140 switch (op)
4141 {
4142 case DW_OP_addr:;
4143 /* Address operand. */
4144 Dwarf_Word addr;
4145 NEED (addrsize);
4146 if (addrsize == 4)
4147 addr = read_4ubyte_unaligned (dbg, data);
4148 else if (addrsize == 8)
4149 addr = read_8ubyte_unaligned (dbg, data);
4150 else
4151 goto invalid;
4152 data += addrsize;
4153 CONSUME (addrsize);
4154
4155 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
4156 printf ("%*s[%2" PRIuMAX "] %s %s\n",
4157 indent, "", (uintmax_t) offset, op_name, a);
4158 free (a);
4159
4160 offset += 1 + addrsize;
4161 break;
4162
4163 case DW_OP_call_ref:
4164 case DW_OP_GNU_variable_value:
4165 /* Offset operand. */
4166 if (ref_size != 4 && ref_size != 8)
4167 goto invalid; /* Cannot be used in CFA. */
4168 NEED (ref_size);
4169 if (ref_size == 4)
4170 addr = read_4ubyte_unaligned (dbg, data);
4171 else
4172 addr = read_8ubyte_unaligned (dbg, data);
4173 data += ref_size;
4174 CONSUME (ref_size);
4175 /* addr is a DIE offset, so format it as one. */
4176 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4177 indent, "", (uintmax_t) offset,
4178 op_name, (uintmax_t) addr);
4179 offset += 1 + ref_size;
4180 break;
4181
4182 case DW_OP_deref_size:
4183 case DW_OP_xderef_size:
4184 case DW_OP_pick:
4185 case DW_OP_const1u:
4186 // XXX value might be modified by relocation
4187 NEED (1);
4188 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4189 indent, "", (uintmax_t) offset,
4190 op_name, *((uint8_t *) data));
4191 ++data;
4192 --len;
4193 offset += 2;
4194 break;
4195
4196 case DW_OP_const2u:
4197 NEED (2);
4198 // XXX value might be modified by relocation
4199 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4200 indent, "", (uintmax_t) offset,
4201 op_name, read_2ubyte_unaligned (dbg, data));
4202 CONSUME (2);
4203 data += 2;
4204 offset += 3;
4205 break;
4206
4207 case DW_OP_const4u:
4208 NEED (4);
4209 // XXX value might be modified by relocation
4210 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4211 indent, "", (uintmax_t) offset,
4212 op_name, read_4ubyte_unaligned (dbg, data));
4213 CONSUME (4);
4214 data += 4;
4215 offset += 5;
4216 break;
4217
4218 case DW_OP_const8u:
4219 NEED (8);
4220 // XXX value might be modified by relocation
4221 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4222 indent, "", (uintmax_t) offset,
4223 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4224 CONSUME (8);
4225 data += 8;
4226 offset += 9;
4227 break;
4228
4229 case DW_OP_const1s:
4230 NEED (1);
4231 // XXX value might be modified by relocation
4232 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4233 indent, "", (uintmax_t) offset,
4234 op_name, *((int8_t *) data));
4235 ++data;
4236 --len;
4237 offset += 2;
4238 break;
4239
4240 case DW_OP_const2s:
4241 NEED (2);
4242 // XXX value might be modified by relocation
4243 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4244 indent, "", (uintmax_t) offset,
4245 op_name, read_2sbyte_unaligned (dbg, data));
4246 CONSUME (2);
4247 data += 2;
4248 offset += 3;
4249 break;
4250
4251 case DW_OP_const4s:
4252 NEED (4);
4253 // XXX value might be modified by relocation
4254 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4255 indent, "", (uintmax_t) offset,
4256 op_name, read_4sbyte_unaligned (dbg, data));
4257 CONSUME (4);
4258 data += 4;
4259 offset += 5;
4260 break;
4261
4262 case DW_OP_const8s:
4263 NEED (8);
4264 // XXX value might be modified by relocation
4265 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4266 indent, "", (uintmax_t) offset,
4267 op_name, read_8sbyte_unaligned (dbg, data));
4268 CONSUME (8);
4269 data += 8;
4270 offset += 9;
4271 break;
4272
4273 case DW_OP_piece:
4274 case DW_OP_regx:
4275 case DW_OP_plus_uconst:
4276 case DW_OP_constu:;
4277 const unsigned char *start = data;
4278 uint64_t uleb;
4279 NEED (1);
4280 get_uleb128 (uleb, data, data + len);
4281 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4282 indent, "", (uintmax_t) offset, op_name, uleb);
4283 CONSUME (data - start);
4284 offset += 1 + (data - start);
4285 break;
4286
4287 case DW_OP_bit_piece:
4288 start = data;
4289 uint64_t uleb2;
4290 NEED (1);
4291 get_uleb128 (uleb, data, data + len);
4292 NEED (1);
4293 get_uleb128 (uleb2, data, data + len);
4294 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4295 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4296 CONSUME (data - start);
4297 offset += 1 + (data - start);
4298 break;
4299
4300 case DW_OP_fbreg:
4301 case DW_OP_breg0 ... DW_OP_breg31:
4302 case DW_OP_consts:
4303 start = data;
4304 int64_t sleb;
4305 NEED (1);
4306 get_sleb128 (sleb, data, data + len);
4307 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4308 indent, "", (uintmax_t) offset, op_name, sleb);
4309 CONSUME (data - start);
4310 offset += 1 + (data - start);
4311 break;
4312
4313 case DW_OP_bregx:
4314 start = data;
4315 NEED (1);
4316 get_uleb128 (uleb, data, data + len);
4317 NEED (1);
4318 get_sleb128 (sleb, data, data + len);
4319 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4320 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4321 CONSUME (data - start);
4322 offset += 1 + (data - start);
4323 break;
4324
4325 case DW_OP_call2:
4326 NEED (2);
4327 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4328 indent, "", (uintmax_t) offset, op_name,
4329 read_2ubyte_unaligned (dbg, data));
4330 CONSUME (2);
4331 data += 2;
4332 offset += 3;
4333 break;
4334
4335 case DW_OP_call4:
4336 NEED (4);
4337 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4338 indent, "", (uintmax_t) offset, op_name,
4339 read_4ubyte_unaligned (dbg, data));
4340 CONSUME (4);
4341 data += 4;
4342 offset += 5;
4343 break;
4344
4345 case DW_OP_skip:
4346 case DW_OP_bra:
4347 NEED (2);
4348 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4349 indent, "", (uintmax_t) offset, op_name,
4350 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4351 CONSUME (2);
4352 data += 2;
4353 offset += 3;
4354 break;
4355
4356 case DW_OP_implicit_value:
4357 start = data;
4358 NEED (1);
4359 get_uleb128 (uleb, data, data + len);
4360 printf ("%*s[%2" PRIuMAX "] %s: ",
4361 indent, "", (uintmax_t) offset, op_name);
4362 NEED (uleb);
4363 print_block (uleb, data);
4364 data += uleb;
4365 CONSUME (data - start);
4366 offset += 1 + (data - start);
4367 break;
4368
4369 case DW_OP_GNU_implicit_pointer:
4370 /* DIE offset operand. */
4371 start = data;
4372 NEED (ref_size);
4373 if (ref_size != 4 && ref_size != 8)
4374 goto invalid; /* Cannot be used in CFA. */
4375 if (ref_size == 4)
4376 addr = read_4ubyte_unaligned (dbg, data);
4377 else
4378 addr = read_8ubyte_unaligned (dbg, data);
4379 data += ref_size;
4380 /* Byte offset operand. */
4381 NEED (1);
4382 get_sleb128 (sleb, data, data + len);
4383
4384 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4385 indent, "", (intmax_t) offset,
4386 op_name, (uintmax_t) addr, sleb);
4387 CONSUME (data - start);
4388 offset += 1 + (data - start);
4389 break;
4390
4391 case DW_OP_GNU_entry_value:
4392 /* Size plus expression block. */
4393 start = data;
4394 NEED (1);
4395 get_uleb128 (uleb, data, data + len);
4396 printf ("%*s[%2" PRIuMAX "] %s:\n",
4397 indent, "", (uintmax_t) offset, op_name);
4398 NEED (uleb);
4399 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4400 addrsize, offset_size, cu, uleb, data);
4401 data += uleb;
4402 CONSUME (data - start);
4403 offset += 1 + (data - start);
4404 break;
4405
4406 case DW_OP_GNU_const_type:
4407 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4408 unsigned size plus block. */
4409 start = data;
4410 NEED (1);
4411 get_uleb128 (uleb, data, data + len);
4412 if (! print_unresolved_addresses && cu != NULL)
4413 uleb += cu->start;
4414 NEED (1);
4415 uint8_t usize = *(uint8_t *) data++;
4416 NEED (usize);
4417 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4418 indent, "", (uintmax_t) offset, op_name, uleb);
4419 print_block (usize, data);
4420 data += usize;
4421 CONSUME (data - start);
4422 offset += 1 + (data - start);
4423 break;
4424
4425 case DW_OP_GNU_regval_type:
4426 /* uleb128 register number, uleb128 CU relative
4427 DW_TAG_base_type DIE offset. */
4428 start = data;
4429 NEED (1);
4430 get_uleb128 (uleb, data, data + len);
4431 NEED (1);
4432 get_uleb128 (uleb2, data, data + len);
4433 if (! print_unresolved_addresses && cu != NULL)
4434 uleb2 += cu->start;
4435 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4436 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4437 CONSUME (data - start);
4438 offset += 1 + (data - start);
4439 break;
4440
4441 case DW_OP_GNU_deref_type:
4442 /* 1-byte unsigned size of value, uleb128 CU relative
4443 DW_TAG_base_type DIE offset. */
4444 start = data;
4445 NEED (1);
4446 usize = *(uint8_t *) data++;
4447 NEED (1);
4448 get_uleb128 (uleb, data, data + len);
4449 if (! print_unresolved_addresses && cu != NULL)
4450 uleb += cu->start;
4451 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4452 indent, "", (uintmax_t) offset,
4453 op_name, usize, uleb);
4454 CONSUME (data - start);
4455 offset += 1 + (data - start);
4456 break;
4457
4458 case DW_OP_GNU_convert:
4459 case DW_OP_GNU_reinterpret:
4460 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4461 for conversion to untyped. */
4462 start = data;
4463 NEED (1);
4464 get_uleb128 (uleb, data, data + len);
4465 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4466 uleb += cu->start;
4467 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4468 indent, "", (uintmax_t) offset, op_name, uleb);
4469 CONSUME (data - start);
4470 offset += 1 + (data - start);
4471 break;
4472
4473 case DW_OP_GNU_parameter_ref:
4474 /* 4 byte CU relative reference to the abstract optimized away
4475 DW_TAG_formal_parameter. */
4476 NEED (4);
4477 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4478 if (! print_unresolved_addresses && cu != NULL)
4479 param_off += cu->start;
4480 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4481 indent, "", (uintmax_t) offset, op_name, param_off);
4482 CONSUME (4);
4483 data += 4;
4484 offset += 5;
4485 break;
4486
4487 default:
4488 /* No Operand. */
4489 printf ("%*s[%2" PRIuMAX "] %s\n",
4490 indent, "", (uintmax_t) offset, op_name);
4491 ++offset;
4492 break;
4493 }
4494
4495 indent = indentrest;
4496 continue;
4497
4498 invalid:
4499 printf (gettext ("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
4500 indent, "", (uintmax_t) offset, op_name);
4501 break;
4502 }
4503}
4504
4505
4506struct listptr
4507{
4508 Dwarf_Off offset:(64 - 3);
4509 bool addr64:1;
4510 bool dwarf64:1;
4511 bool warned:1;
4512 struct Dwarf_CU *cu;
4513};
4514
4515#define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4516#define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4517
4518static Dwarf_Addr
4519listptr_base (struct listptr *p)
4520{
4521 Dwarf_Addr base;
4522 Dwarf_Die cu = CUDIE (p->cu);
4523 /* Find the base address of the compilation unit. It will normally
4524 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4525 address could be overridden by DW_AT_entry_pc. It's been
4526 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4527 compilation units with discontinuous ranges. */
4528 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4529 {
4530 Dwarf_Attribute attr_mem;
4531 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4532 &base) != 0)
4533 base = 0;
4534 }
4535 return base;
4536}
4537
4538static int
4539compare_listptr (const void *a, const void *b, void *arg)
4540{
4541 const char *name = arg;
4542 struct listptr *p1 = (void *) a;
4543 struct listptr *p2 = (void *) b;
4544
4545 if (p1->offset < p2->offset)
4546 return -1;
4547 if (p1->offset > p2->offset)
4548 return 1;
4549
4550 if (!p1->warned && !p2->warned)
4551 {
4552 if (p1->addr64 != p2->addr64)
4553 {
4554 p1->warned = p2->warned = true;
4555 error (0, 0,
4556 gettext ("%s %#" PRIx64 " used with different address sizes"),
4557 name, (uint64_t) p1->offset);
4558 }
4559 if (p1->dwarf64 != p2->dwarf64)
4560 {
4561 p1->warned = p2->warned = true;
4562 error (0, 0,
4563 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4564 name, (uint64_t) p1->offset);
4565 }
4566 if (listptr_base (p1) != listptr_base (p2))
4567 {
4568 p1->warned = p2->warned = true;
4569 error (0, 0,
4570 gettext ("%s %#" PRIx64 " used with different base addresses"),
4571 name, (uint64_t) p1->offset);
4572 }
4573 }
4574
4575 return 0;
4576}
4577
4578struct listptr_table
4579{
4580 size_t n;
4581 size_t alloc;
4582 struct listptr *table;
4583};
4584
4585static struct listptr_table known_loclistptr;
4586static struct listptr_table known_rangelistptr;
4587
4588static void
4589reset_listptr (struct listptr_table *table)
4590{
4591 free (table->table);
4592 table->table = NULL;
4593 table->n = table->alloc = 0;
4594}
4595
4596/* Returns false if offset doesn't fit. See struct listptr. */
4597static bool
4598notice_listptr (enum section_e section, struct listptr_table *table,
4599 uint_fast8_t address_size, uint_fast8_t offset_size,
4600 struct Dwarf_CU *cu, Dwarf_Off offset)
4601{
4602 if (print_debug_sections & section)
4603 {
4604 if (table->n == table->alloc)
4605 {
4606 if (table->alloc == 0)
4607 table->alloc = 128;
4608 else
4609 table->alloc *= 2;
4610 table->table = xrealloc (table->table,
4611 table->alloc * sizeof table->table[0]);
4612 }
4613
4614 struct listptr *p = &table->table[table->n++];
4615
4616 *p = (struct listptr)
4617 {
4618 .addr64 = address_size == 8,
4619 .dwarf64 = offset_size == 8,
4620 .offset = offset,
4621 .cu = cu
4622 };
4623
4624 if (p->offset != offset)
4625 {
4626 table->n--;
4627 return false;
4628 }
4629 }
4630 return true;
4631}
4632
4633static void
4634sort_listptr (struct listptr_table *table, const char *name)
4635{
4636 if (table->n > 0)
4637 qsort_r (table->table, table->n, sizeof table->table[0],
4638 &compare_listptr, (void *) name);
4639}
4640
4641static bool
4642skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4643 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4644 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4645 unsigned char **readp, unsigned char *endp)
4646{
4647 if (table->n == 0)
4648 return false;
4649
4650 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4651 ++*idxp;
4652
4653 struct listptr *p = &table->table[*idxp];
4654
4655 if (*idxp == table->n
4656 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4657 {
4658 *readp = endp;
4659 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4660 offset);
4661 return true;
4662 }
4663
4664 if (p->offset != (Dwarf_Off) offset)
4665 {
4666 *readp += p->offset - offset;
4667 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4668 offset, (Dwarf_Off) p->offset - offset);
4669 return true;
4670 }
4671
4672 if (address_sizep != NULL)
4673 *address_sizep = listptr_address_size (p);
4674 if (offset_sizep != NULL)
4675 *offset_sizep = listptr_offset_size (p);
4676 if (base != NULL)
4677 *base = listptr_base (p);
4678 if (cu != NULL)
4679 *cu = p->cu;
4680
4681 return false;
4682}
4683
4684
4685static void
4686print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4687 Ebl *ebl, GElf_Ehdr *ehdr,
4688 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4689{
4690 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4691 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4692
4693 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4694 " [ Code]\n"),
4695 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4696 (uint64_t) shdr->sh_offset);
4697
4698 Dwarf_Off offset = 0;
4699 while (offset < sh_size)
4700 {
4701 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4702 offset);
4703
4704 while (1)
4705 {
4706 size_t length;
4707 Dwarf_Abbrev abbrev;
4708
4709 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4710 if (res != 0)
4711 {
4712 if (unlikely (res < 0))
4713 {
4714 printf (gettext ("\
4715 *** error while reading abbreviation: %s\n"),
4716 dwarf_errmsg (-1));
4717 return;
4718 }
4719
4720 /* This is the NUL byte at the end of the section. */
4721 ++offset;
4722 break;
4723 }
4724
4725 /* We know these calls can never fail. */
4726 unsigned int code = dwarf_getabbrevcode (&abbrev);
4727 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4728 int has_children = dwarf_abbrevhaschildren (&abbrev);
4729
4730 printf (gettext (" [%5u] offset: %" PRId64
4731 ", children: %s, tag: %s\n"),
4732 code, (int64_t) offset,
4733 has_children ? gettext ("yes") : gettext ("no"),
4734 dwarf_tag_name (tag));
4735
4736 size_t cnt = 0;
4737 unsigned int name;
4738 unsigned int form;
4739 Dwarf_Off enoffset;
4740 while (dwarf_getabbrevattr (&abbrev, cnt,
4741 &name, &form, &enoffset) == 0)
4742 {
4743 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4744 dwarf_attr_name (name), dwarf_form_name (form),
4745 (uint64_t) enoffset);
4746
4747 ++cnt;
4748 }
4749
4750 offset += length;
4751 }
4752 }
4753}
4754
4755
4756/* Print content of DWARF .debug_aranges section. We fortunately do
4757 not have to know a bit about the structure of the section, libdwarf
4758 takes care of it. */
4759static void
4760print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4761 GElf_Shdr *shdr, Dwarf *dbg)
4762{
4763 Dwarf_Aranges *aranges;
4764 size_t cnt;
4765 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4766 {
4767 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4768 dwarf_errmsg (-1));
4769 return;
4770 }
4771
4772 GElf_Shdr glink_mem;
4773 GElf_Shdr *glink;
4774 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4775 if (glink == NULL)
4776 {
4777 error (0, 0, gettext ("invalid sh_link value in section %zu"),
4778 elf_ndxscn (scn));
4779 return;
4780 }
4781
4782 printf (ngettext ("\
4783\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4784 "\
4785\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4786 cnt),
4787 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4788 (uint64_t) shdr->sh_offset, cnt);
4789
4790 /* Compute floor(log16(cnt)). */
4791 size_t tmp = cnt;
4792 int digits = 1;
4793 while (tmp >= 16)
4794 {
4795 ++digits;
4796 tmp >>= 4;
4797 }
4798
4799 for (size_t n = 0; n < cnt; ++n)
4800 {
4801 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4802 if (unlikely (runp == NULL))
4803 {
4804 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4805 return;
4806 }
4807
4808 Dwarf_Addr start;
4809 Dwarf_Word length;
4810 Dwarf_Off offset;
4811
4812 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4813 printf (gettext (" [%*zu] ???\n"), digits, n);
4814 else
4815 printf (gettext (" [%*zu] start: %0#*" PRIx64
4816 ", length: %5" PRIu64 ", CU DIE offset: %6"
4817 PRId64 "\n"),
4818 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4819 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4820 }
4821}
4822
4823
4824/* Print content of DWARF .debug_aranges section. */
4825static void
4826print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4827 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4828 GElf_Shdr *shdr, Dwarf *dbg)
4829{
4830 if (decodedaranges)
4831 {
4832 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4833 return;
4834 }
4835
4836 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4837
4838 if (unlikely (data == NULL))
4839 {
4840 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4841 elf_errmsg (-1));
4842 return;
4843 }
4844
4845 printf (gettext ("\
4846\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4847 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4848 (uint64_t) shdr->sh_offset);
4849
4850 const unsigned char *readp = data->d_buf;
4851 const unsigned char *readendp = readp + data->d_size;
4852
4853 while (readp < readendp)
4854 {
4855 const unsigned char *hdrstart = readp;
4856 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4857
4858 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
4859 if (readp + 4 > readendp)
4860 {
4861 invalid_data:
4862 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4863 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4864 return;
4865 }
4866
4867 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4868 unsigned int length_bytes = 4;
4869 if (length == DWARF3_LENGTH_64_BIT)
4870 {
4871 if (readp + 8 > readendp)
4872 goto invalid_data;
4873 length = read_8ubyte_unaligned_inc (dbg, readp);
4874 length_bytes = 8;
4875 }
4876
4877 const unsigned char *nexthdr = readp + length;
4878 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4879 (uint64_t) length);
4880
4881 if (unlikely (length > (size_t) (readendp - readp)))
4882 goto invalid_data;
4883
4884 if (length == 0)
4885 continue;
4886
4887 if (readp + 2 > readendp)
4888 goto invalid_data;
4889 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4890 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4891 version);
4892 if (version != 2)
4893 {
4894 error (0, 0, gettext ("unsupported aranges version"));
4895 goto next_table;
4896 }
4897
4898 Dwarf_Word offset;
4899 if (readp + length_bytes > readendp)
4900 goto invalid_data;
4901 if (length_bytes == 8)
4902 offset = read_8ubyte_unaligned_inc (dbg, readp);
4903 else
4904 offset = read_4ubyte_unaligned_inc (dbg, readp);
4905 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4906 (uint64_t) offset);
4907
4908 if (readp + 1 > readendp)
4909 goto invalid_data;
4910 unsigned int address_size = *readp++;
4911 printf (gettext (" Address size: %6" PRIu64 "\n"),
4912 (uint64_t) address_size);
4913 if (address_size != 4 && address_size != 8)
4914 {
4915 error (0, 0, gettext ("unsupported address size"));
4916 goto next_table;
4917 }
4918
4919 unsigned int segment_size = *readp++;
4920 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4921 (uint64_t) segment_size);
4922 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4923 {
4924 error (0, 0, gettext ("unsupported segment size"));
4925 goto next_table;
4926 }
4927
4928 /* Round the address to the next multiple of 2*address_size. */
4929 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4930 % (2 * address_size));
4931
4932 while (readp < nexthdr)
4933 {
4934 Dwarf_Word range_address;
4935 Dwarf_Word range_length;
4936 Dwarf_Word segment = 0;
4937 if (readp + 2 * address_size + segment_size > readendp)
4938 goto invalid_data;
4939 if (address_size == 4)
4940 {
4941 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4942 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4943 }
4944 else
4945 {
4946 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4947 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4948 }
4949
4950 if (segment_size == 4)
4951 segment = read_4ubyte_unaligned_inc (dbg, readp);
4952 else if (segment_size == 8)
4953 segment = read_8ubyte_unaligned_inc (dbg, readp);
4954
4955 if (range_address == 0 && range_length == 0 && segment == 0)
4956 break;
4957
4958 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4959 range_address);
4960 char *e = format_dwarf_addr (dwflmod, address_size,
4961 range_address + range_length - 1,
4962 range_length);
4963 if (segment_size != 0)
4964 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4965 (uint64_t) segment);
4966 else
4967 printf (gettext (" %s..%s\n"), b, e);
4968 free (b);
4969 free (e);
4970 }
4971
4972 next_table:
4973 if (readp != nexthdr)
4974 {
4975 size_t padding = nexthdr - readp;
4976 printf (gettext (" %zu padding bytes\n"), padding);
4977 readp = nexthdr;
4978 }
4979 }
4980}
4981
4982
4983/* Print content of DWARF .debug_ranges section. */
4984static void
4985print_debug_ranges_section (Dwfl_Module *dwflmod,
4986 Ebl *ebl, GElf_Ehdr *ehdr,
4987 Elf_Scn *scn, GElf_Shdr *shdr,
4988 Dwarf *dbg)
4989{
4990 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4991
4992 if (unlikely (data == NULL))
4993 {
4994 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4995 elf_errmsg (-1));
4996 return;
4997 }
4998
4999 printf (gettext ("\
5000\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5001 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
5002 (uint64_t) shdr->sh_offset);
5003
5004 sort_listptr (&known_rangelistptr, "rangelistptr");
5005 size_t listptr_idx = 0;
5006
5007 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5008
5009 bool first = true;
5010 Dwarf_Addr base = 0;
5011 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
5012 unsigned char *readp = data->d_buf;
5013 Dwarf_CU *last_cu = NULL;
5014 while (readp < endp)
5015 {
5016 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5017 Dwarf_CU *cu = last_cu;
5018
5019 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
5020 &address_size, NULL, &base, &cu,
5021 offset, &readp, endp))
5022 continue;
5023
5024 if (last_cu != cu)
5025 {
5026 char *basestr = format_dwarf_addr (dwflmod, address_size,
5027 base, base);
5028 Dwarf_Die cudie;
5029 if (dwarf_cu_die (cu, &cudie,
5030 NULL, NULL, NULL, NULL,
5031 NULL, NULL) == NULL)
5032 printf (gettext ("\n Unknown CU base: %s\n"), basestr);
5033 else
5034 printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"),
5035 dwarf_dieoffset (&cudie), basestr);
5036 free (basestr);
5037 }
5038 last_cu = cu;
5039
5040 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
5041 {
5042 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
5043 break;
5044 }
5045
5046 Dwarf_Addr begin;
5047 Dwarf_Addr end;
5048 if (address_size == 8)
5049 {
5050 begin = read_8ubyte_unaligned_inc (dbg, readp);
5051 end = read_8ubyte_unaligned_inc (dbg, readp);
5052 }
5053 else
5054 {
5055 begin = read_4ubyte_unaligned_inc (dbg, readp);
5056 end = read_4ubyte_unaligned_inc (dbg, readp);
5057 if (begin == (Dwarf_Addr) (uint32_t) -1)
5058 begin = (Dwarf_Addr) -1l;
5059 }
5060
5061 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
5062 {
5063 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
5064 printf (gettext (" [%6tx] base address\n %s\n"), offset, b);
5065 free (b);
5066 base = end;
5067 }
5068 else if (begin == 0 && end == 0) /* End of list entry. */
5069 {
5070 if (first)
5071 printf (gettext (" [%6tx] empty list\n"), offset);
5072 first = true;
5073 }
5074 else
5075 {
5076 /* We have an address range entry. */
5077 if (first) /* First address range entry in a list. */
5078 printf (" [%6tx] ", offset);
5079 else
5080 printf (" ");
5081
5082 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
5083 if (! print_unresolved_addresses)
5084 {
5085 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
5086 base + begin);
5087 char *e = format_dwarf_addr (dwflmod, address_size,
5088 base + end - 1, base + end);
5089 printf (" %s..\n", b);
5090 printf (" %s\n", e);
5091 free (b);
5092 free (e);
5093 }
5094
5095 first = false;
5096 }
5097 }
5098}
5099
5100#define REGNAMESZ 16
5101static const char *
5102register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
5103 char name[REGNAMESZ], int *bits, int *type)
5104{
5105 const char *set;
5106 const char *pfx;
5107 int ignore;
5108 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
5109 bits ?: &ignore, type ?: &ignore);
5110 if (n <= 0)
5111 {
5112 if (loc != NULL)
5113 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
5114 else
5115 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
5116 if (bits != NULL)
5117 *bits = loc != NULL ? loc->bits : 0;
5118 if (type != NULL)
5119 *type = DW_ATE_unsigned;
5120 set = "??? unrecognized";
5121 }
5122 else
5123 {
5124 if (bits != NULL && *bits <= 0)
5125 *bits = loc != NULL ? loc->bits : 0;
5126 if (type != NULL && *type == DW_ATE_void)
5127 *type = DW_ATE_unsigned;
5128
5129 }
5130 return set;
5131}
5132
5133static const unsigned char *
5134read_encoded (unsigned int encoding, const unsigned char *readp,
5135 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5136{
5137 if ((encoding & 0xf) == DW_EH_PE_absptr)
5138 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5139 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5140
5141 switch (encoding & 0xf)
5142 {
5143 case DW_EH_PE_uleb128:
5144 get_uleb128 (*res, readp, endp);
5145 break;
5146 case DW_EH_PE_sleb128:
5147 get_sleb128 (*res, readp, endp);
5148 break;
5149 case DW_EH_PE_udata2:
5150 if (readp + 2 > endp)
5151 goto invalid;
5152 *res = read_2ubyte_unaligned_inc (dbg, readp);
5153 break;
5154 case DW_EH_PE_udata4:
5155 if (readp + 4 > endp)
5156 goto invalid;
5157 *res = read_4ubyte_unaligned_inc (dbg, readp);
5158 break;
5159 case DW_EH_PE_udata8:
5160 if (readp + 8 > endp)
5161 goto invalid;
5162 *res = read_8ubyte_unaligned_inc (dbg, readp);
5163 break;
5164 case DW_EH_PE_sdata2:
5165 if (readp + 2 > endp)
5166 goto invalid;
5167 *res = read_2sbyte_unaligned_inc (dbg, readp);
5168 break;
5169 case DW_EH_PE_sdata4:
5170 if (readp + 4 > endp)
5171 goto invalid;
5172 *res = read_4sbyte_unaligned_inc (dbg, readp);
5173 break;
5174 case DW_EH_PE_sdata8:
5175 if (readp + 8 > endp)
5176 goto invalid;
5177 *res = read_8sbyte_unaligned_inc (dbg, readp);
5178 break;
5179 default:
5180 invalid:
5181 error (1, 0,
5182 gettext ("invalid encoding"));
5183 }
5184
5185 return readp;
5186}
5187
5188
5189static void
5190print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
5191 Dwarf_Word vma_base, unsigned int code_align,
5192 int data_align,
5193 unsigned int version, unsigned int ptr_size,
5194 unsigned int encoding,
5195 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
5196{
5197 char regnamebuf[REGNAMESZ];
5198 const char *regname (unsigned int regno)
5199 {
5200 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
5201 return regnamebuf;
5202 }
5203
5204 puts ("\n Program:");
5205 Dwarf_Word pc = vma_base;
5206 while (readp < endp)
5207 {
5208 unsigned int opcode = *readp++;
5209
5210 if (opcode < DW_CFA_advance_loc)
5211 /* Extended opcode. */
5212 switch (opcode)
5213 {
5214 uint64_t op1;
5215 int64_t sop1;
5216 uint64_t op2;
5217 int64_t sop2;
5218
5219 case DW_CFA_nop:
5220 puts (" nop");
5221 break;
5222 case DW_CFA_set_loc:
5223 if ((uint64_t) (endp - readp) < 1)
5224 goto invalid;
5225 readp = read_encoded (encoding, readp, endp, &op1, dbg);
5226 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
5227 op1, pc = vma_base + op1);
5228 break;
5229 case DW_CFA_advance_loc1:
5230 if ((uint64_t) (endp - readp) < 1)
5231 goto invalid;
5232 printf (" advance_loc1 %u to %#" PRIx64 "\n",
5233 *readp, pc += *readp * code_align);
5234 ++readp;
5235 break;
5236 case DW_CFA_advance_loc2:
5237 if ((uint64_t) (endp - readp) < 2)
5238 goto invalid;
5239 op1 = read_2ubyte_unaligned_inc (dbg, readp);
5240 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
5241 op1, pc += op1 * code_align);
5242 break;
5243 case DW_CFA_advance_loc4:
5244 if ((uint64_t) (endp - readp) < 4)
5245 goto invalid;
5246 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5247 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
5248 op1, pc += op1 * code_align);
5249 break;
5250 case DW_CFA_offset_extended:
5251 if ((uint64_t) (endp - readp) < 1)
5252 goto invalid;
5253 get_uleb128 (op1, readp, endp);
5254 if ((uint64_t) (endp - readp) < 1)
5255 goto invalid;
5256 get_uleb128 (op2, readp, endp);
5257 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5258 "\n",
5259 op1, regname (op1), op2 * data_align);
5260 break;
5261 case DW_CFA_restore_extended:
5262 if ((uint64_t) (endp - readp) < 1)
5263 goto invalid;
5264 get_uleb128 (op1, readp, endp);
5265 printf (" restore_extended r%" PRIu64 " (%s)\n",
5266 op1, regname (op1));
5267 break;
5268 case DW_CFA_undefined:
5269 if ((uint64_t) (endp - readp) < 1)
5270 goto invalid;
5271 get_uleb128 (op1, readp, endp);
5272 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5273 break;
5274 case DW_CFA_same_value:
5275 if ((uint64_t) (endp - readp) < 1)
5276 goto invalid;
5277 get_uleb128 (op1, readp, endp);
5278 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5279 break;
5280 case DW_CFA_register:
5281 if ((uint64_t) (endp - readp) < 1)
5282 goto invalid;
5283 get_uleb128 (op1, readp, endp);
5284 if ((uint64_t) (endp - readp) < 1)
5285 goto invalid;
5286 get_uleb128 (op2, readp, endp);
5287 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5288 op1, regname (op1), op2, regname (op2));
5289 break;
5290 case DW_CFA_remember_state:
5291 puts (" remember_state");
5292 break;
5293 case DW_CFA_restore_state:
5294 puts (" restore_state");
5295 break;
5296 case DW_CFA_def_cfa:
5297 if ((uint64_t) (endp - readp) < 1)
5298 goto invalid;
5299 get_uleb128 (op1, readp, endp);
5300 if ((uint64_t) (endp - readp) < 1)
5301 goto invalid;
5302 get_uleb128 (op2, readp, endp);
5303 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5304 op1, regname (op1), op2);
5305 break;
5306 case DW_CFA_def_cfa_register:
5307 if ((uint64_t) (endp - readp) < 1)
5308 goto invalid;
5309 get_uleb128 (op1, readp, endp);
5310 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
5311 op1, regname (op1));
5312 break;
5313 case DW_CFA_def_cfa_offset:
5314 if ((uint64_t) (endp - readp) < 1)
5315 goto invalid;
5316 get_uleb128 (op1, readp, endp);
5317 printf (" def_cfa_offset %" PRIu64 "\n", op1);
5318 break;
5319 case DW_CFA_def_cfa_expression:
5320 if ((uint64_t) (endp - readp) < 1)
5321 goto invalid;
5322 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
5323 printf (" def_cfa_expression %" PRIu64 "\n", op1);
5324 if ((uint64_t) (endp - readp) < op1)
5325 {
5326 invalid:
5327 fputs (gettext (" <INVALID DATA>\n"), stdout);
5328 return;
5329 }
5330 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5331 op1, readp);
5332 readp += op1;
5333 break;
5334 case DW_CFA_expression:
5335 if ((uint64_t) (endp - readp) < 1)
5336 goto invalid;
5337 get_uleb128 (op1, readp, endp);
5338 if ((uint64_t) (endp - readp) < 1)
5339 goto invalid;
5340 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5341 printf (" expression r%" PRIu64 " (%s) \n",
5342 op1, regname (op1));
5343 if ((uint64_t) (endp - readp) < op2)
5344 goto invalid;
5345 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5346 op2, readp);
5347 readp += op2;
5348 break;
5349 case DW_CFA_offset_extended_sf:
5350 if ((uint64_t) (endp - readp) < 1)
5351 goto invalid;
5352 get_uleb128 (op1, readp, endp);
5353 if ((uint64_t) (endp - readp) < 1)
5354 goto invalid;
5355 get_sleb128 (sop2, readp, endp);
5356 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5357 PRId64 "\n",
5358 op1, regname (op1), sop2 * data_align);
5359 break;
5360 case DW_CFA_def_cfa_sf:
5361 if ((uint64_t) (endp - readp) < 1)
5362 goto invalid;
5363 get_uleb128 (op1, readp, endp);
5364 if ((uint64_t) (endp - readp) < 1)
5365 goto invalid;
5366 get_sleb128 (sop2, readp, endp);
5367 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5368 op1, regname (op1), sop2 * data_align);
5369 break;
5370 case DW_CFA_def_cfa_offset_sf:
5371 if ((uint64_t) (endp - readp) < 1)
5372 goto invalid;
5373 get_sleb128 (sop1, readp, endp);
5374 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5375 break;
5376 case DW_CFA_val_offset:
5377 if ((uint64_t) (endp - readp) < 1)
5378 goto invalid;
5379 get_uleb128 (op1, readp, endp);
5380 if ((uint64_t) (endp - readp) < 1)
5381 goto invalid;
5382 get_uleb128 (op2, readp, endp);
5383 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5384 op1, op2 * data_align);
5385 break;
5386 case DW_CFA_val_offset_sf:
5387 if ((uint64_t) (endp - readp) < 1)
5388 goto invalid;
5389 get_uleb128 (op1, readp, endp);
5390 if ((uint64_t) (endp - readp) < 1)
5391 goto invalid;
5392 get_sleb128 (sop2, readp, endp);
5393 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5394 op1, sop2 * data_align);
5395 break;
5396 case DW_CFA_val_expression:
5397 if ((uint64_t) (endp - readp) < 1)
5398 goto invalid;
5399 get_uleb128 (op1, readp, endp);
5400 if ((uint64_t) (endp - readp) < 1)
5401 goto invalid;
5402 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5403 printf (" val_expression r%" PRIu64 " (%s)\n",
5404 op1, regname (op1));
5405 if ((uint64_t) (endp - readp) < op2)
5406 goto invalid;
5407 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5408 NULL, op2, readp);
5409 readp += op2;
5410 break;
5411 case DW_CFA_MIPS_advance_loc8:
5412 if ((uint64_t) (endp - readp) < 8)
5413 goto invalid;
5414 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5415 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5416 op1, pc += op1 * code_align);
5417 break;
5418 case DW_CFA_GNU_window_save:
5419 puts (" GNU_window_save");
5420 break;
5421 case DW_CFA_GNU_args_size:
5422 if ((uint64_t) (endp - readp) < 1)
5423 goto invalid;
5424 get_uleb128 (op1, readp, endp);
5425 printf (" args_size %" PRIu64 "\n", op1);
5426 break;
5427 default:
5428 printf (" ??? (%u)\n", opcode);
5429 break;
5430 }
5431 else if (opcode < DW_CFA_offset)
5432 printf (" advance_loc %u to %#" PRIx64 "\n",
5433 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5434 else if (opcode < DW_CFA_restore)
5435 {
5436 uint64_t offset;
5437 if ((uint64_t) (endp - readp) < 1)
5438 goto invalid;
5439 get_uleb128 (offset, readp, endp);
5440 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5441 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5442 }
5443 else
5444 printf (" restore r%u (%s)\n",
5445 opcode & 0x3f, regname (opcode & 0x3f));
5446 }
5447}
5448
5449
5450static unsigned int
5451encoded_ptr_size (int encoding, unsigned int ptr_size)
5452{
5453 switch (encoding & 7)
5454 {
5455 case DW_EH_PE_udata4:
5456 return 4;
5457 case DW_EH_PE_udata8:
5458 return 8;
5459 case 0:
5460 return ptr_size;
5461 }
5462
5463 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5464 "assuming pointer size of %d.\n", encoding, ptr_size);
5465 return ptr_size;
5466}
5467
5468
5469static unsigned int
5470print_encoding (unsigned int val)
5471{
5472 switch (val & 0xf)
5473 {
5474 case DW_EH_PE_absptr:
5475 fputs ("absptr", stdout);
5476 break;
5477 case DW_EH_PE_uleb128:
5478 fputs ("uleb128", stdout);
5479 break;
5480 case DW_EH_PE_udata2:
5481 fputs ("udata2", stdout);
5482 break;
5483 case DW_EH_PE_udata4:
5484 fputs ("udata4", stdout);
5485 break;
5486 case DW_EH_PE_udata8:
5487 fputs ("udata8", stdout);
5488 break;
5489 case DW_EH_PE_sleb128:
5490 fputs ("sleb128", stdout);
5491 break;
5492 case DW_EH_PE_sdata2:
5493 fputs ("sdata2", stdout);
5494 break;
5495 case DW_EH_PE_sdata4:
5496 fputs ("sdata4", stdout);
5497 break;
5498 case DW_EH_PE_sdata8:
5499 fputs ("sdata8", stdout);
5500 break;
5501 default:
5502 /* We did not use any of the bits after all. */
5503 return val;
5504 }
5505
5506 return val & ~0xf;
5507}
5508
5509
5510static unsigned int
5511print_relinfo (unsigned int val)
5512{
5513 switch (val & 0x70)
5514 {
5515 case DW_EH_PE_pcrel:
5516 fputs ("pcrel", stdout);
5517 break;
5518 case DW_EH_PE_textrel:
5519 fputs ("textrel", stdout);
5520 break;
5521 case DW_EH_PE_datarel:
5522 fputs ("datarel", stdout);
5523 break;
5524 case DW_EH_PE_funcrel:
5525 fputs ("funcrel", stdout);
5526 break;
5527 case DW_EH_PE_aligned:
5528 fputs ("aligned", stdout);
5529 break;
5530 default:
5531 return val;
5532 }
5533
5534 return val & ~0x70;
5535}
5536
5537
5538static void
5539print_encoding_base (const char *pfx, unsigned int fde_encoding)
5540{
5541 printf ("(%s", pfx);
5542
5543 if (fde_encoding == DW_EH_PE_omit)
5544 puts ("omit)");
5545 else
5546 {
5547 unsigned int w = fde_encoding;
5548
5549 w = print_encoding (w);
5550
5551 if (w & 0x70)
5552 {
5553 if (w != fde_encoding)
5554 fputc_unlocked (' ', stdout);
5555
5556 w = print_relinfo (w);
5557 }
5558
5559 if (w != 0)
5560 printf ("%s%x", w != fde_encoding ? " " : "", w);
5561
5562 puts (")");
5563 }
5564}
5565
5566
5567static void
5568print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5569 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5570{
5571 size_t shstrndx;
5572 /* We know this call will succeed since it did in the caller. */
5573 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5574 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5575
5576 /* Needed if we find PC-relative addresses. */
5577 GElf_Addr bias;
5578 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5579 {
5580 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5581 return;
5582 }
5583
5584 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5585 Elf_Data *data = (is_eh_frame
5586 ? elf_rawdata (scn, NULL)
5587 : dbg->sectiondata[IDX_debug_frame]);
5588
5589 if (unlikely (data == NULL))
5590 {
5591 error (0, 0, gettext ("cannot get %s content: %s"),
5592 scnname, elf_errmsg (-1));
5593 return;
5594 }
5595
5596 if (is_eh_frame)
5597 printf (gettext ("\
5598\nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5599 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5600 else
5601 printf (gettext ("\
5602\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5603 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5604
5605 struct cieinfo
5606 {
5607 ptrdiff_t cie_offset;
5608 const char *augmentation;
5609 unsigned int code_alignment_factor;
5610 unsigned int data_alignment_factor;
5611 uint8_t address_size;
5612 uint8_t fde_encoding;
5613 uint8_t lsda_encoding;
5614 struct cieinfo *next;
5615 } *cies = NULL;
5616
5617 const unsigned char *readp = data->d_buf;
5618 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5619 + data->d_size);
5620 while (readp < dataend)
5621 {
5622 if (unlikely (readp + 4 > dataend))
5623 {
5624 invalid_data:
5625 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5626 elf_ndxscn (scn), scnname);
5627 return;
5628 }
5629
5630 /* At the beginning there must be a CIE. There can be multiple,
5631 hence we test tis in a loop. */
5632 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5633
5634 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5635 unsigned int length = 4;
5636 if (unlikely (unit_length == 0xffffffff))
5637 {
5638 if (unlikely (readp + 8 > dataend))
5639 goto invalid_data;
5640
5641 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5642 length = 8;
5643 }
5644
5645 if (unlikely (unit_length == 0))
5646 {
5647 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5648 continue;
5649 }
5650
5651 Dwarf_Word maxsize = dataend - readp;
5652 if (unlikely (unit_length > maxsize))
5653 goto invalid_data;
5654
5655 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5656
5657 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5658 const unsigned char *const cieend = readp + unit_length;
5659 if (unlikely (cieend > dataend || readp + 8 > dataend))
5660 goto invalid_data;
5661
5662 Dwarf_Off cie_id;
5663 if (length == 4)
5664 {
5665 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5666 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5667 cie_id = DW_CIE_ID_64;
5668 }
5669 else
5670 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5671
5672 uint_fast8_t version = 2;
5673 unsigned int code_alignment_factor;
5674 int data_alignment_factor;
5675 unsigned int fde_encoding = 0;
5676 unsigned int lsda_encoding = 0;
5677 Dwarf_Word initial_location = 0;
5678 Dwarf_Word vma_base = 0;
5679
5680 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5681 {
5682 version = *readp++;
5683 const char *const augmentation = (const char *) readp;
5684 readp = memchr (readp, '\0', cieend - readp);
5685 if (unlikely (readp == NULL))
5686 goto invalid_data;
5687 ++readp;
5688
5689 uint_fast8_t segment_size = 0;
5690 if (version >= 4)
5691 {
5692 if (cieend - readp < 5)
5693 goto invalid_data;
5694 ptr_size = *readp++;
5695 segment_size = *readp++;
5696 }
5697
5698 if (cieend - readp < 1)
5699 goto invalid_data;
5700 get_uleb128 (code_alignment_factor, readp, cieend);
5701 if (cieend - readp < 1)
5702 goto invalid_data;
5703 get_sleb128 (data_alignment_factor, readp, cieend);
5704
5705 /* In some variant for unwind data there is another field. */
5706 if (strcmp (augmentation, "eh") == 0)
5707 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5708
5709 unsigned int return_address_register;
5710 if (cieend - readp < 1)
5711 goto invalid_data;
5712 if (unlikely (version == 1))
5713 return_address_register = *readp++;
5714 else
5715 get_uleb128 (return_address_register, readp, cieend);
5716
5717 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5718 " CIE_id: %" PRIu64 "\n"
5719 " version: %u\n"
5720 " augmentation: \"%s\"\n",
5721 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5722 version, augmentation);
5723 if (version >= 4)
5724 printf (" address_size: %u\n"
5725 " segment_size: %u\n",
5726 ptr_size, segment_size);
5727 printf (" code_alignment_factor: %u\n"
5728 " data_alignment_factor: %d\n"
5729 " return_address_register: %u\n",
5730 code_alignment_factor,
5731 data_alignment_factor, return_address_register);
5732
5733 if (augmentation[0] == 'z')
5734 {
5735 unsigned int augmentationlen;
5736 get_uleb128 (augmentationlen, readp, cieend);
5737
5738 if (augmentationlen > (size_t) (cieend - readp))
5739 {
5740 error (0, 0, gettext ("invalid augmentation length"));
5741 readp = cieend;
5742 continue;
5743 }
5744
5745 const char *hdr = "Augmentation data:";
5746 const char *cp = augmentation + 1;
5747 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5748 {
5749 printf (" %-26s%#x ", hdr, *readp);
5750 hdr = "";
5751
5752 if (*cp == 'R')
5753 {
5754 fde_encoding = *readp++;
5755 print_encoding_base (gettext ("FDE address encoding: "),
5756 fde_encoding);
5757 }
5758 else if (*cp == 'L')
5759 {
5760 lsda_encoding = *readp++;
5761 print_encoding_base (gettext ("LSDA pointer encoding: "),
5762 lsda_encoding);
5763 }
5764 else if (*cp == 'P')
5765 {
5766 /* Personality. This field usually has a relocation
5767 attached pointing to __gcc_personality_v0. */
5768 const unsigned char *startp = readp;
5769 unsigned int encoding = *readp++;
5770 uint64_t val = 0;
5771 readp = read_encoded (encoding, readp,
5772 readp - 1 + augmentationlen,
5773 &val, dbg);
5774
5775 while (++startp < readp)
5776 printf ("%#x ", *startp);
5777
5778 putchar ('(');
5779 print_encoding (encoding);
5780 putchar (' ');
5781 switch (encoding & 0xf)
5782 {
5783 case DW_EH_PE_sleb128:
5784 case DW_EH_PE_sdata2:
5785 case DW_EH_PE_sdata4:
5786 printf ("%" PRId64 ")\n", val);
5787 break;
5788 default:
5789 printf ("%#" PRIx64 ")\n", val);
5790 break;
5791 }
5792 }
5793 else
5794 printf ("(%x)\n", *readp++);
5795
5796 ++cp;
5797 }
5798 }
5799
5800 if (likely (ptr_size == 4 || ptr_size == 8))
5801 {
5802 struct cieinfo *newp = alloca (sizeof (*newp));
5803 newp->cie_offset = offset;
5804 newp->augmentation = augmentation;
5805 newp->fde_encoding = fde_encoding;
5806 newp->lsda_encoding = lsda_encoding;
5807 newp->address_size = ptr_size;
5808 newp->code_alignment_factor = code_alignment_factor;
5809 newp->data_alignment_factor = data_alignment_factor;
5810 newp->next = cies;
5811 cies = newp;
5812 }
5813 }
5814 else
5815 {
5816 struct cieinfo *cie = cies;
5817 while (cie != NULL)
5818 if (is_eh_frame
5819 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
5820 : cie_id == (Dwarf_Off) cie->cie_offset)
5821 break;
5822 else
5823 cie = cie->next;
5824 if (unlikely (cie == NULL))
5825 {
5826 puts ("invalid CIE reference in FDE");
5827 return;
5828 }
5829
5830 /* Initialize from CIE data. */
5831 fde_encoding = cie->fde_encoding;
5832 lsda_encoding = cie->lsda_encoding;
5833 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5834 code_alignment_factor = cie->code_alignment_factor;
5835 data_alignment_factor = cie->data_alignment_factor;
5836
5837 const unsigned char *base = readp;
5838 // XXX There are sometimes relocations for this value
5839 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5840 Dwarf_Word address_range
5841 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5842
5843 /* pcrel for an FDE address is relative to the runtime
5844 address of the start_address field itself. Sign extend
5845 if necessary to make sure the calculation is done on the
5846 full 64 bit address even when initial_location only holds
5847 the lower 32 bits. */
5848 Dwarf_Addr pc_start = initial_location;
5849 if (ptr_size == 4)
5850 pc_start = (uint64_t) (int32_t) pc_start;
5851 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5852 pc_start += ((uint64_t) shdr->sh_addr
5853 + (base - (const unsigned char *) data->d_buf)
5854 - bias);
5855
5856 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5857 pc_start, initial_location);
5858 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5859 " CIE_pointer: %" PRIu64 "\n"
5860 " initial_location: %s",
5861 offset, (uint64_t) unit_length,
5862 cie->cie_offset, (uint64_t) cie_id, a);
5863 free (a);
5864 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5865 {
5866 vma_base = (((uint64_t) shdr->sh_offset
5867 + (base - (const unsigned char *) data->d_buf)
5868 + (uint64_t) initial_location)
5869 & (ptr_size == 4
5870 ? UINT64_C (0xffffffff)
5871 : UINT64_C (0xffffffffffffffff)));
5872 printf (gettext (" (offset: %#" PRIx64 ")"),
5873 (uint64_t) vma_base);
5874 }
5875
5876 printf ("\n address_range: %#" PRIx64,
5877 (uint64_t) address_range);
5878 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5879 printf (gettext (" (end offset: %#" PRIx64 ")"),
5880 ((uint64_t) vma_base + (uint64_t) address_range)
5881 & (ptr_size == 4
5882 ? UINT64_C (0xffffffff)
5883 : UINT64_C (0xffffffffffffffff)));
5884 putchar ('\n');
5885
5886 if (cie->augmentation[0] == 'z')
5887 {
5888 unsigned int augmentationlen;
5889 if (cieend - readp < 1)
5890 goto invalid_data;
5891 get_uleb128 (augmentationlen, readp, cieend);
5892
5893 if (augmentationlen > (size_t) (cieend - readp))
5894 {
5895 error (0, 0, gettext ("invalid augmentation length"));
5896 readp = cieend;
5897 continue;
5898 }
5899
5900 if (augmentationlen > 0)
5901 {
5902 const char *hdr = "Augmentation data:";
5903 const char *cp = cie->augmentation + 1;
5904 unsigned int u = 0;
5905 while (*cp != '\0'
5906 && cp < cie->augmentation + augmentationlen + 1)
5907 {
5908 if (*cp == 'L')
5909 {
5910 uint64_t lsda_pointer;
5911 const unsigned char *p
5912 = read_encoded (lsda_encoding, &readp[u],
5913 &readp[augmentationlen],
5914 &lsda_pointer, dbg);
5915 u = p - readp;
5916 printf (gettext ("\
5917 %-26sLSDA pointer: %#" PRIx64 "\n"),
5918 hdr, lsda_pointer);
5919 hdr = "";
5920 }
5921 ++cp;
5922 }
5923
5924 while (u < augmentationlen)
5925 {
5926 printf (" %-26s%#x\n", hdr, readp[u++]);
5927 hdr = "";
5928 }
5929 }
5930
5931 readp += augmentationlen;
5932 }
5933 }
5934
5935 /* Handle the initialization instructions. */
5936 if (ptr_size != 4 && ptr_size !=8)
5937 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5938 else
5939 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5940 data_alignment_factor, version, ptr_size,
5941 fde_encoding, dwflmod, ebl, dbg);
5942 readp = cieend;
5943 }
5944}
5945
5946
5947struct attrcb_args
5948{
5949 Dwfl_Module *dwflmod;
5950 Dwarf *dbg;
5951 Dwarf_Die *die;
5952 int level;
5953 bool silent;
5954 unsigned int version;
5955 unsigned int addrsize;
5956 unsigned int offset_size;
5957 struct Dwarf_CU *cu;
5958};
5959
5960
5961static int
5962attr_callback (Dwarf_Attribute *attrp, void *arg)
5963{
5964 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5965 const int level = cbargs->level;
5966 Dwarf_Die *die = cbargs->die;
5967
5968 unsigned int attr = dwarf_whatattr (attrp);
5969 if (unlikely (attr == 0))
5970 {
5971 if (!cbargs->silent)
5972 error (0, 0, gettext ("DIE [%" PRIx64 "] "
5973 "cannot get attribute code: %s"),
5974 dwarf_dieoffset (die), dwarf_errmsg (-1));
5975 return DWARF_CB_ABORT;
5976 }
5977
5978 unsigned int form = dwarf_whatform (attrp);
5979 if (unlikely (form == 0))
5980 {
5981 if (!cbargs->silent)
5982 error (0, 0, gettext ("DIE [%" PRIx64 "] "
5983 "cannot get attribute form: %s"),
5984 dwarf_dieoffset (die), dwarf_errmsg (-1));
5985 return DWARF_CB_ABORT;
5986 }
5987
5988 switch (form)
5989 {
5990 case DW_FORM_addr:
5991 if (!cbargs->silent)
5992 {
5993 Dwarf_Addr addr;
5994 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5995 {
5996 attrval_out:
5997 if (!cbargs->silent)
5998 error (0, 0, gettext ("DIE [%" PRIx64 "] "
5999 "cannot get attribute '%s' (%s) value: "
6000 "%s"),
6001 dwarf_dieoffset (die),
6002 dwarf_attr_name (attr),
6003 dwarf_form_name (form),
6004 dwarf_errmsg (-1));
6005 /* Don't ABORT, it might be other attributes can be resolved. */
6006 return DWARF_CB_OK;
6007 }
6008 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
6009 addr, addr);
6010 printf (" %*s%-20s (%s) %s\n",
6011 (int) (level * 2), "", dwarf_attr_name (attr),
6012 dwarf_form_name (form), a);
6013 free (a);
6014 }
6015 break;
6016
6017 case DW_FORM_indirect:
6018 case DW_FORM_strp:
6019 case DW_FORM_string:
6020 case DW_FORM_GNU_strp_alt:
6021 if (cbargs->silent)
6022 break;
6023 const char *str = dwarf_formstring (attrp);
6024 if (unlikely (str == NULL))
6025 goto attrval_out;
6026 printf (" %*s%-20s (%s) \"%s\"\n",
6027 (int) (level * 2), "", dwarf_attr_name (attr),
6028 dwarf_form_name (form), str);
6029 break;
6030
6031 case DW_FORM_ref_addr:
6032 case DW_FORM_ref_udata:
6033 case DW_FORM_ref8:
6034 case DW_FORM_ref4:
6035 case DW_FORM_ref2:
6036 case DW_FORM_ref1:
6037 case DW_FORM_GNU_ref_alt:
6038 if (cbargs->silent)
6039 break;
6040 Dwarf_Die ref;
6041 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
6042 goto attrval_out;
6043
6044 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
6045 (int) (level * 2), "", dwarf_attr_name (attr),
6046 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
6047 break;
6048
6049 case DW_FORM_ref_sig8:
6050 if (cbargs->silent)
6051 break;
6052 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
6053 (int) (level * 2), "", dwarf_attr_name (attr),
6054 dwarf_form_name (form),
6055 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
6056 break;
6057
6058 case DW_FORM_sec_offset:
6059 case DW_FORM_udata:
6060 case DW_FORM_sdata:
6061 case DW_FORM_data8:
6062 case DW_FORM_data4:
6063 case DW_FORM_data2:
6064 case DW_FORM_data1:;
6065 Dwarf_Word num;
6066 if (unlikely (dwarf_formudata (attrp, &num) != 0))
6067 goto attrval_out;
6068
6069 const char *valuestr = NULL;
6070 switch (attr)
6071 {
6072 /* This case can take either a constant or a loclistptr. */
6073 case DW_AT_data_member_location:
6074 if (form != DW_FORM_sec_offset
6075 && (cbargs->version >= 4
6076 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
6077 {
6078 if (!cbargs->silent)
6079 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
6080 (int) (level * 2), "", dwarf_attr_name (attr),
6081 dwarf_form_name (form), (uintmax_t) num);
6082 return DWARF_CB_OK;
6083 }
6084 FALLTHROUGH;
6085
6086 /* These cases always take a loclistptr and no constant. */
6087 case DW_AT_location:
6088 case DW_AT_data_location:
6089 case DW_AT_vtable_elem_location:
6090 case DW_AT_string_length:
6091 case DW_AT_use_location:
6092 case DW_AT_frame_base:
6093 case DW_AT_return_addr:
6094 case DW_AT_static_link:
6095 case DW_AT_GNU_call_site_value:
6096 case DW_AT_GNU_call_site_data_value:
6097 case DW_AT_GNU_call_site_target:
6098 case DW_AT_GNU_call_site_target_clobbered:
6099 {
6100 bool nlpt = notice_listptr (section_loc, &known_loclistptr,
6101 cbargs->addrsize, cbargs->offset_size,
6102 cbargs->cu, num);
6103 if (!cbargs->silent)
6104 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
6105 (int) (level * 2), "", dwarf_attr_name (attr),
6106 dwarf_form_name (form), (uintmax_t) num,
6107 nlpt ? "" : " <WARNING offset too big>");
6108 }
6109 return DWARF_CB_OK;
6110
6111 case DW_AT_ranges:
6112 {
6113 bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
6114 cbargs->addrsize, cbargs->offset_size,
6115 cbargs->cu, num);
6116 if (!cbargs->silent)
6117 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
6118 (int) (level * 2), "", dwarf_attr_name (attr),
6119 dwarf_form_name (form), (uintmax_t) num,
6120 nlpt ? "" : " <WARNING offset too big>");
6121 }
6122 return DWARF_CB_OK;
6123
6124 case DW_AT_language:
6125 valuestr = dwarf_lang_name (num);
6126 break;
6127 case DW_AT_encoding:
6128 valuestr = dwarf_encoding_name (num);
6129 break;
6130 case DW_AT_accessibility:
6131 valuestr = dwarf_access_name (num);
6132 break;
6133 case DW_AT_defaulted:
6134 valuestr = dwarf_defaulted_name (num);
6135 break;
6136 case DW_AT_visibility:
6137 valuestr = dwarf_visibility_name (num);
6138 break;
6139 case DW_AT_virtuality:
6140 valuestr = dwarf_virtuality_name (num);
6141 break;
6142 case DW_AT_identifier_case:
6143 valuestr = dwarf_identifier_case_name (num);
6144 break;
6145 case DW_AT_calling_convention:
6146 valuestr = dwarf_calling_convention_name (num);
6147 break;
6148 case DW_AT_inline:
6149 valuestr = dwarf_inline_name (num);
6150 break;
6151 case DW_AT_ordering:
6152 valuestr = dwarf_ordering_name (num);
6153 break;
6154 case DW_AT_discr_list:
6155 valuestr = dwarf_discr_list_name (num);
6156 break;
6157 case DW_AT_decl_file:
6158 case DW_AT_call_file:
6159 {
6160 /* Try to get the actual file, the current interface only
6161 gives us full paths, but we only want to show the file
6162 name for now. */
6163 Dwarf_Die cudie;
6164 if (dwarf_cu_die (cbargs->cu, &cudie,
6165 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
6166 {
6167 Dwarf_Files *files;
6168 size_t nfiles;
6169 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
6170 {
6171 valuestr = dwarf_filesrc (files, num, NULL, NULL);
6172 char *filename = strrchr (valuestr, '/');
6173 if (filename != NULL)
6174 valuestr = filename + 1;
6175 }
6176 }
6177 }
6178 break;
6179 default:
6180 /* Nothing. */
6181 break;
6182 }
6183
6184 if (cbargs->silent)
6185 break;
6186
6187 /* When highpc is in constant form it is relative to lowpc.
6188 In that case also show the address. */
6189 Dwarf_Addr highpc;
6190 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
6191 {
6192 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
6193 highpc, highpc);
6194 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
6195 (int) (level * 2), "", dwarf_attr_name (attr),
6196 dwarf_form_name (form), (uintmax_t) num, a);
6197 free (a);
6198 }
6199 else
6200 {
6201 Dwarf_Sword snum = 0;
6202 if (form == DW_FORM_sdata)
6203 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
6204 goto attrval_out;
6205
6206 if (valuestr == NULL)
6207 {
6208 printf (" %*s%-20s (%s)",
6209 (int) (level * 2), "", dwarf_attr_name (attr),
6210 dwarf_form_name (form));
6211 if (form == DW_FORM_sdata)
6212 printf (" %" PRIdMAX "\n", (intmax_t) snum);
6213 else
6214 printf (" %" PRIuMAX "\n", (uintmax_t) num);
6215 }
6216 else
6217 {
6218 printf (" %*s%-20s (%s) %s",
6219 (int) (level * 2), "", dwarf_attr_name (attr),
6220 dwarf_form_name (form), valuestr);
6221 if (form == DW_FORM_sdata)
6222 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
6223 else
6224 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6225 }
6226 }
6227 break;
6228
6229 case DW_FORM_flag:
6230 if (cbargs->silent)
6231 break;
6232 bool flag;
6233 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6234 goto attrval_out;
6235
6236 printf (" %*s%-20s (%s) %s\n",
6237 (int) (level * 2), "", dwarf_attr_name (attr),
6238 dwarf_form_name (form), flag ? gettext ("yes") : gettext ("no"));
6239 break;
6240
6241 case DW_FORM_flag_present:
6242 if (cbargs->silent)
6243 break;
6244 printf (" %*s%-20s (%s) %s\n",
6245 (int) (level * 2), "", dwarf_attr_name (attr),
6246 dwarf_form_name (form), gettext ("yes"));
6247 break;
6248
6249 case DW_FORM_exprloc:
6250 case DW_FORM_block4:
6251 case DW_FORM_block2:
6252 case DW_FORM_block1:
6253 case DW_FORM_block:
6254 if (cbargs->silent)
6255 break;
6256 Dwarf_Block block;
6257 if (unlikely (dwarf_formblock (attrp, &block) != 0))
6258 goto attrval_out;
6259
6260 printf (" %*s%-20s (%s) ",
6261 (int) (level * 2), "", dwarf_attr_name (attr),
6262 dwarf_form_name (form));
6263
6264 switch (attr)
6265 {
6266 default:
6267 if (form != DW_FORM_exprloc)
6268 {
6269 print_block (block.length, block.data);
6270 break;
6271 }
6272 FALLTHROUGH;
6273
6274 case DW_AT_location:
6275 case DW_AT_data_location:
6276 case DW_AT_data_member_location:
6277 case DW_AT_vtable_elem_location:
6278 case DW_AT_string_length:
6279 case DW_AT_use_location:
6280 case DW_AT_frame_base:
6281 case DW_AT_return_addr:
6282 case DW_AT_static_link:
6283 case DW_AT_allocated:
6284 case DW_AT_associated:
6285 case DW_AT_bit_size:
6286 case DW_AT_bit_offset:
6287 case DW_AT_bit_stride:
6288 case DW_AT_byte_size:
6289 case DW_AT_byte_stride:
6290 case DW_AT_count:
6291 case DW_AT_lower_bound:
6292 case DW_AT_upper_bound:
6293 case DW_AT_GNU_call_site_value:
6294 case DW_AT_GNU_call_site_data_value:
6295 case DW_AT_GNU_call_site_target:
6296 case DW_AT_GNU_call_site_target_clobbered:
6297 putchar ('\n');
6298 print_ops (cbargs->dwflmod, cbargs->dbg,
6299 12 + level * 2, 12 + level * 2,
6300 cbargs->version, cbargs->addrsize, cbargs->offset_size,
6301 attrp->cu, block.length, block.data);
6302 break;
6303 }
6304 break;
6305
6306 default:
6307 if (cbargs->silent)
6308 break;
6309 printf (" %*s%-20s (%s) ???\n",
6310 (int) (level * 2), "", dwarf_attr_name (attr),
6311 dwarf_form_name (form));
6312 break;
6313 }
6314
6315 return DWARF_CB_OK;
6316}
6317
6318static void
6319print_debug_units (Dwfl_Module *dwflmod,
6320 Ebl *ebl, GElf_Ehdr *ehdr,
6321 Elf_Scn *scn, GElf_Shdr *shdr,
6322 Dwarf *dbg, bool debug_types)
6323{
6324 const bool silent = !(print_debug_sections & section_info);
6325 const char *secname = section_name (ebl, ehdr, shdr);
6326
6327 if (!silent)
6328 printf (gettext ("\
6329\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6330 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6331
6332 /* If the section is empty we don't have to do anything. */
6333 if (!silent && shdr->sh_size == 0)
6334 return;
6335
6336 int maxdies = 20;
6337 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6338
6339 Dwarf_Off offset = 0;
6340
6341 /* New compilation unit. */
6342 size_t cuhl;
6343 Dwarf_Half version;
6344 Dwarf_Off abbroffset;
6345 uint8_t addrsize;
6346 uint8_t offsize;
6347 Dwarf_Off nextcu;
6348 uint64_t typesig;
6349 Dwarf_Off typeoff;
6350 next_cu:
6351 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6352 &abbroffset, &addrsize, &offsize,
6353 debug_types ? &typesig : NULL,
6354 debug_types ? &typeoff : NULL) != 0)
6355 goto do_return;
6356
6357 if (!silent)
6358 {
6359 if (debug_types)
6360 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6361 " Version: %" PRIu16 ", Abbreviation section offset: %"
6362 PRIu64 ", Address size: %" PRIu8
6363 ", Offset size: %" PRIu8
6364 "\n Type signature: %#" PRIx64
6365 ", Type offset: %#" PRIx64 "\n"),
6366 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6367 typesig, (uint64_t) typeoff);
6368 else
6369 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6370 " Version: %" PRIu16 ", Abbreviation section offset: %"
6371 PRIu64 ", Address size: %" PRIu8
6372 ", Offset size: %" PRIu8 "\n"),
6373 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6374 }
6375
6376 struct attrcb_args args =
6377 {
6378 .dwflmod = dwflmod,
6379 .dbg = dbg,
6380 .silent = silent,
6381 .version = version,
6382 .addrsize = addrsize,
6383 .offset_size = offsize
6384 };
6385
6386 offset += cuhl;
6387
6388 int level = 0;
6389
6390 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6391 (dbg, offset, &dies[level]) == NULL))
6392 {
6393 if (!silent)
6394 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6395 " in section '%s': %s"),
6396 (uint64_t) offset, secname, dwarf_errmsg (-1));
6397 goto do_return;
6398 }
6399
6400 args.cu = dies[0].cu;
6401
6402 do
6403 {
6404 offset = dwarf_dieoffset (&dies[level]);
6405 if (unlikely (offset == ~0ul))
6406 {
6407 if (!silent)
6408 error (0, 0, gettext ("cannot get DIE offset: %s"),
6409 dwarf_errmsg (-1));
6410 goto do_return;
6411 }
6412
6413 int tag = dwarf_tag (&dies[level]);
6414 if (unlikely (tag == DW_TAG_invalid))
6415 {
6416 if (!silent)
6417 error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
6418 "] in section '%s': %s"),
6419 (uint64_t) offset, secname, dwarf_errmsg (-1));
6420 goto do_return;
6421 }
6422
6423 if (!silent)
6424 {
6425 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
6426 printf (" [%6" PRIx64 "] %*s%-20s abbrev: %u\n",
6427 (uint64_t) offset, (int) (level * 2), "",
6428 dwarf_tag_name (tag), code);
6429 }
6430
6431 /* Print the attribute values. */
6432 args.level = level;
6433 args.die = &dies[level];
6434 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6435
6436 /* Make room for the next level's DIE. */
6437 if (level + 1 == maxdies)
6438 dies = (Dwarf_Die *) xrealloc (dies,
6439 (maxdies += 10)
6440 * sizeof (Dwarf_Die));
6441
6442 int res = dwarf_child (&dies[level], &dies[level + 1]);
6443 if (res > 0)
6444 {
6445 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6446 if (level-- == 0)
6447 break;
6448
6449 if (unlikely (res == -1))
6450 {
6451 if (!silent)
6452 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6453 dwarf_errmsg (-1));
6454 goto do_return;
6455 }
6456 }
6457 else if (unlikely (res < 0))
6458 {
6459 if (!silent)
6460 error (0, 0, gettext ("cannot get next DIE: %s"),
6461 dwarf_errmsg (-1));
6462 goto do_return;
6463 }
6464 else
6465 ++level;
6466 }
6467 while (level >= 0);
6468
6469 offset = nextcu;
6470 if (offset != 0)
6471 goto next_cu;
6472
6473 do_return:
6474 free (dies);
6475}
6476
6477static void
6478print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6479 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6480{
6481 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6482}
6483
6484static void
6485print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6486 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6487{
6488 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6489}
6490
6491
6492static void
6493print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6494 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6495{
6496 printf (gettext ("\
6497\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6498 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6499 (uint64_t) shdr->sh_offset);
6500
6501 size_t address_size
6502 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6503
6504 Dwarf_Off cuoffset;
6505 Dwarf_Off ncuoffset = 0;
6506 size_t hsize;
6507 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6508 NULL, NULL, NULL) == 0)
6509 {
6510 Dwarf_Die cudie;
6511 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6512 continue;
6513
6514 size_t nlines;
6515 Dwarf_Lines *lines;
6516 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6517 continue;
6518
6519 printf (" CU [%" PRIx64 "] %s\n",
6520 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6521 printf (" line:col SBPE* disc isa op address"
6522 " (Statement Block Prologue Epilogue *End)\n");
6523 const char *last_file = "";
6524 for (size_t n = 0; n < nlines; n++)
6525 {
6526 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6527 if (line == NULL)
6528 {
6529 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6530 continue;
6531 }
6532 Dwarf_Word mtime, length;
6533 const char *file = dwarf_linesrc (line, &mtime, &length);
6534 if (file == NULL)
6535 {
6536 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6537 last_file = "";
6538 }
6539 else if (strcmp (last_file, file) != 0)
6540 {
6541 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6542 file, mtime, length);
6543 last_file = file;
6544 }
6545
6546 int lineno, colno;
6547 bool statement, endseq, block, prologue_end, epilogue_begin;
6548 unsigned int lineop, isa, disc;
6549 Dwarf_Addr address;
6550 dwarf_lineaddr (line, &address);
6551 dwarf_lineno (line, &lineno);
6552 dwarf_linecol (line, &colno);
6553 dwarf_lineop_index (line, &lineop);
6554 dwarf_linebeginstatement (line, &statement);
6555 dwarf_lineendsequence (line, &endseq);
6556 dwarf_lineblock (line, &block);
6557 dwarf_lineprologueend (line, &prologue_end);
6558 dwarf_lineepiloguebegin (line, &epilogue_begin);
6559 dwarf_lineisa (line, &isa);
6560 dwarf_linediscriminator (line, &disc);
6561
6562 /* End sequence is special, it is one byte past. */
6563 char *a = format_dwarf_addr (dwflmod, address_size,
6564 address - (endseq ? 1 : 0), address);
6565 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6566 lineno, colno,
6567 (statement ? 'S' : ' '),
6568 (block ? 'B' : ' '),
6569 (prologue_end ? 'P' : ' '),
6570 (epilogue_begin ? 'E' : ' '),
6571 (endseq ? '*' : ' '),
6572 disc, isa, lineop, a);
6573 free (a);
6574
6575 if (endseq)
6576 printf("\n");
6577 }
6578 }
6579}
6580
6581
6582static void
6583print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6584 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6585{
6586 if (decodedline)
6587 {
6588 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6589 return;
6590 }
6591
6592 printf (gettext ("\
6593\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6594 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6595 (uint64_t) shdr->sh_offset);
6596
6597 if (shdr->sh_size == 0)
6598 return;
6599
6600 /* There is no functionality in libdw to read the information in the
6601 way it is represented here. Hardcode the decoder. */
6602 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6603 if (unlikely (data == NULL || data->d_buf == NULL))
6604 {
6605 error (0, 0, gettext ("cannot get line data section data: %s"),
6606 elf_errmsg (-1));
6607 return;
6608 }
6609
6610 const unsigned char *linep = (const unsigned char *) data->d_buf;
6611 const unsigned char *lineendp;
6612
6613 while (linep
6614 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6615 {
6616 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6617
6618 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
6619
6620 if (unlikely (linep + 4 > lineendp))
6621 goto invalid_data;
6622 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6623 unsigned int length = 4;
6624 if (unlikely (unit_length == 0xffffffff))
6625 {
6626 if (unlikely (linep + 8 > lineendp))
6627 {
6628 invalid_data:
6629 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6630 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6631 return;
6632 }
6633 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6634 length = 8;
6635 }
6636
6637 /* Check whether we have enough room in the section. */
6638 if (unlikely (unit_length > (size_t) (lineendp - linep)
6639 || unit_length < 2 + length + 5 * 1))
6640 goto invalid_data;
6641 lineendp = linep + unit_length;
6642
6643 /* The next element of the header is the version identifier. */
6644 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6645
6646 /* Next comes the header length. */
6647 Dwarf_Word header_length;
6648 if (length == 4)
6649 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6650 else
6651 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6652 //const unsigned char *header_start = linep;
6653
6654 /* Next the minimum instruction length. */
6655 uint_fast8_t minimum_instr_len = *linep++;
6656
6657 /* Next the maximum operations per instruction, in version 4 format. */
6658 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6659
6660 /* Then the flag determining the default value of the is_stmt
6661 register. */
6662 uint_fast8_t default_is_stmt = *linep++;
6663
6664 /* Now the line base. */
6665 int_fast8_t line_base = *((const int_fast8_t *) linep);
6666 ++linep;
6667
6668 /* And the line range. */
6669 uint_fast8_t line_range = *linep++;
6670
6671 /* The opcode base. */
6672 uint_fast8_t opcode_base = *linep++;
6673
6674 /* Print what we got so far. */
6675 printf (gettext ("\n"
6676 " Length: %" PRIu64 "\n"
6677 " DWARF version: %" PRIuFAST16 "\n"
6678 " Prologue length: %" PRIu64 "\n"
6679 " Minimum instruction length: %" PRIuFAST8 "\n"
6680 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6681 " Initial value if '%s': %" PRIuFAST8 "\n"
6682 " Line base: %" PRIdFAST8 "\n"
6683 " Line range: %" PRIuFAST8 "\n"
6684 " Opcode base: %" PRIuFAST8 "\n"
6685 "\n"
6686 "Opcodes:\n"),
6687 (uint64_t) unit_length, version, (uint64_t) header_length,
6688 minimum_instr_len, max_ops_per_instr,
6689 "is_stmt", default_is_stmt, line_base,
6690 line_range, opcode_base);
6691
6692 if (unlikely (linep + opcode_base - 1 >= lineendp))
6693 {
6694 invalid_unit:
6695 error (0, 0,
6696 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6697 linep - (const unsigned char *) data->d_buf,
6698 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6699 linep = lineendp;
6700 continue;
6701 }
6702 int opcode_base_l10 = 1;
6703 unsigned int tmp = opcode_base;
6704 while (tmp > 10)
6705 {
6706 tmp /= 10;
6707 ++opcode_base_l10;
6708 }
6709 const uint8_t *standard_opcode_lengths = linep - 1;
6710 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6711 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6712 " [%*" PRIuFAST8 "] %hhu arguments\n",
6713 (int) linep[cnt - 1]),
6714 opcode_base_l10, cnt, linep[cnt - 1]);
6715 linep += opcode_base - 1;
6716 if (unlikely (linep >= lineendp))
6717 goto invalid_unit;
6718
6719 puts (gettext ("\nDirectory table:"));
6720 while (*linep != 0)
6721 {
6722 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6723 if (unlikely (endp == NULL))
6724 goto invalid_unit;
6725
6726 printf (" %s\n", (char *) linep);
6727
6728 linep = endp + 1;
6729 }
6730 /* Skip the final NUL byte. */
6731 ++linep;
6732
6733 if (unlikely (linep >= lineendp))
6734 goto invalid_unit;
6735 puts (gettext ("\nFile name table:\n"
6736 " Entry Dir Time Size Name"));
6737 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6738 {
6739 /* First comes the file name. */
6740 char *fname = (char *) linep;
6741 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6742 if (unlikely (endp == NULL))
6743 goto invalid_unit;
6744 linep = endp + 1;
6745
6746 /* Then the index. */
6747 unsigned int diridx;
6748 if (lineendp - linep < 1)
6749 goto invalid_unit;
6750 get_uleb128 (diridx, linep, lineendp);
6751
6752 /* Next comes the modification time. */
6753 unsigned int mtime;
6754 if (lineendp - linep < 1)
6755 goto invalid_unit;
6756 get_uleb128 (mtime, linep, lineendp);
6757
6758 /* Finally the length of the file. */
6759 unsigned int fsize;
6760 if (lineendp - linep < 1)
6761 goto invalid_unit;
6762 get_uleb128 (fsize, linep, lineendp);
6763
6764 printf (" %-5u %-5u %-9u %-9u %s\n",
6765 cnt, diridx, mtime, fsize, fname);
6766 }
6767 /* Skip the final NUL byte. */
6768 ++linep;
6769
6770 puts (gettext ("\nLine number statements:"));
6771 Dwarf_Word address = 0;
6772 unsigned int op_index = 0;
6773 size_t line = 1;
6774 uint_fast8_t is_stmt = default_is_stmt;
6775
6776 /* Default address value, in case we do not find the CU. */
6777 size_t address_size
6778 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6779
6780 /* Determine the CU this block is for. */
6781 Dwarf_Off cuoffset;
6782 Dwarf_Off ncuoffset = 0;
6783 size_t hsize;
6784 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6785 NULL, NULL, NULL) == 0)
6786 {
6787 Dwarf_Die cudie;
6788 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6789 continue;
6790 Dwarf_Attribute stmt_list;
6791 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6792 continue;
6793 Dwarf_Word lineoff;
6794 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6795 continue;
6796 if (lineoff == start_offset)
6797 {
6798 /* Found the CU. */
6799 address_size = cudie.cu->address_size;
6800 break;
6801 }
6802 }
6803
6804 /* Apply the "operation advance" from a special opcode
6805 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6806 unsigned int op_addr_advance;
6807 bool show_op_index;
6808 inline void advance_pc (unsigned int op_advance)
6809 {
6810 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6811 / max_ops_per_instr);
6812 address += op_advance;
6813 show_op_index = (op_index > 0 ||
6814 (op_index + op_advance) % max_ops_per_instr > 0);
6815 op_index = (op_index + op_advance) % max_ops_per_instr;
6816 }
6817
6818 if (max_ops_per_instr == 0)
6819 {
6820 error (0, 0,
6821 gettext ("invalid maximum operations per instruction is zero"));
6822 linep = lineendp;
6823 continue;
6824 }
6825
6826 while (linep < lineendp)
6827 {
6828 size_t offset = linep - (const unsigned char *) data->d_buf;
6829 unsigned int u128;
6830 int s128;
6831
6832 /* Read the opcode. */
6833 unsigned int opcode = *linep++;
6834
6835 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6836 /* Is this a special opcode? */
6837 if (likely (opcode >= opcode_base))
6838 {
6839 if (unlikely (line_range == 0))
6840 goto invalid_unit;
6841
6842 /* Yes. Handling this is quite easy since the opcode value
6843 is computed with
6844
6845 opcode = (desired line increment - line_base)
6846 + (line_range * address advance) + opcode_base
6847 */
6848 int line_increment = (line_base
6849 + (opcode - opcode_base) % line_range);
6850
6851 /* Perform the increments. */
6852 line += line_increment;
6853 advance_pc ((opcode - opcode_base) / line_range);
6854
6855 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6856 if (show_op_index)
6857 printf (gettext ("\
6858 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6859 opcode, op_addr_advance, a, op_index,
6860 line_increment, line);
6861 else
6862 printf (gettext ("\
6863 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6864 opcode, op_addr_advance, a, line_increment, line);
6865 free (a);
6866 }
6867 else if (opcode == 0)
6868 {
6869 /* This an extended opcode. */
6870 if (unlikely (linep + 2 > lineendp))
6871 goto invalid_unit;
6872
6873 /* The length. */
6874 unsigned int len = *linep++;
6875
6876 if (unlikely (linep + len > lineendp))
6877 goto invalid_unit;
6878
6879 /* The sub-opcode. */
6880 opcode = *linep++;
6881
6882 printf (gettext (" extended opcode %u: "), opcode);
6883
6884 switch (opcode)
6885 {
6886 case DW_LNE_end_sequence:
6887 puts (gettext (" end of sequence"));
6888
6889 /* Reset the registers we care about. */
6890 address = 0;
6891 op_index = 0;
6892 line = 1;
6893 is_stmt = default_is_stmt;
6894 break;
6895
6896 case DW_LNE_set_address:
6897 op_index = 0;
6898 if (unlikely ((size_t) (lineendp - linep) < address_size))
6899 goto invalid_unit;
6900 if (address_size == 4)
6901 address = read_4ubyte_unaligned_inc (dbg, linep);
6902 else
6903 address = read_8ubyte_unaligned_inc (dbg, linep);
6904 {
6905 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6906 printf (gettext (" set address to %s\n"), a);
6907 free (a);
6908 }
6909 break;
6910
6911 case DW_LNE_define_file:
6912 {
6913 char *fname = (char *) linep;
6914 unsigned char *endp = memchr (linep, '\0',
6915 lineendp - linep);
6916 if (unlikely (endp == NULL))
6917 goto invalid_unit;
6918 linep = endp + 1;
6919
6920 unsigned int diridx;
6921 if (lineendp - linep < 1)
6922 goto invalid_unit;
6923 get_uleb128 (diridx, linep, lineendp);
6924 Dwarf_Word mtime;
6925 if (lineendp - linep < 1)
6926 goto invalid_unit;
6927 get_uleb128 (mtime, linep, lineendp);
6928 Dwarf_Word filelength;
6929 if (lineendp - linep < 1)
6930 goto invalid_unit;
6931 get_uleb128 (filelength, linep, lineendp);
6932
6933 printf (gettext ("\
6934 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6935 diridx, (uint64_t) mtime, (uint64_t) filelength,
6936 fname);
6937 }
6938 break;
6939
6940 case DW_LNE_set_discriminator:
6941 /* Takes one ULEB128 parameter, the discriminator. */
6942 if (unlikely (standard_opcode_lengths[opcode] != 1))
6943 goto invalid_unit;
6944
6945 get_uleb128 (u128, linep, lineendp);
6946 printf (gettext (" set discriminator to %u\n"), u128);
6947 break;
6948
6949 default:
6950 /* Unknown, ignore it. */
6951 puts (gettext (" unknown opcode"));
6952 linep += len - 1;
6953 break;
6954 }
6955 }
6956 else if (opcode <= DW_LNS_set_isa)
6957 {
6958 /* This is a known standard opcode. */
6959 switch (opcode)
6960 {
6961 case DW_LNS_copy:
6962 /* Takes no argument. */
6963 puts (gettext (" copy"));
6964 break;
6965
6966 case DW_LNS_advance_pc:
6967 /* Takes one uleb128 parameter which is added to the
6968 address. */
6969 get_uleb128 (u128, linep, lineendp);
6970 advance_pc (u128);
6971 {
6972 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6973 if (show_op_index)
6974 printf (gettext ("\
6975 advance address by %u to %s, op_index to %u\n"),
6976 op_addr_advance, a, op_index);
6977 else
6978 printf (gettext (" advance address by %u to %s\n"),
6979 op_addr_advance, a);
6980 free (a);
6981 }
6982 break;
6983
6984 case DW_LNS_advance_line:
6985 /* Takes one sleb128 parameter which is added to the
6986 line. */
6987 get_sleb128 (s128, linep, lineendp);
6988 line += s128;
6989 printf (gettext ("\
6990 advance line by constant %d to %" PRId64 "\n"),
6991 s128, (int64_t) line);
6992 break;
6993
6994 case DW_LNS_set_file:
6995 /* Takes one uleb128 parameter which is stored in file. */
6996 get_uleb128 (u128, linep, lineendp);
6997 printf (gettext (" set file to %" PRIu64 "\n"),
6998 (uint64_t) u128);
6999 break;
7000
7001 case DW_LNS_set_column:
7002 /* Takes one uleb128 parameter which is stored in column. */
7003 if (unlikely (standard_opcode_lengths[opcode] != 1))
7004 goto invalid_unit;
7005
7006 get_uleb128 (u128, linep, lineendp);
7007 printf (gettext (" set column to %" PRIu64 "\n"),
7008 (uint64_t) u128);
7009 break;
7010
7011 case DW_LNS_negate_stmt:
7012 /* Takes no argument. */
7013 is_stmt = 1 - is_stmt;
7014 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
7015 "is_stmt", is_stmt);
7016 break;
7017
7018 case DW_LNS_set_basic_block:
7019 /* Takes no argument. */
7020 puts (gettext (" set basic block flag"));
7021 break;
7022
7023 case DW_LNS_const_add_pc:
7024 /* Takes no argument. */
7025
7026 if (unlikely (line_range == 0))
7027 goto invalid_unit;
7028
7029 advance_pc ((255 - opcode_base) / line_range);
7030 {
7031 char *a = format_dwarf_addr (dwflmod, 0, address, address);
7032 if (show_op_index)
7033 printf (gettext ("\
7034 advance address by constant %u to %s, op_index to %u\n"),
7035 op_addr_advance, a, op_index);
7036 else
7037 printf (gettext ("\
7038 advance address by constant %u to %s\n"),
7039 op_addr_advance, a);
7040 free (a);
7041 }
7042 break;
7043
7044 case DW_LNS_fixed_advance_pc:
7045 /* Takes one 16 bit parameter which is added to the
7046 address. */
7047 if (unlikely (standard_opcode_lengths[opcode] != 1))
7048 goto invalid_unit;
7049
7050 u128 = read_2ubyte_unaligned_inc (dbg, linep);
7051 address += u128;
7052 op_index = 0;
7053 {
7054 char *a = format_dwarf_addr (dwflmod, 0, address, address);
7055 printf (gettext ("\
7056 advance address by fixed value %u to %s\n"),
7057 u128, a);
7058 free (a);
7059 }
7060 break;
7061
7062 case DW_LNS_set_prologue_end:
7063 /* Takes no argument. */
7064 puts (gettext (" set prologue end flag"));
7065 break;
7066
7067 case DW_LNS_set_epilogue_begin:
7068 /* Takes no argument. */
7069 puts (gettext (" set epilogue begin flag"));
7070 break;
7071
7072 case DW_LNS_set_isa:
7073 /* Takes one uleb128 parameter which is stored in isa. */
7074 if (unlikely (standard_opcode_lengths[opcode] != 1))
7075 goto invalid_unit;
7076
7077 get_uleb128 (u128, linep, lineendp);
7078 printf (gettext (" set isa to %u\n"), u128);
7079 break;
7080 }
7081 }
7082 else
7083 {
7084 /* This is a new opcode the generator but not we know about.
7085 Read the parameters associated with it but then discard
7086 everything. Read all the parameters for this opcode. */
7087 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
7088 " unknown opcode with %" PRIu8 " parameters:",
7089 standard_opcode_lengths[opcode]),
7090 standard_opcode_lengths[opcode]);
7091 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
7092 {
7093 get_uleb128 (u128, linep, lineendp);
7094 if (n != standard_opcode_lengths[opcode])
7095 putc_unlocked (',', stdout);
7096 printf (" %u", u128);
7097 }
7098
7099 /* Next round, ignore this opcode. */
7100 continue;
7101 }
7102 }
7103 }
7104
7105 /* There must only be one data block. */
7106 assert (elf_getdata (scn, data) == NULL);
7107}
7108
7109
7110static void
7111print_debug_loc_section (Dwfl_Module *dwflmod,
7112 Ebl *ebl, GElf_Ehdr *ehdr,
7113 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7114{
7115 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
7116
7117 if (unlikely (data == NULL))
7118 {
7119 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
7120 elf_errmsg (-1));
7121 return;
7122 }
7123
7124 printf (gettext ("\
7125\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7126 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7127 (uint64_t) shdr->sh_offset);
7128
7129 sort_listptr (&known_loclistptr, "loclistptr");
7130 size_t listptr_idx = 0;
7131
7132 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7133 uint_fast8_t offset_size = 4;
7134
7135 bool first = true;
7136 Dwarf_Addr base = 0;
7137 unsigned char *readp = data->d_buf;
7138 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
7139 Dwarf_CU *last_cu = NULL;
7140 while (readp < endp)
7141 {
7142 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
7143 Dwarf_CU *cu = last_cu;
7144
7145 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
7146 &address_size, &offset_size, &base,
7147 &cu, offset, &readp, endp))
7148 continue;
7149
7150 if (last_cu != cu)
7151 {
7152 char *basestr = format_dwarf_addr (dwflmod, address_size,
7153 base, base);
7154 Dwarf_Die cudie;
7155 if (dwarf_cu_die (cu, &cudie,
7156 NULL, NULL, NULL, NULL,
7157 NULL, NULL) == NULL)
7158 printf (gettext ("\n Unknown CU base: %s\n"), basestr);
7159 else
7160 printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"),
7161 dwarf_dieoffset (&cudie), basestr);
7162 free (basestr);
7163 }
7164 last_cu = cu;
7165
7166 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
7167 {
7168 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
7169 break;
7170 }
7171
7172 Dwarf_Addr begin;
7173 Dwarf_Addr end;
7174 if (address_size == 8)
7175 {
7176 begin = read_8ubyte_unaligned_inc (dbg, readp);
7177 end = read_8ubyte_unaligned_inc (dbg, readp);
7178 }
7179 else
7180 {
7181 begin = read_4ubyte_unaligned_inc (dbg, readp);
7182 end = read_4ubyte_unaligned_inc (dbg, readp);
7183 if (begin == (Dwarf_Addr) (uint32_t) -1)
7184 begin = (Dwarf_Addr) -1l;
7185 }
7186
7187 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
7188 {
7189 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
7190 printf (gettext (" [%6tx] base address\n %s\n"), offset, b);
7191 free (b);
7192 base = end;
7193 }
7194 else if (begin == 0 && end == 0) /* End of list entry. */
7195 {
7196 if (first)
7197 printf (gettext (" [%6tx] empty list\n"), offset);
7198 first = true;
7199 }
7200 else
7201 {
7202 /* We have a location expression entry. */
7203 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
7204
7205 if (first) /* First entry in a list. */
7206 printf (" [%6tx] ", offset);
7207 else
7208 printf (" ");
7209
7210 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
7211 if (! print_unresolved_addresses)
7212 {
7213 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
7214 base + begin);
7215 char *e = format_dwarf_addr (dwflmod, address_size,
7216 base + end - 1, base + end);
7217 printf (" %s..\n", b);
7218 printf (" %s\n", e);
7219 free (b);
7220 free (e);
7221 }
7222
7223 if (endp - readp <= (ptrdiff_t) len)
7224 {
7225 fputs (gettext (" <INVALID DATA>\n"), stdout);
7226 break;
7227 }
7228
7229 print_ops (dwflmod, dbg, 11, 11,
7230 cu != NULL ? cu->version : 3,
7231 address_size, offset_size, cu, len, readp);
7232
7233 first = false;
7234 readp += len;
7235 }
7236 }
7237}
7238
7239struct mac_culist
7240{
7241 Dwarf_Die die;
7242 Dwarf_Off offset;
7243 Dwarf_Files *files;
7244 struct mac_culist *next;
7245};
7246
7247
7248static int
7249mac_compare (const void *p1, const void *p2)
7250{
7251 struct mac_culist *m1 = (struct mac_culist *) p1;
7252 struct mac_culist *m2 = (struct mac_culist *) p2;
7253
7254 if (m1->offset < m2->offset)
7255 return -1;
7256 if (m1->offset > m2->offset)
7257 return 1;
7258 return 0;
7259}
7260
7261
7262static void
7263print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7264 Ebl *ebl, GElf_Ehdr *ehdr,
7265 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7266{
7267 printf (gettext ("\
7268\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7269 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7270 (uint64_t) shdr->sh_offset);
7271 putc_unlocked ('\n', stdout);
7272
7273 /* There is no function in libdw to iterate over the raw content of
7274 the section but it is easy enough to do. */
7275 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7276 if (unlikely (data == NULL || data->d_buf == NULL))
7277 {
7278 error (0, 0, gettext ("cannot get macro information section data: %s"),
7279 elf_errmsg (-1));
7280 return;
7281 }
7282
7283 /* Get the source file information for all CUs. */
7284 Dwarf_Off offset;
7285 Dwarf_Off ncu = 0;
7286 size_t hsize;
7287 struct mac_culist *culist = NULL;
7288 size_t nculist = 0;
7289 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7290 {
7291 Dwarf_Die cudie;
7292 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7293 continue;
7294
7295 Dwarf_Attribute attr;
7296 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7297 continue;
7298
7299 Dwarf_Word macoff;
7300 if (dwarf_formudata (&attr, &macoff) != 0)
7301 continue;
7302
7303 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7304 newp->die = cudie;
7305 newp->offset = macoff;
7306 newp->files = NULL;
7307 newp->next = culist;
7308 culist = newp;
7309 ++nculist;
7310 }
7311
7312 /* Convert the list into an array for easier consumption. */
7313 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7314 * sizeof (*cus));
7315 /* Add sentinel. */
7316 cus[nculist].offset = data->d_size;
7317 cus[nculist].files = (Dwarf_Files *) -1l;
7318 if (nculist > 0)
7319 {
7320 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7321 {
7322 assert (cnt < nculist);
7323 cus[cnt] = *culist;
7324 culist = culist->next;
7325 }
7326
7327 /* Sort the array according to the offset in the .debug_macinfo
7328 section. Note we keep the sentinel at the end. */
7329 qsort (cus, nculist, sizeof (*cus), mac_compare);
7330 }
7331
7332 const unsigned char *readp = (const unsigned char *) data->d_buf;
7333 const unsigned char *readendp = readp + data->d_size;
7334 int level = 1;
7335
7336 while (readp < readendp)
7337 {
7338 unsigned int opcode = *readp++;
7339 unsigned int u128;
7340 unsigned int u128_2;
7341 const unsigned char *endp;
7342
7343 switch (opcode)
7344 {
7345 case DW_MACINFO_define:
7346 case DW_MACINFO_undef:
7347 case DW_MACINFO_vendor_ext:
7348 /* For the first two opcodes the parameters are
7349 line, string
7350 For the latter
7351 number, string.
7352 We can treat these cases together. */
7353 get_uleb128 (u128, readp, readendp);
7354
7355 endp = memchr (readp, '\0', readendp - readp);
7356 if (unlikely (endp == NULL))
7357 {
7358 printf (gettext ("\
7359%*s*** non-terminated string at end of section"),
7360 level, "");
7361 return;
7362 }
7363
7364 if (opcode == DW_MACINFO_define)
7365 printf ("%*s#define %s, line %u\n",
7366 level, "", (char *) readp, u128);
7367 else if (opcode == DW_MACINFO_undef)
7368 printf ("%*s#undef %s, line %u\n",
7369 level, "", (char *) readp, u128);
7370 else
7371 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7372
7373 readp = endp + 1;
7374 break;
7375
7376 case DW_MACINFO_start_file:
7377 /* The two parameters are line and file index, in this order. */
7378 get_uleb128 (u128, readp, readendp);
7379 if (readendp - readp < 1)
7380 {
7381 printf (gettext ("\
7382%*s*** missing DW_MACINFO_start_file argument at end of section"),
7383 level, "");
7384 return;
7385 }
7386 get_uleb128 (u128_2, readp, readendp);
7387
7388 /* Find the CU DIE for this file. */
7389 size_t macoff = readp - (const unsigned char *) data->d_buf;
7390 const char *fname = "???";
7391 if (macoff >= cus[0].offset)
7392 {
7393 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
7394 ++cus;
7395
7396 if (cus[0].files == NULL
7397 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7398 cus[0].files = (Dwarf_Files *) -1l;
7399
7400 if (cus[0].files != (Dwarf_Files *) -1l)
7401 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7402 ?: "???");
7403 }
7404
7405 printf ("%*sstart_file %u, [%u] %s\n",
7406 level, "", u128, u128_2, fname);
7407 ++level;
7408 break;
7409
7410 case DW_MACINFO_end_file:
7411 --level;
7412 printf ("%*send_file\n", level, "");
7413 /* Nothing more to do. */
7414 break;
7415
7416 default:
7417 // XXX gcc seems to generate files with a trailing zero.
7418 if (unlikely (opcode != 0 || readp != readendp))
7419 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7420 break;
7421 }
7422 }
7423}
7424
7425
7426static void
7427print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7428 Ebl *ebl, GElf_Ehdr *ehdr,
7429 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7430{
7431 printf (gettext ("\
7432\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7433 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7434 (uint64_t) shdr->sh_offset);
7435 putc_unlocked ('\n', stdout);
7436
7437 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7438 if (unlikely (data == NULL || data->d_buf == NULL))
7439 {
7440 error (0, 0, gettext ("cannot get macro information section data: %s"),
7441 elf_errmsg (-1));
7442 return;
7443 }
7444
7445 /* Get the source file information for all CUs. Uses same
7446 datastructure as macinfo. But uses offset field to directly
7447 match .debug_line offset. And just stored in a list. */
7448 Dwarf_Off offset;
7449 Dwarf_Off ncu = 0;
7450 size_t hsize;
7451 struct mac_culist *culist = NULL;
7452 size_t nculist = 0;
7453 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7454 {
7455 Dwarf_Die cudie;
7456 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7457 continue;
7458
7459 Dwarf_Attribute attr;
7460 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7461 continue;
7462
7463 Dwarf_Word lineoff;
7464 if (dwarf_formudata (&attr, &lineoff) != 0)
7465 continue;
7466
7467 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7468 newp->die = cudie;
7469 newp->offset = lineoff;
7470 newp->files = NULL;
7471 newp->next = culist;
7472 culist = newp;
7473 ++nculist;
7474 }
7475
7476 const unsigned char *readp = (const unsigned char *) data->d_buf;
7477 const unsigned char *readendp = readp + data->d_size;
7478
7479 while (readp < readendp)
7480 {
7481 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7482 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7483
7484 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7485 // optional vendor extension macro entry table.
7486 if (readp + 2 > readendp)
7487 {
7488 invalid_data:
7489 error (0, 0, gettext ("invalid data"));
7490 return;
7491 }
7492 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7493 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7494
7495 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7496 // 5 when it gets standardized.
7497 if (vers != 4 && vers != 5)
7498 {
7499 printf (gettext (" unknown version, cannot parse section\n"));
7500 return;
7501 }
7502
7503 if (readp + 1 > readendp)
7504 goto invalid_data;
7505 const unsigned char flag = *readp++;
7506 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7507
7508 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7509 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7510 Dwarf_Off line_offset = -1;
7511 if (flag & 0x02)
7512 {
7513 if (offset_len == 8)
7514 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7515 else
7516 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7517 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7518 line_offset);
7519 }
7520
7521 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user];
7522 memset (vendor, 0, sizeof vendor);
7523 if (flag & 0x04)
7524 {
7525 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7526 // of arguments, for each argument 1 byte form code.
7527 if (readp + 1 > readendp)
7528 goto invalid_data;
7529 unsigned int tlen = *readp++;
7530 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7531 tlen);
7532 for (unsigned int i = 0; i < tlen; i++)
7533 {
7534 if (readp + 1 > readendp)
7535 goto invalid_data;
7536 unsigned int opcode = *readp++;
7537 printf (gettext (" [%" PRIx8 "]"), opcode);
7538 if (opcode < DW_MACRO_lo_user
7539 || opcode > DW_MACRO_hi_user)
7540 goto invalid_data;
7541 // Record the start of description for this vendor opcode.
7542 // uleb128 nr args, 1 byte per arg form.
7543 vendor[opcode - DW_MACRO_lo_user] = readp;
7544 if (readp + 1 > readendp)
7545 goto invalid_data;
7546 unsigned int args = *readp++;
7547 if (args > 0)
7548 {
7549 printf (gettext (" %" PRIu8 " arguments:"), args);
7550 while (args > 0)
7551 {
7552 if (readp + 1 > readendp)
7553 goto invalid_data;
7554 unsigned int form = *readp++;
7555 printf (" %s", dwarf_form_name (form));
7556 if (form != DW_FORM_data1
7557 && form != DW_FORM_data2
7558 && form != DW_FORM_data4
7559 && form != DW_FORM_data8
7560 && form != DW_FORM_sdata
7561 && form != DW_FORM_udata
7562 && form != DW_FORM_block
7563 && form != DW_FORM_block1
7564 && form != DW_FORM_block2
7565 && form != DW_FORM_block4
7566 && form != DW_FORM_flag
7567 && form != DW_FORM_string
7568 && form != DW_FORM_strp
7569 && form != DW_FORM_sec_offset)
7570 goto invalid_data;
7571 args--;
7572 if (args > 0)
7573 putchar_unlocked (',');
7574 }
7575 }
7576 else
7577 printf (gettext (" no arguments."));
7578 putchar_unlocked ('\n');
7579 }
7580 }
7581 putchar_unlocked ('\n');
7582
7583 int level = 1;
7584 if (readp + 1 > readendp)
7585 goto invalid_data;
7586 unsigned int opcode = *readp++;
7587 while (opcode != 0)
7588 {
7589 unsigned int u128;
7590 unsigned int u128_2;
7591 const unsigned char *endp;
7592 uint64_t off;
7593
7594 switch (opcode)
7595 {
7596 case DW_MACRO_start_file:
7597 get_uleb128 (u128, readp, readendp);
7598 if (readp >= readendp)
7599 goto invalid_data;
7600 get_uleb128 (u128_2, readp, readendp);
7601
7602 /* Find the CU DIE that matches this line offset. */
7603 const char *fname = "???";
7604 if (line_offset != (Dwarf_Off) -1)
7605 {
7606 struct mac_culist *cu = culist;
7607 while (cu != NULL && line_offset != cu->offset)
7608 cu = cu->next;
7609 if (cu != NULL)
7610 {
7611 if (cu->files == NULL
7612 && dwarf_getsrcfiles (&cu->die, &cu->files,
7613 NULL) != 0)
7614 cu->files = (Dwarf_Files *) -1l;
7615
7616 if (cu->files != (Dwarf_Files *) -1l)
7617 fname = (dwarf_filesrc (cu->files, u128_2,
7618 NULL, NULL) ?: "???");
7619 }
7620 }
7621 printf ("%*sstart_file %u, [%u] %s\n",
7622 level, "", u128, u128_2, fname);
7623 ++level;
7624 break;
7625
7626 case DW_MACRO_end_file:
7627 --level;
7628 printf ("%*send_file\n", level, "");
7629 break;
7630
7631 case DW_MACRO_define:
7632 get_uleb128 (u128, readp, readendp);
7633 endp = memchr (readp, '\0', readendp - readp);
7634 if (endp == NULL)
7635 goto invalid_data;
7636 printf ("%*s#define %s, line %u\n",
7637 level, "", readp, u128);
7638 readp = endp + 1;
7639 break;
7640
7641 case DW_MACRO_undef:
7642 get_uleb128 (u128, readp, readendp);
7643 endp = memchr (readp, '\0', readendp - readp);
7644 if (endp == NULL)
7645 goto invalid_data;
7646 printf ("%*s#undef %s, line %u\n",
7647 level, "", readp, u128);
7648 readp = endp + 1;
7649 break;
7650
7651 case DW_MACRO_define_strp:
7652 get_uleb128 (u128, readp, readendp);
7653 if (readp + offset_len > readendp)
7654 goto invalid_data;
7655 if (offset_len == 8)
7656 off = read_8ubyte_unaligned_inc (dbg, readp);
7657 else
7658 off = read_4ubyte_unaligned_inc (dbg, readp);
7659 printf ("%*s#define %s, line %u (indirect)\n",
7660 level, "", dwarf_getstring (dbg, off, NULL), u128);
7661 break;
7662
7663 case DW_MACRO_undef_strp:
7664 get_uleb128 (u128, readp, readendp);
7665 if (readp + offset_len > readendp)
7666 goto invalid_data;
7667 if (offset_len == 8)
7668 off = read_8ubyte_unaligned_inc (dbg, readp);
7669 else
7670 off = read_4ubyte_unaligned_inc (dbg, readp);
7671 printf ("%*s#undef %s, line %u (indirect)\n",
7672 level, "", dwarf_getstring (dbg, off, NULL), u128);
7673 break;
7674
7675 case DW_MACRO_import:
7676 if (readp + offset_len > readendp)
7677 goto invalid_data;
7678 if (offset_len == 8)
7679 off = read_8ubyte_unaligned_inc (dbg, readp);
7680 else
7681 off = read_4ubyte_unaligned_inc (dbg, readp);
7682 printf ("%*s#include offset 0x%" PRIx64 "\n",
7683 level, "", off);
7684 break;
7685
7686 case DW_MACRO_define_sup:
7687 get_uleb128 (u128, readp, readendp);
7688 if (readp + offset_len > readendp)
7689 goto invalid_data;
7690 if (offset_len == 8)
7691 off = read_8ubyte_unaligned_inc (dbg, readp);
7692 else
7693 off = read_4ubyte_unaligned_inc (dbg, readp);
7694 // Needs support for reading from supplementary object file.
7695 printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (sup)\n",
7696 level, "", off, u128);
7697 break;
7698
7699 case DW_MACRO_undef_sup:
7700 get_uleb128 (u128, readp, readendp);
7701 if (readp + offset_len > readendp)
7702 goto invalid_data;
7703 if (offset_len == 8)
7704 off = read_8ubyte_unaligned_inc (dbg, readp);
7705 else
7706 off = read_4ubyte_unaligned_inc (dbg, readp);
7707 // Needs support for reading from supplementary object file.
7708 printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (sup)\n",
7709 level, "", off, u128);
7710 break;
7711
7712 case DW_MACRO_import_sup:
7713 if (readp + offset_len > readendp)
7714 goto invalid_data;
7715 if (offset_len == 8)
7716 off = read_8ubyte_unaligned_inc (dbg, readp);
7717 else
7718 off = read_4ubyte_unaligned_inc (dbg, readp);
7719 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
7720 level, "", off);
7721 break;
7722
7723 case DW_MACRO_define_strx:
7724 get_uleb128 (u128, readp, readendp);
7725 if (readp + offset_len > readendp)
7726 goto invalid_data;
7727 if (offset_len == 8)
7728 off = read_8ubyte_unaligned_inc (dbg, readp);
7729 else
7730 off = read_4ubyte_unaligned_inc (dbg, readp);
7731 // Needs support for reading indirect string offset table
7732 printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (strx)\n",
7733 level, "", off, u128);
7734 break;
7735
7736 case DW_MACRO_undef_strx:
7737 get_uleb128 (u128, readp, readendp);
7738 if (readp + offset_len > readendp)
7739 goto invalid_data;
7740 if (offset_len == 8)
7741 off = read_8ubyte_unaligned_inc (dbg, readp);
7742 else
7743 off = read_4ubyte_unaligned_inc (dbg, readp);
7744 // Needs support for reading indirect string offset table.
7745 printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (strx)\n",
7746 level, "", off, u128);
7747 break;
7748
7749 default:
7750 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7751 if (opcode < DW_MACRO_lo_user
7752 || opcode > DW_MACRO_lo_user
7753 || vendor[opcode - DW_MACRO_lo_user] == NULL)
7754 goto invalid_data;
7755
7756 const unsigned char *op_desc;
7757 op_desc = vendor[opcode - DW_MACRO_lo_user];
7758
7759 // Just skip the arguments, we cannot really interpret them,
7760 // but print as much as we can.
7761 unsigned int args = *op_desc++;
7762 while (args > 0)
7763 {
7764 unsigned int form = *op_desc++;
7765 Dwarf_Word val;
7766 switch (form)
7767 {
7768 case DW_FORM_data1:
7769 if (readp + 1 > readendp)
7770 goto invalid_data;
7771 val = *readp++;
7772 printf (" %" PRIx8, (unsigned int) val);
7773 break;
7774
7775 case DW_FORM_data2:
7776 if (readp + 2 > readendp)
7777 goto invalid_data;
7778 val = read_2ubyte_unaligned_inc (dbg, readp);
7779 printf(" %" PRIx16, (unsigned int) val);
7780 break;
7781
7782 case DW_FORM_data4:
7783 if (readp + 4 > readendp)
7784 goto invalid_data;
7785 val = read_4ubyte_unaligned_inc (dbg, readp);
7786 printf (" %" PRIx32, (unsigned int) val);
7787 break;
7788
7789 case DW_FORM_data8:
7790 if (readp + 8 > readendp)
7791 goto invalid_data;
7792 val = read_8ubyte_unaligned_inc (dbg, readp);
7793 printf (" %" PRIx64, val);
7794 break;
7795
7796 case DW_FORM_sdata:
7797 get_sleb128 (val, readp, readendp);
7798 printf (" %" PRIx64, val);
7799 break;
7800
7801 case DW_FORM_udata:
7802 get_uleb128 (val, readp, readendp);
7803 printf (" %" PRIx64, val);
7804 break;
7805
7806 case DW_FORM_block:
7807 get_uleb128 (val, readp, readendp);
7808 printf (" block[%" PRIu64 "]", val);
7809 if (readp + val > readendp)
7810 goto invalid_data;
7811 readp += val;
7812 break;
7813
7814 case DW_FORM_block1:
7815 if (readp + 1 > readendp)
7816 goto invalid_data;
7817 val = *readp++;
7818 printf (" block[%" PRIu64 "]", val);
7819 if (readp + val > readendp)
7820 goto invalid_data;
7821 break;
7822
7823 case DW_FORM_block2:
7824 if (readp + 2 > readendp)
7825 goto invalid_data;
7826 val = read_2ubyte_unaligned_inc (dbg, readp);
7827 printf (" block[%" PRIu64 "]", val);
7828 if (readp + val > readendp)
7829 goto invalid_data;
7830 break;
7831
7832 case DW_FORM_block4:
7833 if (readp + 2 > readendp)
7834 goto invalid_data;
7835 val =read_4ubyte_unaligned_inc (dbg, readp);
7836 printf (" block[%" PRIu64 "]", val);
7837 if (readp + val > readendp)
7838 goto invalid_data;
7839 break;
7840
7841 case DW_FORM_flag:
7842 if (readp + 1 > readendp)
7843 goto invalid_data;
7844 val = *readp++;
7845 printf (" %s", val != 0 ? gettext ("yes") : gettext ("no"));
7846 break;
7847
7848 case DW_FORM_string:
7849 endp = memchr (readp, '\0', readendp - readp);
7850 if (endp == NULL)
7851 goto invalid_data;
7852 printf (" %s", readp);
7853 readp = endp + 1;
7854 break;
7855
7856 case DW_FORM_strp:
7857 if (readp + offset_len > readendp)
7858 goto invalid_data;
7859 if (offset_len == 8)
7860 val = read_8ubyte_unaligned_inc (dbg, readp);
7861 else
7862 val = read_4ubyte_unaligned_inc (dbg, readp);
7863 printf (" %s", dwarf_getstring (dbg, val, NULL));
7864 break;
7865
7866 case DW_FORM_sec_offset:
7867 if (readp + offset_len > readendp)
7868 goto invalid_data;
7869 if (offset_len == 8)
7870 val = read_8ubyte_unaligned_inc (dbg, readp);
7871 else
7872 val = read_4ubyte_unaligned_inc (dbg, readp);
7873 printf (" %" PRIx64, val);
7874 break;
7875
7876 default:
7877 error (0, 0, gettext ("vendor opcode not verified?"));
7878 return;
7879 }
7880
7881 args--;
7882 if (args > 0)
7883 putchar_unlocked (',');
7884 }
7885 putchar_unlocked ('\n');
7886 }
7887
7888 if (readp + 1 > readendp)
7889 goto invalid_data;
7890 opcode = *readp++;
7891 if (opcode == 0)
7892 putchar_unlocked ('\n');
7893 }
7894 }
7895}
7896
7897
7898/* Callback for printing global names. */
7899static int
7900print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7901 void *arg)
7902{
7903 int *np = (int *) arg;
7904
7905 printf (gettext (" [%5d] DIE offset: %6" PRId64
7906 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7907 (*np)++, global->die_offset, global->cu_offset, global->name);
7908
7909 return 0;
7910}
7911
7912
7913/* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7914static void
7915print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7916 Ebl *ebl, GElf_Ehdr *ehdr,
7917 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7918{
7919 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7920 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7921 (uint64_t) shdr->sh_offset);
7922
7923 int n = 0;
7924 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7925}
7926
7927/* Print the content of the DWARF string section '.debug_str'. */
7928static void
7929print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7930 Ebl *ebl, GElf_Ehdr *ehdr,
7931 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7932{
7933 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7934 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7935
7936 /* Compute floor(log16(shdr->sh_size)). */
7937 GElf_Addr tmp = sh_size;
7938 int digits = 1;
7939 while (tmp >= 16)
7940 {
7941 ++digits;
7942 tmp >>= 4;
7943 }
7944 digits = MAX (4, digits);
7945
7946 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7947 " %*s String\n"),
7948 elf_ndxscn (scn),
7949 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7950 /* TRANS: the debugstr| prefix makes the string unique. */
7951 digits + 2, sgettext ("debugstr|Offset"));
7952
7953 Dwarf_Off offset = 0;
7954 while (offset < sh_size)
7955 {
7956 size_t len;
7957 const char *str = dwarf_getstring (dbg, offset, &len);
7958 if (unlikely (str == NULL))
7959 {
7960 printf (gettext (" *** error while reading strings: %s\n"),
7961 dwarf_errmsg (-1));
7962 break;
7963 }
7964
7965 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7966
7967 offset += len + 1;
7968 }
7969}
7970
7971
7972/* Print the content of the call frame search table section
7973 '.eh_frame_hdr'. */
7974static void
7975print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7976 Ebl *ebl __attribute__ ((unused)),
7977 GElf_Ehdr *ehdr __attribute__ ((unused)),
7978 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7979{
7980 printf (gettext ("\
7981\nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7982 elf_ndxscn (scn));
7983
7984 Elf_Data *data = elf_rawdata (scn, NULL);
7985
7986 if (unlikely (data == NULL))
7987 {
7988 error (0, 0, gettext ("cannot get %s content: %s"),
7989 ".eh_frame_hdr", elf_errmsg (-1));
7990 return;
7991 }
7992
7993 const unsigned char *readp = data->d_buf;
7994 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7995 + data->d_size);
7996
7997 if (unlikely (readp + 4 > dataend))
7998 {
7999 invalid_data:
8000 error (0, 0, gettext ("invalid data"));
8001 return;
8002 }
8003
8004 unsigned int version = *readp++;
8005 unsigned int eh_frame_ptr_enc = *readp++;
8006 unsigned int fde_count_enc = *readp++;
8007 unsigned int table_enc = *readp++;
8008
8009 printf (" version: %u\n"
8010 " eh_frame_ptr_enc: %#x ",
8011 version, eh_frame_ptr_enc);
8012 print_encoding_base ("", eh_frame_ptr_enc);
8013 printf (" fde_count_enc: %#x ", fde_count_enc);
8014 print_encoding_base ("", fde_count_enc);
8015 printf (" table_enc: %#x ", table_enc);
8016 print_encoding_base ("", table_enc);
8017
8018 uint64_t eh_frame_ptr = 0;
8019 if (eh_frame_ptr_enc != DW_EH_PE_omit)
8020 {
8021 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
8022 dbg);
8023 if (unlikely (readp == NULL))
8024 goto invalid_data;
8025
8026 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
8027 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
8028 printf (" (offset: %#" PRIx64 ")",
8029 /* +4 because of the 4 byte header of the section. */
8030 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
8031
8032 putchar_unlocked ('\n');
8033 }
8034
8035 uint64_t fde_count = 0;
8036 if (fde_count_enc != DW_EH_PE_omit)
8037 {
8038 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
8039 if (unlikely (readp == NULL))
8040 goto invalid_data;
8041
8042 printf (" fde_count: %" PRIu64 "\n", fde_count);
8043 }
8044
8045 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
8046 return;
8047
8048 puts (" Table:");
8049
8050 /* Optimize for the most common case. */
8051 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
8052 while (fde_count > 0 && readp + 8 <= dataend)
8053 {
8054 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
8055 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
8056 + (int64_t) initial_location);
8057 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
8058 // XXX Possibly print symbol name or section offset for initial_offset
8059 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
8060 " fde=[%6" PRIx64 "]\n",
8061 initial_location, initial_offset,
8062 address, address - (eh_frame_ptr + 4));
8063 }
8064 else
8065 while (0 && readp < dataend)
8066 {
8067
8068 }
8069}
8070
8071
8072/* Print the content of the exception handling table section
8073 '.eh_frame_hdr'. */
8074static void
8075print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
8076 Ebl *ebl __attribute__ ((unused)),
8077 GElf_Ehdr *ehdr __attribute__ ((unused)),
8078 Elf_Scn *scn,
8079 GElf_Shdr *shdr __attribute__ ((unused)),
8080 Dwarf *dbg __attribute__ ((unused)))
8081{
8082 printf (gettext ("\
8083\nException handling table section [%2zu] '.gcc_except_table':\n"),
8084 elf_ndxscn (scn));
8085
8086 Elf_Data *data = elf_rawdata (scn, NULL);
8087
8088 if (unlikely (data == NULL))
8089 {
8090 error (0, 0, gettext ("cannot get %s content: %s"),
8091 ".gcc_except_table", elf_errmsg (-1));
8092 return;
8093 }
8094
8095 const unsigned char *readp = data->d_buf;
8096 const unsigned char *const dataend = readp + data->d_size;
8097
8098 if (unlikely (readp + 1 > dataend))
8099 {
8100 invalid_data:
8101 error (0, 0, gettext ("invalid data"));
8102 return;
8103 }
8104 unsigned int lpstart_encoding = *readp++;
8105 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
8106 print_encoding_base ("", lpstart_encoding);
8107 if (lpstart_encoding != DW_EH_PE_omit)
8108 {
8109 uint64_t lpstart;
8110 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
8111 printf (" LPStart: %#" PRIx64 "\n", lpstart);
8112 }
8113
8114 if (unlikely (readp + 1 > dataend))
8115 goto invalid_data;
8116 unsigned int ttype_encoding = *readp++;
8117 printf (gettext (" TType encoding: %#x "), ttype_encoding);
8118 print_encoding_base ("", ttype_encoding);
8119 const unsigned char *ttype_base = NULL;
8120 if (ttype_encoding != DW_EH_PE_omit)
8121 {
8122 unsigned int ttype_base_offset;
8123 get_uleb128 (ttype_base_offset, readp, dataend);
8124 printf (" TType base offset: %#x\n", ttype_base_offset);
8125 if ((size_t) (dataend - readp) > ttype_base_offset)
8126 ttype_base = readp + ttype_base_offset;
8127 }
8128
8129 if (unlikely (readp + 1 > dataend))
8130 goto invalid_data;
8131 unsigned int call_site_encoding = *readp++;
8132 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
8133 print_encoding_base ("", call_site_encoding);
8134 unsigned int call_site_table_len;
8135 get_uleb128 (call_site_table_len, readp, dataend);
8136
8137 const unsigned char *const action_table = readp + call_site_table_len;
8138 if (unlikely (action_table > dataend))
8139 goto invalid_data;
8140 unsigned int u = 0;
8141 unsigned int max_action = 0;
8142 while (readp < action_table)
8143 {
8144 if (u == 0)
8145 puts (gettext ("\n Call site table:"));
8146
8147 uint64_t call_site_start;
8148 readp = read_encoded (call_site_encoding, readp, dataend,
8149 &call_site_start, dbg);
8150 uint64_t call_site_length;
8151 readp = read_encoded (call_site_encoding, readp, dataend,
8152 &call_site_length, dbg);
8153 uint64_t landing_pad;
8154 readp = read_encoded (call_site_encoding, readp, dataend,
8155 &landing_pad, dbg);
8156 unsigned int action;
8157 get_uleb128 (action, readp, dataend);
8158 max_action = MAX (action, max_action);
8159 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
8160 " Call site length: %" PRIu64 "\n"
8161 " Landing pad: %#" PRIx64 "\n"
8162 " Action: %u\n"),
8163 u++, call_site_start, call_site_length, landing_pad, action);
8164 }
8165 if (readp != action_table)
8166 goto invalid_data;
8167
8168 unsigned int max_ar_filter = 0;
8169 if (max_action > 0)
8170 {
8171 puts ("\n Action table:");
8172
8173 size_t maxdata = (size_t) (dataend - action_table);
8174 if (max_action > maxdata || maxdata - max_action < 1)
8175 {
8176 invalid_action_table:
8177 fputs (gettext (" <INVALID DATA>\n"), stdout);
8178 return;
8179 }
8180
8181 const unsigned char *const action_table_end
8182 = action_table + max_action + 1;
8183
8184 u = 0;
8185 do
8186 {
8187 int ar_filter;
8188 get_sleb128 (ar_filter, readp, action_table_end);
8189 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
8190 max_ar_filter = ar_filter;
8191 int ar_disp;
8192 if (readp >= action_table_end)
8193 goto invalid_action_table;
8194 get_sleb128 (ar_disp, readp, action_table_end);
8195
8196 printf (" [%4u] ar_filter: % d\n"
8197 " ar_disp: % -5d",
8198 u, ar_filter, ar_disp);
8199 if (abs (ar_disp) & 1)
8200 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
8201 else if (ar_disp != 0)
8202 puts (" -> ???");
8203 else
8204 putchar_unlocked ('\n');
8205 ++u;
8206 }
8207 while (readp < action_table_end);
8208 }
8209
8210 if (max_ar_filter > 0 && ttype_base != NULL)
8211 {
8212 unsigned char dsize;
8213 puts ("\n TType table:");
8214
8215 // XXX Not *4, size of encoding;
8216 switch (ttype_encoding & 7)
8217 {
8218 case DW_EH_PE_udata2:
8219 case DW_EH_PE_sdata2:
8220 dsize = 2;
8221 break;
8222 case DW_EH_PE_udata4:
8223 case DW_EH_PE_sdata4:
8224 dsize = 4;
8225 break;
8226 case DW_EH_PE_udata8:
8227 case DW_EH_PE_sdata8:
8228 dsize = 8;
8229 break;
8230 default:
8231 dsize = 0;
8232 error (1, 0, gettext ("invalid TType encoding"));
8233 }
8234
8235 if (max_ar_filter
8236 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
8237 goto invalid_data;
8238
8239 readp = ttype_base - max_ar_filter * dsize;
8240 do
8241 {
8242 uint64_t ttype;
8243 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
8244 dbg);
8245 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
8246 }
8247 while (readp < ttype_base);
8248 }
8249}
8250
8251/* Print the content of the '.gdb_index' section.
8252 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
8253*/
8254static void
8255print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8256 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8257{
8258 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
8259 " contains %" PRId64 " bytes :\n"),
8260 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
8261 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
8262
8263 Elf_Data *data = elf_rawdata (scn, NULL);
8264
8265 if (unlikely (data == NULL))
8266 {
8267 error (0, 0, gettext ("cannot get %s content: %s"),
8268 ".gdb_index", elf_errmsg (-1));
8269 return;
8270 }
8271
8272 // .gdb_index is always in little endian.
8273 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
8274 dbg = &dummy_dbg;
8275
8276 const unsigned char *readp = data->d_buf;
8277 const unsigned char *const dataend = readp + data->d_size;
8278
8279 if (unlikely (readp + 4 > dataend))
8280 {
8281 invalid_data:
8282 error (0, 0, gettext ("invalid data"));
8283 return;
8284 }
8285
8286 int32_t vers = read_4ubyte_unaligned (dbg, readp);
8287 printf (gettext (" Version: %" PRId32 "\n"), vers);
8288
8289 // The only difference between version 4 and version 5 is the
8290 // hash used for generating the table. Version 6 contains symbols
8291 // for inlined functions, older versions didn't. Version 7 adds
8292 // symbol kinds. Version 8 just indicates that it correctly includes
8293 // TUs for symbols.
8294 if (vers < 4 || vers > 8)
8295 {
8296 printf (gettext (" unknown version, cannot parse section\n"));
8297 return;
8298 }
8299
8300 readp += 4;
8301 if (unlikely (readp + 4 > dataend))
8302 goto invalid_data;
8303
8304 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
8305 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
8306
8307 readp += 4;
8308 if (unlikely (readp + 4 > dataend))
8309 goto invalid_data;
8310
8311 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
8312 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
8313
8314 readp += 4;
8315 if (unlikely (readp + 4 > dataend))
8316 goto invalid_data;
8317
8318 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
8319 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
8320
8321 readp += 4;
8322 if (unlikely (readp + 4 > dataend))
8323 goto invalid_data;
8324
8325 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8326 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
8327
8328 readp += 4;
8329 if (unlikely (readp + 4 > dataend))
8330 goto invalid_data;
8331
8332 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8333 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8334
8335 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
8336 < const_off))
8337 goto invalid_data;
8338
8339 readp = data->d_buf + cu_off;
8340
8341 const unsigned char *nextp = data->d_buf + tu_off;
8342 if (tu_off >= data->d_size)
8343 goto invalid_data;
8344
8345 size_t cu_nr = (nextp - readp) / 16;
8346
8347 printf (gettext ("\n CU list at offset %#" PRIx32
8348 " contains %zu entries:\n"),
8349 cu_off, cu_nr);
8350
8351 size_t n = 0;
8352 while (dataend - readp >= 16 && n < cu_nr)
8353 {
8354 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8355 readp += 8;
8356
8357 uint64_t len = read_8ubyte_unaligned (dbg, readp);
8358 readp += 8;
8359
8360 printf (" [%4zu] start: %0#8" PRIx64
8361 ", length: %5" PRIu64 "\n", n, off, len);
8362 n++;
8363 }
8364
8365 readp = data->d_buf + tu_off;
8366 nextp = data->d_buf + addr_off;
8367 if (addr_off >= data->d_size)
8368 goto invalid_data;
8369
8370 size_t tu_nr = (nextp - readp) / 24;
8371
8372 printf (gettext ("\n TU list at offset %#" PRIx32
8373 " contains %zu entries:\n"),
8374 tu_off, tu_nr);
8375
8376 n = 0;
8377 while (dataend - readp >= 24 && n < tu_nr)
8378 {
8379 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8380 readp += 8;
8381
8382 uint64_t type = read_8ubyte_unaligned (dbg, readp);
8383 readp += 8;
8384
8385 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8386 readp += 8;
8387
8388 printf (" [%4zu] CU offset: %5" PRId64
8389 ", type offset: %5" PRId64
8390 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8391 n++;
8392 }
8393
8394 readp = data->d_buf + addr_off;
8395 nextp = data->d_buf + sym_off;
8396 if (sym_off >= data->d_size)
8397 goto invalid_data;
8398
8399 size_t addr_nr = (nextp - readp) / 20;
8400
8401 printf (gettext ("\n Address list at offset %#" PRIx32
8402 " contains %zu entries:\n"),
8403 addr_off, addr_nr);
8404
8405 n = 0;
8406 while (dataend - readp >= 20 && n < addr_nr)
8407 {
8408 uint64_t low = read_8ubyte_unaligned (dbg, readp);
8409 readp += 8;
8410
8411 uint64_t high = read_8ubyte_unaligned (dbg, readp);
8412 readp += 8;
8413
8414 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8415 readp += 4;
8416
8417 char *l = format_dwarf_addr (dwflmod, 8, low, low);
8418 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8419 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8420 n, l, h, idx);
8421 free (l);
8422 free (h);
8423 n++;
8424 }
8425
8426 const unsigned char *const_start = data->d_buf + const_off;
8427 if (const_off >= data->d_size)
8428 goto invalid_data;
8429
8430 readp = data->d_buf + sym_off;
8431 nextp = const_start;
8432 size_t sym_nr = (nextp - readp) / 8;
8433
8434 printf (gettext ("\n Symbol table at offset %#" PRIx32
8435 " contains %zu slots:\n"),
8436 addr_off, sym_nr);
8437
8438 n = 0;
8439 while (dataend - readp >= 8 && n < sym_nr)
8440 {
8441 uint32_t name = read_4ubyte_unaligned (dbg, readp);
8442 readp += 4;
8443
8444 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8445 readp += 4;
8446
8447 if (name != 0 || vector != 0)
8448 {
8449 const unsigned char *sym = const_start + name;
8450 if (unlikely ((size_t) (dataend - const_start) < name
8451 || memchr (sym, '\0', dataend - sym) == NULL))
8452 goto invalid_data;
8453
8454 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8455
8456 const unsigned char *readcus = const_start + vector;
8457 if (unlikely ((size_t) (dataend - const_start) < vector))
8458 goto invalid_data;
8459 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8460 while (cus--)
8461 {
8462 uint32_t cu_kind, cu, kind;
8463 bool is_static;
8464 readcus += 4;
8465 if (unlikely (readcus + 4 > dataend))
8466 goto invalid_data;
8467 cu_kind = read_4ubyte_unaligned (dbg, readcus);
8468 cu = cu_kind & ((1 << 24) - 1);
8469 kind = (cu_kind >> 28) & 7;
8470 is_static = cu_kind & (1U << 31);
8471 if (cu > cu_nr - 1)
8472 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8473 else
8474 printf ("%" PRId32, cu);
8475 if (kind != 0)
8476 {
8477 printf (" (");
8478 switch (kind)
8479 {
8480 case 1:
8481 printf ("type");
8482 break;
8483 case 2:
8484 printf ("var");
8485 break;
8486 case 3:
8487 printf ("func");
8488 break;
8489 case 4:
8490 printf ("other");
8491 break;
8492 default:
8493 printf ("unknown-0x%" PRIx32, kind);
8494 break;
8495 }
8496 printf (":%c)", (is_static ? 'S' : 'G'));
8497 }
8498 if (cus > 0)
8499 printf (", ");
8500 }
8501 printf ("\n");
8502 }
8503 n++;
8504 }
8505}
8506
8507static void
8508print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8509{
8510 /* Before we start the real work get a debug context descriptor. */
8511 Dwarf_Addr dwbias;
8512 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8513 Dwarf dummy_dbg =
8514 {
8515 .elf = ebl->elf,
8516 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8517 };
8518 if (dbg == NULL)
8519 {
8520 if ((print_debug_sections & ~section_exception) != 0)
8521 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8522 dwfl_errmsg (-1));
8523 dbg = &dummy_dbg;
8524 }
8525
8526 /* Get the section header string table index. */
8527 size_t shstrndx;
8528 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8529 error (EXIT_FAILURE, 0,
8530 gettext ("cannot get section header string table index"));
8531
8532 /* Look through all the sections for the debugging sections to print. */
8533 Elf_Scn *scn = NULL;
8534 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8535 {
8536 GElf_Shdr shdr_mem;
8537 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8538
8539 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8540 {
8541 static const struct
8542 {
8543 const char *name;
8544 enum section_e bitmask;
8545 void (*fp) (Dwfl_Module *, Ebl *,
8546 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8547 } debug_sections[] =
8548 {
8549#define NEW_SECTION(name) \
8550 { ".debug_" #name, section_##name, print_debug_##name##_section }
8551 NEW_SECTION (abbrev),
8552 NEW_SECTION (aranges),
8553 NEW_SECTION (frame),
8554 NEW_SECTION (info),
8555 NEW_SECTION (types),
8556 NEW_SECTION (line),
8557 NEW_SECTION (loc),
8558 NEW_SECTION (pubnames),
8559 NEW_SECTION (str),
8560 NEW_SECTION (macinfo),
8561 NEW_SECTION (macro),
8562 NEW_SECTION (ranges),
8563 { ".eh_frame", section_frame | section_exception,
8564 print_debug_frame_section },
8565 { ".eh_frame_hdr", section_frame | section_exception,
8566 print_debug_frame_hdr_section },
8567 { ".gcc_except_table", section_frame | section_exception,
8568 print_debug_exception_table },
8569 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8570 };
8571 const int ndebug_sections = (sizeof (debug_sections)
8572 / sizeof (debug_sections[0]));
8573 const char *name = elf_strptr (ebl->elf, shstrndx,
8574 shdr->sh_name);
8575 if (name == NULL)
8576 continue;
8577
8578 int n;
8579 for (n = 0; n < ndebug_sections; ++n)
8580 if (strcmp (name, debug_sections[n].name) == 0
8581 || (name[0] == '.' && name[1] == 'z'
8582 && debug_sections[n].name[1] == 'd'
8583 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8584 )
8585 {
8586 if ((print_debug_sections | implicit_debug_sections)
8587 & debug_sections[n].bitmask)
8588 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8589 break;
8590 }
8591 }
8592 }
8593
8594 reset_listptr (&known_loclistptr);
8595 reset_listptr (&known_rangelistptr);
8596}
8597
8598
8599#define ITEM_INDENT 4
8600#define WRAP_COLUMN 75
8601
8602/* Print "NAME: FORMAT", wrapping when output text would make the line
8603 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8604 but this function is also used for registers which should be printed
8605 aligned. Fortunately registers output uses fixed fields width (such
8606 as %11d) for the alignment.
8607
8608 Line breaks should not depend on the particular values although that
8609 may happen in some cases of the core items. */
8610
8611static unsigned int
8612__attribute__ ((format (printf, 6, 7)))
8613print_core_item (unsigned int colno, char sep, unsigned int wrap,
8614 size_t name_width, const char *name, const char *format, ...)
8615{
8616 size_t len = strlen (name);
8617 if (name_width < len)
8618 name_width = len;
8619
8620 char *out;
8621 va_list ap;
8622 va_start (ap, format);
8623 int out_len = vasprintf (&out, format, ap);
8624 va_end (ap);
8625 if (out_len == -1)
8626 error (EXIT_FAILURE, 0, _("memory exhausted"));
8627
8628 size_t n = name_width + sizeof ": " - 1 + out_len;
8629
8630 if (colno == 0)
8631 {
8632 printf ("%*s", ITEM_INDENT, "");
8633 colno = ITEM_INDENT + n;
8634 }
8635 else if (colno + 2 + n < wrap)
8636 {
8637 printf ("%c ", sep);
8638 colno += 2 + n;
8639 }
8640 else
8641 {
8642 printf ("\n%*s", ITEM_INDENT, "");
8643 colno = ITEM_INDENT + n;
8644 }
8645
8646 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8647
8648 free (out);
8649
8650 return colno;
8651}
8652
8653static const void *
8654convert (Elf *core, Elf_Type type, uint_fast16_t count,
8655 void *value, const void *data, size_t size)
8656{
8657 Elf_Data valuedata =
8658 {
8659 .d_type = type,
8660 .d_buf = value,
8661 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8662 .d_version = EV_CURRENT,
8663 };
8664 Elf_Data indata =
8665 {
8666 .d_type = type,
8667 .d_buf = (void *) data,
8668 .d_size = valuedata.d_size,
8669 .d_version = EV_CURRENT,
8670 };
8671
8672 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8673 ? elf32_xlatetom : elf64_xlatetom)
8674 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8675 if (d == NULL)
8676 error (EXIT_FAILURE, 0,
8677 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8678
8679 return data + indata.d_size;
8680}
8681
8682typedef uint8_t GElf_Byte;
8683
8684static unsigned int
8685handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8686 unsigned int colno, size_t *repeated_size)
8687{
8688 uint_fast16_t count = item->count ?: 1;
8689 /* Ebl_Core_Item count is always a small number.
8690 Make sure the backend didn't put in some large bogus value. */
8691 assert (count < 128);
8692
8693#define TYPES \
8694 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8695 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8696 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8697 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8698 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8699 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8700
8701#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
8702 typedef union { TYPES; } value_t;
8703 void *data = alloca (count * sizeof (value_t));
8704#undef DO_TYPE
8705
8706#define DO_TYPE(NAME, Name, hex, dec) \
8707 GElf_##Name *value_##Name __attribute__((unused)) = data
8708 TYPES;
8709#undef DO_TYPE
8710
8711 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8712 size_t convsize = size;
8713 if (repeated_size != NULL)
8714 {
8715 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8716 {
8717 data = alloca (*repeated_size);
8718 count *= *repeated_size / size;
8719 convsize = count * size;
8720 *repeated_size -= convsize;
8721 }
8722 else if (item->count != 0 || item->format != '\n')
8723 *repeated_size -= size;
8724 }
8725
8726 convert (core, item->type, count, data, desc + item->offset, convsize);
8727
8728 Elf_Type type = item->type;
8729 if (type == ELF_T_ADDR)
8730 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8731
8732 switch (item->format)
8733 {
8734 case 'd':
8735 assert (count == 1);
8736 switch (type)
8737 {
8738#define DO_TYPE(NAME, Name, hex, dec) \
8739 case ELF_T_##NAME: \
8740 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8741 0, item->name, dec, value_##Name[0]); \
8742 break
8743 TYPES;
8744#undef DO_TYPE
8745 default:
8746 abort ();
8747 }
8748 break;
8749
8750 case 'x':
8751 assert (count == 1);
8752 switch (type)
8753 {
8754#define DO_TYPE(NAME, Name, hex, dec) \
8755 case ELF_T_##NAME: \
8756 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8757 0, item->name, hex, value_##Name[0]); \
8758 break
8759 TYPES;
8760#undef DO_TYPE
8761 default:
8762 abort ();
8763 }
8764 break;
8765
8766 case 'b':
8767 case 'B':
8768 assert (size % sizeof (unsigned int) == 0);
8769 unsigned int nbits = count * size * 8;
8770 unsigned int pop = 0;
8771 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8772 pop += __builtin_popcount (*i);
8773 bool negate = pop > nbits / 2;
8774 const unsigned int bias = item->format == 'b';
8775
8776 {
8777 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8778 char *p = printed;
8779 *p = '\0';
8780
8781 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8782 {
8783 assert (size == sizeof (unsigned int) * 2);
8784 for (unsigned int *i = data;
8785 (void *) i < data + count * size; i += 2)
8786 {
8787 unsigned int w = i[1];
8788 i[1] = i[0];
8789 i[0] = w;
8790 }
8791 }
8792
8793 unsigned int lastbit = 0;
8794 unsigned int run = 0;
8795 for (const unsigned int *i = data;
8796 (void *) i < data + count * size; ++i)
8797 {
8798 unsigned int bit = ((void *) i - data) * 8;
8799 unsigned int w = negate ? ~*i : *i;
8800 while (w != 0)
8801 {
8802 /* Note that a right shift equal to (or greater than)
8803 the number of bits of w is undefined behaviour. In
8804 particular when the least significant bit is bit 32
8805 (w = 0x8000000) then w >>= n is undefined. So
8806 explicitly handle that case separately. */
8807 unsigned int n = ffs (w);
8808 if (n < sizeof (w) * 8)
8809 w >>= n;
8810 else
8811 w = 0;
8812 bit += n;
8813
8814 if (lastbit != 0 && lastbit + 1 == bit)
8815 ++run;
8816 else
8817 {
8818 if (lastbit == 0)
8819 p += sprintf (p, "%u", bit - bias);
8820 else if (run == 0)
8821 p += sprintf (p, ",%u", bit - bias);
8822 else
8823 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8824 run = 0;
8825 }
8826
8827 lastbit = bit;
8828 }
8829 }
8830 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8831 p += sprintf (p, "-%u", lastbit - bias);
8832
8833 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8834 negate ? "~<%s>" : "<%s>", printed);
8835 }
8836 break;
8837
8838 case 'T':
8839 case (char) ('T'|0x80):
8840 assert (count == 2);
8841 Dwarf_Word sec;
8842 Dwarf_Word usec;
8843 switch (type)
8844 {
8845#define DO_TYPE(NAME, Name, hex, dec) \
8846 case ELF_T_##NAME: \
8847 sec = value_##Name[0]; \
8848 usec = value_##Name[1]; \
8849 break
8850 TYPES;
8851#undef DO_TYPE
8852 default:
8853 abort ();
8854 }
8855 if (unlikely (item->format == (char) ('T'|0x80)))
8856 {
8857 /* This is a hack for an ill-considered 64-bit ABI where
8858 tv_usec is actually a 32-bit field with 32 bits of padding
8859 rounding out struct timeval. We've already converted it as
8860 a 64-bit field. For little-endian, this just means the
8861 high half is the padding; it's presumably zero, but should
8862 be ignored anyway. For big-endian, it means the 32-bit
8863 field went into the high half of USEC. */
8864 GElf_Ehdr ehdr_mem;
8865 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8866 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8867 usec >>= 32;
8868 else
8869 usec &= UINT32_MAX;
8870 }
8871 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8872 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8873 break;
8874
8875 case 'c':
8876 assert (count == 1);
8877 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8878 "%c", value_Byte[0]);
8879 break;
8880
8881 case 's':
8882 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8883 "%.*s", (int) count, value_Byte);
8884 break;
8885
8886 case '\n':
8887 /* This is a list of strings separated by '\n'. */
8888 assert (item->count == 0);
8889 assert (repeated_size != NULL);
8890 assert (item->name == NULL);
8891 if (unlikely (item->offset >= *repeated_size))
8892 break;
8893
8894 const char *s = desc + item->offset;
8895 size = *repeated_size - item->offset;
8896 *repeated_size = 0;
8897 while (size > 0)
8898 {
8899 const char *eol = memchr (s, '\n', size);
8900 int len = size;
8901 if (eol != NULL)
8902 len = eol - s;
8903 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8904 if (eol == NULL)
8905 break;
8906 size -= eol + 1 - s;
8907 s = eol + 1;
8908 }
8909
8910 colno = WRAP_COLUMN;
8911 break;
8912
8913 case 'h':
8914 break;
8915
8916 default:
8917 error (0, 0, "XXX not handling format '%c' for %s",
8918 item->format, item->name);
8919 break;
8920 }
8921
8922#undef TYPES
8923
8924 return colno;
8925}
8926
8927
8928/* Sort items by group, and by layout offset within each group. */
8929static int
8930compare_core_items (const void *a, const void *b)
8931{
8932 const Ebl_Core_Item *const *p1 = a;
8933 const Ebl_Core_Item *const *p2 = b;
8934 const Ebl_Core_Item *item1 = *p1;
8935 const Ebl_Core_Item *item2 = *p2;
8936
8937 return ((item1->group == item2->group ? 0
8938 : strcmp (item1->group, item2->group))
8939 ?: (int) item1->offset - (int) item2->offset);
8940}
8941
8942/* Sort item groups by layout offset of the first item in the group. */
8943static int
8944compare_core_item_groups (const void *a, const void *b)
8945{
8946 const Ebl_Core_Item *const *const *p1 = a;
8947 const Ebl_Core_Item *const *const *p2 = b;
8948 const Ebl_Core_Item *const *group1 = *p1;
8949 const Ebl_Core_Item *const *group2 = *p2;
8950 const Ebl_Core_Item *item1 = *group1;
8951 const Ebl_Core_Item *item2 = *group2;
8952
8953 return (int) item1->offset - (int) item2->offset;
8954}
8955
8956static unsigned int
8957handle_core_items (Elf *core, const void *desc, size_t descsz,
8958 const Ebl_Core_Item *items, size_t nitems)
8959{
8960 if (nitems == 0)
8961 return 0;
8962 unsigned int colno = 0;
8963
8964 /* FORMAT '\n' makes sense to be present only as a single item as it
8965 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8966 if present as a single item but they can be also processed with other
8967 items below. */
8968 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8969 || items[0].format == 'B'))
8970 {
8971 assert (items[0].offset == 0);
8972 size_t size = descsz;
8973 colno = handle_core_item (core, items, desc, colno, &size);
8974 /* If SIZE is not zero here there is some remaining data. But we do not
8975 know how to process it anyway. */
8976 return colno;
8977 }
8978 for (size_t i = 0; i < nitems; ++i)
8979 assert (items[i].format != '\n');
8980
8981 /* Sort to collect the groups together. */
8982 const Ebl_Core_Item *sorted_items[nitems];
8983 for (size_t i = 0; i < nitems; ++i)
8984 sorted_items[i] = &items[i];
8985 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8986
8987 /* Collect the unique groups and sort them. */
8988 const Ebl_Core_Item **groups[nitems];
8989 groups[0] = &sorted_items[0];
8990 size_t ngroups = 1;
8991 for (size_t i = 1; i < nitems; ++i)
8992 if (sorted_items[i]->group != sorted_items[i - 1]->group
8993 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8994 groups[ngroups++] = &sorted_items[i];
8995 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8996
8997 /* Write out all the groups. */
8998 const void *last = desc;
8999 do
9000 {
9001 for (size_t i = 0; i < ngroups; ++i)
9002 {
9003 for (const Ebl_Core_Item **item = groups[i];
9004 (item < &sorted_items[nitems]
9005 && ((*item)->group == groups[i][0]->group
9006 || !strcmp ((*item)->group, groups[i][0]->group)));
9007 ++item)
9008 colno = handle_core_item (core, *item, desc, colno, NULL);
9009
9010 /* Force a line break at the end of the group. */
9011 colno = WRAP_COLUMN;
9012 }
9013
9014 if (descsz == 0)
9015 break;
9016
9017 /* This set of items consumed a certain amount of the note's data.
9018 If there is more data there, we have another unit of the same size.
9019 Loop to print that out too. */
9020 const Ebl_Core_Item *item = &items[nitems - 1];
9021 size_t eltsz = item->offset + gelf_fsize (core, item->type,
9022 item->count ?: 1, EV_CURRENT);
9023
9024 int reps = -1;
9025 do
9026 {
9027 ++reps;
9028 desc += eltsz;
9029 descsz -= eltsz;
9030 }
9031 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
9032
9033 if (reps == 1)
9034 {
9035 /* For just one repeat, print it unabridged twice. */
9036 desc -= eltsz;
9037 descsz += eltsz;
9038 }
9039 else if (reps > 1)
9040 printf (gettext ("\n%*s... <repeats %u more times> ..."),
9041 ITEM_INDENT, "", reps);
9042
9043 last = desc;
9044 }
9045 while (descsz > 0);
9046
9047 return colno;
9048}
9049
9050static unsigned int
9051handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
9052 unsigned int colno)
9053{
9054 desc += regloc->offset;
9055
9056 abort (); /* XXX */
9057 return colno;
9058}
9059
9060
9061static unsigned int
9062handle_core_register (Ebl *ebl, Elf *core, int maxregname,
9063 const Ebl_Register_Location *regloc, const void *desc,
9064 unsigned int colno)
9065{
9066 if (regloc->bits % 8 != 0)
9067 return handle_bit_registers (regloc, desc, colno);
9068
9069 desc += regloc->offset;
9070
9071 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
9072 {
9073 char name[REGNAMESZ];
9074 int bits;
9075 int type;
9076 register_info (ebl, reg, regloc, name, &bits, &type);
9077
9078#define TYPES \
9079 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
9080 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
9081 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
9082 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
9083
9084#define BITS(bits, xtype, sfmt, ufmt) \
9085 uint##bits##_t b##bits; int##bits##_t b##bits##s
9086 union { TYPES; uint64_t b128[2]; } value;
9087#undef BITS
9088
9089 switch (type)
9090 {
9091 case DW_ATE_unsigned:
9092 case DW_ATE_signed:
9093 case DW_ATE_address:
9094 switch (bits)
9095 {
9096#define BITS(bits, xtype, sfmt, ufmt) \
9097 case bits: \
9098 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
9099 if (type == DW_ATE_signed) \
9100 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
9101 maxregname, name, \
9102 sfmt, value.b##bits##s); \
9103 else \
9104 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
9105 maxregname, name, \
9106 ufmt, value.b##bits); \
9107 break
9108
9109 TYPES;
9110
9111 case 128:
9112 assert (type == DW_ATE_unsigned);
9113 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
9114 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
9115 colno = print_core_item (colno, ' ', WRAP_COLUMN,
9116 maxregname, name,
9117 "0x%.16" PRIx64 "%.16" PRIx64,
9118 value.b128[!be], value.b128[be]);
9119 break;
9120
9121 default:
9122 abort ();
9123#undef BITS
9124 }
9125 break;
9126
9127 default:
9128 /* Print each byte in hex, the whole thing in native byte order. */
9129 assert (bits % 8 == 0);
9130 const uint8_t *bytes = desc;
9131 desc += bits / 8;
9132 char hex[bits / 4 + 1];
9133 hex[bits / 4] = '\0';
9134 int incr = 1;
9135 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
9136 {
9137 bytes += bits / 8 - 1;
9138 incr = -1;
9139 }
9140 size_t idx = 0;
9141 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
9142 {
9143 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
9144 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
9145 }
9146 colno = print_core_item (colno, ' ', WRAP_COLUMN,
9147 maxregname, name, "0x%s", hex);
9148 break;
9149 }
9150 desc += regloc->pad;
9151
9152#undef TYPES
9153 }
9154
9155 return colno;
9156}
9157
9158
9159struct register_info
9160{
9161 const Ebl_Register_Location *regloc;
9162 const char *set;
9163 char name[REGNAMESZ];
9164 int regno;
9165 int bits;
9166 int type;
9167};
9168
9169static int
9170register_bitpos (const struct register_info *r)
9171{
9172 return (r->regloc->offset * 8
9173 + ((r->regno - r->regloc->regno)
9174 * (r->regloc->bits + r->regloc->pad * 8)));
9175}
9176
9177static int
9178compare_sets_by_info (const struct register_info *r1,
9179 const struct register_info *r2)
9180{
9181 return ((int) r2->bits - (int) r1->bits
9182 ?: register_bitpos (r1) - register_bitpos (r2));
9183}
9184
9185/* Sort registers by set, and by size and layout offset within each set. */
9186static int
9187compare_registers (const void *a, const void *b)
9188{
9189 const struct register_info *r1 = a;
9190 const struct register_info *r2 = b;
9191
9192 /* Unused elements sort last. */
9193 if (r1->regloc == NULL)
9194 return r2->regloc == NULL ? 0 : 1;
9195 if (r2->regloc == NULL)
9196 return -1;
9197
9198 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
9199 ?: compare_sets_by_info (r1, r2));
9200}
9201
9202/* Sort register sets by layout offset of the first register in the set. */
9203static int
9204compare_register_sets (const void *a, const void *b)
9205{
9206 const struct register_info *const *p1 = a;
9207 const struct register_info *const *p2 = b;
9208 return compare_sets_by_info (*p1, *p2);
9209}
9210
9211static unsigned int
9212handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
9213 const Ebl_Register_Location *reglocs, size_t nregloc)
9214{
9215 if (nregloc == 0)
9216 return 0;
9217
9218 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
9219 if (maxnreg <= 0)
9220 {
9221 for (size_t i = 0; i < nregloc; ++i)
9222 if (maxnreg < reglocs[i].regno + reglocs[i].count)
9223 maxnreg = reglocs[i].regno + reglocs[i].count;
9224 assert (maxnreg > 0);
9225 }
9226
9227 struct register_info regs[maxnreg];
9228 memset (regs, 0, sizeof regs);
9229
9230 /* Sort to collect the sets together. */
9231 int maxreg = 0;
9232 for (size_t i = 0; i < nregloc; ++i)
9233 for (int reg = reglocs[i].regno;
9234 reg < reglocs[i].regno + reglocs[i].count;
9235 ++reg)
9236 {
9237 assert (reg < maxnreg);
9238 if (reg > maxreg)
9239 maxreg = reg;
9240 struct register_info *info = &regs[reg];
9241 info->regloc = &reglocs[i];
9242 info->regno = reg;
9243 info->set = register_info (ebl, reg, &reglocs[i],
9244 info->name, &info->bits, &info->type);
9245 }
9246 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
9247
9248 /* Collect the unique sets and sort them. */
9249 inline bool same_set (const struct register_info *a,
9250 const struct register_info *b)
9251 {
9252 return (a < &regs[maxnreg] && a->regloc != NULL
9253 && b < &regs[maxnreg] && b->regloc != NULL
9254 && a->bits == b->bits
9255 && (a->set == b->set || !strcmp (a->set, b->set)));
9256 }
9257 struct register_info *sets[maxreg + 1];
9258 sets[0] = &regs[0];
9259 size_t nsets = 1;
9260 for (int i = 1; i <= maxreg; ++i)
9261 if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
9262 sets[nsets++] = &regs[i];
9263 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
9264
9265 /* Write out all the sets. */
9266 unsigned int colno = 0;
9267 for (size_t i = 0; i < nsets; ++i)
9268 {
9269 /* Find the longest name of a register in this set. */
9270 size_t maxname = 0;
9271 const struct register_info *end;
9272 for (end = sets[i]; same_set (sets[i], end); ++end)
9273 {
9274 size_t len = strlen (end->name);
9275 if (len > maxname)
9276 maxname = len;
9277 }
9278
9279 for (const struct register_info *reg = sets[i];
9280 reg < end;
9281 reg += reg->regloc->count ?: 1)
9282 colno = handle_core_register (ebl, core, maxname,
9283 reg->regloc, desc, colno);
9284
9285 /* Force a line break at the end of the group. */
9286 colno = WRAP_COLUMN;
9287 }
9288
9289 return colno;
9290}
9291
9292static void
9293handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9294{
9295 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
9296 if (data == NULL)
9297 elf_error:
9298 error (EXIT_FAILURE, 0,
9299 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9300
9301 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
9302 for (size_t i = 0; i < nauxv; ++i)
9303 {
9304 GElf_auxv_t av_mem;
9305 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
9306 if (av == NULL)
9307 goto elf_error;
9308
9309 const char *name;
9310 const char *fmt;
9311 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
9312 {
9313 /* Unknown type. */
9314 if (av->a_un.a_val == 0)
9315 printf (" %" PRIu64 "\n", av->a_type);
9316 else
9317 printf (" %" PRIu64 ": %#" PRIx64 "\n",
9318 av->a_type, av->a_un.a_val);
9319 }
9320 else
9321 switch (fmt[0])
9322 {
9323 case '\0': /* Normally zero. */
9324 if (av->a_un.a_val == 0)
9325 {
9326 printf (" %s\n", name);
9327 break;
9328 }
9329 FALLTHROUGH;
9330 case 'x': /* hex */
9331 case 'p': /* address */
9332 case 's': /* address of string */
9333 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
9334 break;
9335 case 'u':
9336 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
9337 break;
9338 case 'd':
9339 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
9340 break;
9341
9342 case 'b':
9343 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
9344 GElf_Xword bit = 1;
9345 const char *pfx = "<";
9346 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9347 {
9348 if (av->a_un.a_val & bit)
9349 {
9350 printf ("%s%s", pfx, p);
9351 pfx = " ";
9352 }
9353 bit <<= 1;
9354 }
9355 printf (">\n");
9356 break;
9357
9358 default:
9359 abort ();
9360 }
9361 }
9362}
9363
9364static bool
9365buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9366{
9367 return ptr < end && (size_t) (end - ptr) >= sz;
9368}
9369
9370static bool
9371buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9372 int *retp)
9373{
9374 if (! buf_has_data (*ptrp, end, 4))
9375 return false;
9376
9377 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9378 return true;
9379}
9380
9381static bool
9382buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9383 uint64_t *retp)
9384{
9385 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9386 if (! buf_has_data (*ptrp, end, sz))
9387 return false;
9388
9389 union
9390 {
9391 uint64_t u64;
9392 uint32_t u32;
9393 } u;
9394
9395 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9396
9397 if (sz == 4)
9398 *retp = u.u32;
9399 else
9400 *retp = u.u64;
9401 return true;
9402}
9403
9404static void
9405handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9406{
9407 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9408 if (data == NULL)
9409 error (EXIT_FAILURE, 0,
9410 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9411
9412 unsigned char const *ptr = data->d_buf;
9413 unsigned char const *const end = data->d_buf + data->d_size;
9414
9415 /* Siginfo head is three ints: signal number, error number, origin
9416 code. */
9417 int si_signo, si_errno, si_code;
9418 if (! buf_read_int (core, &ptr, end, &si_signo)
9419 || ! buf_read_int (core, &ptr, end, &si_errno)
9420 || ! buf_read_int (core, &ptr, end, &si_code))
9421 {
9422 fail:
9423 printf (" Not enough data in NT_SIGINFO note.\n");
9424 return;
9425 }
9426
9427 /* Next is a pointer-aligned union of structures. On 64-bit
9428 machines, that implies a word of padding. */
9429 if (gelf_getclass (core) == ELFCLASS64)
9430 ptr += 4;
9431
9432 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
9433 si_signo, si_errno, si_code);
9434
9435 if (si_code > 0)
9436 switch (si_signo)
9437 {
9438 case CORE_SIGILL:
9439 case CORE_SIGFPE:
9440 case CORE_SIGSEGV:
9441 case CORE_SIGBUS:
9442 {
9443 uint64_t addr;
9444 if (! buf_read_ulong (core, &ptr, end, &addr))
9445 goto fail;
9446 printf (" fault address: %#" PRIx64 "\n", addr);
9447 break;
9448 }
9449 default:
9450 ;
9451 }
9452 else if (si_code == CORE_SI_USER)
9453 {
9454 int pid, uid;
9455 if (! buf_read_int (core, &ptr, end, &pid)
9456 || ! buf_read_int (core, &ptr, end, &uid))
9457 goto fail;
9458 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
9459 }
9460}
9461
9462static void
9463handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9464{
9465 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9466 if (data == NULL)
9467 error (EXIT_FAILURE, 0,
9468 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9469
9470 unsigned char const *ptr = data->d_buf;
9471 unsigned char const *const end = data->d_buf + data->d_size;
9472
9473 uint64_t count, page_size;
9474 if (! buf_read_ulong (core, &ptr, end, &count)
9475 || ! buf_read_ulong (core, &ptr, end, &page_size))
9476 {
9477 fail:
9478 printf (" Not enough data in NT_FILE note.\n");
9479 return;
9480 }
9481
9482 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9483 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9484 if (count > maxcount)
9485 goto fail;
9486
9487 /* Where file names are stored. */
9488 unsigned char const *const fstart = ptr + 3 * count * addrsize;
9489 char const *fptr = (char *) fstart;
9490
9491 printf (" %" PRId64 " files:\n", count);
9492 for (uint64_t i = 0; i < count; ++i)
9493 {
9494 uint64_t mstart, mend, moffset;
9495 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9496 || ! buf_read_ulong (core, &ptr, fstart, &mend)
9497 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9498 goto fail;
9499
9500 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9501 if (fnext == NULL)
9502 goto fail;
9503
9504 int ct = printf (" %08" PRIx64 "-%08" PRIx64
9505 " %08" PRIx64 " %" PRId64,
9506 mstart, mend, moffset * page_size, mend - mstart);
9507 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9508
9509 fptr = fnext + 1;
9510 }
9511}
9512
9513static void
9514handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9515 const char *name, const void *desc)
9516{
9517 GElf_Word regs_offset;
9518 size_t nregloc;
9519 const Ebl_Register_Location *reglocs;
9520 size_t nitems;
9521 const Ebl_Core_Item *items;
9522
9523 if (! ebl_core_note (ebl, nhdr, name,
9524 &regs_offset, &nregloc, &reglocs, &nitems, &items))
9525 return;
9526
9527 /* Pass 0 for DESCSZ when there are registers in the note,
9528 so that the ITEMS array does not describe the whole thing.
9529 For non-register notes, the actual descsz might be a multiple
9530 of the unit size, not just exactly the unit size. */
9531 unsigned int colno = handle_core_items (ebl->elf, desc,
9532 nregloc == 0 ? nhdr->n_descsz : 0,
9533 items, nitems);
9534 if (colno != 0)
9535 putchar_unlocked ('\n');
9536
9537 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9538 reglocs, nregloc);
9539 if (colno != 0)
9540 putchar_unlocked ('\n');
9541}
9542
9543static void
9544handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9545 GElf_Off start, Elf_Data *data)
9546{
9547 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
9548
9549 if (data == NULL)
9550 goto bad_note;
9551
9552 size_t offset = 0;
9553 GElf_Nhdr nhdr;
9554 size_t name_offset;
9555 size_t desc_offset;
9556 while (offset < data->d_size
9557 && (offset = gelf_getnote (data, offset,
9558 &nhdr, &name_offset, &desc_offset)) > 0)
9559 {
9560 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
9561 const char *desc = data->d_buf + desc_offset;
9562
9563 char buf[100];
9564 char buf2[100];
9565 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
9566 (int) nhdr.n_namesz, name, nhdr.n_descsz,
9567 ehdr->e_type == ET_CORE
9568 ? ebl_core_note_type_name (ebl, nhdr.n_type,
9569 buf, sizeof (buf))
9570 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9571 buf2, sizeof (buf2)));
9572
9573 /* Filter out invalid entries. */
9574 if (memchr (name, '\0', nhdr.n_namesz) != NULL
9575 /* XXX For now help broken Linux kernels. */
9576 || 1)
9577 {
9578 if (ehdr->e_type == ET_CORE)
9579 {
9580 if (nhdr.n_type == NT_AUXV
9581 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9582 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9583 && !memcmp (name, "CORE", 4))
9584 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9585 start + desc_offset);
9586 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9587 switch (nhdr.n_type)
9588 {
9589 case NT_SIGINFO:
9590 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9591 start + desc_offset);
9592 break;
9593
9594 case NT_FILE:
9595 handle_file_note (ebl->elf, nhdr.n_descsz,
9596 start + desc_offset);
9597 break;
9598
9599 default:
9600 handle_core_note (ebl, &nhdr, name, desc);
9601 }
9602 else
9603 handle_core_note (ebl, &nhdr, name, desc);
9604 }
9605 else
9606 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9607 }
9608 }
9609
9610 if (offset == data->d_size)
9611 return;
9612
9613 bad_note:
9614 error (0, 0,
9615 gettext ("cannot get content of note: %s"),
9616 data != NULL ? "garbage data" : elf_errmsg (-1));
9617}
9618
9619static void
9620handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9621{
9622 /* If we have section headers, just look for SHT_NOTE sections.
9623 In a debuginfo file, the program headers are not reliable. */
9624 if (shnum != 0)
9625 {
9626 /* Get the section header string table index. */
9627 size_t shstrndx;
9628 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9629 error (EXIT_FAILURE, 0,
9630 gettext ("cannot get section header string table index"));
9631
9632 Elf_Scn *scn = NULL;
9633 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9634 {
9635 GElf_Shdr shdr_mem;
9636 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9637
9638 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9639 /* Not what we are looking for. */
9640 continue;
9641
9642 printf (gettext ("\
9643\nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9644 elf_ndxscn (scn),
9645 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9646 shdr->sh_size, shdr->sh_offset);
9647
9648 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9649 elf_getdata (scn, NULL));
9650 }
9651 return;
9652 }
9653
9654 /* We have to look through the program header to find the note
9655 sections. There can be more than one. */
9656 for (size_t cnt = 0; cnt < phnum; ++cnt)
9657 {
9658 GElf_Phdr mem;
9659 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9660
9661 if (phdr == NULL || phdr->p_type != PT_NOTE)
9662 /* Not what we are looking for. */
9663 continue;
9664
9665 printf (gettext ("\
9666\nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9667 phdr->p_filesz, phdr->p_offset);
9668
9669 handle_notes_data (ebl, ehdr, phdr->p_offset,
9670 elf_getdata_rawchunk (ebl->elf,
9671 phdr->p_offset, phdr->p_filesz,
9672 ELF_T_NHDR));
9673 }
9674}
9675
9676
9677static void
9678hex_dump (const uint8_t *data, size_t len)
9679{
9680 size_t pos = 0;
9681 while (pos < len)
9682 {
9683 printf (" 0x%08zx ", pos);
9684
9685 const size_t chunk = MIN (len - pos, 16);
9686
9687 for (size_t i = 0; i < chunk; ++i)
9688 if (i % 4 == 3)
9689 printf ("%02x ", data[pos + i]);
9690 else
9691 printf ("%02x", data[pos + i]);
9692
9693 if (chunk < 16)
9694 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9695
9696 for (size_t i = 0; i < chunk; ++i)
9697 {
9698 unsigned char b = data[pos + i];
9699 printf ("%c", isprint (b) ? b : '.');
9700 }
9701
9702 putchar ('\n');
9703 pos += chunk;
9704 }
9705}
9706
9707static void
9708dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9709{
9710 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9711 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
9712 elf_ndxscn (scn), name);
9713 else
9714 {
9715 if (print_decompress)
9716 {
9717 /* We try to decompress the section, but keep the old shdr around
9718 so we can show both the original shdr size and the uncompressed
9719 data size. */
9720 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9721 {
9722 if (elf_compress (scn, 0, 0) < 0)
9723 printf ("WARNING: %s [%zd]\n",
9724 gettext ("Couldn't uncompress section"),
9725 elf_ndxscn (scn));
9726 }
9727 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9728 {
9729 if (elf_compress_gnu (scn, 0, 0) < 0)
9730 printf ("WARNING: %s [%zd]\n",
9731 gettext ("Couldn't uncompress section"),
9732 elf_ndxscn (scn));
9733 }
9734 }
9735
9736 Elf_Data *data = elf_rawdata (scn, NULL);
9737 if (data == NULL)
9738 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9739 elf_ndxscn (scn), name, elf_errmsg (-1));
9740 else
9741 {
9742 if (data->d_size == shdr->sh_size)
9743 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9744 " bytes at offset %#0" PRIx64 ":\n"),
9745 elf_ndxscn (scn), name,
9746 shdr->sh_size, shdr->sh_offset);
9747 else
9748 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9749 " bytes (%zd uncompressed) at offset %#0"
9750 PRIx64 ":\n"),
9751 elf_ndxscn (scn), name,
9752 shdr->sh_size, data->d_size, shdr->sh_offset);
9753 hex_dump (data->d_buf, data->d_size);
9754 }
9755 }
9756}
9757
9758static void
9759print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9760{
9761 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9762 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
9763 elf_ndxscn (scn), name);
9764 else
9765 {
9766 if (print_decompress)
9767 {
9768 /* We try to decompress the section, but keep the old shdr around
9769 so we can show both the original shdr size and the uncompressed
9770 data size. */
9771 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9772 {
9773 if (elf_compress (scn, 0, 0) < 0)
9774 printf ("WARNING: %s [%zd]\n",
9775 gettext ("Couldn't uncompress section"),
9776 elf_ndxscn (scn));
9777 }
9778 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9779 {
9780 if (elf_compress_gnu (scn, 0, 0) < 0)
9781 printf ("WARNING: %s [%zd]\n",
9782 gettext ("Couldn't uncompress section"),
9783 elf_ndxscn (scn));
9784 }
9785 }
9786
9787 Elf_Data *data = elf_rawdata (scn, NULL);
9788 if (data == NULL)
9789 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9790 elf_ndxscn (scn), name, elf_errmsg (-1));
9791 else
9792 {
9793 if (data->d_size == shdr->sh_size)
9794 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9795 " bytes at offset %#0" PRIx64 ":\n"),
9796 elf_ndxscn (scn), name,
9797 shdr->sh_size, shdr->sh_offset);
9798 else
9799 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9800 " bytes (%zd uncompressed) at offset %#0"
9801 PRIx64 ":\n"),
9802 elf_ndxscn (scn), name,
9803 shdr->sh_size, data->d_size, shdr->sh_offset);
9804
9805 const char *start = data->d_buf;
9806 const char *const limit = start + data->d_size;
9807 do
9808 {
9809 const char *end = memchr (start, '\0', limit - start);
9810 const size_t pos = start - (const char *) data->d_buf;
9811 if (unlikely (end == NULL))
9812 {
9813 printf (" [%6zx]- %.*s\n",
9814 pos, (int) (limit - start), start);
9815 break;
9816 }
9817 printf (" [%6zx] %s\n", pos, start);
9818 start = end + 1;
9819 } while (start < limit);
9820 }
9821 }
9822}
9823
9824static void
9825for_each_section_argument (Elf *elf, const struct section_argument *list,
9826 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9827 const char *name))
9828{
9829 /* Get the section header string table index. */
9830 size_t shstrndx;
9831 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9832 error (EXIT_FAILURE, 0,
9833 gettext ("cannot get section header string table index"));
9834
9835 for (const struct section_argument *a = list; a != NULL; a = a->next)
9836 {
9837 Elf_Scn *scn;
9838 GElf_Shdr shdr_mem;
9839 const char *name = NULL;
9840
9841 char *endp = NULL;
9842 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9843 if (endp != a->arg && *endp == '\0')
9844 {
9845 scn = elf_getscn (elf, shndx);
9846 if (scn == NULL)
9847 {
9848 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9849 continue;
9850 }
9851
9852 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9853 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9854 elf_errmsg (-1));
9855 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9856 }
9857 else
9858 {
9859 /* Need to look up the section by name. */
9860 scn = NULL;
9861 bool found = false;
9862 while ((scn = elf_nextscn (elf, scn)) != NULL)
9863 {
9864 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9865 continue;
9866 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9867 if (name == NULL)
9868 continue;
9869 if (!strcmp (name, a->arg))
9870 {
9871 found = true;
9872 (*dump) (scn, &shdr_mem, name);
9873 }
9874 }
9875
9876 if (unlikely (!found) && !a->implicit)
9877 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9878 }
9879 }
9880}
9881
9882static void
9883dump_data (Ebl *ebl)
9884{
9885 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9886}
9887
9888static void
9889dump_strings (Ebl *ebl)
9890{
9891 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9892}
9893
9894static void
9895print_strings (Ebl *ebl)
9896{
9897 /* Get the section header string table index. */
9898 size_t shstrndx;
9899 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9900 error (EXIT_FAILURE, 0,
9901 gettext ("cannot get section header string table index"));
9902
9903 Elf_Scn *scn;
9904 GElf_Shdr shdr_mem;
9905 const char *name;
9906 scn = NULL;
9907 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9908 {
9909 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9910 continue;
9911
9912 if (shdr_mem.sh_type != SHT_PROGBITS
9913 || !(shdr_mem.sh_flags & SHF_STRINGS))
9914 continue;
9915
9916 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9917 if (name == NULL)
9918 continue;
9919
9920 print_string_section (scn, &shdr_mem, name);
9921 }
9922}
9923
9924static void
9925dump_archive_index (Elf *elf, const char *fname)
9926{
9927 size_t narsym;
9928 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9929 if (arsym == NULL)
9930 {
9931 int result = elf_errno ();
9932 if (unlikely (result != ELF_E_NO_INDEX))
9933 error (EXIT_FAILURE, 0,
9934 gettext ("cannot get symbol index of archive '%s': %s"),
9935 fname, elf_errmsg (result));
9936 else
9937 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9938 return;
9939 }
9940
9941 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
9942 fname, narsym);
9943
9944 size_t as_off = 0;
9945 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9946 {
9947 if (s->as_off != as_off)
9948 {
9949 as_off = s->as_off;
9950
9951 Elf *subelf = NULL;
9952 if (unlikely (elf_rand (elf, as_off) == 0)
9953 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9954 == NULL))
9955#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9956 while (1)
9957#endif
9958 error (EXIT_FAILURE, 0,
9959 gettext ("cannot extract member at offset %zu in '%s': %s"),
9960 as_off, fname, elf_errmsg (-1));
9961
9962 const Elf_Arhdr *h = elf_getarhdr (subelf);
9963
9964 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9965
9966 elf_end (subelf);
9967 }
9968
9969 printf ("\t%s\n", s->as_name);
9970 }
9971}
9972
9973#include "debugpred.h"