1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2012 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1999.
6 Red Hat elfutils is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 2 of the License.
10 Red Hat elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with Red Hat elfutils; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
19 Red Hat elfutils is an included package of the Open Invention Network.
20 An included package of the Open Invention Network is a package for which
21 Open Invention Network licensees cross-license their patents. No patent
22 license is granted, either expressly or impliedly, by designation as an
23 included package. Should you wish to participate in the Open Invention
24 Network licensing program, please visit www.openinventionnetwork.com
25 <http://www.openinventionnetwork.com>. */
51 #include <sys/param.h>
55 #include "../libelf/libelfP.h"
56 #include "../libelf/common.h"
57 #include "../libebl/libeblP.h"
58 #include "../libdw/libdwP.h"
59 #include "../libdwfl/libdwflP.h"
60 #include "../libdw/memory-access.h"
63 /* Name and version of program. */
64 static void print_version (FILE *stream, struct argp_state *state);
65 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
67 /* Bug report address. */
68 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
70 /* Definitions of arguments for argp functions. */
71 static const struct argp_option options[] =
73 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
74 { "all", 'a', NULL, 0,
75 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
76 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
77 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
78 { "histogram", 'I', NULL, 0,
79 N_("Display histogram of bucket list lengths"), 0 },
80 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
81 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
82 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
83 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
84 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
85 { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
86 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
87 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
88 { "arch-specific", 'A', NULL, 0,
89 N_("Display architecture specific information, if any"), 0 },
90 { "exception", 'e', NULL, 0,
91 N_("Display sections for exception handling"), 0 },
93 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
94 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
95 N_("Display DWARF section content. SECTION can be one of abbrev, "
96 "aranges, frame, gdb_index, info, loc, line, ranges, pubnames, str, "
97 "macinfo, or exception"), 0 },
98 { "hex-dump", 'x', "SECTION", 0,
99 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
100 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
101 N_("Print string contents of sections"), 0 },
102 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
103 { "archive-index", 'c', NULL, 0,
104 N_("Display the symbol index of an archive"), 0 },
106 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
107 { "numeric-addresses", 'N', NULL, 0,
108 N_("Do not find symbol names for addresses in DWARF data"), 0 },
109 { "wide", 'W', NULL, 0,
110 N_("Ignored for compatibility (lines always wide)"), 0 },
111 { NULL, 0, NULL, 0, NULL, 0 }
114 /* Short description of program. */
115 static const char doc[] = N_("\
116 Print information from ELF file in human-readable form.");
118 /* Strings for arguments in help texts. */
119 static const char args_doc[] = N_("FILE...");
121 /* Prototype for option handler. */
122 static error_t parse_opt (int key, char *arg, struct argp_state *state);
124 /* Data structure to communicate with argp functions. */
125 static struct argp argp =
127 options, parse_opt, args_doc, doc, NULL, NULL, NULL
131 /* Flags set by the option controlling the output. */
133 /* True if dynamic segment should be printed. */
134 static bool print_dynamic_table;
136 /* True if the file header should be printed. */
137 static bool print_file_header;
139 /* True if the program headers should be printed. */
140 static bool print_program_header;
142 /* True if relocations should be printed. */
143 static bool print_relocations;
145 /* True if the section headers should be printed. */
146 static bool print_section_header;
148 /* True if the symbol table should be printed. */
149 static bool print_symbol_table;
151 /* True if the version information should be printed. */
152 static bool print_version_info;
154 /* True if section groups should be printed. */
155 static bool print_section_groups;
157 /* True if bucket list length histogram should be printed. */
158 static bool print_histogram;
160 /* True if the architecture specific data should be printed. */
161 static bool print_arch;
163 /* True if note section content should be printed. */
164 static bool print_notes;
166 /* True if SHF_STRINGS section content should be printed. */
167 static bool print_string_sections;
169 /* True if archive index should be printed. */
170 static bool print_archive_index;
172 /* True if any of the control options except print_archive_index is set. */
173 static bool any_control_option;
175 /* True if we should print addresses from DWARF in symbolic form. */
176 static bool print_address_names = true;
178 /* Select printing of debugging sections. */
179 static enum section_e
181 section_abbrev = 1, /* .debug_abbrev */
182 section_aranges = 2, /* .debug_aranges */
183 section_frame = 4, /* .debug_frame or .eh_frame & al. */
184 section_info = 8, /* .debug_info, .debug_types */
185 section_types = section_info,
186 section_line = 16, /* .debug_line */
187 section_loc = 32, /* .debug_loc */
188 section_pubnames = 64, /* .debug_pubnames */
189 section_str = 128, /* .debug_str */
190 section_macinfo = 256, /* .debug_macinfo */
191 section_ranges = 512, /* .debug_ranges */
192 section_exception = 1024, /* .eh_frame & al. */
193 section_gdb_index = 2048, /* .gdb_index */
194 section_all = (section_abbrev | section_aranges | section_frame
195 | section_info | section_line | section_loc
196 | section_pubnames | section_str | section_macinfo
197 | section_ranges | section_exception | section_gdb_index)
198 } print_debug_sections, implicit_debug_sections;
200 /* Select hex dumping of sections. */
201 static struct section_argument *dump_data_sections;
202 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
204 /* Select string dumping of sections. */
205 static struct section_argument *string_sections;
206 static struct section_argument **string_sections_tail = &string_sections;
208 struct section_argument
210 struct section_argument *next;
215 /* Numbers of sections and program headers in the file. */
220 /* Declarations of local functions. */
221 static void process_file (int fd, const char *fname, bool only_one);
222 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
223 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
224 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
225 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
226 static void print_scngrp (Ebl *ebl);
227 static void print_dynamic (Ebl *ebl);
228 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
229 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
231 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
233 static void print_symtab (Ebl *ebl, int type);
234 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
235 static void print_verinfo (Ebl *ebl);
236 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
237 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
238 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
240 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
241 static void handle_hash (Ebl *ebl);
242 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
243 static void print_liblist (Ebl *ebl);
244 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
245 static void dump_data (Ebl *ebl);
246 static void dump_strings (Ebl *ebl);
247 static void print_strings (Ebl *ebl);
248 static void dump_archive_index (Elf *, const char *);
252 main (int argc, char *argv[])
255 setlocale (LC_ALL, "");
257 /* Initialize the message catalog. */
258 textdomain (PACKAGE_TARNAME);
260 /* Parse and process arguments. */
262 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
264 /* Before we start tell the ELF library which version we are using. */
265 elf_version (EV_CURRENT);
267 /* Now process all the files given at the command line. */
268 bool only_one = remaining + 1 == argc;
272 int fd = open (argv[remaining], O_RDONLY);
275 error (0, errno, gettext ("cannot open input file"));
279 process_file (fd, argv[remaining], only_one);
283 while (++remaining < argc);
285 return error_message_count != 0;
289 /* Handle program arguments. */
291 parse_opt (int key, char *arg,
292 struct argp_state *state __attribute__ ((unused)))
294 void add_dump_section (const char *name, bool implicit)
296 struct section_argument *a = xmalloc (sizeof *a);
299 a->implicit = implicit;
300 struct section_argument ***tailp
301 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
309 print_file_header = true;
310 print_program_header = true;
311 print_relocations = true;
312 print_section_header = true;
313 print_symbol_table = true;
314 print_version_info = true;
315 print_dynamic_table = true;
316 print_section_groups = true;
317 print_histogram = true;
320 implicit_debug_sections |= section_exception;
321 add_dump_section (".strtab", true);
322 add_dump_section (".dynstr", true);
323 add_dump_section (".comment", true);
324 any_control_option = true;
328 any_control_option = true;
331 print_dynamic_table = true;
332 any_control_option = true;
335 print_debug_sections |= section_exception;
336 any_control_option = true;
339 print_section_groups = true;
340 any_control_option = true;
343 print_file_header = true;
344 any_control_option = true;
347 print_histogram = true;
348 any_control_option = true;
351 print_program_header = true;
352 any_control_option = true;
356 any_control_option = true;
359 print_relocations = true;
360 any_control_option = true;
363 print_section_header = true;
364 any_control_option = true;
367 print_symbol_table = true;
368 any_control_option = true;
371 print_version_info = true;
372 any_control_option = true;
375 print_archive_index = true;
379 print_debug_sections = section_all;
380 else if (strcmp (arg, "abbrev") == 0)
381 print_debug_sections |= section_abbrev;
382 else if (strcmp (arg, "aranges") == 0)
383 print_debug_sections |= section_aranges;
384 else if (strcmp (arg, "ranges") == 0)
386 print_debug_sections |= section_ranges;
387 implicit_debug_sections |= section_info;
389 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
390 print_debug_sections |= section_frame;
391 else if (strcmp (arg, "info") == 0)
392 print_debug_sections |= section_info;
393 else if (strcmp (arg, "loc") == 0)
395 print_debug_sections |= section_loc;
396 implicit_debug_sections |= section_info;
398 else if (strcmp (arg, "line") == 0)
399 print_debug_sections |= section_line;
400 else if (strcmp (arg, "pubnames") == 0)
401 print_debug_sections |= section_pubnames;
402 else if (strcmp (arg, "str") == 0)
403 print_debug_sections |= section_str;
404 else if (strcmp (arg, "macinfo") == 0)
405 print_debug_sections |= section_macinfo;
406 else if (strcmp (arg, "exception") == 0)
407 print_debug_sections |= section_exception;
408 else if (strcmp (arg, "gdb_index") == 0)
409 print_debug_sections |= section_gdb_index;
412 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
414 argp_help (&argp, stderr, ARGP_HELP_SEE,
415 program_invocation_short_name);
418 any_control_option = true;
421 any_control_option = true;
424 print_string_sections = true;
429 add_dump_section (arg, false);
430 any_control_option = true;
433 print_address_names = false;
435 case ARGP_KEY_NO_ARGS:
436 fputs (gettext ("Missing file name.\n"), stderr);
439 if (! any_control_option && ! print_archive_index)
441 fputs (gettext ("No operation specified.\n"), stderr);
443 argp_help (&argp, stderr, ARGP_HELP_SEE,
444 program_invocation_short_name);
448 case 'W': /* Ignored. */
451 return ARGP_ERR_UNKNOWN;
457 /* Print the version information. */
459 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
461 fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
462 fprintf (stream, gettext ("\
463 Copyright (C) %s Red Hat, Inc.\n\
464 This is free software; see the source for copying conditions. There is NO\n\
465 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
467 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
471 /* Check if the file is an archive, and if so dump its index. */
473 check_archive_index (int fd, const char *fname, bool only_one)
475 /* Create an `Elf' descriptor. */
476 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
478 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
482 if (elf_kind (elf) == ELF_K_AR)
485 printf ("\n%s:\n\n", fname);
486 dump_archive_index (elf, fname);
490 gettext ("'%s' is not an archive, cannot print archive index"),
493 /* Now we can close the descriptor. */
494 if (elf_end (elf) != 0)
495 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
500 /* Trivial callback used for checking if we opened an archive. */
502 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
503 void **userdata __attribute__ ((unused)),
504 const char *name __attribute__ ((unused)),
505 Dwarf_Addr base __attribute__ ((unused)),
509 return DWARF_CB_ABORT;
510 *(bool *) arg = true;
514 struct process_dwflmod_args
521 process_dwflmod (Dwfl_Module *dwflmod,
522 void **userdata __attribute__ ((unused)),
523 const char *name __attribute__ ((unused)),
524 Dwarf_Addr base __attribute__ ((unused)),
527 const struct process_dwflmod_args *a = arg;
529 /* Print the file name. */
533 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
535 printf ("\n%s:\n\n", fname);
538 process_elf_file (dwflmod, a->fd);
543 /* Stub libdwfl callback, only the ELF handle already open is ever used. */
545 find_no_debuginfo (Dwfl_Module *mod __attribute__ ((unused)),
546 void **userdata __attribute__ ((unused)),
547 const char *modname __attribute__ ((unused)),
548 Dwarf_Addr base __attribute__ ((unused)),
549 const char *file_name __attribute__ ((unused)),
550 const char *debuglink_file __attribute__ ((unused)),
551 GElf_Word debuglink_crc __attribute__ ((unused)),
552 char **debuginfo_file_name __attribute__ ((unused)))
557 /* Process one input file. */
559 process_file (int fd, const char *fname, bool only_one)
561 if (print_archive_index)
562 check_archive_index (fd, fname, only_one);
564 if (!any_control_option)
567 /* Duplicate an fd for dwfl_report_offline to swallow. */
568 int dwfl_fd = dup (fd);
569 if (unlikely (dwfl_fd < 0))
570 error (EXIT_FAILURE, errno, "dup");
572 /* Use libdwfl in a trivial way to open the libdw handle for us.
573 This takes care of applying relocations to DWARF data in ET_REL files. */
574 static const Dwfl_Callbacks callbacks =
576 .section_address = dwfl_offline_section_address,
577 .find_debuginfo = find_no_debuginfo
579 Dwfl *dwfl = dwfl_begin (&callbacks);
580 if (likely (dwfl != NULL))
581 /* Let 0 be the logical address of the file (or first in archive). */
582 dwfl->offline_next_address = 0;
583 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
586 if (fstat64 (dwfl_fd, &st) != 0)
587 error (0, errno, gettext ("cannot stat input file"));
588 else if (unlikely (st.st_size == 0))
589 error (0, 0, gettext ("input file is empty"));
591 error (0, 0, gettext ("failed reading '%s': %s"),
592 fname, dwfl_errmsg (-1));
593 close (dwfl_fd); /* Consumed on success, not on failure. */
597 dwfl_report_end (dwfl, NULL, NULL);
601 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
603 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
606 /* Process the one or more modules gleaned from this file. */
607 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
608 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
614 /* Process one ELF file. */
616 process_elf_file (Dwfl_Module *dwflmod, int fd)
619 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
622 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
627 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
631 Ebl *ebl = ebl_openbackend (elf);
632 if (unlikely (ebl == NULL))
635 error (0, errno, gettext ("cannot create EBL handle"));
639 /* Determine the number of sections. */
640 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
641 error (EXIT_FAILURE, 0,
642 gettext ("cannot determine number of sections: %s"),
645 /* Determine the number of phdrs. */
646 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
647 error (EXIT_FAILURE, 0,
648 gettext ("cannot determine number of program headers: %s"),
651 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs
652 and may have applied relocation to some sections.
653 So we need to get a fresh Elf handle on the file to display those. */
654 bool print_unrelocated = (print_section_header
656 || dump_data_sections != NULL
659 Elf *pure_elf = NULL;
661 if (ehdr->e_type == ET_REL && print_unrelocated)
663 /* Read the file afresh. */
664 off64_t aroff = elf_getaroff (elf);
665 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
668 /* Archive member. */
669 (void) elf_rand (pure_elf, aroff);
670 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
674 if (pure_elf == NULL)
676 pure_ebl = ebl_openbackend (pure_elf);
677 if (pure_ebl == NULL)
681 if (print_file_header)
682 print_ehdr (ebl, ehdr);
683 if (print_section_header)
684 print_shdr (pure_ebl, ehdr);
685 if (print_program_header)
686 print_phdr (ebl, ehdr);
687 if (print_section_groups)
689 if (print_dynamic_table)
691 if (print_relocations)
692 print_relocs (pure_ebl, ehdr);
695 if (print_symbol_table)
696 print_symtab (ebl, SHT_DYNSYM);
697 if (print_version_info)
699 if (print_symbol_table)
700 print_symtab (ebl, SHT_SYMTAB);
704 print_attributes (ebl, ehdr);
705 if (dump_data_sections != NULL)
706 dump_data (pure_ebl);
707 if (string_sections != NULL)
709 if ((print_debug_sections | implicit_debug_sections) != 0)
710 print_debug (dwflmod, ebl, ehdr);
712 handle_notes (pure_ebl, ehdr);
713 if (print_string_sections)
716 ebl_closebackend (ebl);
720 ebl_closebackend (pure_ebl);
726 /* Print file type. */
728 print_file_type (unsigned short int e_type)
730 if (likely (e_type <= ET_CORE))
732 static const char *const knowntypes[] =
735 N_("REL (Relocatable file)"),
736 N_("EXEC (Executable file)"),
737 N_("DYN (Shared object file)"),
738 N_("CORE (Core file)")
740 puts (gettext (knowntypes[e_type]));
742 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
743 printf (gettext ("OS Specific: (%x)\n"), e_type);
744 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
745 printf (gettext ("Processor Specific: (%x)\n"), e_type);
751 /* Print ELF header. */
753 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
755 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
756 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
757 printf (" %02hhx", ehdr->e_ident[cnt]);
759 printf (gettext ("\n Class: %s\n"),
760 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
761 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
764 printf (gettext (" Data: %s\n"),
765 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
766 ? "2's complement, little endian"
767 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
768 ? "2's complement, big endian" : "\?\?\?");
770 printf (gettext (" Ident Version: %hhd %s\n"),
771 ehdr->e_ident[EI_VERSION],
772 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
776 printf (gettext (" OS/ABI: %s\n"),
777 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
779 printf (gettext (" ABI Version: %hhd\n"),
780 ehdr->e_ident[EI_ABIVERSION]);
782 fputs_unlocked (gettext (" Type: "), stdout);
783 print_file_type (ehdr->e_type);
785 printf (gettext (" Machine: %s\n"), ebl->name);
787 printf (gettext (" Version: %d %s\n"),
789 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
791 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
794 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
795 ehdr->e_phoff, gettext ("(bytes into file)"));
797 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
798 ehdr->e_shoff, gettext ("(bytes into file)"));
800 printf (gettext (" Flags: %s\n"),
801 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
803 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
804 ehdr->e_ehsize, gettext ("(bytes)"));
806 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
807 ehdr->e_phentsize, gettext ("(bytes)"));
809 printf (gettext (" Number of program headers entries: %" PRId16),
811 if (ehdr->e_phnum == PN_XNUM)
814 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
816 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
817 (uint32_t) shdr->sh_info);
819 fputs_unlocked (gettext (" ([0] not available)"), stdout);
821 fputc_unlocked ('\n', stdout);
823 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
824 ehdr->e_shentsize, gettext ("(bytes)"));
826 printf (gettext (" Number of section headers entries: %" PRId16),
828 if (ehdr->e_shnum == 0)
831 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
833 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
834 (uint32_t) shdr->sh_size);
836 fputs_unlocked (gettext (" ([0] not available)"), stdout);
838 fputc_unlocked ('\n', stdout);
840 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
843 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
845 /* We managed to get the zeroth section. */
846 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
847 (uint32_t) shdr->sh_link);
850 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
851 buf[sizeof (buf) - 1] = '\0';
854 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
858 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
864 get_visibility_type (int value)
882 /* Print the section headers. */
884 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
889 if (! print_file_header)
891 There are %d section headers, starting at offset %#" PRIx64 ":\n\
893 ehdr->e_shnum, ehdr->e_shoff);
895 /* Get the section header string table index. */
896 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
897 error (EXIT_FAILURE, 0,
898 gettext ("cannot get section header string table index"));
900 puts (gettext ("Section Headers:"));
902 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
903 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
905 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
907 for (cnt = 0; cnt < shnum; ++cnt)
909 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
911 if (unlikely (scn == NULL))
912 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
915 /* Get the section header. */
917 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
918 if (unlikely (shdr == NULL))
919 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
924 if (shdr->sh_flags & SHF_WRITE)
926 if (shdr->sh_flags & SHF_ALLOC)
928 if (shdr->sh_flags & SHF_EXECINSTR)
930 if (shdr->sh_flags & SHF_MERGE)
932 if (shdr->sh_flags & SHF_STRINGS)
934 if (shdr->sh_flags & SHF_INFO_LINK)
936 if (shdr->sh_flags & SHF_LINK_ORDER)
938 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
940 if (shdr->sh_flags & SHF_GROUP)
942 if (shdr->sh_flags & SHF_TLS)
944 if (shdr->sh_flags & SHF_ORDERED)
946 if (shdr->sh_flags & SHF_EXCLUDE)
951 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
952 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
955 elf_strptr (ebl->elf, shstrndx, shdr->sh_name)
957 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
958 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
959 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
960 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
961 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
965 fputc_unlocked ('\n', stdout);
969 /* Print the program header. */
971 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
973 if (ehdr->e_phnum == 0)
974 /* No program header, this is OK in relocatable objects. */
977 puts (gettext ("Program Headers:"));
978 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
980 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
983 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
985 /* Process all program headers. */
986 bool has_relro = false;
987 GElf_Addr relro_from = 0;
988 GElf_Addr relro_to = 0;
989 for (size_t cnt = 0; cnt < phnum; ++cnt)
993 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
995 /* If for some reason the header cannot be returned show this. */
996 if (unlikely (phdr == NULL))
1002 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1003 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1004 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1006 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1007 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1010 phdr->p_flags & PF_R ? 'R' : ' ',
1011 phdr->p_flags & PF_W ? 'W' : ' ',
1012 phdr->p_flags & PF_X ? 'E' : ' ',
1015 if (phdr->p_type == PT_INTERP)
1017 /* We can show the user the name of the interpreter. */
1019 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1021 if (filedata != NULL && phdr->p_offset < maxsize)
1022 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1023 filedata + phdr->p_offset);
1025 else if (phdr->p_type == PT_GNU_RELRO)
1028 relro_from = phdr->p_vaddr;
1029 relro_to = relro_from + phdr->p_memsz;
1033 if (ehdr->e_shnum == 0)
1034 /* No sections in the file. Punt. */
1037 /* Get the section header string table index. */
1039 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1040 error (EXIT_FAILURE, 0,
1041 gettext ("cannot get section header string table index"));
1043 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1045 for (size_t cnt = 0; cnt < phnum; ++cnt)
1047 /* Print the segment number. */
1048 printf (" %2.2zu ", cnt);
1051 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1052 /* This must not happen. */
1053 if (unlikely (phdr == NULL))
1054 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1057 /* Iterate over the sections. */
1058 bool in_relro = false;
1060 for (size_t inner = 1; inner < shnum; ++inner)
1062 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1063 /* This should not happen. */
1064 if (unlikely (scn == NULL))
1065 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1068 /* Get the section header. */
1070 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1071 if (unlikely (shdr == NULL))
1072 error (EXIT_FAILURE, 0,
1073 gettext ("cannot get section header: %s"),
1076 if (shdr->sh_size > 0
1077 /* Compare allocated sections by VMA, unallocated
1078 sections by file offset. */
1079 && (shdr->sh_flags & SHF_ALLOC
1080 ? (shdr->sh_addr >= phdr->p_vaddr
1081 && (shdr->sh_addr + shdr->sh_size
1082 <= phdr->p_vaddr + phdr->p_memsz))
1083 : (shdr->sh_offset >= phdr->p_offset
1084 && (shdr->sh_offset + shdr->sh_size
1085 <= phdr->p_offset + phdr->p_filesz))))
1087 if (has_relro && !in_relro
1088 && shdr->sh_addr >= relro_from
1089 && shdr->sh_addr + shdr->sh_size <= relro_to)
1091 fputs_unlocked (" [RELRO:", stdout);
1094 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1096 fputs_unlocked ("]", stdout);
1099 else if (has_relro && in_relro
1100 && shdr->sh_addr + shdr->sh_size > relro_to)
1101 fputs_unlocked ("] <RELRO:", stdout);
1102 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1106 fputs_unlocked (" [RO:", stdout);
1112 /* Determine the segment this section is part of. */
1114 GElf_Phdr *phdr2 = NULL;
1115 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1117 GElf_Phdr phdr2_mem;
1118 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1120 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1121 && shdr->sh_addr >= phdr2->p_vaddr
1122 && (shdr->sh_addr + shdr->sh_size
1123 <= phdr2->p_vaddr + phdr2->p_memsz))
1129 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1131 fputs_unlocked (" [RO:", stdout);
1134 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1136 fputs_unlocked ("]", stdout);
1143 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1145 /* Signal that this sectin is only partially covered. */
1146 if (has_relro && in_relro
1147 && shdr->sh_addr + shdr->sh_size > relro_to)
1149 fputs_unlocked (">", stdout);
1154 if (in_relro || in_ro)
1155 fputs_unlocked ("]", stdout);
1157 /* Finish the line. */
1158 fputc_unlocked ('\n', stdout);
1164 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1166 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1171 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1173 /* Get the data of the section. */
1174 Elf_Data *data = elf_getdata (scn, NULL);
1176 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1177 GElf_Shdr symshdr_mem;
1178 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1179 Elf_Data *symdata = elf_getdata (symscn, NULL);
1181 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1185 /* Get the section header string table index. */
1187 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1188 error (EXIT_FAILURE, 0,
1189 gettext ("cannot get section header string table index"));
1191 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1194 printf ((grpref[0] & GRP_COMDAT)
1196 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1198 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1199 data->d_size / sizeof (Elf32_Word) - 1)
1201 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1202 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1203 data->d_size / sizeof (Elf32_Word) - 1),
1205 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1206 elf_strptr (ebl->elf, symshdr->sh_link,
1207 gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
1208 ?: gettext ("<INVALID SYMBOL>"),
1209 data->d_size / sizeof (Elf32_Word) - 1);
1211 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1213 GElf_Shdr grpshdr_mem;
1214 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1218 printf (" [%2u] %s\n",
1221 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1222 ? str : gettext ("<INVALID SECTION>"));
1228 print_scngrp (Ebl *ebl)
1230 /* Find all relocation sections and handle them. */
1231 Elf_Scn *scn = NULL;
1233 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1235 /* Handle the section if it is a symbol table. */
1237 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1239 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1240 handle_scngrp (ebl, scn, shdr);
1245 static const struct flags
1251 { DF_ORIGIN, "ORIGIN" },
1252 { DF_SYMBOLIC, "SYMBOLIC" },
1253 { DF_TEXTREL, "TEXTREL" },
1254 { DF_BIND_NOW, "BIND_NOW" },
1255 { DF_STATIC_TLS, "STATIC_TLS" }
1257 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1259 static const struct flags dt_flags_1[] =
1261 { DF_1_NOW, "NOW" },
1262 { DF_1_GLOBAL, "GLOBAL" },
1263 { DF_1_GROUP, "GROUP" },
1264 { DF_1_NODELETE, "NODELETE" },
1265 { DF_1_LOADFLTR, "LOADFLTR" },
1266 { DF_1_INITFIRST, "INITFIRST" },
1267 { DF_1_NOOPEN, "NOOPEN" },
1268 { DF_1_ORIGIN, "ORIGIN" },
1269 { DF_1_DIRECT, "DIRECT" },
1270 { DF_1_TRANS, "TRANS" },
1271 { DF_1_INTERPOSE, "INTERPOSE" },
1272 { DF_1_NODEFLIB, "NODEFLIB" },
1273 { DF_1_NODUMP, "NODUMP" },
1274 { DF_1_CONFALT, "CONFALT" },
1275 { DF_1_ENDFILTEE, "ENDFILTEE" },
1276 { DF_1_DISPRELDNE, "DISPRELDNE" },
1277 { DF_1_DISPRELPND, "DISPRELPND" },
1279 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1281 static const struct flags dt_feature_1[] =
1283 { DTF_1_PARINIT, "PARINIT" },
1284 { DTF_1_CONFEXP, "CONFEXP" }
1286 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1287 / sizeof (dt_feature_1[0]));
1289 static const struct flags dt_posflag_1[] =
1291 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1292 { DF_P1_GROUPPERM, "GROUPPERM" }
1294 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1295 / sizeof (dt_posflag_1[0]));
1299 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1305 for (cnt = 0; cnt < nflags; ++cnt)
1306 if (d_val & flags[cnt].mask)
1309 putchar_unlocked (' ');
1310 fputs_unlocked (flags[cnt].str, stdout);
1311 d_val &= ~flags[cnt].mask;
1318 putchar_unlocked (' ');
1319 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1322 putchar_unlocked ('\n');
1327 print_dt_flags (int class, GElf_Xword d_val)
1329 print_flags (class, d_val, dt_flags, ndt_flags);
1334 print_dt_flags_1 (int class, GElf_Xword d_val)
1336 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1341 print_dt_feature_1 (int class, GElf_Xword d_val)
1343 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1348 print_dt_posflag_1 (int class, GElf_Xword d_val)
1350 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1355 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1357 int class = gelf_getclass (ebl->elf);
1363 /* Get the data of the section. */
1364 data = elf_getdata (scn, NULL);
1368 /* Get the section header string table index. */
1369 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1370 error (EXIT_FAILURE, 0,
1371 gettext ("cannot get section header string table index"));
1373 printf (ngettext ("\
1374 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1376 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1377 shdr->sh_size / shdr->sh_entsize),
1378 (unsigned long int) (shdr->sh_size / shdr->sh_entsize),
1379 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1381 (int) shdr->sh_link,
1382 elf_strptr (ebl->elf, shstrndx,
1383 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1385 fputs_unlocked (gettext (" Type Value\n"), stdout);
1387 for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1390 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1396 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1404 /* No further output. */
1405 fputc_unlocked ('\n', stdout);
1409 printf (gettext ("Shared library: [%s]\n"),
1410 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1414 printf (gettext ("Library soname: [%s]\n"),
1415 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1419 printf (gettext ("Library rpath: [%s]\n"),
1420 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1424 printf (gettext ("Library runpath: [%s]\n"),
1425 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1438 case DT_INIT_ARRAYSZ:
1439 case DT_FINI_ARRAYSZ:
1442 case DT_GNU_CONFLICTSZ:
1443 case DT_GNU_LIBLISTSZ:
1444 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1451 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1455 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1457 puts (tagname ?: "???");
1461 print_dt_flags (class, dyn->d_un.d_val);
1465 print_dt_flags_1 (class, dyn->d_un.d_val);
1469 print_dt_feature_1 (class, dyn->d_un.d_val);
1473 print_dt_posflag_1 (class, dyn->d_un.d_val);
1477 printf ("%#0*" PRIx64 "\n",
1478 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1485 /* Print the dynamic segment. */
1487 print_dynamic (Ebl *ebl)
1489 for (size_t i = 0; i < phnum; ++i)
1492 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1494 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1496 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1498 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1499 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1500 handle_dynamic (ebl, scn, shdr);
1507 /* Print relocations. */
1509 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1511 /* Find all relocation sections and handle them. */
1512 Elf_Scn *scn = NULL;
1514 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1516 /* Handle the section if it is a symbol table. */
1518 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1520 if (likely (shdr != NULL))
1522 if (shdr->sh_type == SHT_REL)
1523 handle_relocs_rel (ebl, ehdr, scn, shdr);
1524 else if (shdr->sh_type == SHT_RELA)
1525 handle_relocs_rela (ebl, ehdr, scn, shdr);
1531 /* Handle a relocation section. */
1533 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1535 int class = gelf_getclass (ebl->elf);
1536 int nentries = shdr->sh_size / shdr->sh_entsize;
1538 /* Get the data of the section. */
1539 Elf_Data *data = elf_getdata (scn, NULL);
1543 /* Get the symbol table information. */
1544 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1545 GElf_Shdr symshdr_mem;
1546 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1547 Elf_Data *symdata = elf_getdata (symscn, NULL);
1549 /* Get the section header of the section the relocations are for. */
1550 GElf_Shdr destshdr_mem;
1551 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1554 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1556 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1561 /* Search for the optional extended section index table. */
1562 Elf_Data *xndxdata = NULL;
1563 int xndxscnidx = elf_scnshndx (scn);
1564 if (unlikely (xndxscnidx > 0))
1565 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1567 /* Get the section header string table index. */
1569 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1570 error (EXIT_FAILURE, 0,
1571 gettext ("cannot get section header string table index"));
1573 if (shdr->sh_info != 0)
1574 printf (ngettext ("\
1575 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1577 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1580 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1581 (unsigned int) shdr->sh_info,
1582 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1586 /* The .rel.dyn section does not refer to a specific section but
1587 instead of section index zero. Do not try to print a section
1589 printf (ngettext ("\
1590 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1592 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1594 (unsigned int) elf_ndxscn (scn),
1595 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1598 fputs_unlocked (class == ELFCLASS32
1600 Offset Type Value Name\n")
1602 Offset Type Value Name\n"),
1605 int is_statically_linked = 0;
1606 for (int cnt = 0; cnt < nentries; ++cnt)
1609 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1610 if (likely (rel != NULL))
1615 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1616 GELF_R_SYM (rel->r_info),
1618 if (unlikely (sym == NULL))
1620 /* As a special case we have to handle relocations in static
1621 executables. This only happens for IRELATIVE relocations
1622 (so far). There is no symbol table. */
1623 if (is_statically_linked == 0)
1625 /* Find the program header and look for a PT_INTERP entry. */
1626 is_statically_linked = -1;
1627 if (ehdr->e_type == ET_EXEC)
1629 is_statically_linked = 1;
1631 for (size_t inner = 0; inner < phnum; ++inner)
1634 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1636 if (phdr != NULL && phdr->p_type == PT_INTERP)
1638 is_statically_linked = -1;
1645 if (is_statically_linked > 0 && shdr->sh_link == 0)
1647 %#0*" PRIx64 " %-20s %*s %s\n",
1648 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1649 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1650 /* Avoid the leading R_ which isn't carrying any
1652 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1653 buf, sizeof (buf)) + 2
1654 : gettext ("<INVALID RELOC>"),
1655 class == ELFCLASS32 ? 10 : 18, "",
1656 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1658 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1659 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1660 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1661 /* Avoid the leading R_ which isn't carrying any
1663 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1664 buf, sizeof (buf)) + 2
1665 : gettext ("<INVALID RELOC>"),
1666 gettext ("INVALID SYMBOL"),
1667 (long int) GELF_R_SYM (rel->r_info));
1669 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1670 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1671 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1672 likely (ebl_reloc_type_check (ebl,
1673 GELF_R_TYPE (rel->r_info)))
1674 /* Avoid the leading R_ which isn't carrying any
1676 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1677 buf, sizeof (buf)) + 2
1678 : gettext ("<INVALID RELOC>"),
1679 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1680 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1683 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
1684 sym->st_shndx == SHN_XINDEX
1685 ? xndx : sym->st_shndx),
1688 if (unlikely (destshdr == NULL))
1689 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1690 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1691 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1692 /* Avoid the leading R_ which isn't carrying any
1694 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1695 buf, sizeof (buf)) + 2
1696 : gettext ("<INVALID RELOC>"),
1697 gettext ("INVALID SECTION"),
1698 (long int) (sym->st_shndx == SHN_XINDEX
1699 ? xndx : sym->st_shndx));
1701 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1702 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1703 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1704 /* Avoid the leading R_ which isn't carrying any
1706 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1707 buf, sizeof (buf)) + 2
1708 : gettext ("<INVALID RELOC>"),
1709 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1710 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1717 /* Handle a relocation section. */
1719 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1721 int class = gelf_getclass (ebl->elf);
1722 int nentries = shdr->sh_size / shdr->sh_entsize;
1724 /* Get the data of the section. */
1725 Elf_Data *data = elf_getdata (scn, NULL);
1729 /* Get the symbol table information. */
1730 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1731 GElf_Shdr symshdr_mem;
1732 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1733 Elf_Data *symdata = elf_getdata (symscn, NULL);
1735 /* Get the section header of the section the relocations are for. */
1736 GElf_Shdr destshdr_mem;
1737 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1740 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1742 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1747 /* Search for the optional extended section index table. */
1748 Elf_Data *xndxdata = NULL;
1749 int xndxscnidx = elf_scnshndx (scn);
1750 if (unlikely (xndxscnidx > 0))
1751 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1753 /* Get the section header string table index. */
1755 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1756 error (EXIT_FAILURE, 0,
1757 gettext ("cannot get section header string table index"));
1759 printf (ngettext ("\
1760 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1762 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1765 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1766 (unsigned int) shdr->sh_info,
1767 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1770 fputs_unlocked (class == ELFCLASS32
1772 Offset Type Value Addend Name\n")
1774 Offset Type Value Addend Name\n"),
1777 int is_statically_linked = 0;
1778 for (int cnt = 0; cnt < nentries; ++cnt)
1781 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
1782 if (likely (rel != NULL))
1787 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1788 GELF_R_SYM (rel->r_info),
1791 if (unlikely (sym == NULL))
1793 /* As a special case we have to handle relocations in static
1794 executables. This only happens for IRELATIVE relocations
1795 (so far). There is no symbol table. */
1796 if (is_statically_linked == 0)
1798 /* Find the program header and look for a PT_INTERP entry. */
1799 is_statically_linked = -1;
1800 if (ehdr->e_type == ET_EXEC)
1802 is_statically_linked = 1;
1804 for (size_t inner = 0; inner < phnum; ++inner)
1807 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1809 if (phdr != NULL && phdr->p_type == PT_INTERP)
1811 is_statically_linked = -1;
1818 if (is_statically_linked > 0 && shdr->sh_link == 0)
1820 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
1821 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1822 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1823 /* Avoid the leading R_ which isn't carrying any
1825 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1826 buf, sizeof (buf)) + 2
1827 : gettext ("<INVALID RELOC>"),
1828 class == ELFCLASS32 ? 10 : 18, "",
1830 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1832 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
1833 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1834 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1835 /* Avoid the leading R_ which isn't carrying any
1837 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1838 buf, sizeof (buf)) + 2
1839 : gettext ("<INVALID RELOC>"),
1840 gettext ("INVALID SYMBOL"),
1841 (long int) GELF_R_SYM (rel->r_info));
1843 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1845 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
1846 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1847 likely (ebl_reloc_type_check (ebl,
1848 GELF_R_TYPE (rel->r_info)))
1849 /* Avoid the leading R_ which isn't carrying any
1851 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1852 buf, sizeof (buf)) + 2
1853 : gettext ("<INVALID RELOC>"),
1854 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1856 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1859 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
1860 sym->st_shndx == SHN_XINDEX
1861 ? xndx : sym->st_shndx),
1864 if (unlikely (shdr == NULL))
1865 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
1866 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1867 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1868 /* Avoid the leading R_ which isn't carrying any
1870 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1871 buf, sizeof (buf)) + 2
1872 : gettext ("<INVALID RELOC>"),
1873 gettext ("INVALID SECTION"),
1874 (long int) (sym->st_shndx == SHN_XINDEX
1875 ? xndx : sym->st_shndx));
1878 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
1879 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1880 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1881 /* Avoid the leading R_ which isn't carrying any
1883 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1884 buf, sizeof (buf)) + 2
1885 : gettext ("<INVALID RELOC>"),
1886 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1888 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1895 /* Print the program header. */
1897 print_symtab (Ebl *ebl, int type)
1899 /* Find the symbol table(s). For this we have to search through the
1901 Elf_Scn *scn = NULL;
1903 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1905 /* Handle the section if it is a symbol table. */
1907 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1909 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
1910 handle_symtab (ebl, scn, shdr);
1916 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1918 Elf_Data *versym_data = NULL;
1919 Elf_Data *verneed_data = NULL;
1920 Elf_Data *verdef_data = NULL;
1921 Elf_Data *xndx_data = NULL;
1922 int class = gelf_getclass (ebl->elf);
1923 Elf32_Word verneed_stridx = 0;
1924 Elf32_Word verdef_stridx = 0;
1926 /* Get the data of the section. */
1927 Elf_Data *data = elf_getdata (scn, NULL);
1931 /* Find out whether we have other sections we might need. */
1932 Elf_Scn *runscn = NULL;
1933 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
1935 GElf_Shdr runshdr_mem;
1936 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
1938 if (likely (runshdr != NULL))
1940 if (runshdr->sh_type == SHT_GNU_versym
1941 && runshdr->sh_link == elf_ndxscn (scn))
1942 /* Bingo, found the version information. Now get the data. */
1943 versym_data = elf_getdata (runscn, NULL);
1944 else if (runshdr->sh_type == SHT_GNU_verneed)
1946 /* This is the information about the needed versions. */
1947 verneed_data = elf_getdata (runscn, NULL);
1948 verneed_stridx = runshdr->sh_link;
1950 else if (runshdr->sh_type == SHT_GNU_verdef)
1952 /* This is the information about the defined versions. */
1953 verdef_data = elf_getdata (runscn, NULL);
1954 verdef_stridx = runshdr->sh_link;
1956 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
1957 && runshdr->sh_link == elf_ndxscn (scn))
1958 /* Extended section index. */
1959 xndx_data = elf_getdata (runscn, NULL);
1963 /* Get the section header string table index. */
1965 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1966 error (EXIT_FAILURE, 0,
1967 gettext ("cannot get section header string table index"));
1969 /* Now we can compute the number of entries in the section. */
1970 unsigned int nsyms = data->d_size / (class == ELFCLASS32
1971 ? sizeof (Elf32_Sym)
1972 : sizeof (Elf64_Sym));
1974 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
1975 "\nSymbol table [%2u] '%s' contains %u entries:\n",
1977 (unsigned int) elf_ndxscn (scn),
1978 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
1980 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
1981 " %lu local symbols String table: [%2u] '%s'\n",
1983 (unsigned long int) shdr->sh_info,
1984 (unsigned int) shdr->sh_link,
1985 elf_strptr (ebl->elf, shstrndx,
1986 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1989 fputs_unlocked (class == ELFCLASS32
1991 Num: Value Size Type Bind Vis Ndx Name\n")
1993 Num: Value Size Type Bind Vis Ndx Name\n"),
1996 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2003 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2005 if (unlikely (sym == NULL))
2008 /* Determine the real section index. */
2009 if (likely (sym->st_shndx != SHN_XINDEX))
2010 xndx = sym->st_shndx;
2013 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2015 class == ELFCLASS32 ? 8 : 16,
2018 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2019 typebuf, sizeof (typebuf)),
2020 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2021 bindbuf, sizeof (bindbuf)),
2022 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2023 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2024 sizeof (scnbuf), NULL, shnum),
2025 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2027 if (versym_data != NULL)
2029 /* Get the version information. */
2030 GElf_Versym versym_mem;
2031 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2033 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2035 bool is_nobits = false;
2036 bool check_def = xndx != SHN_UNDEF;
2038 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2040 GElf_Shdr symshdr_mem;
2041 GElf_Shdr *symshdr =
2042 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2044 is_nobits = (symshdr != NULL
2045 && symshdr->sh_type == SHT_NOBITS);
2048 if (is_nobits || ! check_def)
2050 /* We must test both. */
2051 GElf_Vernaux vernaux_mem;
2052 GElf_Vernaux *vernaux = NULL;
2053 size_t vn_offset = 0;
2055 GElf_Verneed verneed_mem;
2056 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2058 while (verneed != NULL)
2060 size_t vna_offset = vn_offset;
2062 vernaux = gelf_getvernaux (verneed_data,
2063 vna_offset += verneed->vn_aux,
2065 while (vernaux != NULL
2066 && vernaux->vna_other != *versym
2067 && vernaux->vna_next != 0)
2069 /* Update the offset. */
2070 vna_offset += vernaux->vna_next;
2072 vernaux = (vernaux->vna_next == 0
2074 : gelf_getvernaux (verneed_data,
2079 /* Check whether we found the version. */
2080 if (vernaux != NULL && vernaux->vna_other == *versym)
2084 vn_offset += verneed->vn_next;
2085 verneed = (verneed->vn_next == 0
2087 : gelf_getverneed (verneed_data, vn_offset,
2091 if (vernaux != NULL && vernaux->vna_other == *versym)
2094 elf_strptr (ebl->elf, verneed_stridx,
2096 (unsigned int) vernaux->vna_other);
2099 else if (unlikely (! is_nobits))
2100 error (0, 0, gettext ("bad dynamic symbol"));
2105 if (check_def && *versym != 0x8001)
2107 /* We must test both. */
2108 size_t vd_offset = 0;
2110 GElf_Verdef verdef_mem;
2111 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2113 while (verdef != NULL)
2115 if (verdef->vd_ndx == (*versym & 0x7fff))
2116 /* Found the definition. */
2119 vd_offset += verdef->vd_next;
2120 verdef = (verdef->vd_next == 0
2122 : gelf_getverdef (verdef_data, vd_offset,
2128 GElf_Verdaux verdaux_mem;
2129 GElf_Verdaux *verdaux
2130 = gelf_getverdaux (verdef_data,
2131 vd_offset + verdef->vd_aux,
2134 if (verdaux != NULL)
2135 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2136 elf_strptr (ebl->elf, verdef_stridx,
2137 verdaux->vda_name));
2143 putchar_unlocked ('\n');
2148 /* Print version information. */
2150 print_verinfo (Ebl *ebl)
2152 /* Find the version information sections. For this we have to
2153 search through the section table. */
2154 Elf_Scn *scn = NULL;
2156 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2158 /* Handle the section if it is part of the versioning handling. */
2160 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2162 if (likely (shdr != NULL))
2164 if (shdr->sh_type == SHT_GNU_verneed)
2165 handle_verneed (ebl, scn, shdr);
2166 else if (shdr->sh_type == SHT_GNU_verdef)
2167 handle_verdef (ebl, scn, shdr);
2168 else if (shdr->sh_type == SHT_GNU_versym)
2169 handle_versym (ebl, scn, shdr);
2176 get_ver_flags (unsigned int flags)
2178 static char buf[32];
2182 return gettext ("none");
2184 if (flags & VER_FLG_BASE)
2185 endp = stpcpy (buf, "BASE ");
2189 if (flags & VER_FLG_WEAK)
2192 endp = stpcpy (endp, "| ");
2194 endp = stpcpy (endp, "WEAK ");
2197 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2199 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2200 buf[sizeof (buf) - 1] = '\0';
2208 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2210 int class = gelf_getclass (ebl->elf);
2212 /* Get the data of the section. */
2213 Elf_Data *data = elf_getdata (scn, NULL);
2217 /* Get the section header string table index. */
2219 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2220 error (EXIT_FAILURE, 0,
2221 gettext ("cannot get section header string table index"));
2224 printf (ngettext ("\
2225 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2227 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2229 (unsigned int) elf_ndxscn (scn),
2230 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2231 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2233 (unsigned int) shdr->sh_link,
2234 elf_strptr (ebl->elf, shstrndx,
2235 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2238 unsigned int offset = 0;
2239 for (int cnt = shdr->sh_info; --cnt >= 0; )
2241 /* Get the data at the next offset. */
2242 GElf_Verneed needmem;
2243 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2244 if (unlikely (need == NULL))
2247 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2248 offset, (unsigned short int) need->vn_version,
2249 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2250 (unsigned short int) need->vn_cnt);
2252 unsigned int auxoffset = offset + need->vn_aux;
2253 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2255 GElf_Vernaux auxmem;
2256 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2257 if (unlikely (aux == NULL))
2260 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2262 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2263 get_ver_flags (aux->vna_flags),
2264 (unsigned short int) aux->vna_other);
2266 auxoffset += aux->vna_next;
2269 /* Find the next offset. */
2270 offset += need->vn_next;
2276 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2278 /* Get the data of the section. */
2279 Elf_Data *data = elf_getdata (scn, NULL);
2283 /* Get the section header string table index. */
2285 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2286 error (EXIT_FAILURE, 0,
2287 gettext ("cannot get section header string table index"));
2289 int class = gelf_getclass (ebl->elf);
2291 printf (ngettext ("\
2292 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2294 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2296 (unsigned int) elf_ndxscn (scn),
2297 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2299 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2301 (unsigned int) shdr->sh_link,
2302 elf_strptr (ebl->elf, shstrndx,
2303 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2306 unsigned int offset = 0;
2307 for (int cnt = shdr->sh_info; --cnt >= 0; )
2309 /* Get the data at the next offset. */
2311 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2312 if (unlikely (def == NULL))
2315 unsigned int auxoffset = offset + def->vd_aux;
2316 GElf_Verdaux auxmem;
2317 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2318 if (unlikely (aux == NULL))
2322 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2323 offset, def->vd_version,
2324 get_ver_flags (def->vd_flags),
2327 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2329 auxoffset += aux->vda_next;
2330 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2332 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2333 if (unlikely (aux == NULL))
2336 printf (gettext (" %#06x: Parent %d: %s\n"),
2338 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2340 auxoffset += aux->vda_next;
2343 /* Find the next offset. */
2344 offset += def->vd_next;
2350 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2352 int class = gelf_getclass (ebl->elf);
2353 const char **vername;
2354 const char **filename;
2356 /* Get the data of the section. */
2357 Elf_Data *data = elf_getdata (scn, NULL);
2361 /* Get the section header string table index. */
2363 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2364 error (EXIT_FAILURE, 0,
2365 gettext ("cannot get section header string table index"));
2367 /* We have to find the version definition section and extract the
2369 Elf_Scn *defscn = NULL;
2370 Elf_Scn *needscn = NULL;
2372 Elf_Scn *verscn = NULL;
2373 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2375 GElf_Shdr vershdr_mem;
2376 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2378 if (likely (vershdr != NULL))
2380 if (vershdr->sh_type == SHT_GNU_verdef)
2382 else if (vershdr->sh_type == SHT_GNU_verneed)
2388 if (defscn != NULL || needscn != NULL)
2390 /* We have a version information (better should have). Now get
2391 the version names. First find the maximum version number. */
2395 /* Run through the version definitions and find the highest
2397 unsigned int offset = 0;
2399 GElf_Shdr defshdrmem;
2402 defdata = elf_getdata (defscn, NULL);
2403 if (unlikely (defdata == NULL))
2406 defshdr = gelf_getshdr (defscn, &defshdrmem);
2407 if (unlikely (defshdr == NULL))
2410 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2415 /* Get the data at the next offset. */
2416 def = gelf_getverdef (defdata, offset, &defmem);
2417 if (unlikely (def == NULL))
2420 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2422 offset += def->vd_next;
2425 if (needscn != NULL)
2427 unsigned int offset = 0;
2429 GElf_Shdr needshdrmem;
2430 GElf_Shdr *needshdr;
2432 needdata = elf_getdata (needscn, NULL);
2433 if (unlikely (needdata == NULL))
2436 needshdr = gelf_getshdr (needscn, &needshdrmem);
2437 if (unlikely (needshdr == NULL))
2440 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2442 GElf_Verneed needmem;
2444 unsigned int auxoffset;
2447 /* Get the data at the next offset. */
2448 need = gelf_getverneed (needdata, offset, &needmem);
2449 if (unlikely (need == NULL))
2452 /* Run through the auxiliary entries. */
2453 auxoffset = offset + need->vn_aux;
2454 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2456 GElf_Vernaux auxmem;
2459 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2460 if (unlikely (aux == NULL))
2463 nvername = MAX (nvername,
2464 (size_t) (aux->vna_other & 0x7fff));
2466 auxoffset += aux->vna_next;
2469 offset += need->vn_next;
2473 /* This is the number of versions we know about. */
2476 /* Allocate the array. */
2477 vername = (const char **) alloca (nvername * sizeof (const char *));
2478 filename = (const char **) alloca (nvername * sizeof (const char *));
2480 /* Run through the data structures again and collect the strings. */
2483 /* Run through the version definitions and find the highest
2485 unsigned int offset = 0;
2487 GElf_Shdr defshdrmem;
2490 defdata = elf_getdata (defscn, NULL);
2491 if (unlikely (defdata == NULL))
2494 defshdr = gelf_getshdr (defscn, &defshdrmem);
2495 if (unlikely (defshdr == NULL))
2498 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2501 /* Get the data at the next offset. */
2503 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2504 GElf_Verdaux auxmem;
2505 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2506 offset + def->vd_aux,
2508 if (unlikely (def == NULL || aux == NULL))
2511 vername[def->vd_ndx & 0x7fff]
2512 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2513 filename[def->vd_ndx & 0x7fff] = NULL;
2515 offset += def->vd_next;
2518 if (needscn != NULL)
2520 unsigned int offset = 0;
2522 Elf_Data *needdata = elf_getdata (needscn, NULL);
2523 GElf_Shdr needshdrmem;
2524 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2525 if (unlikely (needdata == NULL || needshdr == NULL))
2528 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2530 /* Get the data at the next offset. */
2531 GElf_Verneed needmem;
2532 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2534 if (unlikely (need == NULL))
2537 /* Run through the auxiliary entries. */
2538 unsigned int auxoffset = offset + need->vn_aux;
2539 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2541 GElf_Vernaux auxmem;
2542 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2544 if (unlikely (aux == NULL))
2547 vername[aux->vna_other & 0x7fff]
2548 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2549 filename[aux->vna_other & 0x7fff]
2550 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2552 auxoffset += aux->vna_next;
2555 offset += need->vn_next;
2566 /* Print the header. */
2568 printf (ngettext ("\
2569 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2571 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2572 shdr->sh_size / shdr->sh_entsize),
2573 (unsigned int) elf_ndxscn (scn),
2574 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2575 (int) (shdr->sh_size / shdr->sh_entsize),
2576 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2578 (unsigned int) shdr->sh_link,
2579 elf_strptr (ebl->elf, shstrndx,
2580 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2583 /* Now we can finally look at the actual contents of this section. */
2584 for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
2587 printf ("\n %4d:", cnt);
2590 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2598 fputs_unlocked (gettext (" 0 *local* "),
2603 fputs_unlocked (gettext (" 1 *global* "),
2608 n = printf ("%4d%c%s",
2609 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2610 (unsigned int) (*sym & 0x7fff) < nvername
2611 ? vername[*sym & 0x7fff] : "???");
2612 if ((unsigned int) (*sym & 0x7fff) < nvername
2613 && filename[*sym & 0x7fff] != NULL)
2614 n += printf ("(%s)", filename[*sym & 0x7fff]);
2615 printf ("%*s", MAX (0, 33 - (int) n), " ");
2619 putchar_unlocked ('\n');
2624 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2625 uint_fast32_t maxlength, Elf32_Word nbucket,
2626 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2628 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2630 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2631 ++counts[lengths[cnt]];
2634 printf (ngettext ("\
2635 \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",
2637 \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",
2639 (unsigned int) elf_ndxscn (scn),
2640 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2642 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2645 (unsigned int) shdr->sh_link,
2646 elf_strptr (ebl->elf, shstrndx,
2647 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2650 if (extrastr != NULL)
2651 fputs (extrastr, stdout);
2653 if (likely (nbucket > 0))
2655 uint64_t success = 0;
2657 /* xgettext:no-c-format */
2658 fputs_unlocked (gettext ("\
2659 Length Number % of total Coverage\n"), stdout);
2660 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2661 counts[0], (counts[0] * 100.0) / nbucket);
2663 uint64_t nzero_counts = 0;
2664 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2666 nzero_counts += counts[cnt] * cnt;
2668 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2669 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2670 (nzero_counts * 100.0) / nsyms);
2674 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2677 success += counts[cnt] * acc;
2681 Average number of tests: successful lookup: %f\n\
2682 unsuccessful lookup: %f\n"),
2683 (double) success / (double) nzero_counts,
2684 (double) nzero_counts / (double) nbucket);
2691 /* This function handles the traditional System V-style hash table format. */
2693 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2695 Elf_Data *data = elf_getdata (scn, NULL);
2696 if (unlikely (data == NULL))
2698 error (0, 0, gettext ("cannot get data for section %d: %s"),
2699 (int) elf_ndxscn (scn), elf_errmsg (-1));
2703 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2704 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2705 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2706 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2708 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2710 uint_fast32_t maxlength = 0;
2711 uint_fast32_t nsyms = 0;
2712 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2714 Elf32_Word inner = bucket[cnt];
2715 while (inner > 0 && inner < nchain)
2718 if (maxlength < ++lengths[cnt])
2721 inner = chain[inner];
2725 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2732 /* This function handles the incorrect, System V-style hash table
2733 format some 64-bit architectures use. */
2735 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2737 Elf_Data *data = elf_getdata (scn, NULL);
2738 if (unlikely (data == NULL))
2740 error (0, 0, gettext ("cannot get data for section %d: %s"),
2741 (int) elf_ndxscn (scn), elf_errmsg (-1));
2745 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
2746 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
2747 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
2748 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
2750 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2752 uint_fast32_t maxlength = 0;
2753 uint_fast32_t nsyms = 0;
2754 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
2756 Elf64_Xword inner = bucket[cnt];
2757 while (inner > 0 && inner < nchain)
2760 if (maxlength < ++lengths[cnt])
2763 inner = chain[inner];
2767 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2774 /* This function handles the GNU-style hash table format. */
2776 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2778 Elf_Data *data = elf_getdata (scn, NULL);
2779 if (unlikely (data == NULL))
2781 error (0, 0, gettext ("cannot get data for section %d: %s"),
2782 (int) elf_ndxscn (scn), elf_errmsg (-1));
2786 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2787 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
2789 /* Next comes the size of the bitmap. It's measured in words for
2790 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
2792 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
2793 if (gelf_getclass (ebl->elf) == ELFCLASS64)
2796 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
2798 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2800 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
2801 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
2802 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
2805 /* Compute distribution of chain lengths. */
2806 uint_fast32_t maxlength = 0;
2807 uint_fast32_t nsyms = 0;
2808 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2809 if (bucket[cnt] != 0)
2811 Elf32_Word inner = bucket[cnt] - symbias;
2815 if (maxlength < ++lengths[cnt])
2818 while ((chain[inner++] & 1) == 0);
2821 /* Count bits in bitmask. */
2822 uint_fast32_t nbits = 0;
2823 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
2825 uint_fast32_t word = bitmask[cnt];
2827 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
2828 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
2829 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
2830 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
2831 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
2835 if (unlikely (asprintf (&str, gettext ("\
2837 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
2838 (unsigned int) symbias,
2839 bitmask_words * sizeof (Elf32_Word),
2841 / (uint_fast32_t) (bitmask_words
2842 * sizeof (Elf32_Word) * 8)),
2843 (unsigned int) shift) == -1))
2844 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
2846 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2854 /* Find the symbol table(s). For this we have to search through the
2857 handle_hash (Ebl *ebl)
2859 /* Get the section header string table index. */
2861 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2862 error (EXIT_FAILURE, 0,
2863 gettext ("cannot get section header string table index"));
2865 Elf_Scn *scn = NULL;
2866 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2868 /* Handle the section if it is a symbol table. */
2870 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2872 if (likely (shdr != NULL))
2874 if (shdr->sh_type == SHT_HASH)
2876 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
2877 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
2879 handle_sysv_hash (ebl, scn, shdr, shstrndx);
2881 else if (shdr->sh_type == SHT_GNU_HASH)
2882 handle_gnu_hash (ebl, scn, shdr, shstrndx);
2889 print_liblist (Ebl *ebl)
2891 /* Find the library list sections. For this we have to search
2892 through the section table. */
2893 Elf_Scn *scn = NULL;
2895 /* Get the section header string table index. */
2897 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2898 error (EXIT_FAILURE, 0,
2899 gettext ("cannot get section header string table index"));
2901 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2904 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2906 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
2908 int nentries = shdr->sh_size / shdr->sh_entsize;
2909 printf (ngettext ("\
2910 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2912 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2915 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2919 Elf_Data *data = elf_getdata (scn, NULL);
2924 Library Time Stamp Checksum Version Flags"));
2926 for (int cnt = 0; cnt < nentries; ++cnt)
2929 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
2930 if (unlikely (lib == NULL))
2933 time_t t = (time_t) lib->l_time_stamp;
2934 struct tm *tm = gmtime (&t);
2935 if (unlikely (tm == NULL))
2938 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
2939 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
2940 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
2941 tm->tm_hour, tm->tm_min, tm->tm_sec,
2942 (unsigned int) lib->l_checksum,
2943 (unsigned int) lib->l_version,
2944 (unsigned int) lib->l_flags);
2951 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
2953 /* Find the object attributes sections. For this we have to search
2954 through the section table. */
2955 Elf_Scn *scn = NULL;
2957 /* Get the section header string table index. */
2959 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2960 error (EXIT_FAILURE, 0,
2961 gettext ("cannot get section header string table index"));
2963 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2966 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2968 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
2969 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
2970 || ehdr->e_machine != EM_ARM)))
2974 \nObject attributes section [%2zu] '%s' of %" PRIu64
2975 " bytes at offset %#0" PRIx64 ":\n"),
2977 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2978 shdr->sh_size, shdr->sh_offset);
2980 Elf_Data *data = elf_rawdata (scn, NULL);
2984 const unsigned char *p = data->d_buf;
2986 if (unlikely (*p++ != 'A'))
2989 fputs_unlocked (gettext (" Owner Size\n"), stdout);
2991 inline size_t left (void)
2993 return (const unsigned char *) data->d_buf + data->d_size - p;
2996 while (left () >= 4)
2999 memcpy (&len, p, sizeof len);
3001 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3004 if (unlikely (len > left ()))
3007 const unsigned char *name = p + sizeof len;
3010 unsigned const char *q = memchr (name, '\0', len);
3011 if (unlikely (q == NULL))
3015 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3017 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3018 || (q - name == sizeof "gnu"
3019 && !memcmp (name, "gnu", sizeof "gnu")))
3022 const unsigned char *const sub = q;
3024 unsigned int subsection_tag;
3025 get_uleb128 (subsection_tag, q);
3026 if (unlikely (q >= p))
3029 uint32_t subsection_len;
3030 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3033 memcpy (&subsection_len, q, sizeof subsection_len);
3035 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3036 CONVERT (subsection_len);
3038 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3041 const unsigned char *r = q + sizeof subsection_len;
3042 q = sub + subsection_len;
3044 switch (subsection_tag)
3047 printf (gettext (" %-4u %12" PRIu32 "\n"),
3048 subsection_tag, subsection_len);
3051 case 1: /* Tag_File */
3052 printf (gettext (" File: %11" PRIu32 "\n"),
3058 get_uleb128 (tag, r);
3059 if (unlikely (r >= q))
3063 const char *string = NULL;
3064 if (tag == 32 || (tag & 1) == 0)
3066 get_uleb128 (value, r);
3070 if (tag == 32 || (tag & 1) != 0)
3072 r = memchr (r, '\0', q - r);
3078 const char *tag_name = NULL;
3079 const char *value_name = NULL;
3080 ebl_check_object_attribute (ebl, (const char *) name,
3082 &tag_name, &value_name);
3084 if (tag_name != NULL)
3087 printf (gettext (" %s: %" PRId64 ", %s\n"),
3088 tag_name, value, string);
3089 else if (string == NULL && value_name == NULL)
3090 printf (gettext (" %s: %" PRId64 "\n"),
3093 printf (gettext (" %s: %s\n"),
3094 tag_name, string ?: value_name);
3100 printf (gettext (" %u: %" PRId64 "\n"),
3103 printf (gettext (" %u: %s\n"),
3115 format_dwarf_addr (Dwfl_Module *dwflmod,
3116 int address_size, Dwarf_Addr address)
3118 /* See if there is a name we can give for this address. */
3120 const char *name = print_address_names
3121 ? dwfl_module_addrsym (dwflmod, address, &sym, NULL) : NULL;
3123 sym.st_value = address - sym.st_value;
3125 /* Relativize the address. */
3126 int n = dwfl_module_relocations (dwflmod);
3127 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3129 /* In an ET_REL file there is a section name to refer to. */
3130 const char *scn = (i < 0 ? NULL
3131 : dwfl_module_relocation_info (dwflmod, i, NULL));
3135 ? (sym.st_value != 0
3137 ? (address_size == 0
3138 ? asprintf (&result,
3139 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3140 scn, address, name, sym.st_value)
3141 : asprintf (&result,
3142 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3143 scn, 2 + address_size * 2, address,
3144 name, sym.st_value))
3145 : (address_size == 0
3146 ? asprintf (&result,
3147 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3148 address, name, sym.st_value)
3149 : asprintf (&result,
3150 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3151 2 + address_size * 2, address,
3152 name, sym.st_value)))
3154 ? (address_size == 0
3155 ? asprintf (&result,
3156 gettext ("%s+%#" PRIx64 " <%s>"),
3158 : asprintf (&result,
3159 gettext ("%s+%#0*" PRIx64 " <%s>"),
3160 scn, 2 + address_size * 2, address, name))
3161 : (address_size == 0
3162 ? asprintf (&result,
3163 gettext ("%#" PRIx64 " <%s>"),
3165 : asprintf (&result,
3166 gettext ("%#0*" PRIx64 " <%s>"),
3167 2 + address_size * 2, address, name))))
3169 ? (address_size == 0
3170 ? asprintf (&result,
3171 gettext ("%s+%#" PRIx64),
3173 : asprintf (&result,
3174 gettext ("%s+%#0*" PRIx64),
3175 scn, 2 + address_size * 2, address))
3176 : (address_size == 0
3177 ? asprintf (&result,
3180 : asprintf (&result,
3182 2 + address_size * 2, address)))) < 0)
3183 error (EXIT_FAILURE, 0, _("memory exhausted"));
3189 dwarf_tag_string (unsigned int tag)
3191 static const char *const known_tags[] =
3193 [DW_TAG_array_type] = "array_type",
3194 [DW_TAG_class_type] = "class_type",
3195 [DW_TAG_entry_point] = "entry_point",
3196 [DW_TAG_enumeration_type] = "enumeration_type",
3197 [DW_TAG_formal_parameter] = "formal_parameter",
3198 [DW_TAG_imported_declaration] = "imported_declaration",
3199 [DW_TAG_label] = "label",
3200 [DW_TAG_lexical_block] = "lexical_block",
3201 [DW_TAG_member] = "member",
3202 [DW_TAG_pointer_type] = "pointer_type",
3203 [DW_TAG_reference_type] = "reference_type",
3204 [DW_TAG_compile_unit] = "compile_unit",
3205 [DW_TAG_string_type] = "string_type",
3206 [DW_TAG_structure_type] = "structure_type",
3207 [DW_TAG_subroutine_type] = "subroutine_type",
3208 [DW_TAG_typedef] = "typedef",
3209 [DW_TAG_union_type] = "union_type",
3210 [DW_TAG_unspecified_parameters] = "unspecified_parameters",
3211 [DW_TAG_variant] = "variant",
3212 [DW_TAG_common_block] = "common_block",
3213 [DW_TAG_common_inclusion] = "common_inclusion",
3214 [DW_TAG_inheritance] = "inheritance",
3215 [DW_TAG_inlined_subroutine] = "inlined_subroutine",
3216 [DW_TAG_module] = "module",
3217 [DW_TAG_ptr_to_member_type] = "ptr_to_member_type",
3218 [DW_TAG_set_type] = "set_type",
3219 [DW_TAG_subrange_type] = "subrange_type",
3220 [DW_TAG_with_stmt] = "with_stmt",
3221 [DW_TAG_access_declaration] = "access_declaration",
3222 [DW_TAG_base_type] = "base_type",
3223 [DW_TAG_catch_block] = "catch_block",
3224 [DW_TAG_const_type] = "const_type",
3225 [DW_TAG_constant] = "constant",
3226 [DW_TAG_enumerator] = "enumerator",
3227 [DW_TAG_file_type] = "file_type",
3228 [DW_TAG_friend] = "friend",
3229 [DW_TAG_namelist] = "namelist",
3230 [DW_TAG_namelist_item] = "namelist_item",
3231 [DW_TAG_packed_type] = "packed_type",
3232 [DW_TAG_subprogram] = "subprogram",
3233 [DW_TAG_template_type_parameter] = "template_type_parameter",
3234 [DW_TAG_template_value_parameter] = "template_value_parameter",
3235 [DW_TAG_thrown_type] = "thrown_type",
3236 [DW_TAG_try_block] = "try_block",
3237 [DW_TAG_variant_part] = "variant_part",
3238 [DW_TAG_variable] = "variable",
3239 [DW_TAG_volatile_type] = "volatile_type",
3240 [DW_TAG_dwarf_procedure] = "dwarf_procedure",
3241 [DW_TAG_restrict_type] = "restrict_type",
3242 [DW_TAG_interface_type] = "interface_type",
3243 [DW_TAG_namespace] = "namespace",
3244 [DW_TAG_imported_module] = "imported_module",
3245 [DW_TAG_unspecified_type] = "unspecified_type",
3246 [DW_TAG_partial_unit] = "partial_unit",
3247 [DW_TAG_imported_unit] = "imported_unit",
3248 [DW_TAG_mutable_type] = "mutable_type",
3249 [DW_TAG_condition] = "condition",
3250 [DW_TAG_shared_type] = "shared_type",
3251 [DW_TAG_type_unit] = "type_unit",
3252 [DW_TAG_rvalue_reference_type] = "rvalue_reference_type",
3253 [DW_TAG_template_alias] = "template_alias",
3255 const unsigned int nknown_tags = (sizeof (known_tags)
3256 / sizeof (known_tags[0]));
3257 static char buf[40];
3258 const char *result = NULL;
3260 if (likely (tag < nknown_tags))
3261 result = known_tags[tag];
3263 if (unlikely (result == NULL))
3264 /* There are a few known extensions. */
3267 case DW_TAG_MIPS_loop:
3268 result = "MIPS_loop";
3271 case DW_TAG_format_label:
3272 result = "format_label";
3275 case DW_TAG_function_template:
3276 result = "function_template";
3279 case DW_TAG_class_template:
3280 result = "class_template";
3283 case DW_TAG_GNU_BINCL:
3284 result = "GNU_BINCL";
3287 case DW_TAG_GNU_EINCL:
3288 result = "GNU_EINCL";
3291 case DW_TAG_GNU_template_template_param:
3292 result = "GNU_template_template_param";
3295 case DW_TAG_GNU_template_parameter_pack:
3296 result = "GNU_template_parameter_pack";
3299 case DW_TAG_GNU_formal_parameter_pack:
3300 result = "GNU_formal_parameter_pack";
3303 case DW_TAG_GNU_call_site:
3304 result = "GNU_call_site";
3307 case DW_TAG_GNU_call_site_parameter:
3308 result = "GNU_call_site_parameter";
3312 if (tag < DW_TAG_lo_user)
3313 snprintf (buf, sizeof buf, gettext ("unknown tag %hx"), tag);
3315 snprintf (buf, sizeof buf, gettext ("unknown user tag %hx"), tag);
3325 dwarf_attr_string (unsigned int attrnum)
3327 static const char *const known_attrs[] =
3329 [DW_AT_sibling] = "sibling",
3330 [DW_AT_location] = "location",
3331 [DW_AT_name] = "name",
3332 [DW_AT_ordering] = "ordering",
3333 [DW_AT_subscr_data] = "subscr_data",
3334 [DW_AT_byte_size] = "byte_size",
3335 [DW_AT_bit_offset] = "bit_offset",
3336 [DW_AT_bit_size] = "bit_size",
3337 [DW_AT_element_list] = "element_list",
3338 [DW_AT_stmt_list] = "stmt_list",
3339 [DW_AT_low_pc] = "low_pc",
3340 [DW_AT_high_pc] = "high_pc",
3341 [DW_AT_language] = "language",
3342 [DW_AT_member] = "member",
3343 [DW_AT_discr] = "discr",
3344 [DW_AT_discr_value] = "discr_value",
3345 [DW_AT_visibility] = "visibility",
3346 [DW_AT_import] = "import",
3347 [DW_AT_string_length] = "string_length",
3348 [DW_AT_common_reference] = "common_reference",
3349 [DW_AT_comp_dir] = "comp_dir",
3350 [DW_AT_const_value] = "const_value",
3351 [DW_AT_containing_type] = "containing_type",
3352 [DW_AT_default_value] = "default_value",
3353 [DW_AT_inline] = "inline",
3354 [DW_AT_is_optional] = "is_optional",
3355 [DW_AT_lower_bound] = "lower_bound",
3356 [DW_AT_producer] = "producer",
3357 [DW_AT_prototyped] = "prototyped",
3358 [DW_AT_return_addr] = "return_addr",
3359 [DW_AT_start_scope] = "start_scope",
3360 [DW_AT_bit_stride] = "bit_stride",
3361 [DW_AT_upper_bound] = "upper_bound",
3362 [DW_AT_abstract_origin] = "abstract_origin",
3363 [DW_AT_accessibility] = "accessibility",
3364 [DW_AT_address_class] = "address_class",
3365 [DW_AT_artificial] = "artificial",
3366 [DW_AT_base_types] = "base_types",
3367 [DW_AT_calling_convention] = "calling_convention",
3368 [DW_AT_count] = "count",
3369 [DW_AT_data_member_location] = "data_member_location",
3370 [DW_AT_decl_column] = "decl_column",
3371 [DW_AT_decl_file] = "decl_file",
3372 [DW_AT_decl_line] = "decl_line",
3373 [DW_AT_declaration] = "declaration",
3374 [DW_AT_discr_list] = "discr_list",
3375 [DW_AT_encoding] = "encoding",
3376 [DW_AT_external] = "external",
3377 [DW_AT_frame_base] = "frame_base",
3378 [DW_AT_friend] = "friend",
3379 [DW_AT_identifier_case] = "identifier_case",
3380 [DW_AT_macro_info] = "macro_info",
3381 [DW_AT_namelist_item] = "namelist_item",
3382 [DW_AT_priority] = "priority",
3383 [DW_AT_segment] = "segment",
3384 [DW_AT_specification] = "specification",
3385 [DW_AT_static_link] = "static_link",
3386 [DW_AT_type] = "type",
3387 [DW_AT_use_location] = "use_location",
3388 [DW_AT_variable_parameter] = "variable_parameter",
3389 [DW_AT_virtuality] = "virtuality",
3390 [DW_AT_vtable_elem_location] = "vtable_elem_location",
3391 [DW_AT_allocated] = "allocated",
3392 [DW_AT_associated] = "associated",
3393 [DW_AT_data_location] = "data_location",
3394 [DW_AT_byte_stride] = "byte_stride",
3395 [DW_AT_entry_pc] = "entry_pc",
3396 [DW_AT_use_UTF8] = "use_UTF8",
3397 [DW_AT_extension] = "extension",
3398 [DW_AT_ranges] = "ranges",
3399 [DW_AT_trampoline] = "trampoline",
3400 [DW_AT_call_column] = "call_column",
3401 [DW_AT_call_file] = "call_file",
3402 [DW_AT_call_line] = "call_line",
3403 [DW_AT_description] = "description",
3404 [DW_AT_binary_scale] = "binary_scale",
3405 [DW_AT_decimal_scale] = "decimal_scale",
3406 [DW_AT_small] = "small",
3407 [DW_AT_decimal_sign] = "decimal_sign",
3408 [DW_AT_digit_count] = "digit_count",
3409 [DW_AT_picture_string] = "picture_string",
3410 [DW_AT_mutable] = "mutable",
3411 [DW_AT_threads_scaled] = "threads_scaled",
3412 [DW_AT_explicit] = "explicit",
3413 [DW_AT_object_pointer] = "object_pointer",
3414 [DW_AT_endianity] = "endianity",
3415 [DW_AT_elemental] = "elemental",
3416 [DW_AT_pure] = "pure",
3417 [DW_AT_recursive] = "recursive",
3418 [DW_AT_signature] = "signature",
3419 [DW_AT_main_subprogram] = "main_subprogram",
3420 [DW_AT_data_bit_offset] = "data_bit_offset",
3421 [DW_AT_const_expr] = "const_expr",
3422 [DW_AT_enum_class] = "enum_class",
3423 [DW_AT_linkage_name] = "linkage_name",
3425 const unsigned int nknown_attrs = (sizeof (known_attrs)
3426 / sizeof (known_attrs[0]));
3427 static char buf[40];
3428 const char *result = NULL;
3430 if (likely (attrnum < nknown_attrs))
3431 result = known_attrs[attrnum];
3433 if (unlikely (result == NULL))
3434 /* There are a few known extensions. */
3437 case DW_AT_MIPS_fde:
3438 result = "MIPS_fde";
3441 case DW_AT_MIPS_loop_begin:
3442 result = "MIPS_loop_begin";
3445 case DW_AT_MIPS_tail_loop_begin:
3446 result = "MIPS_tail_loop_begin";
3449 case DW_AT_MIPS_epilog_begin:
3450 result = "MIPS_epilog_begin";
3453 case DW_AT_MIPS_loop_unroll_factor:
3454 result = "MIPS_loop_unroll_factor";
3457 case DW_AT_MIPS_software_pipeline_depth:
3458 result = "MIPS_software_pipeline_depth";
3461 case DW_AT_MIPS_linkage_name:
3462 result = "MIPS_linkage_name";
3465 case DW_AT_MIPS_stride:
3466 result = "MIPS_stride";
3469 case DW_AT_MIPS_abstract_name:
3470 result = "MIPS_abstract_name";
3473 case DW_AT_MIPS_clone_origin:
3474 result = "MIPS_clone_origin";
3477 case DW_AT_MIPS_has_inlines:
3478 result = "MIPS_has_inlines";
3481 case DW_AT_MIPS_stride_byte:
3482 result = "MIPS_stride_byte";
3485 case DW_AT_MIPS_stride_elem:
3486 result = "MIPS_stride_elem";
3489 case DW_AT_MIPS_ptr_dopetype:
3490 result = "MIPS_ptr_dopetype";
3493 case DW_AT_MIPS_allocatable_dopetype:
3494 result = "MIPS_allocatable_dopetype";
3497 case DW_AT_MIPS_assumed_shape_dopetype:
3498 result = "MIPS_assumed_shape_dopetype";
3501 case DW_AT_MIPS_assumed_size:
3502 result = "MIPS_assumed_size";
3505 case DW_AT_sf_names:
3506 result = "sf_names";
3509 case DW_AT_src_info:
3510 result = "src_info";
3513 case DW_AT_mac_info:
3514 result = "mac_info";
3517 case DW_AT_src_coords:
3518 result = "src_coords";
3521 case DW_AT_body_begin:
3522 result = "body_begin";
3525 case DW_AT_body_end:
3526 result = "body_end";
3529 case DW_AT_GNU_vector:
3530 result = "GNU_vector";
3533 case DW_AT_GNU_guarded_by:
3534 result = "GNU_guarded_by";
3537 case DW_AT_GNU_pt_guarded_by:
3538 result = "GNU_pt_guarded_by";
3541 case DW_AT_GNU_guarded:
3542 result = "GNU_guarded";
3545 case DW_AT_GNU_pt_guarded:
3546 result = "GNU_pt_guarded";
3549 case DW_AT_GNU_locks_excluded:
3550 result = "GNU_locks_excluded";
3553 case DW_AT_GNU_exclusive_locks_required:
3554 result = "GNU_exclusive_locks_required";
3557 case DW_AT_GNU_shared_locks_required:
3558 result = "GNU_shared_locks_required";
3561 case DW_AT_GNU_odr_signature:
3562 result = "GNU_odr_signature";
3565 case DW_AT_GNU_template_name:
3566 result = "GNU_template_name";
3569 case DW_AT_GNU_call_site_value:
3570 result = "GNU_call_site_value";
3573 case DW_AT_GNU_call_site_data_value:
3574 result = "GNU_call_site_data_value";
3577 case DW_AT_GNU_call_site_target:
3578 result = "GNU_call_site_target";
3581 case DW_AT_GNU_call_site_target_clobbered:
3582 result = "GNU_call_site_target_clobbered";
3585 case DW_AT_GNU_tail_call:
3586 result = "GNU_tail_call";
3589 case DW_AT_GNU_all_tail_call_sites:
3590 result = "GNU_all_tail_call_sites";
3593 case DW_AT_GNU_all_call_sites:
3594 result = "GNU_all_call_sites";
3597 case DW_AT_GNU_all_source_call_sites:
3598 result = "GNU_all_source_call_sites";
3602 if (attrnum < DW_AT_lo_user)
3603 snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"),
3606 snprintf (buf, sizeof buf, gettext ("unknown user attribute %hx"),
3617 dwarf_form_string (unsigned int form)
3619 static const char *const known_forms[] =
3621 [DW_FORM_addr] = "addr",
3622 [DW_FORM_block2] = "block2",
3623 [DW_FORM_block4] = "block4",
3624 [DW_FORM_data2] = "data2",
3625 [DW_FORM_data4] = "data4",
3626 [DW_FORM_data8] = "data8",
3627 [DW_FORM_string] = "string",
3628 [DW_FORM_block] = "block",
3629 [DW_FORM_block1] = "block1",
3630 [DW_FORM_data1] = "data1",
3631 [DW_FORM_flag] = "flag",
3632 [DW_FORM_sdata] = "sdata",
3633 [DW_FORM_strp] = "strp",
3634 [DW_FORM_udata] = "udata",
3635 [DW_FORM_ref_addr] = "ref_addr",
3636 [DW_FORM_ref1] = "ref1",
3637 [DW_FORM_ref2] = "ref2",
3638 [DW_FORM_ref4] = "ref4",
3639 [DW_FORM_ref8] = "ref8",
3640 [DW_FORM_ref_udata] = "ref_udata",
3641 [DW_FORM_indirect] = "indirect",
3642 [DW_FORM_sec_offset] = "sec_offset",
3643 [DW_FORM_exprloc] = "exprloc",
3644 [DW_FORM_flag_present] = "flag_present",
3645 [DW_FORM_ref_sig8] = "ref_sig8",
3647 const unsigned int nknown_forms = (sizeof (known_forms)
3648 / sizeof (known_forms[0]));
3649 static char buf[40];
3650 const char *result = NULL;
3652 if (likely (form < nknown_forms))
3653 result = known_forms[form];
3655 if (unlikely (result == NULL))
3657 snprintf (buf, sizeof buf, gettext ("unknown form %#" PRIx64),
3667 dwarf_lang_string (unsigned int lang)
3669 static const char *const known[] =
3671 [DW_LANG_C89] = "ISO C89",
3673 [DW_LANG_Ada83] = "Ada83",
3674 [DW_LANG_C_plus_plus] = "C++",
3675 [DW_LANG_Cobol74] = "Cobol74",
3676 [DW_LANG_Cobol85] = "Cobol85",
3677 [DW_LANG_Fortran77] = "Fortran77",
3678 [DW_LANG_Fortran90] = "Fortran90",
3679 [DW_LANG_Pascal83] = "Pascal83",
3680 [DW_LANG_Modula2] = "Modula2",
3681 [DW_LANG_Java] = "Java",
3682 [DW_LANG_C99] = "ISO C99",
3683 [DW_LANG_Ada95] = "Ada95",
3684 [DW_LANG_Fortran95] = "Fortran95",
3685 [DW_LANG_PL1] = "PL1",
3686 [DW_LANG_Objc] = "Objective C",
3687 [DW_LANG_ObjC_plus_plus] = "Objective C++",
3688 [DW_LANG_UPC] = "UPC",
3692 if (likely (lang < sizeof (known) / sizeof (known[0])))
3694 else if (lang == DW_LANG_Mips_Assembler)
3695 /* This language tag is used for assembler in general. */
3698 if (lang >= DW_LANG_lo_user && lang <= DW_LANG_hi_user)
3700 static char buf[30];
3701 snprintf (buf, sizeof (buf), "lo_user+%u", lang - DW_LANG_lo_user);
3710 dwarf_inline_string (unsigned int code)
3712 static const char *const known[] =
3714 [DW_INL_not_inlined] = "not_inlined",
3715 [DW_INL_inlined] = "inlined",
3716 [DW_INL_declared_not_inlined] = "declared_not_inlined",
3717 [DW_INL_declared_inlined] = "declared_inlined"
3720 if (likely (code < sizeof (known) / sizeof (known[0])))
3728 dwarf_encoding_string (unsigned int code)
3730 static const char *const known[] =
3732 [DW_ATE_void] = "void",
3733 [DW_ATE_address] = "address",
3734 [DW_ATE_boolean] = "boolean",
3735 [DW_ATE_complex_float] = "complex_float",
3736 [DW_ATE_float] = "float",
3737 [DW_ATE_signed] = "signed",
3738 [DW_ATE_signed_char] = "signed_char",
3739 [DW_ATE_unsigned] = "unsigned",
3740 [DW_ATE_unsigned_char] = "unsigned_char",
3741 [DW_ATE_imaginary_float] = "imaginary_float",
3742 [DW_ATE_packed_decimal] = "packed_decimal",
3743 [DW_ATE_numeric_string] = "numeric_string",
3744 [DW_ATE_edited] = "edited",
3745 [DW_ATE_signed_fixed] = "signed_fixed",
3746 [DW_ATE_unsigned_fixed] = "unsigned_fixed",
3747 [DW_ATE_decimal_float] = "decimal_float",
3750 if (likely (code < sizeof (known) / sizeof (known[0])))
3753 if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user)
3755 static char buf[30];
3756 snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user);
3765 dwarf_access_string (unsigned int code)
3767 static const char *const known[] =
3769 [DW_ACCESS_public] = "public",
3770 [DW_ACCESS_protected] = "protected",
3771 [DW_ACCESS_private] = "private"
3774 if (likely (code < sizeof (known) / sizeof (known[0])))
3782 dwarf_visibility_string (unsigned int code)
3784 static const char *const known[] =
3786 [DW_VIS_local] = "local",
3787 [DW_VIS_exported] = "exported",
3788 [DW_VIS_qualified] = "qualified"
3791 if (likely (code < sizeof (known) / sizeof (known[0])))
3799 dwarf_virtuality_string (unsigned int code)
3801 static const char *const known[] =
3803 [DW_VIRTUALITY_none] = "none",
3804 [DW_VIRTUALITY_virtual] = "virtual",
3805 [DW_VIRTUALITY_pure_virtual] = "pure_virtual"
3808 if (likely (code < sizeof (known) / sizeof (known[0])))
3816 dwarf_identifier_case_string (unsigned int code)
3818 static const char *const known[] =
3820 [DW_ID_case_sensitive] = "sensitive",
3821 [DW_ID_up_case] = "up_case",
3822 [DW_ID_down_case] = "down_case",
3823 [DW_ID_case_insensitive] = "insensitive"
3826 if (likely (code < sizeof (known) / sizeof (known[0])))
3834 dwarf_calling_convention_string (unsigned int code)
3836 static const char *const known[] =
3838 [DW_CC_normal] = "normal",
3839 [DW_CC_program] = "program",
3840 [DW_CC_nocall] = "nocall",
3843 if (likely (code < sizeof (known) / sizeof (known[0])))
3846 if (code >= DW_CC_lo_user && code <= DW_CC_hi_user)
3848 static char buf[30];
3849 snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_CC_lo_user);
3858 dwarf_ordering_string (unsigned int code)
3860 static const char *const known[] =
3862 [DW_ORD_row_major] = "row_major",
3863 [DW_ORD_col_major] = "col_major"
3866 if (likely (code < sizeof (known) / sizeof (known[0])))
3874 dwarf_discr_list_string (unsigned int code)
3876 static const char *const known[] =
3878 [DW_DSC_label] = "label",
3879 [DW_DSC_range] = "range"
3882 if (likely (code < sizeof (known) / sizeof (known[0])))
3890 print_block (size_t n, const void *block)
3893 puts (_("empty block"));
3896 printf (_("%zu byte block:"), n);
3897 const unsigned char *data = block;
3899 printf (" %02x", *data++);
3906 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3907 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3908 Dwarf_Word len, const unsigned char *data)
3910 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3912 static const char *const known[] =
3914 [DW_OP_addr] = "addr",
3915 [DW_OP_deref] = "deref",
3916 [DW_OP_const1u] = "const1u",
3917 [DW_OP_const1s] = "const1s",
3918 [DW_OP_const2u] = "const2u",
3919 [DW_OP_const2s] = "const2s",
3920 [DW_OP_const4u] = "const4u",
3921 [DW_OP_const4s] = "const4s",
3922 [DW_OP_const8u] = "const8u",
3923 [DW_OP_const8s] = "const8s",
3924 [DW_OP_constu] = "constu",
3925 [DW_OP_consts] = "consts",
3926 [DW_OP_dup] = "dup",
3927 [DW_OP_drop] = "drop",
3928 [DW_OP_over] = "over",
3929 [DW_OP_pick] = "pick",
3930 [DW_OP_swap] = "swap",
3931 [DW_OP_rot] = "rot",
3932 [DW_OP_xderef] = "xderef",
3933 [DW_OP_abs] = "abs",
3934 [DW_OP_and] = "and",
3935 [DW_OP_div] = "div",
3936 [DW_OP_minus] = "minus",
3937 [DW_OP_mod] = "mod",
3938 [DW_OP_mul] = "mul",
3939 [DW_OP_neg] = "neg",
3940 [DW_OP_not] = "not",
3942 [DW_OP_plus] = "plus",
3943 [DW_OP_plus_uconst] = "plus_uconst",
3944 [DW_OP_shl] = "shl",
3945 [DW_OP_shr] = "shr",
3946 [DW_OP_shra] = "shra",
3947 [DW_OP_xor] = "xor",
3948 [DW_OP_bra] = "bra",
3955 [DW_OP_skip] = "skip",
3956 [DW_OP_lit0] = "lit0",
3957 [DW_OP_lit1] = "lit1",
3958 [DW_OP_lit2] = "lit2",
3959 [DW_OP_lit3] = "lit3",
3960 [DW_OP_lit4] = "lit4",
3961 [DW_OP_lit5] = "lit5",
3962 [DW_OP_lit6] = "lit6",
3963 [DW_OP_lit7] = "lit7",
3964 [DW_OP_lit8] = "lit8",
3965 [DW_OP_lit9] = "lit9",
3966 [DW_OP_lit10] = "lit10",
3967 [DW_OP_lit11] = "lit11",
3968 [DW_OP_lit12] = "lit12",
3969 [DW_OP_lit13] = "lit13",
3970 [DW_OP_lit14] = "lit14",
3971 [DW_OP_lit15] = "lit15",
3972 [DW_OP_lit16] = "lit16",
3973 [DW_OP_lit17] = "lit17",
3974 [DW_OP_lit18] = "lit18",
3975 [DW_OP_lit19] = "lit19",
3976 [DW_OP_lit20] = "lit20",
3977 [DW_OP_lit21] = "lit21",
3978 [DW_OP_lit22] = "lit22",
3979 [DW_OP_lit23] = "lit23",
3980 [DW_OP_lit24] = "lit24",
3981 [DW_OP_lit25] = "lit25",
3982 [DW_OP_lit26] = "lit26",
3983 [DW_OP_lit27] = "lit27",
3984 [DW_OP_lit28] = "lit28",
3985 [DW_OP_lit29] = "lit29",
3986 [DW_OP_lit30] = "lit30",
3987 [DW_OP_lit31] = "lit31",
3988 [DW_OP_reg0] = "reg0",
3989 [DW_OP_reg1] = "reg1",
3990 [DW_OP_reg2] = "reg2",
3991 [DW_OP_reg3] = "reg3",
3992 [DW_OP_reg4] = "reg4",
3993 [DW_OP_reg5] = "reg5",
3994 [DW_OP_reg6] = "reg6",
3995 [DW_OP_reg7] = "reg7",
3996 [DW_OP_reg8] = "reg8",
3997 [DW_OP_reg9] = "reg9",
3998 [DW_OP_reg10] = "reg10",
3999 [DW_OP_reg11] = "reg11",
4000 [DW_OP_reg12] = "reg12",
4001 [DW_OP_reg13] = "reg13",
4002 [DW_OP_reg14] = "reg14",
4003 [DW_OP_reg15] = "reg15",
4004 [DW_OP_reg16] = "reg16",
4005 [DW_OP_reg17] = "reg17",
4006 [DW_OP_reg18] = "reg18",
4007 [DW_OP_reg19] = "reg19",
4008 [DW_OP_reg20] = "reg20",
4009 [DW_OP_reg21] = "reg21",
4010 [DW_OP_reg22] = "reg22",
4011 [DW_OP_reg23] = "reg23",
4012 [DW_OP_reg24] = "reg24",
4013 [DW_OP_reg25] = "reg25",
4014 [DW_OP_reg26] = "reg26",
4015 [DW_OP_reg27] = "reg27",
4016 [DW_OP_reg28] = "reg28",
4017 [DW_OP_reg29] = "reg29",
4018 [DW_OP_reg30] = "reg30",
4019 [DW_OP_reg31] = "reg31",
4020 [DW_OP_breg0] = "breg0",
4021 [DW_OP_breg1] = "breg1",
4022 [DW_OP_breg2] = "breg2",
4023 [DW_OP_breg3] = "breg3",
4024 [DW_OP_breg4] = "breg4",
4025 [DW_OP_breg5] = "breg5",
4026 [DW_OP_breg6] = "breg6",
4027 [DW_OP_breg7] = "breg7",
4028 [DW_OP_breg8] = "breg8",
4029 [DW_OP_breg9] = "breg9",
4030 [DW_OP_breg10] = "breg10",
4031 [DW_OP_breg11] = "breg11",
4032 [DW_OP_breg12] = "breg12",
4033 [DW_OP_breg13] = "breg13",
4034 [DW_OP_breg14] = "breg14",
4035 [DW_OP_breg15] = "breg15",
4036 [DW_OP_breg16] = "breg16",
4037 [DW_OP_breg17] = "breg17",
4038 [DW_OP_breg18] = "breg18",
4039 [DW_OP_breg19] = "breg19",
4040 [DW_OP_breg20] = "breg20",
4041 [DW_OP_breg21] = "breg21",
4042 [DW_OP_breg22] = "breg22",
4043 [DW_OP_breg23] = "breg23",
4044 [DW_OP_breg24] = "breg24",
4045 [DW_OP_breg25] = "breg25",
4046 [DW_OP_breg26] = "breg26",
4047 [DW_OP_breg27] = "breg27",
4048 [DW_OP_breg28] = "breg28",
4049 [DW_OP_breg29] = "breg29",
4050 [DW_OP_breg30] = "breg30",
4051 [DW_OP_breg31] = "breg31",
4052 [DW_OP_regx] = "regx",
4053 [DW_OP_fbreg] = "fbreg",
4054 [DW_OP_bregx] = "bregx",
4055 [DW_OP_piece] = "piece",
4056 [DW_OP_deref_size] = "deref_size",
4057 [DW_OP_xderef_size] = "xderef_size",
4058 [DW_OP_nop] = "nop",
4059 [DW_OP_push_object_address] = "push_object_address",
4060 [DW_OP_call2] = "call2",
4061 [DW_OP_call4] = "call4",
4062 [DW_OP_call_ref] = "call_ref",
4063 [DW_OP_form_tls_address] = "form_tls_address",
4064 [DW_OP_call_frame_cfa] = "call_frame_cfa",
4065 [DW_OP_bit_piece] = "bit_piece",
4066 [DW_OP_implicit_value] = "implicit_value",
4067 [DW_OP_stack_value] = "stack_value",
4068 [DW_OP_GNU_implicit_pointer] = "GNU_implicit_pointer",
4069 [DW_OP_GNU_entry_value] = "GNU_entry_value",
4070 [DW_OP_GNU_const_type] = "GNU_const_type",
4071 [DW_OP_GNU_regval_type] = "GNU_regval_type",
4072 [DW_OP_GNU_deref_type] = "GNU_deref_type",
4073 [DW_OP_GNU_convert] = "GNU_convert",
4074 [DW_OP_GNU_reinterpret] = "GNU_reinterpret",
4079 printf ("%*s(empty)\n", indent, "");
4083 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4084 #define CONSUME(n) NEED (n); else len -= (n)
4086 Dwarf_Word offset = 0;
4089 uint_fast8_t op = *data++;
4094 /* Address operand. */
4098 addr = read_4ubyte_unaligned (dbg, data);
4101 assert (addrsize == 8);
4102 addr = read_8ubyte_unaligned (dbg, data);
4107 char *a = format_dwarf_addr (dwflmod, 0, addr);
4108 printf ("%*s[%4" PRIuMAX "] %s %s\n",
4109 indent, "", (uintmax_t) offset, known[op], a);
4112 offset += 1 + addrsize;
4115 case DW_OP_call_ref:
4116 /* Offset operand. */
4119 addr = read_4ubyte_unaligned (dbg, data);
4122 assert (ref_size == 8);
4123 addr = read_8ubyte_unaligned (dbg, data);
4128 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4129 indent, "", (uintmax_t) offset,
4130 known[op], (uintmax_t) addr);
4131 offset += 1 + ref_size;
4134 case DW_OP_deref_size:
4135 case DW_OP_xderef_size:
4138 // XXX value might be modified by relocation
4140 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4141 indent, "", (uintmax_t) offset,
4142 known[op], *((uint8_t *) data));
4150 // XXX value might be modified by relocation
4151 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4152 indent, "", (uintmax_t) offset,
4153 known[op], read_2ubyte_unaligned (dbg, data));
4161 // XXX value might be modified by relocation
4162 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4163 indent, "", (uintmax_t) offset,
4164 known[op], read_4ubyte_unaligned (dbg, data));
4172 // XXX value might be modified by relocation
4173 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4174 indent, "", (uintmax_t) offset,
4175 known[op], read_8ubyte_unaligned (dbg, data));
4183 // XXX value might be modified by relocation
4184 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4185 indent, "", (uintmax_t) offset,
4186 known[op], *((int8_t *) data));
4194 // XXX value might be modified by relocation
4195 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4196 indent, "", (uintmax_t) offset,
4197 known[op], read_2sbyte_unaligned (dbg, data));
4205 // XXX value might be modified by relocation
4206 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4207 indent, "", (uintmax_t) offset,
4208 known[op], read_4sbyte_unaligned (dbg, data));
4216 // XXX value might be modified by relocation
4217 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4218 indent, "", (uintmax_t) offset,
4219 known[op], read_8sbyte_unaligned (dbg, data));
4227 case DW_OP_plus_uconst:
4229 const unsigned char *start = data;
4232 get_uleb128 (uleb, data); /* XXX check overrun */
4233 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4234 indent, "", (uintmax_t) offset, known[op], uleb);
4235 CONSUME (data - start);
4236 offset += 1 + (data - start);
4239 case DW_OP_bit_piece:
4243 get_uleb128 (uleb, data); /* XXX check overrun */
4244 get_uleb128 (uleb2, data); /* XXX check overrun */
4245 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4246 indent, "", (uintmax_t) offset, known[op], uleb, uleb2);
4247 CONSUME (data - start);
4248 offset += 1 + (data - start);
4252 case DW_OP_breg0 ... DW_OP_breg31:
4257 get_sleb128 (sleb, data); /* XXX check overrun */
4258 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4259 indent, "", (uintmax_t) offset, known[op], sleb);
4260 CONSUME (data - start);
4261 offset += 1 + (data - start);
4267 get_uleb128 (uleb, data); /* XXX check overrun */
4268 get_sleb128 (sleb, data); /* XXX check overrun */
4269 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4270 indent, "", (uintmax_t) offset, known[op], uleb, sleb);
4271 CONSUME (data - start);
4272 offset += 1 + (data - start);
4277 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4278 indent, "", (uintmax_t) offset, known[op],
4279 read_2ubyte_unaligned (dbg, data));
4286 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4287 indent, "", (uintmax_t) offset, known[op],
4288 read_4ubyte_unaligned (dbg, data));
4296 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4297 indent, "", (uintmax_t) offset, known[op],
4298 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data)));
4304 case DW_OP_implicit_value:
4307 get_uleb128 (uleb, data); /* XXX check overrun */
4308 printf ("%*s[%4" PRIuMAX "] %s: ",
4309 indent, "", (uintmax_t) offset, known[op]);
4311 print_block (uleb, data);
4313 CONSUME (data - start);
4314 offset += 1 + (data - start);
4317 case DW_OP_GNU_implicit_pointer:
4318 /* DIE offset operand. */
4320 NEED (ref_size + 1);
4322 addr = read_4ubyte_unaligned (dbg, data);
4325 assert (ref_size == 8);
4326 addr = read_8ubyte_unaligned (dbg, data);
4329 /* Byte offset operand. */
4330 get_sleb128 (sleb, data); /* XXX check overrun */
4332 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX ", %+" PRId64 "\n",
4333 indent, "", (intmax_t) offset,
4334 known[op], (uintmax_t) addr, sleb);
4335 CONSUME (data - start);
4336 offset += 1 + (data - start);
4339 case DW_OP_GNU_entry_value:
4340 /* Size plus expression block. */
4343 get_uleb128 (uleb, data); /* XXX check overrun */
4344 printf ("%*s[%4" PRIuMAX "] %s:\n",
4345 indent, "", (uintmax_t) offset, known[op]);
4347 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4348 addrsize, offset_size, uleb, data);
4350 CONSUME (data - start);
4351 offset += 1 + (data - start);
4354 case DW_OP_GNU_const_type:
4355 /* DIE offset, size plus block. */
4358 get_uleb128 (uleb, data); /* XXX check overrun */
4359 uint8_t usize = *(uint8_t *) data++;
4361 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4362 indent, "", (uintmax_t) offset, known[op], uleb);
4363 print_block (usize, data);
4365 CONSUME (data - start);
4366 offset += 1 + (data - start);
4369 case DW_OP_GNU_regval_type:
4372 get_uleb128 (uleb, data); /* XXX check overrun */
4373 get_uleb128 (uleb2, data); /* XXX check overrun */
4374 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %#" PRIx64 "\n",
4375 indent, "", (uintmax_t) offset, known[op], uleb, uleb2);
4376 CONSUME (data - start);
4377 offset += 1 + (data - start);
4380 case DW_OP_GNU_deref_type:
4383 usize = *(uint8_t *) data++;
4384 get_uleb128 (uleb, data); /* XXX check overrun */
4385 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4386 indent, "", (uintmax_t) offset,
4387 known[op], usize, uleb);
4388 CONSUME (data - start);
4389 offset += 1 + (data - start);
4392 case DW_OP_GNU_convert:
4393 case DW_OP_GNU_reinterpret:
4396 get_uleb128 (uleb, data); /* XXX check overrun */
4397 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4398 indent, "", (uintmax_t) offset, known[op], uleb);
4399 CONSUME (data - start);
4400 offset += 1 + (data - start);
4405 if (op < sizeof known / sizeof known[0] && known[op] != NULL)
4406 printf ("%*s[%4" PRIuMAX "] %s\n",
4407 indent, "", (uintmax_t) offset, known[op]);
4409 printf ("%*s[%4" PRIuMAX "] %#x\n",
4410 indent, "", (uintmax_t) offset, op);
4415 indent = indentrest;
4419 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4420 indent, "", (uintmax_t) offset, known[op]);
4428 Dwarf_Off offset:(64 - 3);
4434 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4435 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4438 compare_listptr (const void *a, const void *b, void *arg)
4440 const char *name = arg;
4441 struct listptr *p1 = (void *) a;
4442 struct listptr *p2 = (void *) b;
4444 if (p1->offset < p2->offset)
4446 if (p1->offset > p2->offset)
4449 if (!p1->warned && !p2->warned)
4451 if (p1->addr64 != p2->addr64)
4453 p1->warned = p2->warned = true;
4455 gettext ("%s %#" PRIx64 " used with different address sizes"),
4456 name, (uint64_t) p1->offset);
4458 if (p1->dwarf64 != p2->dwarf64)
4460 p1->warned = p2->warned = true;
4462 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4463 name, (uint64_t) p1->offset);
4470 struct listptr_table
4474 struct listptr *table;
4477 static struct listptr_table known_loclistptr;
4478 static struct listptr_table known_rangelistptr;
4481 reset_listptr (struct listptr_table *table)
4483 free (table->table);
4484 table->table = NULL;
4485 table->n = table->alloc = 0;
4489 notice_listptr (enum section_e section, struct listptr_table *table,
4490 uint_fast8_t address_size, uint_fast8_t offset_size,
4493 if (print_debug_sections & section)
4495 if (table->n == table->alloc)
4497 if (table->alloc == 0)
4501 table->table = xrealloc (table->table,
4502 table->alloc * sizeof table->table[0]);
4505 struct listptr *p = &table->table[table->n++];
4507 *p = (struct listptr)
4509 .addr64 = address_size == 8,
4510 .dwarf64 = offset_size == 8,
4513 assert (p->offset == offset);
4518 sort_listptr (struct listptr_table *table, const char *name)
4521 qsort_r (table->table, table->n, sizeof table->table[0],
4522 &compare_listptr, (void *) name);
4526 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4527 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4528 ptrdiff_t offset, unsigned char **readp, unsigned char *endp)
4533 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4536 struct listptr *p = &table->table[*idxp];
4538 if (*idxp == table->n
4539 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4542 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4547 if (p->offset != (Dwarf_Off) offset)
4549 *readp += p->offset - offset;
4550 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4551 offset, (Dwarf_Off) p->offset - offset);
4555 if (address_sizep != NULL)
4556 *address_sizep = listptr_address_size (p);
4557 if (offset_sizep != NULL)
4558 *offset_sizep = listptr_offset_size (p);
4565 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4566 Ebl *ebl, GElf_Ehdr *ehdr,
4567 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4569 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4571 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4572 (uint64_t) shdr->sh_offset);
4574 Dwarf_Off offset = 0;
4575 while (offset < dbg->sectiondata[IDX_debug_abbrev]->d_size)
4577 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4583 Dwarf_Abbrev abbrev;
4585 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4588 if (unlikely (res < 0))
4591 *** error while reading abbreviation: %s\n"),
4596 /* This is the NUL byte at the end of the section. */
4601 /* We know these calls can never fail. */
4602 unsigned int code = dwarf_getabbrevcode (&abbrev);
4603 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4604 int has_children = dwarf_abbrevhaschildren (&abbrev);
4606 printf (gettext (" [%5u] offset: %" PRId64
4607 ", children: %s, tag: %s\n"),
4608 code, (int64_t) offset,
4609 has_children ? gettext ("yes") : gettext ("no"),
4610 dwarf_tag_string (tag));
4616 while (dwarf_getabbrevattr (&abbrev, cnt,
4617 &name, &form, &enoffset) == 0)
4619 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4620 dwarf_attr_string (name), dwarf_form_string (form),
4621 (uint64_t) enoffset);
4632 /* Print content of DWARF .debug_aranges section. We fortunately do
4633 not have to know a bit about the structure of the section, libdwarf
4634 takes care of it. */
4636 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4637 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4638 GElf_Shdr *shdr, Dwarf *dbg)
4640 Dwarf_Aranges *aranges;
4642 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4644 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4649 printf (ngettext ("\
4650 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4652 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4654 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4655 (uint64_t) shdr->sh_offset, cnt);
4657 /* Compute floor(log16(cnt)). */
4666 for (size_t n = 0; n < cnt; ++n)
4668 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4669 if (unlikely (runp == NULL))
4671 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4679 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4680 printf (gettext (" [%*zu] ???\n"), digits, n);
4682 printf (gettext (" [%*zu] start: %0#*" PRIx64
4683 ", length: %5" PRIu64 ", CU DIE offset: %6"
4685 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4686 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4690 /* Print content of DWARF .debug_ranges section. */
4692 print_debug_ranges_section (Dwfl_Module *dwflmod,
4693 Ebl *ebl, GElf_Ehdr *ehdr,
4694 Elf_Scn *scn, GElf_Shdr *shdr,
4697 Elf_Data *data = elf_rawdata (scn, NULL);
4699 if (unlikely (data == NULL))
4701 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4707 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4708 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4709 (uint64_t) shdr->sh_offset);
4711 sort_listptr (&known_rangelistptr, "rangelistptr");
4712 size_t listptr_idx = 0;
4714 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4717 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4718 unsigned char *readp = data->d_buf;
4719 while (readp < endp)
4721 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4723 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4724 &address_size, NULL,
4725 offset, &readp, endp))
4728 if (unlikely (data->d_size - offset < address_size * 2))
4730 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4736 if (address_size == 8)
4738 begin = read_8ubyte_unaligned_inc (dbg, readp);
4739 end = read_8ubyte_unaligned_inc (dbg, readp);
4743 begin = read_4ubyte_unaligned_inc (dbg, readp);
4744 end = read_4ubyte_unaligned_inc (dbg, readp);
4745 if (begin == (Dwarf_Addr) (uint32_t) -1)
4746 begin = (Dwarf_Addr) -1l;
4749 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4751 char *b = format_dwarf_addr (dwflmod, address_size, end);
4752 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4755 else if (begin == 0 && end == 0) /* End of list entry. */
4758 printf (gettext (" [%6tx] empty list\n"), offset);
4763 char *b = format_dwarf_addr (dwflmod, address_size, begin);
4764 char *e = format_dwarf_addr (dwflmod, address_size, end);
4765 /* We have an address range entry. */
4766 if (first) /* First address range entry in a list. */
4767 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4769 printf (gettext (" %s..%s\n"), b, e);
4778 #define REGNAMESZ 16
4780 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4781 char name[REGNAMESZ], int *bits, int *type)
4786 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4787 bits ?: &ignore, type ?: &ignore);
4790 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4794 *type = DW_ATE_unsigned;
4795 set = "??? unrecognized";
4799 if (bits != NULL && *bits <= 0)
4801 if (type != NULL && *type == DW_ATE_void)
4802 *type = DW_ATE_unsigned;
4809 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4810 Dwarf_Word vma_base, unsigned int code_align,
4812 unsigned int version, unsigned int ptr_size,
4813 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4815 char regnamebuf[REGNAMESZ];
4816 const char *regname (unsigned int regno)
4818 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4822 puts ("\n Program:");
4823 Dwarf_Word pc = vma_base;
4824 while (readp < endp)
4826 unsigned int opcode = *readp++;
4828 if (opcode < DW_CFA_advance_loc)
4829 /* Extended opcode. */
4840 case DW_CFA_set_loc:
4841 // XXX overflow check
4842 get_uleb128 (op1, readp);
4844 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4846 case DW_CFA_advance_loc1:
4847 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4848 *readp, pc += *readp * code_align);
4851 case DW_CFA_advance_loc2:
4852 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4853 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4854 op1, pc += op1 * code_align);
4856 case DW_CFA_advance_loc4:
4857 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4858 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4859 op1, pc += op1 * code_align);
4861 case DW_CFA_offset_extended:
4862 // XXX overflow check
4863 get_uleb128 (op1, readp);
4864 get_uleb128 (op2, readp);
4865 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4867 op1, regname (op1), op2 * data_align);
4869 case DW_CFA_restore_extended:
4870 // XXX overflow check
4871 get_uleb128 (op1, readp);
4872 printf (" restore_extended r%" PRIu64 " (%s)\n",
4873 op1, regname (op1));
4875 case DW_CFA_undefined:
4876 // XXX overflow check
4877 get_uleb128 (op1, readp);
4878 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4880 case DW_CFA_same_value:
4881 // XXX overflow check
4882 get_uleb128 (op1, readp);
4883 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4885 case DW_CFA_register:
4886 // XXX overflow check
4887 get_uleb128 (op1, readp);
4888 get_uleb128 (op2, readp);
4889 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4890 op1, regname (op1), op2, regname (op2));
4892 case DW_CFA_remember_state:
4893 puts (" remember_state");
4895 case DW_CFA_restore_state:
4896 puts (" restore_state");
4898 case DW_CFA_def_cfa:
4899 // XXX overflow check
4900 get_uleb128 (op1, readp);
4901 get_uleb128 (op2, readp);
4902 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4903 op1, regname (op1), op2);
4905 case DW_CFA_def_cfa_register:
4906 // XXX overflow check
4907 get_uleb128 (op1, readp);
4908 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
4909 op1, regname (op1));
4911 case DW_CFA_def_cfa_offset:
4912 // XXX overflow check
4913 get_uleb128 (op1, readp);
4914 printf (" def_cfa_offset %" PRIu64 "\n", op1);
4916 case DW_CFA_def_cfa_expression:
4917 // XXX overflow check
4918 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
4919 printf (" def_cfa_expression %" PRIu64 "\n", op1);
4920 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op1, readp);
4923 case DW_CFA_expression:
4924 // XXX overflow check
4925 get_uleb128 (op1, readp);
4926 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4927 printf (" expression r%" PRIu64 " (%s) \n",
4928 op1, regname (op1));
4929 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op2, readp);
4932 case DW_CFA_offset_extended_sf:
4933 // XXX overflow check
4934 get_uleb128 (op1, readp);
4935 get_sleb128 (sop2, readp);
4936 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
4938 op1, regname (op1), sop2 * data_align);
4940 case DW_CFA_def_cfa_sf:
4941 // XXX overflow check
4942 get_uleb128 (op1, readp);
4943 get_sleb128 (sop2, readp);
4944 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
4945 op1, regname (op1), sop2 * data_align);
4947 case DW_CFA_def_cfa_offset_sf:
4948 // XXX overflow check
4949 get_sleb128 (sop1, readp);
4950 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
4952 case DW_CFA_val_offset:
4953 // XXX overflow check
4954 get_uleb128 (op1, readp);
4955 get_uleb128 (op2, readp);
4956 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
4957 op1, op2 * data_align);
4959 case DW_CFA_val_offset_sf:
4960 // XXX overflow check
4961 get_uleb128 (op1, readp);
4962 get_sleb128 (sop2, readp);
4963 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
4964 op1, sop2 * data_align);
4966 case DW_CFA_val_expression:
4967 // XXX overflow check
4968 get_uleb128 (op1, readp);
4969 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4970 printf (" val_expression r%" PRIu64 " (%s)\n",
4971 op1, regname (op1));
4972 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op2, readp);
4975 case DW_CFA_MIPS_advance_loc8:
4976 op1 = read_8ubyte_unaligned_inc (dbg, readp);
4977 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
4978 op1, pc += op1 * code_align);
4980 case DW_CFA_GNU_window_save:
4981 puts (" GNU_window_save");
4983 case DW_CFA_GNU_args_size:
4984 // XXX overflow check
4985 get_uleb128 (op1, readp);
4986 printf (" args_size %" PRIu64 "\n", op1);
4989 printf (" ??? (%u)\n", opcode);
4992 else if (opcode < DW_CFA_offset)
4993 printf (" advance_loc %u to %#" PRIx64 "\n",
4994 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
4995 else if (opcode < DW_CFA_restore)
4998 // XXX overflow check
4999 get_uleb128 (offset, readp);
5000 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5001 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5004 printf (" restore r%u (%s)\n",
5005 opcode & 0x3f, regname (opcode & 0x3f));
5011 encoded_ptr_size (int encoding, unsigned int ptr_size)
5013 switch (encoding & 7)
5028 print_encoding (unsigned int val)
5032 case DW_EH_PE_absptr:
5033 fputs ("absptr", stdout);
5035 case DW_EH_PE_uleb128:
5036 fputs ("uleb128", stdout);
5038 case DW_EH_PE_udata2:
5039 fputs ("udata2", stdout);
5041 case DW_EH_PE_udata4:
5042 fputs ("udata4", stdout);
5044 case DW_EH_PE_udata8:
5045 fputs ("udata8", stdout);
5047 case DW_EH_PE_sleb128:
5048 fputs ("sleb128", stdout);
5050 case DW_EH_PE_sdata2:
5051 fputs ("sdata2", stdout);
5053 case DW_EH_PE_sdata4:
5054 fputs ("sdata4", stdout);
5056 case DW_EH_PE_sdata8:
5057 fputs ("sdata8", stdout);
5060 /* We did not use any of the bits after all. */
5069 print_relinfo (unsigned int val)
5073 case DW_EH_PE_pcrel:
5074 fputs ("pcrel", stdout);
5076 case DW_EH_PE_textrel:
5077 fputs ("textrel", stdout);
5079 case DW_EH_PE_datarel:
5080 fputs ("datarel", stdout);
5082 case DW_EH_PE_funcrel:
5083 fputs ("funcrel", stdout);
5085 case DW_EH_PE_aligned:
5086 fputs ("aligned", stdout);
5097 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5099 printf ("(%s", pfx);
5101 if (fde_encoding == DW_EH_PE_omit)
5105 unsigned int w = fde_encoding;
5107 w = print_encoding (w);
5111 if (w != fde_encoding)
5112 fputc_unlocked (' ', stdout);
5114 w = print_relinfo (w);
5118 printf ("%s%x", w != fde_encoding ? " " : "", w);
5125 static const unsigned char *
5126 read_encoded (unsigned int encoding, const unsigned char *readp,
5127 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5129 if ((encoding & 0xf) == DW_EH_PE_absptr)
5130 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5131 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5133 switch (encoding & 0xf)
5135 case DW_EH_PE_uleb128:
5136 // XXX buffer overrun check
5137 get_uleb128 (*res, readp);
5139 case DW_EH_PE_sleb128:
5140 // XXX buffer overrun check
5141 get_sleb128 (*res, readp);
5143 case DW_EH_PE_udata2:
5144 if (readp + 2 > endp)
5146 *res = read_2ubyte_unaligned_inc (dbg, readp);
5148 case DW_EH_PE_udata4:
5149 if (readp + 4 > endp)
5151 *res = read_4ubyte_unaligned_inc (dbg, readp);
5153 case DW_EH_PE_udata8:
5154 if (readp + 8 > endp)
5156 *res = read_8ubyte_unaligned_inc (dbg, readp);
5158 case DW_EH_PE_sdata2:
5159 if (readp + 2 > endp)
5161 *res = read_2sbyte_unaligned_inc (dbg, readp);
5163 case DW_EH_PE_sdata4:
5164 if (readp + 4 > endp)
5166 *res = read_4sbyte_unaligned_inc (dbg, readp);
5168 case DW_EH_PE_sdata8:
5169 if (readp + 8 > endp)
5171 *res = read_8sbyte_unaligned_inc (dbg, readp);
5176 gettext ("invalid encoding"));
5184 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5185 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5188 /* We know this call will succeed since it did in the caller. */
5189 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5190 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5192 Elf_Data *data = elf_rawdata (scn, NULL);
5194 if (unlikely (data == NULL))
5196 error (0, 0, gettext ("cannot get %s content: %s"),
5197 scnname, elf_errmsg (-1));
5200 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5204 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5205 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5208 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5209 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5213 ptrdiff_t cie_offset;
5214 const char *augmentation;
5215 unsigned int code_alignment_factor;
5216 unsigned int data_alignment_factor;
5217 uint8_t address_size;
5218 uint8_t fde_encoding;
5219 uint8_t lsda_encoding;
5220 struct cieinfo *next;
5223 const unsigned char *readp = data->d_buf;
5224 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5226 while (readp < dataend)
5228 if (unlikely (readp + 4 > dataend))
5231 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5232 elf_ndxscn (scn), scnname);
5236 /* At the beginning there must be a CIE. There can be multiple,
5237 hence we test tis in a loop. */
5238 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5240 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5241 unsigned int length = 4;
5242 if (unlikely (unit_length == 0xffffffff))
5244 if (unlikely (readp + 8 > dataend))
5247 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5251 if (unlikely (unit_length == 0))
5253 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5257 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5259 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5260 const unsigned char *const cieend = readp + unit_length;
5261 if (unlikely (cieend > dataend || readp + 8 > dataend))
5267 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5268 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5269 cie_id = DW_CIE_ID_64;
5272 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5274 uint_fast8_t version = 2;
5275 unsigned int code_alignment_factor;
5276 int data_alignment_factor;
5277 unsigned int fde_encoding = 0;
5278 unsigned int lsda_encoding = 0;
5279 Dwarf_Word initial_location = 0;
5280 Dwarf_Word vma_base = 0;
5282 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5285 const char *const augmentation = (const char *) readp;
5286 readp = memchr (readp, '\0', cieend - readp);
5287 if (unlikely (readp == NULL))
5291 uint_fast8_t segment_size = 0;
5294 if (cieend - readp < 5)
5296 ptr_size = *readp++;
5297 segment_size = *readp++;
5300 // XXX Check overflow
5301 get_uleb128 (code_alignment_factor, readp);
5302 // XXX Check overflow
5303 get_sleb128 (data_alignment_factor, readp);
5305 /* In some variant for unwind data there is another field. */
5306 if (strcmp (augmentation, "eh") == 0)
5307 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5309 unsigned int return_address_register;
5310 if (unlikely (version == 1))
5311 return_address_register = *readp++;
5313 // XXX Check overflow
5314 get_uleb128 (return_address_register, readp);
5316 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5317 " CIE_id: %" PRIu64 "\n"
5319 " augmentation: \"%s\"\n",
5320 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5321 version, augmentation);
5323 printf (" address_size: %u\n"
5324 " segment_size: %u\n",
5325 ptr_size, segment_size);
5326 printf (" code_alignment_factor: %u\n"
5327 " data_alignment_factor: %d\n"
5328 " return_address_register: %u\n",
5329 code_alignment_factor,
5330 data_alignment_factor, return_address_register);
5332 if (augmentation[0] == 'z')
5334 unsigned int augmentationlen;
5335 get_uleb128 (augmentationlen, readp);
5337 if (augmentationlen > (size_t) (dataend - readp))
5338 error (1, 0, gettext ("invalid augmentation length"));
5340 const char *hdr = "Augmentation data:";
5341 const char *cp = augmentation + 1;
5344 printf (" %-26s%#x ", hdr, *readp);
5349 fde_encoding = *readp++;
5350 print_encoding_base (gettext ("FDE address encoding: "),
5353 else if (*cp == 'L')
5355 lsda_encoding = *readp++;
5356 print_encoding_base (gettext ("LSDA pointer encoding: "),
5359 else if (*cp == 'P')
5361 /* Personality. This field usually has a relocation
5362 attached pointing to __gcc_personality_v0. */
5363 const unsigned char *startp = readp;
5364 unsigned int encoding = *readp++;
5366 readp = read_encoded (encoding, readp,
5367 readp - 1 + augmentationlen,
5370 while (++startp < readp)
5371 printf ("%#x ", *startp);
5374 print_encoding (encoding);
5376 switch (encoding & 0xf)
5378 case DW_EH_PE_sleb128:
5379 case DW_EH_PE_sdata2:
5380 case DW_EH_PE_sdata4:
5381 printf ("%" PRId64 ")\n", val);
5384 printf ("%#" PRIx64 ")\n", val);
5389 printf ("(%x)\n", *readp++);
5395 if (likely (ptr_size == 4 || ptr_size == 8))
5397 struct cieinfo *newp = alloca (sizeof (*newp));
5398 newp->cie_offset = offset;
5399 newp->augmentation = augmentation;
5400 newp->fde_encoding = fde_encoding;
5401 newp->lsda_encoding = lsda_encoding;
5402 newp->address_size = ptr_size;
5403 newp->code_alignment_factor = code_alignment_factor;
5404 newp->data_alignment_factor = data_alignment_factor;
5411 struct cieinfo *cie = cies;
5414 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5415 : (ptrdiff_t) cie_id == cie->cie_offset)
5419 if (unlikely (cie == NULL))
5421 puts ("invalid CIE reference in FDE");
5425 /* Initialize from CIE data. */
5426 fde_encoding = cie->fde_encoding;
5427 lsda_encoding = cie->lsda_encoding;
5428 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5429 code_alignment_factor = cie->code_alignment_factor;
5430 data_alignment_factor = cie->data_alignment_factor;
5432 const unsigned char *base = readp;
5433 // XXX There are sometimes relocations for this value
5434 initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5435 Dwarf_Word address_range
5436 = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5438 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5440 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5441 " CIE_pointer: %" PRIu64 "\n"
5442 " initial_location: %s",
5443 offset, (uint64_t) unit_length,
5444 cie->cie_offset, (uint64_t) cie_id, a);
5446 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5448 vma_base = (((uint64_t) shdr->sh_offset
5449 + (base - (const unsigned char *) data->d_buf)
5450 + (uint64_t) initial_location)
5452 ? UINT64_C (0xffffffff)
5453 : UINT64_C (0xffffffffffffffff)));
5454 printf (gettext (" (offset: %#" PRIx64 ")"),
5455 (uint64_t) vma_base);
5458 printf ("\n address_range: %#" PRIx64,
5459 (uint64_t) address_range);
5460 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5461 printf (gettext (" (end offset: %#" PRIx64 ")"),
5462 ((uint64_t) vma_base + (uint64_t) address_range)
5464 ? UINT64_C (0xffffffff)
5465 : UINT64_C (0xffffffffffffffff)));
5468 if (cie->augmentation[0] == 'z')
5470 unsigned int augmentationlen;
5471 get_uleb128 (augmentationlen, readp);
5473 if (augmentationlen > 0)
5475 const char *hdr = "Augmentation data:";
5476 const char *cp = cie->augmentation + 1;
5482 uint64_t lsda_pointer;
5483 const unsigned char *p
5484 = read_encoded (lsda_encoding, &readp[u],
5485 &readp[augmentationlen],
5486 &lsda_pointer, dbg);
5489 %-26sLSDA pointer: %#" PRIx64 "\n"),
5496 while (u < augmentationlen)
5498 printf (" %-26s%#x\n", hdr, readp[u++]);
5503 readp += augmentationlen;
5507 /* Handle the initialization instructions. */
5508 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5509 data_alignment_factor, version, ptr_size,
5518 Dwfl_Module *dwflmod;
5522 unsigned int version;
5523 unsigned int addrsize;
5524 unsigned int offset_size;
5525 Dwarf_Off cu_offset;
5530 attr_callback (Dwarf_Attribute *attrp, void *arg)
5532 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5533 const int level = cbargs->level;
5535 unsigned int attr = dwarf_whatattr (attrp);
5536 if (unlikely (attr == 0))
5538 if (!cbargs->silent)
5539 error (0, 0, gettext ("cannot get attribute code: %s"),
5541 return DWARF_CB_ABORT;
5544 unsigned int form = dwarf_whatform (attrp);
5545 if (unlikely (form == 0))
5547 if (!cbargs->silent)
5548 error (0, 0, gettext ("cannot get attribute form: %s"),
5550 return DWARF_CB_ABORT;
5556 if (!cbargs->silent)
5559 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5562 if (!cbargs->silent)
5563 error (0, 0, gettext ("cannot get attribute value: %s"),
5565 return DWARF_CB_ABORT;
5567 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr);
5568 printf (" %*s%-20s (%s) %s\n",
5569 (int) (level * 2), "", dwarf_attr_string (attr),
5570 dwarf_form_string (form), a);
5575 case DW_FORM_indirect:
5577 case DW_FORM_string:
5580 const char *str = dwarf_formstring (attrp);
5581 if (unlikely (str == NULL))
5583 printf (" %*s%-20s (%s) \"%s\"\n",
5584 (int) (level * 2), "", dwarf_attr_string (attr),
5585 dwarf_form_string (form), str);
5588 case DW_FORM_ref_addr:
5589 case DW_FORM_ref_udata:
5597 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5600 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5601 (int) (level * 2), "", dwarf_attr_string (attr),
5602 dwarf_form_string (form), (uintmax_t) dwarf_dieoffset (&ref));
5605 case DW_FORM_ref_sig8:
5608 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5609 (int) (level * 2), "", dwarf_attr_string (attr),
5610 dwarf_form_string (form),
5611 read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5614 case DW_FORM_sec_offset:
5620 case DW_FORM_data1:;
5622 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5625 const char *valuestr = NULL;
5628 /* This case can take either a constant or a loclistptr. */
5629 case DW_AT_data_member_location:
5630 if (form != DW_FORM_sec_offset
5631 && (cbargs->version >= 4
5632 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5634 if (!cbargs->silent)
5635 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5636 (int) (level * 2), "", dwarf_attr_string (attr),
5637 dwarf_form_string (form), (uintmax_t) num);
5640 /* else fallthrough */
5642 /* These cases always take a loclistptr and no constant. */
5643 case DW_AT_location:
5644 case DW_AT_data_location:
5645 case DW_AT_vtable_elem_location:
5646 case DW_AT_string_length:
5647 case DW_AT_use_location:
5648 case DW_AT_frame_base:
5649 case DW_AT_return_addr:
5650 case DW_AT_static_link:
5651 case DW_AT_GNU_call_site_value:
5652 case DW_AT_GNU_call_site_data_value:
5653 case DW_AT_GNU_call_site_target:
5654 case DW_AT_GNU_call_site_target_clobbered:
5655 notice_listptr (section_loc, &known_loclistptr,
5656 cbargs->addrsize, cbargs->offset_size, num);
5657 if (!cbargs->silent)
5658 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5659 (int) (level * 2), "", dwarf_attr_string (attr),
5660 dwarf_form_string (form), (uintmax_t) num);
5664 notice_listptr (section_ranges, &known_rangelistptr,
5665 cbargs->addrsize, cbargs->offset_size, num);
5666 if (!cbargs->silent)
5667 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5668 (int) (level * 2), "", dwarf_attr_string (attr),
5669 dwarf_form_string (form), (uintmax_t) num);
5672 case DW_AT_language:
5673 valuestr = dwarf_lang_string (num);
5675 case DW_AT_encoding:
5676 valuestr = dwarf_encoding_string (num);
5678 case DW_AT_accessibility:
5679 valuestr = dwarf_access_string (num);
5681 case DW_AT_visibility:
5682 valuestr = dwarf_visibility_string (num);
5684 case DW_AT_virtuality:
5685 valuestr = dwarf_virtuality_string (num);
5687 case DW_AT_identifier_case:
5688 valuestr = dwarf_identifier_case_string (num);
5690 case DW_AT_calling_convention:
5691 valuestr = dwarf_calling_convention_string (num);
5694 valuestr = dwarf_inline_string (num);
5696 case DW_AT_ordering:
5697 valuestr = dwarf_ordering_string (num);
5699 case DW_AT_discr_list:
5700 valuestr = dwarf_discr_list_string (num);
5710 if (valuestr == NULL)
5711 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
5712 (int) (level * 2), "", dwarf_attr_string (attr),
5713 dwarf_form_string (form), (uintmax_t) num);
5715 printf (" %*s%-20s (%s) %s (%" PRIuMAX ")\n",
5716 (int) (level * 2), "", dwarf_attr_string (attr),
5717 dwarf_form_string (form), valuestr, (uintmax_t) num);
5724 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5727 printf (" %*s%-20s (%s) %s\n",
5728 (int) (level * 2), "", dwarf_attr_string (attr),
5729 dwarf_form_string (form), nl_langinfo (flag ? YESSTR : NOSTR));
5732 case DW_FORM_flag_present:
5735 printf (" %*s%-20s (%s) %s\n",
5736 (int) (level * 2), "", dwarf_attr_string (attr),
5737 dwarf_form_string (form), nl_langinfo (YESSTR));
5740 case DW_FORM_exprloc:
5741 case DW_FORM_block4:
5742 case DW_FORM_block2:
5743 case DW_FORM_block1:
5748 if (unlikely (dwarf_formblock (attrp, &block) != 0))
5751 printf (" %*s%-20s (%s) ",
5752 (int) (level * 2), "", dwarf_attr_string (attr),
5753 dwarf_form_string (form));
5758 if (form != DW_FORM_exprloc)
5760 print_block (block.length, block.data);
5765 case DW_AT_location:
5766 case DW_AT_data_location:
5767 case DW_AT_data_member_location:
5768 case DW_AT_vtable_elem_location:
5769 case DW_AT_string_length:
5770 case DW_AT_use_location:
5771 case DW_AT_frame_base:
5772 case DW_AT_return_addr:
5773 case DW_AT_static_link:
5774 case DW_AT_allocated:
5775 case DW_AT_associated:
5776 case DW_AT_bit_size:
5777 case DW_AT_bit_offset:
5778 case DW_AT_bit_stride:
5779 case DW_AT_byte_size:
5780 case DW_AT_byte_stride:
5782 case DW_AT_lower_bound:
5783 case DW_AT_upper_bound:
5784 case DW_AT_GNU_call_site_value:
5785 case DW_AT_GNU_call_site_data_value:
5786 case DW_AT_GNU_call_site_target:
5787 case DW_AT_GNU_call_site_target_clobbered:
5789 print_ops (cbargs->dwflmod, cbargs->dbg,
5790 12 + level * 2, 12 + level * 2,
5791 cbargs->version, cbargs->addrsize, cbargs->offset_size,
5792 block.length, block.data);
5800 printf (" %*s%-20s (form: %#x) ???\n",
5801 (int) (level * 2), "", dwarf_attr_string (attr),
5810 print_debug_units (Dwfl_Module *dwflmod,
5811 Ebl *ebl, GElf_Ehdr *ehdr,
5812 Elf_Scn *scn, GElf_Shdr *shdr,
5813 Dwarf *dbg, bool debug_types)
5815 const bool silent = !(print_debug_sections & section_info);
5816 const char *secname = section_name (ebl, ehdr, shdr);
5820 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5821 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5823 /* If the section is empty we don't have to do anything. */
5824 if (!silent && shdr->sh_size == 0)
5828 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5830 Dwarf_Off offset = 0;
5832 /* New compilation unit. */
5835 Dwarf_Off abbroffset;
5842 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5843 &abbroffset, &addrsize, &offsize,
5844 debug_types ? &typesig : NULL,
5845 debug_types ? &typeoff : NULL) != 0)
5851 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5852 " Version: %" PRIu16 ", Abbreviation section offset: %"
5853 PRIu64 ", Address size: %" PRIu8
5854 ", Offset size: %" PRIu8
5855 "\n Type signature: %#" PRIx64
5856 ", Type offset: %#" PRIx64 "\n"),
5857 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5858 typesig, (uint64_t) typeoff);
5860 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5861 " Version: %" PRIu16 ", Abbreviation section offset: %"
5862 PRIu64 ", Address size: %" PRIu8
5863 ", Offset size: %" PRIu8 "\n"),
5864 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5867 struct attrcb_args args =
5873 .addrsize = addrsize,
5874 .offset_size = offsize,
5882 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
5883 (dbg, offset, &dies[level]) == NULL))
5886 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
5887 " in section '%s': %s"),
5888 (uint64_t) offset, secname, dwarf_errmsg (-1));
5894 offset = dwarf_dieoffset (&dies[level]);
5895 if (unlikely (offset == ~0ul))
5898 error (0, 0, gettext ("cannot get DIE offset: %s"),
5903 int tag = dwarf_tag (&dies[level]);
5904 if (unlikely (tag == DW_TAG_invalid))
5907 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
5908 " in section '%s': %s"),
5909 (uint64_t) offset, secname, dwarf_errmsg (-1));
5914 printf (" [%6" PRIx64 "] %*s%s\n",
5915 (uint64_t) offset, (int) (level * 2), "",
5916 dwarf_tag_string (tag));
5918 /* Print the attribute values. */
5920 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
5922 /* Make room for the next level's DIE. */
5923 if (level + 1 == maxdies)
5924 dies = (Dwarf_Die *) xrealloc (dies,
5926 * sizeof (Dwarf_Die));
5928 int res = dwarf_child (&dies[level], &dies[level + 1]);
5931 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
5935 if (unlikely (res == -1))
5938 error (0, 0, gettext ("cannot get next DIE: %s\n"),
5943 else if (unlikely (res < 0))
5946 error (0, 0, gettext ("cannot get next DIE: %s"),
5964 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5965 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5967 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
5971 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5972 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5974 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
5979 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5980 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5983 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5984 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
5985 (uint64_t) shdr->sh_offset);
5987 if (shdr->sh_size == 0)
5990 /* There is no functionality in libdw to read the information in the
5991 way it is represented here. Hardcode the decoder. */
5992 Elf_Data *data = elf_getdata (scn, NULL);
5993 if (unlikely (data == NULL || data->d_buf == NULL))
5995 error (0, 0, gettext ("cannot get line data section data: %s"),
6000 const unsigned char *linep = (const unsigned char *) data->d_buf;
6001 const unsigned char *lineendp;
6004 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6006 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6008 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6010 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6011 unsigned int length = 4;
6012 if (unlikely (unit_length == 0xffffffff))
6014 if (unlikely (linep + 8 > lineendp))
6017 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6018 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6021 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6025 /* Check whether we have enough room in the section. */
6026 if (unit_length < 2 + length + 5 * 1
6027 || unlikely (linep + unit_length > lineendp))
6029 lineendp = linep + unit_length;
6031 /* The next element of the header is the version identifier. */
6032 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6034 /* Next comes the header length. */
6035 Dwarf_Word header_length;
6037 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6039 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6040 //const unsigned char *header_start = linep;
6042 /* Next the minimum instruction length. */
6043 uint_fast8_t minimum_instr_len = *linep++;
6045 /* Next the maximum operations per instruction, in version 4 format. */
6046 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6048 /* Then the flag determining the default value of the is_stmt
6050 uint_fast8_t default_is_stmt = *linep++;
6052 /* Now the line base. */
6053 int_fast8_t line_base = *((const int_fast8_t *) linep);
6056 /* And the line range. */
6057 uint_fast8_t line_range = *linep++;
6059 /* The opcode base. */
6060 uint_fast8_t opcode_base = *linep++;
6062 /* Print what we got so far. */
6063 printf (gettext ("\n"
6064 " Length: %" PRIu64 "\n"
6065 " DWARF version: %" PRIuFAST16 "\n"
6066 " Prologue length: %" PRIu64 "\n"
6067 " Minimum instruction length: %" PRIuFAST8 "\n"
6068 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6069 " Initial value if '%s': %" PRIuFAST8 "\n"
6070 " Line base: %" PRIdFAST8 "\n"
6071 " Line range: %" PRIuFAST8 "\n"
6072 " Opcode base: %" PRIuFAST8 "\n"
6075 (uint64_t) unit_length, version, (uint64_t) header_length,
6076 minimum_instr_len, max_ops_per_instr,
6077 "is_stmt", default_is_stmt, line_base,
6078 line_range, opcode_base);
6080 if (unlikely (linep + opcode_base - 1 >= lineendp))
6084 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6085 linep - (const unsigned char *) data->d_buf,
6086 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6090 int opcode_base_l10 = 1;
6091 unsigned int tmp = opcode_base;
6097 const uint8_t *standard_opcode_lengths = linep - 1;
6098 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6099 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6100 " [%*" PRIuFAST8 "] %hhu arguments\n",
6101 (int) linep[cnt - 1]),
6102 opcode_base_l10, cnt, linep[cnt - 1]);
6103 linep += opcode_base - 1;
6104 if (unlikely (linep >= lineendp))
6107 puts (gettext ("\nDirectory table:"));
6110 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6111 if (unlikely (endp == NULL))
6114 printf (" %s\n", (char *) linep);
6118 /* Skip the final NUL byte. */
6121 if (unlikely (linep >= lineendp))
6123 puts (gettext ("\nFile name table:\n"
6124 " Entry Dir Time Size Name"));
6125 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6127 /* First comes the file name. */
6128 char *fname = (char *) linep;
6129 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6130 if (unlikely (endp == NULL))
6134 /* Then the index. */
6135 unsigned int diridx;
6136 get_uleb128 (diridx, linep);
6138 /* Next comes the modification time. */
6140 get_uleb128 (mtime, linep);
6142 /* Finally the length of the file. */
6144 get_uleb128 (fsize, linep);
6146 printf (" %-5u %-5u %-9u %-9u %s\n",
6147 cnt, diridx, mtime, fsize, fname);
6149 /* Skip the final NUL byte. */
6152 puts (gettext ("\nLine number statements:"));
6153 Dwarf_Word address = 0;
6154 unsigned int op_index = 0;
6156 uint_fast8_t is_stmt = default_is_stmt;
6158 /* Default address value, in case we do not find the CU. */
6160 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6162 /* Determine the CU this block is for. */
6164 Dwarf_Off ncuoffset = 0;
6166 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6167 NULL, NULL, NULL) == 0)
6170 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6172 Dwarf_Attribute stmt_list;
6173 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6176 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6178 if (lineoff == start_offset)
6181 address_size = cudie.cu->address_size;
6186 /* Apply the "operation advance" from a special opcode
6187 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6188 unsigned int op_addr_advance;
6190 inline void advance_pc (unsigned int op_advance)
6192 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6193 / max_ops_per_instr);
6194 address += op_advance;
6195 show_op_index = (op_index > 0 ||
6196 (op_index + op_advance) % max_ops_per_instr > 0);
6197 op_index = (op_index + op_advance) % max_ops_per_instr;
6200 while (linep < lineendp)
6202 size_t offset = linep - (const unsigned char *) data->d_buf;
6206 /* Read the opcode. */
6207 unsigned int opcode = *linep++;
6209 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6210 /* Is this a special opcode? */
6211 if (likely (opcode >= opcode_base))
6213 /* Yes. Handling this is quite easy since the opcode value
6216 opcode = (desired line increment - line_base)
6217 + (line_range * address advance) + opcode_base
6219 int line_increment = (line_base
6220 + (opcode - opcode_base) % line_range);
6222 /* Perform the increments. */
6223 line += line_increment;
6224 advance_pc ((opcode - opcode_base) / line_range);
6226 char *a = format_dwarf_addr (dwflmod, 0, address);
6229 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6230 opcode, op_addr_advance, a, op_index,
6231 line_increment, line);
6234 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6235 opcode, op_addr_advance, a, line_increment, line);
6238 else if (opcode == 0)
6240 /* This an extended opcode. */
6241 if (unlikely (linep + 2 > lineendp))
6245 unsigned int len = *linep++;
6247 if (unlikely (linep + len > lineendp))
6250 /* The sub-opcode. */
6253 printf (gettext (" extended opcode %u: "), opcode);
6257 case DW_LNE_end_sequence:
6258 puts (gettext (" end of sequence"));
6260 /* Reset the registers we care about. */
6264 is_stmt = default_is_stmt;
6267 case DW_LNE_set_address:
6269 if (address_size == 4)
6270 address = read_4ubyte_unaligned_inc (dbg, linep);
6272 address = read_8ubyte_unaligned_inc (dbg, linep);
6274 char *a = format_dwarf_addr (dwflmod, 0, address);
6275 printf (gettext (" set address to %s\n"), a);
6280 case DW_LNE_define_file:
6282 char *fname = (char *) linep;
6283 unsigned char *endp = memchr (linep, '\0',
6285 if (unlikely (endp == NULL))
6289 unsigned int diridx;
6290 get_uleb128 (diridx, linep);
6292 get_uleb128 (mtime, linep);
6293 Dwarf_Word filelength;
6294 get_uleb128 (filelength, linep);
6297 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6298 diridx, (uint64_t) mtime, (uint64_t) filelength,
6303 case DW_LNE_set_discriminator:
6304 /* Takes one ULEB128 parameter, the discriminator. */
6305 if (unlikely (standard_opcode_lengths[opcode] != 1))
6308 get_uleb128 (u128, linep);
6309 printf (gettext (" set discriminator to %u\n"), u128);
6313 /* Unknown, ignore it. */
6314 puts (gettext (" unknown opcode"));
6319 else if (opcode <= DW_LNS_set_isa)
6321 /* This is a known standard opcode. */
6325 /* Takes no argument. */
6326 puts (gettext (" copy"));
6329 case DW_LNS_advance_pc:
6330 /* Takes one uleb128 parameter which is added to the
6332 get_uleb128 (u128, linep);
6335 char *a = format_dwarf_addr (dwflmod, 0, address);
6338 advance address by %u to %s, op_index to %u\n"),
6339 op_addr_advance, a, op_index);
6341 printf (gettext (" advance address by %u to %s\n"),
6342 op_addr_advance, a);
6347 case DW_LNS_advance_line:
6348 /* Takes one sleb128 parameter which is added to the
6350 get_sleb128 (s128, linep);
6353 advance line by constant %d to %" PRId64 "\n"),
6354 s128, (int64_t) line);
6357 case DW_LNS_set_file:
6358 /* Takes one uleb128 parameter which is stored in file. */
6359 get_uleb128 (u128, linep);
6360 printf (gettext (" set file to %" PRIu64 "\n"),
6364 case DW_LNS_set_column:
6365 /* Takes one uleb128 parameter which is stored in column. */
6366 if (unlikely (standard_opcode_lengths[opcode] != 1))
6369 get_uleb128 (u128, linep);
6370 printf (gettext (" set column to %" PRIu64 "\n"),
6374 case DW_LNS_negate_stmt:
6375 /* Takes no argument. */
6376 is_stmt = 1 - is_stmt;
6377 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6378 "is_stmt", is_stmt);
6381 case DW_LNS_set_basic_block:
6382 /* Takes no argument. */
6383 puts (gettext (" set basic block flag"));
6386 case DW_LNS_const_add_pc:
6387 /* Takes no argument. */
6388 advance_pc ((255 - opcode_base) / line_range);
6390 char *a = format_dwarf_addr (dwflmod, 0, address);
6393 advance address by constant %u to %s, op_index to %u\n"),
6394 op_addr_advance, a, op_index);
6397 advance address by constant %u to %s\n"),
6398 op_addr_advance, a);
6403 case DW_LNS_fixed_advance_pc:
6404 /* Takes one 16 bit parameter which is added to the
6406 if (unlikely (standard_opcode_lengths[opcode] != 1))
6409 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6413 char *a = format_dwarf_addr (dwflmod, 0, address);
6415 advance address by fixed value %u to %s\n"),
6421 case DW_LNS_set_prologue_end:
6422 /* Takes no argument. */
6423 puts (gettext (" set prologue end flag"));
6426 case DW_LNS_set_epilogue_begin:
6427 /* Takes no argument. */
6428 puts (gettext (" set epilogue begin flag"));
6431 case DW_LNS_set_isa:
6432 /* Takes one uleb128 parameter which is stored in isa. */
6433 if (unlikely (standard_opcode_lengths[opcode] != 1))
6436 get_uleb128 (u128, linep);
6437 printf (gettext (" set isa to %u\n"), u128);
6443 /* This is a new opcode the generator but not we know about.
6444 Read the parameters associated with it but then discard
6445 everything. Read all the parameters for this opcode. */
6446 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6447 " unknown opcode with %" PRIu8 " parameters:",
6448 standard_opcode_lengths[opcode]),
6449 standard_opcode_lengths[opcode]);
6450 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6452 get_uleb128 (u128, linep);
6453 if (n != standard_opcode_lengths[opcode])
6454 putc_unlocked (',', stdout);
6455 printf (" %u", u128);
6458 /* Next round, ignore this opcode. */
6464 /* There must only be one data block. */
6465 assert (elf_getdata (scn, data) == NULL);
6470 print_debug_loc_section (Dwfl_Module *dwflmod,
6471 Ebl *ebl, GElf_Ehdr *ehdr,
6472 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6474 Elf_Data *data = elf_rawdata (scn, NULL);
6476 if (unlikely (data == NULL))
6478 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6484 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6485 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6486 (uint64_t) shdr->sh_offset);
6488 sort_listptr (&known_loclistptr, "loclistptr");
6489 size_t listptr_idx = 0;
6491 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6492 uint_fast8_t offset_size = 4;
6495 unsigned char *readp = data->d_buf;
6496 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6497 while (readp < endp)
6499 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6501 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6502 &address_size, &offset_size,
6503 offset, &readp, endp))
6506 if (unlikely (data->d_size - offset < address_size * 2))
6508 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6514 if (address_size == 8)
6516 begin = read_8ubyte_unaligned_inc (dbg, readp);
6517 end = read_8ubyte_unaligned_inc (dbg, readp);
6521 begin = read_4ubyte_unaligned_inc (dbg, readp);
6522 end = read_4ubyte_unaligned_inc (dbg, readp);
6523 if (begin == (Dwarf_Addr) (uint32_t) -1)
6524 begin = (Dwarf_Addr) -1l;
6527 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6529 char *b = format_dwarf_addr (dwflmod, address_size, end);
6530 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6533 else if (begin == 0 && end == 0) /* End of list entry. */
6536 printf (gettext (" [%6tx] empty list\n"), offset);
6541 /* We have a location expression entry. */
6542 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6544 char *b = format_dwarf_addr (dwflmod, address_size, begin);
6545 char *e = format_dwarf_addr (dwflmod, address_size, end);
6547 if (first) /* First entry in a list. */
6548 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6550 printf (gettext (" %s..%s"), b, e);
6555 if (endp - readp <= (ptrdiff_t) len)
6557 fputs (gettext (" <INVALID DATA>\n"), stdout);
6561 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6562 3 /*XXX*/, address_size, offset_size, len, readp);
6575 struct mac_culist *next;
6580 mac_compare (const void *p1, const void *p2)
6582 struct mac_culist *m1 = (struct mac_culist *) p1;
6583 struct mac_culist *m2 = (struct mac_culist *) p2;
6585 if (m1->offset < m2->offset)
6587 if (m1->offset > m2->offset)
6594 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6595 Ebl *ebl, GElf_Ehdr *ehdr,
6596 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6599 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6600 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6601 (uint64_t) shdr->sh_offset);
6602 putc_unlocked ('\n', stdout);
6604 /* There is no function in libdw to iterate over the raw content of
6605 the section but it is easy enough to do. */
6606 Elf_Data *data = elf_getdata (scn, NULL);
6607 if (unlikely (data == NULL || data->d_buf == NULL))
6609 error (0, 0, gettext ("cannot get macro information section data: %s"),
6614 /* Get the source file information for all CUs. */
6618 struct mac_culist *culist = NULL;
6620 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6623 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6626 Dwarf_Attribute attr;
6627 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6631 if (dwarf_formudata (&attr, &macoff) != 0)
6634 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6636 newp->offset = macoff;
6638 newp->next = culist;
6643 /* Convert the list into an array for easier consumption. */
6644 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6647 cus[nculist].offset = data->d_size;
6650 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6652 assert (cnt < nculist);
6654 culist = culist->next;
6657 /* Sort the array according to the offset in the .debug_macinfo
6658 section. Note we keep the sentinel at the end. */
6659 qsort (cus, nculist, sizeof (*cus), mac_compare);
6662 const unsigned char *readp = (const unsigned char *) data->d_buf;
6663 const unsigned char *readendp = readp + data->d_size;
6666 while (readp < readendp)
6668 unsigned int opcode = *readp++;
6670 unsigned int u128_2;
6671 const unsigned char *endp;
6675 case DW_MACINFO_define:
6676 case DW_MACINFO_undef:
6677 case DW_MACINFO_vendor_ext:
6678 /* For the first two opcodes the parameters are
6682 We can treat these cases together. */
6683 get_uleb128 (u128, readp);
6685 endp = memchr (readp, '\0', readendp - readp);
6686 if (unlikely (endp == NULL))
6689 %*s*** non-terminated string at end of section"),
6694 if (opcode == DW_MACINFO_define)
6695 printf ("%*s#define %s, line %u\n",
6696 level, "", (char *) readp, u128);
6697 else if (opcode == DW_MACINFO_undef)
6698 printf ("%*s#undef %s, line %u\n",
6699 level, "", (char *) readp, u128);
6701 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6706 case DW_MACINFO_start_file:
6707 /* The two parameters are line and file index, in this order. */
6708 get_uleb128 (u128, readp);
6709 get_uleb128 (u128_2, readp);
6711 /* Find the CU DIE for this file. */
6712 size_t macoff = readp - (const unsigned char *) data->d_buf;
6713 const char *fname = "???";
6714 if (macoff >= cus[0].offset)
6716 while (macoff >= cus[1].offset)
6719 if (cus[0].files == NULL
6720 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6721 cus[0].files = (Dwarf_Files *) -1l;
6723 if (cus[0].files != (Dwarf_Files *) -1l)
6724 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6728 printf ("%*sstart_file %u, [%u] %s\n",
6729 level, "", u128, u128_2, fname);
6733 case DW_MACINFO_end_file:
6735 printf ("%*send_file\n", level, "");
6736 /* Nothing more to do. */
6740 // XXX gcc seems to generate files with a trailing zero.
6741 if (unlikely (opcode != 0 || readp != readendp))
6742 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6749 /* Callback for printing global names. */
6751 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
6754 int *np = (int *) arg;
6756 printf (gettext (" [%5d] DIE offset: %6" PRId64
6757 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
6758 (*np)++, global->die_offset, global->cu_offset, global->name);
6764 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
6766 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6767 Ebl *ebl, GElf_Ehdr *ehdr,
6768 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6770 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6771 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6772 (uint64_t) shdr->sh_offset);
6775 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
6778 /* Print the content of the DWARF string section '.debug_str'. */
6780 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6781 Ebl *ebl, GElf_Ehdr *ehdr,
6782 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6784 const size_t sh_size = dbg->sectiondata[IDX_debug_str]->d_size;
6786 /* Compute floor(log16(shdr->sh_size)). */
6787 GElf_Addr tmp = sh_size;
6794 digits = MAX (4, digits);
6796 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
6799 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
6800 /* TRANS: the debugstr| prefix makes the string unique. */
6801 digits + 2, sgettext ("debugstr|Offset"));
6803 Dwarf_Off offset = 0;
6804 while (offset < sh_size)
6807 const char *str = dwarf_getstring (dbg, offset, &len);
6808 if (unlikely (str == NULL))
6810 printf (gettext (" *** error while reading strings: %s\n"),
6815 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
6822 /* Print the content of the call frame search table section
6825 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6826 Ebl *ebl __attribute__ ((unused)),
6827 GElf_Ehdr *ehdr __attribute__ ((unused)),
6828 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6831 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
6834 Elf_Data *data = elf_rawdata (scn, NULL);
6836 if (unlikely (data == NULL))
6838 error (0, 0, gettext ("cannot get %s content: %s"),
6839 ".eh_frame_hdr", elf_errmsg (-1));
6843 const unsigned char *readp = data->d_buf;
6844 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6847 if (unlikely (readp + 4 > dataend))
6850 error (0, 0, gettext ("invalid data"));
6854 unsigned int version = *readp++;
6855 unsigned int eh_frame_ptr_enc = *readp++;
6856 unsigned int fde_count_enc = *readp++;
6857 unsigned int table_enc = *readp++;
6859 printf (" version: %u\n"
6860 " eh_frame_ptr_enc: %#x ",
6861 version, eh_frame_ptr_enc);
6862 print_encoding_base ("", eh_frame_ptr_enc);
6863 printf (" fde_count_enc: %#x ", fde_count_enc);
6864 print_encoding_base ("", fde_count_enc);
6865 printf (" table_enc: %#x ", table_enc);
6866 print_encoding_base ("", table_enc);
6868 uint64_t eh_frame_ptr = 0;
6869 if (eh_frame_ptr_enc != DW_EH_PE_omit)
6871 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
6873 if (unlikely (readp == NULL))
6876 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
6877 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
6878 printf (" (offset: %#" PRIx64 ")",
6879 /* +4 because of the 4 byte header of the section. */
6880 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
6882 putchar_unlocked ('\n');
6885 uint64_t fde_count = 0;
6886 if (fde_count_enc != DW_EH_PE_omit)
6888 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
6889 if (unlikely (readp == NULL))
6892 printf (" fde_count: %" PRIu64 "\n", fde_count);
6895 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
6900 /* Optimize for the most common case. */
6901 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
6902 while (fde_count > 0 && readp + 8 <= dataend)
6904 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
6905 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
6906 + (int64_t) initial_location);
6907 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
6908 // XXX Possibly print symbol name or section offset for initial_offset
6909 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
6910 " fde=[%6" PRIx64 "]\n",
6911 initial_location, initial_offset,
6912 address, address - (eh_frame_ptr + 4));
6915 while (0 && readp < dataend)
6922 /* Print the content of the exception handling table section
6925 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
6926 Ebl *ebl __attribute__ ((unused)),
6927 GElf_Ehdr *ehdr __attribute__ ((unused)),
6929 GElf_Shdr *shdr __attribute__ ((unused)),
6930 Dwarf *dbg __attribute__ ((unused)))
6933 \nException handling table section [%2zu] '.gcc_except_table':\n"),
6936 Elf_Data *data = elf_rawdata (scn, NULL);
6938 if (unlikely (data == NULL))
6940 error (0, 0, gettext ("cannot get %s content: %s"),
6941 ".gcc_except_table", elf_errmsg (-1));
6945 const unsigned char *readp = data->d_buf;
6946 const unsigned char *const dataend = readp + data->d_size;
6948 if (unlikely (readp + 1 > dataend))
6951 error (0, 0, gettext ("invalid data"));
6954 unsigned int lpstart_encoding = *readp++;
6955 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
6956 print_encoding_base ("", lpstart_encoding);
6957 if (lpstart_encoding != DW_EH_PE_omit)
6960 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
6961 printf (" LPStart: %#" PRIx64 "\n", lpstart);
6964 if (unlikely (readp + 1 > dataend))
6966 unsigned int ttype_encoding = *readp++;
6967 printf (gettext (" TType encoding: %#x "), ttype_encoding);
6968 print_encoding_base ("", ttype_encoding);
6969 const unsigned char *ttype_base = NULL;
6970 if (ttype_encoding != DW_EH_PE_omit)
6972 unsigned int ttype_base_offset;
6973 get_uleb128 (ttype_base_offset, readp);
6974 printf (" TType base offset: %#x\n", ttype_base_offset);
6975 ttype_base = readp + ttype_base_offset;
6978 if (unlikely (readp + 1 > dataend))
6980 unsigned int call_site_encoding = *readp++;
6981 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
6982 print_encoding_base ("", call_site_encoding);
6983 unsigned int call_site_table_len;
6984 get_uleb128 (call_site_table_len, readp);
6986 const unsigned char *const action_table = readp + call_site_table_len;
6987 if (unlikely (action_table > dataend))
6990 unsigned int max_action = 0;
6991 while (readp < action_table)
6994 puts (gettext ("\n Call site table:"));
6996 uint64_t call_site_start;
6997 readp = read_encoded (call_site_encoding, readp, dataend,
6998 &call_site_start, dbg);
6999 uint64_t call_site_length;
7000 readp = read_encoded (call_site_encoding, readp, dataend,
7001 &call_site_length, dbg);
7002 uint64_t landing_pad;
7003 readp = read_encoded (call_site_encoding, readp, dataend,
7005 unsigned int action;
7006 get_uleb128 (action, readp);
7007 max_action = MAX (action, max_action);
7008 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7009 " Call site length: %" PRIu64 "\n"
7010 " Landing pad: %#" PRIx64 "\n"
7012 u++, call_site_start, call_site_length, landing_pad, action);
7014 assert (readp == action_table);
7016 unsigned int max_ar_filter = 0;
7019 puts ("\n Action table:");
7021 const unsigned char *const action_table_end
7022 = action_table + max_action + 1;
7028 get_sleb128 (ar_filter, readp);
7029 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7030 max_ar_filter = ar_filter;
7032 get_sleb128 (ar_disp, readp);
7034 printf (" [%4u] ar_filter: % d\n"
7036 u, ar_filter, ar_disp);
7037 if (abs (ar_disp) & 1)
7038 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7039 else if (ar_disp != 0)
7042 putchar_unlocked ('\n');
7045 while (readp < action_table_end);
7048 if (max_ar_filter > 0)
7050 puts ("\n TType table:");
7052 // XXX Not *4, size of encoding;
7053 switch (ttype_encoding & 7)
7055 case DW_EH_PE_udata2:
7056 case DW_EH_PE_sdata2:
7057 readp = ttype_base - max_ar_filter * 2;
7059 case DW_EH_PE_udata4:
7060 case DW_EH_PE_sdata4:
7061 readp = ttype_base - max_ar_filter * 4;
7063 case DW_EH_PE_udata8:
7064 case DW_EH_PE_sdata8:
7065 readp = ttype_base - max_ar_filter * 8;
7068 error (1, 0, gettext ("invalid TType encoding"));
7074 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7076 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7078 while (readp < ttype_base);
7082 /* Print the content of the '.gdb_index' section.
7083 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7086 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7087 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7089 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7090 " contains %" PRId64 " bytes :\n"),
7091 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7092 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7094 Elf_Data *data = elf_rawdata (scn, NULL);
7096 if (unlikely (data == NULL))
7098 error (0, 0, gettext ("cannot get %s content: %s"),
7099 ".gdb_index", elf_errmsg (-1));
7103 // .gdb_index is always in little endian.
7104 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7107 const unsigned char *readp = data->d_buf;
7108 const unsigned char *const dataend = readp + data->d_size;
7110 if (unlikely (readp + 4 > dataend))
7113 error (0, 0, gettext ("invalid data"));
7117 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7118 printf (gettext (" Version: %" PRId32 "\n"), vers);
7120 // The only difference between version 4 and version 5 is the
7121 // hash used for generating the table.
7122 if (vers < 4 || vers > 5)
7124 printf (gettext (" unknown version, cannot parse section\n"));
7129 if (unlikely (readp + 4 > dataend))
7132 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7133 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7136 if (unlikely (readp + 4 > dataend))
7139 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7140 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7143 if (unlikely (readp + 4 > dataend))
7146 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7147 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
7150 if (unlikely (readp + 4 > dataend))
7153 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7154 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
7157 if (unlikely (readp + 4 > dataend))
7160 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7161 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7163 readp = data->d_buf + cu_off;
7165 const unsigned char *nextp = data->d_buf + tu_off;
7166 size_t nr = (nextp - readp) / 16;
7168 printf (gettext ("\n CU list at offset %#" PRIx32
7169 " contains %zu entries:\n"),
7173 while (readp + 16 <= dataend && n < nr)
7175 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7178 uint64_t len = read_8ubyte_unaligned (dbg, readp);
7181 printf (" [%4zu] start: %0#8" PRIx64
7182 ", length: %5" PRIu64 "\n", n, off, len);
7186 readp = data->d_buf + tu_off;
7187 nextp = data->d_buf + addr_off;
7188 nr = (nextp - readp) / 24;
7190 printf (gettext ("\n TU list at offset %#" PRIx32
7191 " contains %zu entries:\n"),
7195 while (readp + 24 <= dataend && n < nr)
7197 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7200 uint64_t type = read_8ubyte_unaligned (dbg, readp);
7203 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7206 printf (" [%4zu] CU offset: %5" PRId64
7207 ", type offset: %5" PRId64
7208 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7212 readp = data->d_buf + addr_off;
7213 nextp = data->d_buf + sym_off;
7214 nr = (nextp - readp) / 20;
7216 printf (gettext ("\n Address list at offset %#" PRIx32
7217 " contains %zu entries:\n"),
7221 while (readp + 20 <= dataend && n < nr)
7223 uint64_t low = read_8ubyte_unaligned (dbg, readp);
7226 uint64_t high = read_8ubyte_unaligned (dbg, readp);
7229 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7232 char *l = format_dwarf_addr (dwflmod, 8, low);
7233 char *h = format_dwarf_addr (dwflmod, 8, high - 1);
7234 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7239 readp = data->d_buf + sym_off;
7240 nextp = data->d_buf + const_off;
7241 nr = (nextp - readp) / 8;
7243 printf (gettext ("\n Symbol table at offset %#" PRIx32
7244 " contains %zu slots:\n"),
7248 while (readp + 8 <= dataend && n < nr)
7250 uint32_t name = read_4ubyte_unaligned (dbg, readp);
7253 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7256 if (name != 0 || vector != 0)
7258 const unsigned char *sym = data->d_buf + const_off + name;
7259 if (unlikely (sym > dataend))
7262 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7264 const unsigned char *readcus = data->d_buf + const_off + vector;
7265 if (unlikely (readcus + 8 > dataend))
7268 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7273 cu = read_4ubyte_unaligned (dbg, readcus);
7274 printf ("%" PRId32 "%s", cu, ((cus > 0) ? ", " : ""));
7283 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7285 /* Before we start the real work get a debug context descriptor. */
7287 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7291 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7295 if ((print_debug_sections & ~section_exception) != 0)
7296 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7298 if ((print_debug_sections & section_exception) == 0)
7303 /* Get the section header string table index. */
7305 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7306 error (EXIT_FAILURE, 0,
7307 gettext ("cannot get section header string table index"));
7309 /* Look through all the sections for the debugging sections to print. */
7310 Elf_Scn *scn = NULL;
7311 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7314 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7316 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7321 enum section_e bitmask;
7322 void (*fp) (Dwfl_Module *, Ebl *,
7323 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7324 } debug_sections[] =
7326 #define NEW_SECTION(name) \
7327 { ".debug_" #name, section_##name, print_debug_##name##_section }
7328 NEW_SECTION (abbrev),
7329 NEW_SECTION (aranges),
7330 NEW_SECTION (frame),
7332 NEW_SECTION (types),
7335 NEW_SECTION (pubnames),
7337 NEW_SECTION (macinfo),
7338 NEW_SECTION (ranges),
7339 { ".eh_frame", section_frame | section_exception,
7340 print_debug_frame_section },
7341 { ".eh_frame_hdr", section_frame | section_exception,
7342 print_debug_frame_hdr_section },
7343 { ".gcc_except_table", section_frame | section_exception,
7344 print_debug_exception_table },
7345 { ".gdb_index", section_gdb_index, print_gdb_index_section }
7347 const int ndebug_sections = (sizeof (debug_sections)
7348 / sizeof (debug_sections[0]));
7349 const char *name = elf_strptr (ebl->elf, shstrndx,
7353 for (n = 0; n < ndebug_sections; ++n)
7354 if (strcmp (name, debug_sections[n].name) == 0
7356 || (name[0] == '.' && name[1] == 'z'
7357 && debug_sections[n].name[1] == 'd'
7358 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
7362 if ((print_debug_sections | implicit_debug_sections)
7363 & debug_sections[n].bitmask)
7364 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
7370 reset_listptr (&known_loclistptr);
7371 reset_listptr (&known_rangelistptr);
7375 #define ITEM_INDENT 4
7376 #define ITEM_WRAP_COLUMN 150
7377 #define REGISTER_WRAP_COLUMN 75
7379 /* Print "NAME: FORMAT", wrapping when FORMAT_MAX chars of FORMAT would
7380 make the line exceed ITEM_WRAP_COLUMN. Unpadded numbers look better
7381 for the core items. But we do not want the line breaks to depend on
7382 the particular values. */
7384 __attribute__ ((format (printf, 7, 8)))
7385 print_core_item (unsigned int colno, char sep, unsigned int wrap,
7386 size_t name_width, const char *name,
7387 size_t format_max, const char *format, ...)
7389 size_t len = strlen (name);
7390 if (name_width < len)
7393 size_t n = name_width + sizeof ": " - 1 + format_max;
7397 printf ("%*s", ITEM_INDENT, "");
7398 colno = ITEM_INDENT + n;
7400 else if (colno + 2 + n < wrap)
7402 printf ("%c ", sep);
7407 printf ("\n%*s", ITEM_INDENT, "");
7408 colno = ITEM_INDENT + n;
7411 printf ("%s: %*s", name, (int) (name_width - len), "");
7414 va_start (ap, format);
7415 vprintf (format, ap);
7422 convert (Elf *core, Elf_Type type, uint_fast16_t count,
7423 void *value, const void *data, size_t size)
7425 Elf_Data valuedata =
7429 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
7430 .d_version = EV_CURRENT,
7435 .d_buf = (void *) data,
7436 .d_size = valuedata.d_size,
7437 .d_version = EV_CURRENT,
7440 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
7441 ? elf32_xlatetom : elf64_xlatetom)
7442 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
7444 error (EXIT_FAILURE, 0,
7445 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
7447 return data + indata.d_size;
7450 typedef uint8_t GElf_Byte;
7453 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
7454 unsigned int colno, size_t *repeated_size)
7456 uint_fast16_t count = item->count ?: 1;
7459 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8, 4); \
7460 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16, 6); \
7461 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32, 11); \
7462 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32, 11); \
7463 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64, 20); \
7464 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64, 20)
7466 #define DO_TYPE(NAME, Name, hex, dec, max) GElf_##Name Name[count]
7467 union { TYPES; } value;
7470 void *data = &value;
7471 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
7472 size_t convsize = size;
7473 if (repeated_size != NULL)
7475 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
7477 data = alloca (*repeated_size);
7478 count *= *repeated_size / size;
7479 convsize = count * size;
7480 *repeated_size -= convsize;
7482 else if (item->count != 0 || item->format != '\n')
7483 *repeated_size -= size;
7486 convert (core, item->type, count, data, desc + item->offset, convsize);
7488 Elf_Type type = item->type;
7489 if (type == ELF_T_ADDR)
7490 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
7492 switch (item->format)
7495 assert (count == 1);
7498 #define DO_TYPE(NAME, Name, hex, dec, max) \
7499 case ELF_T_##NAME: \
7500 colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, \
7501 0, item->name, max, dec, value.Name[0]); \
7511 assert (count == 1);
7514 #define DO_TYPE(NAME, Name, hex, dec, max) \
7515 case ELF_T_##NAME: \
7516 colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, \
7517 0, item->name, max, hex, value.Name[0]); \
7528 assert (size % sizeof (unsigned int) == 0);
7529 unsigned int nbits = count * size * 8;
7530 unsigned int pop = 0;
7531 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
7532 pop += __builtin_popcount (*i);
7533 bool negate = pop > nbits / 2;
7534 const unsigned int bias = item->format == 'b';
7537 char printed[(negate ? nbits - pop : pop) * 16];
7541 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
7543 assert (size == sizeof (unsigned int) * 2);
7544 for (unsigned int *i = data;
7545 (void *) i < data + count * size; i += 2)
7547 unsigned int w = i[1];
7553 unsigned int lastbit = 0;
7554 for (const unsigned int *i = data;
7555 (void *) i < data + count * size; ++i)
7557 unsigned int bit = ((void *) i - data) * 8;
7558 unsigned int w = negate ? ~*i : *i;
7559 unsigned int run = 0;
7566 if (lastbit + 1 == bit)
7571 p += sprintf (p, "%u", bit - bias);
7573 p += sprintf (p, ",%u", bit - bias);
7575 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
7582 if (lastbit > 0 && lastbit + 1 != nbits)
7583 p += sprintf (p, "-%u", nbits - bias);
7585 colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
7587 negate ? "~<%s>" : "<%s>", printed);
7592 case (char) ('T'|0x80):
7593 assert (count == 2);
7599 #define DO_TYPE(NAME, Name, hex, dec, max) \
7600 case ELF_T_##NAME: \
7601 sec = value.Name[0]; \
7602 usec = value.Name[1]; \
7610 if (unlikely (item->format == (char) ('T'|0x80)))
7612 /* This is a hack for an ill-considered 64-bit ABI where
7613 tv_usec is actually a 32-bit field with 32 bits of padding
7614 rounding out struct timeval. We've already converted it as
7615 a 64-bit field. For little-endian, this just means the
7616 high half is the padding; it's presumably zero, but should
7617 be ignored anyway. For big-endian, it means the 32-bit
7618 field went into the high half of USEC. */
7620 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
7621 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
7626 colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
7627 maxfmt, "%" PRIu64 ".%.6" PRIu64, sec, usec);
7631 assert (count == 1);
7632 colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
7633 1, "%c", value.Byte[0]);
7637 colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
7638 count, "%.*s", (int) count, value.Byte);
7642 /* This is a list of strings separated by '\n'. */
7643 assert (item->count == 0);
7644 assert (repeated_size != NULL);
7645 assert (item->name == NULL);
7646 if (unlikely (item->offset >= *repeated_size))
7649 const char *s = desc + item->offset;
7650 size = *repeated_size - item->offset;
7654 const char *eol = memchr (s, '\n', size);
7658 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
7661 size -= eol + 1 - s;
7665 colno = ITEM_WRAP_COLUMN;
7669 error (0, 0, "XXX not handling format '%c' for %s",
7670 item->format, item->name);
7680 /* Sort items by group, and by layout offset within each group. */
7682 compare_core_items (const void *a, const void *b)
7684 const Ebl_Core_Item *const *p1 = a;
7685 const Ebl_Core_Item *const *p2 = b;
7686 const Ebl_Core_Item *item1 = *p1;
7687 const Ebl_Core_Item *item2 = *p2;
7689 return ((item1->group == item2->group ? 0
7690 : strcmp (item1->group, item2->group))
7691 ?: (int) item1->offset - (int) item2->offset);
7694 /* Sort item groups by layout offset of the first item in the group. */
7696 compare_core_item_groups (const void *a, const void *b)
7698 const Ebl_Core_Item *const *const *p1 = a;
7699 const Ebl_Core_Item *const *const *p2 = b;
7700 const Ebl_Core_Item *const *group1 = *p1;
7701 const Ebl_Core_Item *const *group2 = *p2;
7702 const Ebl_Core_Item *item1 = *group1;
7703 const Ebl_Core_Item *item2 = *group2;
7705 return (int) item1->offset - (int) item2->offset;
7709 handle_core_items (Elf *core, const void *desc, size_t descsz,
7710 const Ebl_Core_Item *items, size_t nitems)
7715 /* Sort to collect the groups together. */
7716 const Ebl_Core_Item *sorted_items[nitems];
7717 for (size_t i = 0; i < nitems; ++i)
7718 sorted_items[i] = &items[i];
7719 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
7721 /* Collect the unique groups and sort them. */
7722 const Ebl_Core_Item **groups[nitems];
7723 groups[0] = &sorted_items[0];
7725 for (size_t i = 1; i < nitems; ++i)
7726 if (sorted_items[i]->group != sorted_items[i - 1]->group
7727 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
7728 groups[ngroups++] = &sorted_items[i];
7729 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
7731 /* Write out all the groups. */
7732 unsigned int colno = 0;
7734 const void *last = desc;
7737 size_t size = descsz;
7738 colno = handle_core_item (core, sorted_items[0], desc, colno, &size);
7741 desc += descsz - size;
7747 for (size_t i = 0; i < ngroups; ++i)
7749 for (const Ebl_Core_Item **item = groups[i];
7750 (item < &sorted_items[nitems]
7751 && ((*item)->group == groups[i][0]->group
7752 || !strcmp ((*item)->group, groups[i][0]->group)));
7754 colno = handle_core_item (core, *item, desc, colno, NULL);
7756 /* Force a line break at the end of the group. */
7757 colno = ITEM_WRAP_COLUMN;
7763 /* This set of items consumed a certain amount of the note's data.
7764 If there is more data there, we have another unit of the same size.
7765 Loop to print that out too. */
7766 const Ebl_Core_Item *item = &items[nitems - 1];
7767 size_t eltsz = item->offset + gelf_fsize (core, item->type,
7768 item->count ?: 1, EV_CURRENT);
7777 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
7781 /* For just one repeat, print it unabridged twice. */
7786 printf (gettext ("\n%*s... <repeats %u more times> ..."),
7787 ITEM_INDENT, "", reps);
7797 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
7800 desc += regloc->offset;
7808 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
7809 const Ebl_Register_Location *regloc, const void *desc,
7812 if (regloc->bits % 8 != 0)
7813 return handle_bit_registers (regloc, desc, colno);
7815 desc += regloc->offset;
7817 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
7819 char name[REGNAMESZ];
7822 register_info (ebl, reg, regloc, name, &bits, &type);
7825 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8, 4); \
7826 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16, 6); \
7827 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32, 11); \
7828 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64, 20)
7830 #define BITS(bits, xtype, sfmt, ufmt, max) \
7831 uint##bits##_t b##bits; int##bits##_t b##bits##s
7832 union { TYPES; uint64_t b128[2]; } value;
7837 case DW_ATE_unsigned:
7839 case DW_ATE_address:
7842 #define BITS(bits, xtype, sfmt, ufmt, max) \
7844 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
7845 if (type == DW_ATE_signed) \
7846 colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, \
7848 max, sfmt, value.b##bits##s); \
7850 colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, \
7852 max, ufmt, value.b##bits); \
7858 assert (type == DW_ATE_unsigned);
7859 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
7860 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
7861 colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,
7863 34, "0x%.16" PRIx64 "%.16" PRIx64,
7864 value.b128[!be], value.b128[be]);
7874 /* Print each byte in hex, the whole thing in native byte order. */
7875 assert (bits % 8 == 0);
7876 const uint8_t *bytes = desc;
7878 char hex[bits / 4 + 1];
7879 hex[bits / 4] = '\0';
7881 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
7883 bytes += bits / 8 - 1;
7887 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
7889 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
7890 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
7892 colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,
7894 2 + sizeof hex - 1, "0x%s", hex);
7897 desc += regloc->pad;
7906 struct register_info
7908 const Ebl_Register_Location *regloc;
7910 char name[REGNAMESZ];
7917 register_bitpos (const struct register_info *r)
7919 return (r->regloc->offset * 8
7920 + ((r->regno - r->regloc->regno)
7921 * (r->regloc->bits + r->regloc->pad * 8)));
7925 compare_sets_by_info (const struct register_info *r1,
7926 const struct register_info *r2)
7928 return ((int) r2->bits - (int) r1->bits
7929 ?: register_bitpos (r1) - register_bitpos (r2));
7932 /* Sort registers by set, and by size and layout offset within each set. */
7934 compare_registers (const void *a, const void *b)
7936 const struct register_info *r1 = a;
7937 const struct register_info *r2 = b;
7939 /* Unused elements sort last. */
7940 if (r1->regloc == NULL)
7941 return r2->regloc == NULL ? 0 : 1;
7942 if (r2->regloc == NULL)
7945 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
7946 ?: compare_sets_by_info (r1, r2));
7949 /* Sort register sets by layout offset of the first register in the set. */
7951 compare_register_sets (const void *a, const void *b)
7953 const struct register_info *const *p1 = a;
7954 const struct register_info *const *p2 = b;
7955 return compare_sets_by_info (*p1, *p2);
7959 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
7960 const Ebl_Register_Location *reglocs, size_t nregloc)
7965 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
7968 for (size_t i = 0; i < nregloc; ++i)
7969 if (maxnreg < reglocs[i].regno + reglocs[i].count)
7970 maxnreg = reglocs[i].regno + reglocs[i].count;
7971 assert (maxnreg > 0);
7974 struct register_info regs[maxnreg];
7975 memset (regs, 0, sizeof regs);
7977 /* Sort to collect the sets together. */
7979 for (size_t i = 0; i < nregloc; ++i)
7980 for (int reg = reglocs[i].regno;
7981 reg < reglocs[i].regno + reglocs[i].count;
7984 assert (reg < maxnreg);
7987 struct register_info *info = ®s[reg];
7988 info->regloc = ®locs[i];
7990 info->set = register_info (ebl, reg, ®locs[i],
7991 info->name, &info->bits, &info->type);
7993 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
7995 /* Collect the unique sets and sort them. */
7996 inline bool same_set (const struct register_info *a,
7997 const struct register_info *b)
7999 return (a < ®s[maxnreg] && a->regloc != NULL
8000 && b < ®s[maxnreg] && b->regloc != NULL
8001 && a->bits == b->bits
8002 && (a->set == b->set || !strcmp (a->set, b->set)));
8004 struct register_info *sets[maxreg + 1];
8007 for (int i = 1; i <= maxreg; ++i)
8008 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8009 sets[nsets++] = ®s[i];
8010 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8012 /* Write out all the sets. */
8013 unsigned int colno = 0;
8014 for (size_t i = 0; i < nsets; ++i)
8016 /* Find the longest name of a register in this set. */
8018 const struct register_info *end;
8019 for (end = sets[i]; same_set (sets[i], end); ++end)
8021 size_t len = strlen (end->name);
8026 for (const struct register_info *reg = sets[i];
8028 reg += reg->regloc->count ?: 1)
8029 colno = handle_core_register (ebl, core, maxname,
8030 reg->regloc, desc, colno);
8032 /* Force a line break at the end of the group. */
8033 colno = REGISTER_WRAP_COLUMN;
8040 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8042 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8045 error (EXIT_FAILURE, 0,
8046 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8048 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8049 for (size_t i = 0; i < nauxv; ++i)
8052 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8058 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8061 if (av->a_un.a_val == 0)
8062 printf (" %" PRIu64 "\n", av->a_type);
8064 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8065 av->a_type, av->a_un.a_val);
8070 case '\0': /* Normally zero. */
8071 if (av->a_un.a_val == 0)
8073 printf (" %s\n", name);
8078 case 'p': /* address */
8079 case 's': /* address of string */
8080 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8083 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8086 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8090 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8092 const char *pfx = "<";
8093 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8095 if (av->a_un.a_val & bit)
8097 printf ("%s%s", pfx, p);
8112 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8113 const char *name, const void *desc)
8115 GElf_Word regs_offset;
8117 const Ebl_Register_Location *reglocs;
8119 const Ebl_Core_Item *items;
8121 if (! ebl_core_note (ebl, nhdr, name,
8122 ®s_offset, &nregloc, ®locs, &nitems, &items))
8125 /* Pass 0 for DESCSZ when there are registers in the note,
8126 so that the ITEMS array does not describe the whole thing.
8127 For non-register notes, the actual descsz might be a multiple
8128 of the unit size, not just exactly the unit size. */
8129 unsigned int colno = handle_core_items (ebl->elf, desc,
8130 nregloc == 0 ? nhdr->n_descsz : 0,
8133 putchar_unlocked ('\n');
8135 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8138 putchar_unlocked ('\n');
8142 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8143 GElf_Off start, Elf_Data *data)
8145 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
8154 while (offset < data->d_size
8155 && (offset = gelf_getnote (data, offset,
8156 &nhdr, &name_offset, &desc_offset)) > 0)
8158 const char *name = data->d_buf + name_offset;
8159 const char *desc = data->d_buf + desc_offset;
8163 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
8164 (int) nhdr.n_namesz, name, nhdr.n_descsz,
8165 ehdr->e_type == ET_CORE
8166 ? ebl_core_note_type_name (ebl, nhdr.n_type,
8168 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8169 buf2, sizeof (buf2)));
8171 /* Filter out invalid entries. */
8172 if (memchr (name, '\0', nhdr.n_namesz) != NULL
8173 /* XXX For now help broken Linux kernels. */
8176 if (ehdr->e_type == ET_CORE)
8178 if (nhdr.n_type == NT_AUXV
8179 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
8180 || (nhdr.n_namesz == 5 && name[4] == '\0'))
8181 && !memcmp (name, "CORE", 4))
8182 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
8183 start + desc_offset);
8185 handle_core_note (ebl, &nhdr, name, desc);
8188 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
8192 if (offset == data->d_size)
8196 error (EXIT_FAILURE, 0,
8197 gettext ("cannot get content of note section: %s"),
8202 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
8204 /* If we have section headers, just look for SHT_NOTE sections.
8205 In a debuginfo file, the program headers are not reliable. */
8208 /* Get the section header string table index. */
8210 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
8211 error (EXIT_FAILURE, 0,
8212 gettext ("cannot get section header string table index"));
8214 Elf_Scn *scn = NULL;
8215 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8218 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8220 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
8221 /* Not what we are looking for. */
8225 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8227 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
8228 shdr->sh_size, shdr->sh_offset);
8230 handle_notes_data (ebl, ehdr, shdr->sh_offset,
8231 elf_getdata (scn, NULL));
8236 /* We have to look through the program header to find the note
8237 sections. There can be more than one. */
8238 for (size_t cnt = 0; cnt < phnum; ++cnt)
8241 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
8243 if (phdr == NULL || phdr->p_type != PT_NOTE)
8244 /* Not what we are looking for. */
8248 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8249 phdr->p_filesz, phdr->p_offset);
8251 handle_notes_data (ebl, ehdr, phdr->p_offset,
8252 elf_getdata_rawchunk (ebl->elf,
8253 phdr->p_offset, phdr->p_filesz,
8260 hex_dump (const uint8_t *data, size_t len)
8265 printf (" 0x%08Zx ", pos);
8267 const size_t chunk = MIN (len - pos, 16);
8269 for (size_t i = 0; i < chunk; ++i)
8271 printf ("%02x ", data[pos + i]);
8273 printf ("%02x", data[pos + i]);
8276 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
8278 for (size_t i = 0; i < chunk; ++i)
8280 unsigned char b = data[pos + i];
8281 printf ("%c", isprint (b) ? b : '.');
8290 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
8292 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
8293 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
8294 elf_ndxscn (scn), name);
8297 Elf_Data *data = elf_rawdata (scn, NULL);
8299 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
8300 elf_ndxscn (scn), name, elf_errmsg (-1));
8303 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
8304 " bytes at offset %#0" PRIx64 ":\n"),
8305 elf_ndxscn (scn), name,
8306 shdr->sh_size, shdr->sh_offset);
8307 hex_dump (data->d_buf, data->d_size);
8313 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
8315 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
8316 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
8317 elf_ndxscn (scn), name);
8320 Elf_Data *data = elf_rawdata (scn, NULL);
8322 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
8323 elf_ndxscn (scn), name, elf_errmsg (-1));
8326 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
8327 " bytes at offset %#0" PRIx64 ":\n"),
8328 elf_ndxscn (scn), name,
8329 shdr->sh_size, shdr->sh_offset);
8331 const char *start = data->d_buf;
8332 const char *const limit = start + data->d_size;
8335 const char *end = memchr (start, '\0', limit - start);
8336 const size_t pos = start - (const char *) data->d_buf;
8337 if (unlikely (end == NULL))
8339 printf (" [%6Zx]- %.*s\n",
8340 pos, (int) (limit - start), start);
8343 printf (" [%6Zx] %s\n", pos, start);
8345 } while (start < limit);
8351 for_each_section_argument (Elf *elf, const struct section_argument *list,
8352 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
8355 /* Get the section header string table index. */
8357 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
8358 error (EXIT_FAILURE, 0,
8359 gettext ("cannot get section header string table index"));
8361 for (const struct section_argument *a = list; a != NULL; a = a->next)
8365 const char *name = NULL;
8368 unsigned long int shndx = strtoul (a->arg, &endp, 0);
8369 if (endp != a->arg && *endp == '\0')
8371 scn = elf_getscn (elf, shndx);
8374 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
8378 if (gelf_getshdr (scn, &shdr_mem) == NULL)
8379 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
8381 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
8385 /* Need to look up the section by name. */
8388 while ((scn = elf_nextscn (elf, scn)) != NULL)
8390 if (gelf_getshdr (scn, &shdr_mem) == NULL)
8392 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
8395 if (!strcmp (name, a->arg))
8398 (*dump) (scn, &shdr_mem, name);
8402 if (unlikely (!found) && !a->implicit)
8403 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
8409 dump_data (Ebl *ebl)
8411 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
8415 dump_strings (Ebl *ebl)
8417 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
8421 print_strings (Ebl *ebl)
8423 /* Get the section header string table index. */
8425 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8426 error (EXIT_FAILURE, 0,
8427 gettext ("cannot get section header string table index"));
8433 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8435 if (gelf_getshdr (scn, &shdr_mem) == NULL)
8438 if (shdr_mem.sh_type != SHT_PROGBITS
8439 || !(shdr_mem.sh_flags & SHF_STRINGS))
8442 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
8446 print_string_section (scn, &shdr_mem, name);
8451 dump_archive_index (Elf *elf, const char *fname)
8454 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
8457 int result = elf_errno ();
8458 if (unlikely (result != ELF_E_NO_INDEX))
8459 error (EXIT_FAILURE, 0,
8460 gettext ("cannot get symbol index of archive '%s': %s"),
8461 fname, elf_errmsg (result));
8463 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
8467 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
8471 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
8473 if (s->as_off != as_off)
8478 if (unlikely (elf_rand (elf, as_off) == 0)
8479 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
8481 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
8484 error (EXIT_FAILURE, 0,
8485 gettext ("cannot extract member at offset %Zu in '%s': %s"),
8486 as_off, fname, elf_errmsg (-1));
8488 const Elf_Arhdr *h = elf_getarhdr (subelf);
8490 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
8495 printf ("\t%s\n", s->as_name);
8499 #include "debugpred.h"