1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2016 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1999.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
49 #include <printversion.h>
50 #include "../libelf/libelfP.h"
51 #include "../libelf/common.h"
52 #include "../libebl/libeblP.h"
53 #include "../libdwelf/libdwelf.h"
54 #include "../libdw/libdwP.h"
55 #include "../libdwfl/libdwflP.h"
56 #include "../libdw/memory-access.h"
58 #include "../libdw/known-dwarf.h"
61 #define CORE_SIGILL SIGILL
62 #define CORE_SIGBUS SIGBUS
63 #define CORE_SIGFPE SIGFPE
64 #define CORE_SIGSEGV SIGSEGV
65 #define CORE_SI_USER SI_USER
67 /* We want the linux version of those as that is what shows up in the core files. */
68 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
69 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
70 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
72 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */
75 /* Name and version of program. */
76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
78 /* Bug report address. */
79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
81 /* argp key value for --elf-section, non-ascii. */
82 #define ELF_INPUT_SECTION 256
84 /* Definitions of arguments for argp functions. */
85 static const struct argp_option options[] =
87 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
88 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
89 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
91 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
92 { "all", 'a', NULL, 0,
93 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
94 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
95 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
96 { "histogram", 'I', NULL, 0,
97 N_("Display histogram of bucket list lengths"), 0 },
98 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
99 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
100 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
101 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
102 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
103 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
104 N_("Display the symbol table sections"), 0 },
105 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
106 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
107 { "arch-specific", 'A', NULL, 0,
108 N_("Display architecture specific information, if any"), 0 },
109 { "exception", 'e', NULL, 0,
110 N_("Display sections for exception handling"), 0 },
112 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
113 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
114 N_("Display DWARF section content. SECTION can be one of abbrev, "
115 "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
116 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
117 { "hex-dump", 'x', "SECTION", 0,
118 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
119 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
120 N_("Print string contents of sections"), 0 },
121 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
122 { "archive-index", 'c', NULL, 0,
123 N_("Display the symbol index of an archive"), 0 },
125 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
126 { "numeric-addresses", 'N', NULL, 0,
127 N_("Do not find symbol names for addresses in DWARF data"), 0 },
128 { "unresolved-address-offsets", 'U', NULL, 0,
129 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
130 { "wide", 'W', NULL, 0,
131 N_("Ignored for compatibility (lines always wide)"), 0 },
132 { "decompress", 'z', NULL, 0,
133 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
134 { NULL, 0, NULL, 0, NULL, 0 }
137 /* Short description of program. */
138 static const char doc[] = N_("\
139 Print information from ELF file in human-readable form.");
141 /* Strings for arguments in help texts. */
142 static const char args_doc[] = N_("FILE...");
144 /* Prototype for option handler. */
145 static error_t parse_opt (int key, char *arg, struct argp_state *state);
147 /* Data structure to communicate with argp functions. */
148 static struct argp argp =
150 options, parse_opt, args_doc, doc, NULL, NULL, NULL
153 /* If non-null, the section from which we should read to (compressed) ELF. */
154 static const char *elf_input_section = NULL;
156 /* Flags set by the option controlling the output. */
158 /* True if dynamic segment should be printed. */
159 static bool print_dynamic_table;
161 /* True if the file header should be printed. */
162 static bool print_file_header;
164 /* True if the program headers should be printed. */
165 static bool print_program_header;
167 /* True if relocations should be printed. */
168 static bool print_relocations;
170 /* True if the section headers should be printed. */
171 static bool print_section_header;
173 /* True if the symbol table should be printed. */
174 static bool print_symbol_table;
176 /* A specific section name, or NULL to print all symbol tables. */
177 static char *symbol_table_section;
179 /* True if the version information should be printed. */
180 static bool print_version_info;
182 /* True if section groups should be printed. */
183 static bool print_section_groups;
185 /* True if bucket list length histogram should be printed. */
186 static bool print_histogram;
188 /* True if the architecture specific data should be printed. */
189 static bool print_arch;
191 /* True if note section content should be printed. */
192 static bool print_notes;
194 /* True if SHF_STRINGS section content should be printed. */
195 static bool print_string_sections;
197 /* True if archive index should be printed. */
198 static bool print_archive_index;
200 /* True if any of the control options except print_archive_index is set. */
201 static bool any_control_option;
203 /* True if we should print addresses from DWARF in symbolic form. */
204 static bool print_address_names = true;
206 /* True if we should print raw values instead of relativized addresses. */
207 static bool print_unresolved_addresses = false;
209 /* True if we should print the .debug_aranges section using libdw. */
210 static bool decodedaranges = false;
212 /* True if we should print the .debug_aranges section using libdw. */
213 static bool decodedline = false;
215 /* True if we want to show more information about compressed sections. */
216 static bool print_decompress = false;
218 /* Select printing of debugging sections. */
219 static enum section_e
221 section_abbrev = 1, /* .debug_abbrev */
222 section_aranges = 2, /* .debug_aranges */
223 section_frame = 4, /* .debug_frame or .eh_frame & al. */
224 section_info = 8, /* .debug_info, .debug_types */
225 section_types = section_info,
226 section_line = 16, /* .debug_line */
227 section_loc = 32, /* .debug_loc */
228 section_pubnames = 64, /* .debug_pubnames */
229 section_str = 128, /* .debug_str */
230 section_macinfo = 256, /* .debug_macinfo */
231 section_ranges = 512, /* .debug_ranges */
232 section_exception = 1024, /* .eh_frame & al. */
233 section_gdb_index = 2048, /* .gdb_index */
234 section_macro = 4096, /* .debug_macro */
235 section_all = (section_abbrev | section_aranges | section_frame
236 | section_info | section_line | section_loc
237 | section_pubnames | section_str | section_macinfo
238 | section_ranges | section_exception | section_gdb_index
240 } print_debug_sections, implicit_debug_sections;
242 /* Select hex dumping of sections. */
243 static struct section_argument *dump_data_sections;
244 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
246 /* Select string dumping of sections. */
247 static struct section_argument *string_sections;
248 static struct section_argument **string_sections_tail = &string_sections;
250 struct section_argument
252 struct section_argument *next;
257 /* Numbers of sections and program headers in the file. */
262 /* Declarations of local functions. */
263 static void process_file (int fd, const char *fname, bool only_one);
264 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
265 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
266 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
267 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
268 static void print_scngrp (Ebl *ebl);
269 static void print_dynamic (Ebl *ebl);
270 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
271 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
273 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
275 static void print_symtab (Ebl *ebl, int type);
276 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
277 static void print_verinfo (Ebl *ebl);
278 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
279 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
280 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
282 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
283 static void handle_hash (Ebl *ebl);
284 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
285 static void print_liblist (Ebl *ebl);
286 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
287 static void dump_data (Ebl *ebl);
288 static void dump_strings (Ebl *ebl);
289 static void print_strings (Ebl *ebl);
290 static void dump_archive_index (Elf *, const char *);
294 main (int argc, char *argv[])
297 setlocale (LC_ALL, "");
299 /* Initialize the message catalog. */
300 textdomain (PACKAGE_TARNAME);
302 /* Parse and process arguments. */
304 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
306 /* Before we start tell the ELF library which version we are using. */
307 elf_version (EV_CURRENT);
309 /* Now process all the files given at the command line. */
310 bool only_one = remaining + 1 == argc;
314 int fd = open (argv[remaining], O_RDONLY);
317 error (0, errno, gettext ("cannot open input file"));
321 process_file (fd, argv[remaining], only_one);
325 while (++remaining < argc);
327 return error_message_count != 0;
331 /* Handle program arguments. */
333 parse_opt (int key, char *arg,
334 struct argp_state *state __attribute__ ((unused)))
336 void add_dump_section (const char *name, bool implicit)
338 struct section_argument *a = xmalloc (sizeof *a);
341 a->implicit = implicit;
342 struct section_argument ***tailp
343 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
351 print_file_header = true;
352 print_program_header = true;
353 print_relocations = true;
354 print_section_header = true;
355 print_symbol_table = true;
356 print_version_info = true;
357 print_dynamic_table = true;
358 print_section_groups = true;
359 print_histogram = true;
362 implicit_debug_sections |= section_exception;
363 add_dump_section (".strtab", true);
364 add_dump_section (".dynstr", true);
365 add_dump_section (".comment", true);
366 any_control_option = true;
370 any_control_option = true;
373 print_dynamic_table = true;
374 any_control_option = true;
377 print_debug_sections |= section_exception;
378 any_control_option = true;
381 print_section_groups = true;
382 any_control_option = true;
385 print_file_header = true;
386 any_control_option = true;
389 print_histogram = true;
390 any_control_option = true;
393 print_program_header = true;
394 any_control_option = true;
398 any_control_option = true;
401 print_relocations = true;
402 any_control_option = true;
405 print_section_header = true;
406 any_control_option = true;
409 print_symbol_table = true;
410 any_control_option = true;
411 symbol_table_section = arg;
414 print_version_info = true;
415 any_control_option = true;
418 print_archive_index = true;
422 print_debug_sections = section_all;
423 else if (strcmp (arg, "abbrev") == 0)
424 print_debug_sections |= section_abbrev;
425 else if (strcmp (arg, "aranges") == 0)
426 print_debug_sections |= section_aranges;
427 else if (strcmp (arg, "decodedaranges") == 0)
429 print_debug_sections |= section_aranges;
430 decodedaranges = true;
432 else if (strcmp (arg, "ranges") == 0)
434 print_debug_sections |= section_ranges;
435 implicit_debug_sections |= section_info;
437 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
438 print_debug_sections |= section_frame;
439 else if (strcmp (arg, "info") == 0)
440 print_debug_sections |= section_info;
441 else if (strcmp (arg, "loc") == 0)
443 print_debug_sections |= section_loc;
444 implicit_debug_sections |= section_info;
446 else if (strcmp (arg, "line") == 0)
447 print_debug_sections |= section_line;
448 else if (strcmp (arg, "decodedline") == 0)
450 print_debug_sections |= section_line;
453 else if (strcmp (arg, "pubnames") == 0)
454 print_debug_sections |= section_pubnames;
455 else if (strcmp (arg, "str") == 0)
456 print_debug_sections |= section_str;
457 else if (strcmp (arg, "macinfo") == 0)
458 print_debug_sections |= section_macinfo;
459 else if (strcmp (arg, "macro") == 0)
460 print_debug_sections |= section_macro;
461 else if (strcmp (arg, "exception") == 0)
462 print_debug_sections |= section_exception;
463 else if (strcmp (arg, "gdb_index") == 0)
464 print_debug_sections |= section_gdb_index;
467 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
469 argp_help (&argp, stderr, ARGP_HELP_SEE,
470 program_invocation_short_name);
473 any_control_option = true;
476 any_control_option = true;
479 print_string_sections = true;
484 add_dump_section (arg, false);
485 any_control_option = true;
488 print_address_names = false;
491 print_unresolved_addresses = true;
493 case ARGP_KEY_NO_ARGS:
494 fputs (gettext ("Missing file name.\n"), stderr);
497 if (! any_control_option && ! print_archive_index)
499 fputs (gettext ("No operation specified.\n"), stderr);
501 argp_help (&argp, stderr, ARGP_HELP_SEE,
502 program_invocation_short_name);
506 case 'W': /* Ignored. */
509 print_decompress = true;
511 case ELF_INPUT_SECTION:
513 elf_input_section = ".gnu_debugdata";
515 elf_input_section = arg;
518 return ARGP_ERR_UNKNOWN;
524 /* Create a file descriptor to read the data from the
525 elf_input_section given a file descriptor to an ELF file. */
527 open_input_section (int fd)
532 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
535 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
540 if (elf_getshdrnum (elf, &shnums) < 0)
542 error (0, 0, gettext ("cannot determine number of sections: %s"),
549 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
551 error (0, 0, gettext ("cannot get section header string table index"));
555 for (cnt = 0; cnt < shnums; ++cnt)
557 Elf_Scn *scn = elf_getscn (elf, cnt);
560 error (0, 0, gettext ("cannot get section: %s"),
566 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
567 if (unlikely (shdr == NULL))
569 error (0, 0, gettext ("cannot get section header: %s"),
574 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
577 error (0, 0, gettext ("cannot get section name"));
581 if (strcmp (sname, elf_input_section) == 0)
583 Elf_Data *data = elf_rawdata (scn, NULL);
586 error (0, 0, gettext ("cannot get %s content: %s"),
587 sname, elf_errmsg (-1));
591 /* Create (and immediately unlink) a temporary file to store
592 section data in to create a file descriptor for it. */
593 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
594 static const char suffix[] = "/readelfXXXXXX";
595 int tmplen = strlen (tmpdir) + sizeof (suffix);
596 char *tempname = alloca (tmplen);
597 sprintf (tempname, "%s%s", tmpdir, suffix);
599 int sfd = mkstemp (tempname);
602 error (0, 0, gettext ("cannot create temp file '%s'"),
608 ssize_t size = data->d_size;
609 if (write_retry (sfd, data->d_buf, size) != size)
611 error (0, 0, gettext ("cannot write section data"));
615 if (elf_end (elf) != 0)
617 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
622 if (lseek (sfd, 0, SEEK_SET) == -1)
624 error (0, 0, gettext ("error while rewinding file descriptor"));
632 /* Named section not found. */
633 if (elf_end (elf) != 0)
634 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
639 /* Check if the file is an archive, and if so dump its index. */
641 check_archive_index (int fd, const char *fname, bool only_one)
643 /* Create an `Elf' descriptor. */
644 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
646 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
650 if (elf_kind (elf) == ELF_K_AR)
653 printf ("\n%s:\n\n", fname);
654 dump_archive_index (elf, fname);
658 gettext ("'%s' is not an archive, cannot print archive index"),
661 /* Now we can close the descriptor. */
662 if (elf_end (elf) != 0)
663 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
668 /* Trivial callback used for checking if we opened an archive. */
670 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
671 void **userdata __attribute__ ((unused)),
672 const char *name __attribute__ ((unused)),
673 Dwarf_Addr base __attribute__ ((unused)),
677 return DWARF_CB_ABORT;
678 *(bool *) arg = true;
682 struct process_dwflmod_args
689 process_dwflmod (Dwfl_Module *dwflmod,
690 void **userdata __attribute__ ((unused)),
691 const char *name __attribute__ ((unused)),
692 Dwarf_Addr base __attribute__ ((unused)),
695 const struct process_dwflmod_args *a = arg;
697 /* Print the file name. */
701 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
703 printf ("\n%s:\n\n", fname);
706 process_elf_file (dwflmod, a->fd);
711 /* Stub libdwfl callback, only the ELF handle already open is ever used.
712 Only used for finding the alternate debug file if the Dwarf comes from
713 the main file. We are not interested in separate debuginfo. */
715 find_no_debuginfo (Dwfl_Module *mod,
719 const char *file_name,
720 const char *debuglink_file,
721 GElf_Word debuglink_crc,
722 char **debuginfo_file_name)
725 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
727 /* We are only interested if the Dwarf has been setup on the main
728 elf file but is only missing the alternate debug link. If dwbias
729 hasn't even been setup, this is searching for separate debuginfo
730 for the main elf. We don't care in that case. */
731 if (dwbias == (Dwarf_Addr) -1)
734 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
735 file_name, debuglink_file,
736 debuglink_crc, debuginfo_file_name);
739 /* Process one input file. */
741 process_file (int fd, const char *fname, bool only_one)
743 if (print_archive_index)
744 check_archive_index (fd, fname, only_one);
746 if (!any_control_option)
749 if (elf_input_section != NULL)
751 /* Replace fname and fd with section content. */
752 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
753 sprintf (fnname, "%s:%s", fname, elf_input_section);
754 fd = open_input_section (fd);
757 error (0, 0, gettext ("No such section '%s' in '%s'"),
758 elf_input_section, fname);
764 /* Duplicate an fd for dwfl_report_offline to swallow. */
765 int dwfl_fd = dup (fd);
766 if (unlikely (dwfl_fd < 0))
767 error (EXIT_FAILURE, errno, "dup");
769 /* Use libdwfl in a trivial way to open the libdw handle for us.
770 This takes care of applying relocations to DWARF data in ET_REL files. */
771 static const Dwfl_Callbacks callbacks =
773 .section_address = dwfl_offline_section_address,
774 .find_debuginfo = find_no_debuginfo
776 Dwfl *dwfl = dwfl_begin (&callbacks);
777 if (likely (dwfl != NULL))
778 /* Let 0 be the logical address of the file (or first in archive). */
779 dwfl->offline_next_address = 0;
780 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
783 if (fstat (dwfl_fd, &st) != 0)
784 error (0, errno, gettext ("cannot stat input file"));
785 else if (unlikely (st.st_size == 0))
786 error (0, 0, gettext ("input file is empty"));
788 error (0, 0, gettext ("failed reading '%s': %s"),
789 fname, dwfl_errmsg (-1));
790 close (dwfl_fd); /* Consumed on success, not on failure. */
794 dwfl_report_end (dwfl, NULL, NULL);
798 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
800 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
803 /* Process the one or more modules gleaned from this file. */
804 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
805 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
809 /* Need to close the replaced fd if we created it. Caller takes
811 if (elf_input_section != NULL)
815 /* Check whether there are any compressed sections in the ELF file. */
817 elf_contains_chdrs (Elf *elf)
820 while ((scn = elf_nextscn (elf, scn)) != NULL)
823 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
824 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
830 /* Process one ELF file. */
832 process_elf_file (Dwfl_Module *dwflmod, int fd)
835 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
838 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
843 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
847 Ebl *ebl = ebl_openbackend (elf);
848 if (unlikely (ebl == NULL))
851 error (0, errno, gettext ("cannot create EBL handle"));
855 /* Determine the number of sections. */
856 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
857 error (EXIT_FAILURE, 0,
858 gettext ("cannot determine number of sections: %s"),
861 /* Determine the number of phdrs. */
862 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
863 error (EXIT_FAILURE, 0,
864 gettext ("cannot determine number of program headers: %s"),
867 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
868 may have applied relocation to some sections. If there are any
869 compressed sections, any pass (or libdw/libdwfl) might have
870 uncompressed them. So we need to get a fresh Elf handle on the
871 file to display those. */
872 bool print_unchanged = ((print_section_header
874 || dump_data_sections != NULL
876 && (ehdr->e_type == ET_REL
877 || elf_contains_chdrs (ebl->elf)));
879 Elf *pure_elf = NULL;
883 /* Read the file afresh. */
884 off_t aroff = elf_getaroff (elf);
885 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
888 /* Archive member. */
889 (void) elf_rand (pure_elf, aroff);
890 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
894 if (pure_elf == NULL)
896 pure_ebl = ebl_openbackend (pure_elf);
897 if (pure_ebl == NULL)
901 if (print_file_header)
902 print_ehdr (ebl, ehdr);
903 if (print_section_header)
904 print_shdr (pure_ebl, ehdr);
905 if (print_program_header)
906 print_phdr (ebl, ehdr);
907 if (print_section_groups)
909 if (print_dynamic_table)
911 if (print_relocations)
912 print_relocs (pure_ebl, ehdr);
915 if (print_symbol_table)
916 print_symtab (ebl, SHT_DYNSYM);
917 if (print_version_info)
919 if (print_symbol_table)
920 print_symtab (ebl, SHT_SYMTAB);
924 print_attributes (ebl, ehdr);
925 if (dump_data_sections != NULL)
926 dump_data (pure_ebl);
927 if (string_sections != NULL)
929 if ((print_debug_sections | implicit_debug_sections) != 0)
930 print_debug (dwflmod, ebl, ehdr);
932 handle_notes (pure_ebl, ehdr);
933 if (print_string_sections)
936 ebl_closebackend (ebl);
940 ebl_closebackend (pure_ebl);
946 /* Print file type. */
948 print_file_type (unsigned short int e_type)
950 if (likely (e_type <= ET_CORE))
952 static const char *const knowntypes[] =
955 N_("REL (Relocatable file)"),
956 N_("EXEC (Executable file)"),
957 N_("DYN (Shared object file)"),
958 N_("CORE (Core file)")
960 puts (gettext (knowntypes[e_type]));
962 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
963 printf (gettext ("OS Specific: (%x)\n"), e_type);
964 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
965 printf (gettext ("Processor Specific: (%x)\n"), e_type);
971 /* Print ELF header. */
973 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
975 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
976 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
977 printf (" %02hhx", ehdr->e_ident[cnt]);
979 printf (gettext ("\n Class: %s\n"),
980 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
981 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
984 printf (gettext (" Data: %s\n"),
985 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
986 ? "2's complement, little endian"
987 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
988 ? "2's complement, big endian" : "\?\?\?");
990 printf (gettext (" Ident Version: %hhd %s\n"),
991 ehdr->e_ident[EI_VERSION],
992 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
996 printf (gettext (" OS/ABI: %s\n"),
997 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
999 printf (gettext (" ABI Version: %hhd\n"),
1000 ehdr->e_ident[EI_ABIVERSION]);
1002 fputs_unlocked (gettext (" Type: "), stdout);
1003 print_file_type (ehdr->e_type);
1005 printf (gettext (" Machine: %s\n"), ebl->name);
1007 printf (gettext (" Version: %d %s\n"),
1009 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1011 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
1014 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
1015 ehdr->e_phoff, gettext ("(bytes into file)"));
1017 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
1018 ehdr->e_shoff, gettext ("(bytes into file)"));
1020 printf (gettext (" Flags: %s\n"),
1021 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1023 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
1024 ehdr->e_ehsize, gettext ("(bytes)"));
1026 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
1027 ehdr->e_phentsize, gettext ("(bytes)"));
1029 printf (gettext (" Number of program headers entries: %" PRId16),
1031 if (ehdr->e_phnum == PN_XNUM)
1034 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1036 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1037 (uint32_t) shdr->sh_info);
1039 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1041 fputc_unlocked ('\n', stdout);
1043 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1044 ehdr->e_shentsize, gettext ("(bytes)"));
1046 printf (gettext (" Number of section headers entries: %" PRId16),
1048 if (ehdr->e_shnum == 0)
1051 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1053 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1054 (uint32_t) shdr->sh_size);
1056 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1058 fputc_unlocked ('\n', stdout);
1060 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1063 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1065 /* We managed to get the zeroth section. */
1066 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1067 (uint32_t) shdr->sh_link);
1070 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1071 buf[sizeof (buf) - 1] = '\0';
1074 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1078 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1084 get_visibility_type (int value)
1102 elf_ch_type_name (unsigned int code)
1107 if (code == ELFCOMPRESS_ZLIB)
1113 /* Print the section headers. */
1115 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1120 if (! print_file_header)
1122 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1124 ehdr->e_shnum, ehdr->e_shoff);
1126 /* Get the section header string table index. */
1127 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1128 error (EXIT_FAILURE, 0,
1129 gettext ("cannot get section header string table index"));
1131 puts (gettext ("Section Headers:"));
1133 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1134 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1136 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1138 if (print_decompress)
1140 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1141 puts (gettext (" [Compression Size Al]"));
1143 puts (gettext (" [Compression Size Al]"));
1146 for (cnt = 0; cnt < shnum; ++cnt)
1148 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1150 if (unlikely (scn == NULL))
1151 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1154 /* Get the section header. */
1156 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1157 if (unlikely (shdr == NULL))
1158 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1163 if (shdr->sh_flags & SHF_WRITE)
1165 if (shdr->sh_flags & SHF_ALLOC)
1167 if (shdr->sh_flags & SHF_EXECINSTR)
1169 if (shdr->sh_flags & SHF_MERGE)
1171 if (shdr->sh_flags & SHF_STRINGS)
1173 if (shdr->sh_flags & SHF_INFO_LINK)
1175 if (shdr->sh_flags & SHF_LINK_ORDER)
1177 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1179 if (shdr->sh_flags & SHF_GROUP)
1181 if (shdr->sh_flags & SHF_TLS)
1183 if (shdr->sh_flags & SHF_COMPRESSED)
1185 if (shdr->sh_flags & SHF_ORDERED)
1187 if (shdr->sh_flags & SHF_EXCLUDE)
1193 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1194 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1195 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1198 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1199 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1200 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1201 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1202 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1203 shdr->sh_addralign);
1205 if (print_decompress)
1207 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1210 if (gelf_getchdr (scn, &chdr) != NULL)
1211 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1213 elf_ch_type_name (chdr.ch_type),
1215 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1216 chdr.ch_size, chdr.ch_addralign);
1219 gettext ("bad compression header for section %zd: %s"),
1220 elf_ndxscn (scn), elf_errmsg (-1));
1222 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1225 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1226 printf (" [GNU ZLIB %0*zx ]\n",
1227 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1230 gettext ("bad gnu compressed size for section %zd: %s"),
1231 elf_ndxscn (scn), elf_errmsg (-1));
1236 fputc_unlocked ('\n', stdout);
1240 /* Print the program header. */
1242 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1245 /* No program header, this is OK in relocatable objects. */
1248 puts (gettext ("Program Headers:"));
1249 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1251 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1254 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1256 /* Process all program headers. */
1257 bool has_relro = false;
1258 GElf_Addr relro_from = 0;
1259 GElf_Addr relro_to = 0;
1260 for (size_t cnt = 0; cnt < phnum; ++cnt)
1264 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1266 /* If for some reason the header cannot be returned show this. */
1267 if (unlikely (phdr == NULL))
1273 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1274 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1275 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1277 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1278 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1281 phdr->p_flags & PF_R ? 'R' : ' ',
1282 phdr->p_flags & PF_W ? 'W' : ' ',
1283 phdr->p_flags & PF_X ? 'E' : ' ',
1286 if (phdr->p_type == PT_INTERP)
1288 /* If we are sure the file offset is valid then we can show
1289 the user the name of the interpreter. We check whether
1290 there is a section at the file offset. Normally there
1291 would be a section called ".interp". But in separate
1292 .debug files it is a NOBITS section (and so doesn't match
1293 with gelf_offscn). Which probably means the offset is
1294 not valid another reason could be because the ELF file
1295 just doesn't contain any section headers, in that case
1296 just play it safe and don't display anything. */
1298 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1300 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1303 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1305 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1306 && filedata != NULL && phdr->p_offset < maxsize
1307 && phdr->p_filesz <= maxsize - phdr->p_offset
1308 && memchr (filedata + phdr->p_offset, '\0',
1309 phdr->p_filesz) != NULL)
1310 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1311 filedata + phdr->p_offset);
1313 else if (phdr->p_type == PT_GNU_RELRO)
1316 relro_from = phdr->p_vaddr;
1317 relro_to = relro_from + phdr->p_memsz;
1321 if (ehdr->e_shnum == 0)
1322 /* No sections in the file. Punt. */
1325 /* Get the section header string table index. */
1327 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1328 error (EXIT_FAILURE, 0,
1329 gettext ("cannot get section header string table index"));
1331 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1333 for (size_t cnt = 0; cnt < phnum; ++cnt)
1335 /* Print the segment number. */
1336 printf (" %2.2zu ", cnt);
1339 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1340 /* This must not happen. */
1341 if (unlikely (phdr == NULL))
1342 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1345 /* Iterate over the sections. */
1346 bool in_relro = false;
1348 for (size_t inner = 1; inner < shnum; ++inner)
1350 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1351 /* This should not happen. */
1352 if (unlikely (scn == NULL))
1353 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1356 /* Get the section header. */
1358 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1359 if (unlikely (shdr == NULL))
1360 error (EXIT_FAILURE, 0,
1361 gettext ("cannot get section header: %s"),
1364 if (shdr->sh_size > 0
1365 /* Compare allocated sections by VMA, unallocated
1366 sections by file offset. */
1367 && (shdr->sh_flags & SHF_ALLOC
1368 ? (shdr->sh_addr >= phdr->p_vaddr
1369 && (shdr->sh_addr + shdr->sh_size
1370 <= phdr->p_vaddr + phdr->p_memsz))
1371 : (shdr->sh_offset >= phdr->p_offset
1372 && (shdr->sh_offset + shdr->sh_size
1373 <= phdr->p_offset + phdr->p_filesz))))
1375 if (has_relro && !in_relro
1376 && shdr->sh_addr >= relro_from
1377 && shdr->sh_addr + shdr->sh_size <= relro_to)
1379 fputs_unlocked (" [RELRO:", stdout);
1382 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1384 fputs_unlocked ("]", stdout);
1387 else if (has_relro && in_relro
1388 && shdr->sh_addr + shdr->sh_size > relro_to)
1389 fputs_unlocked ("] <RELRO:", stdout);
1390 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1394 fputs_unlocked (" [RO:", stdout);
1400 /* Determine the segment this section is part of. */
1402 GElf_Phdr phdr2_mem;
1403 GElf_Phdr *phdr2 = NULL;
1404 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1406 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1408 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1409 && shdr->sh_addr >= phdr2->p_vaddr
1410 && (shdr->sh_addr + shdr->sh_size
1411 <= phdr2->p_vaddr + phdr2->p_memsz))
1417 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1419 fputs_unlocked (" [RO:", stdout);
1422 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1424 fputs_unlocked ("]", stdout);
1431 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1433 /* Signal that this sectin is only partially covered. */
1434 if (has_relro && in_relro
1435 && shdr->sh_addr + shdr->sh_size > relro_to)
1437 fputs_unlocked (">", stdout);
1442 if (in_relro || in_ro)
1443 fputs_unlocked ("]", stdout);
1445 /* Finish the line. */
1446 fputc_unlocked ('\n', stdout);
1452 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1454 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1459 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1461 /* Get the data of the section. */
1462 Elf_Data *data = elf_getdata (scn, NULL);
1464 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1465 GElf_Shdr symshdr_mem;
1466 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1467 Elf_Data *symdata = elf_getdata (symscn, NULL);
1469 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1473 /* Get the section header string table index. */
1475 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1476 error (EXIT_FAILURE, 0,
1477 gettext ("cannot get section header string table index"));
1479 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1482 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1484 printf ((grpref[0] & GRP_COMDAT)
1486 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1488 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1489 data->d_size / sizeof (Elf32_Word) - 1)
1491 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1492 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1493 data->d_size / sizeof (Elf32_Word) - 1),
1495 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1497 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1498 ?: gettext ("<INVALID SYMBOL>"),
1499 data->d_size / sizeof (Elf32_Word) - 1);
1501 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1503 GElf_Shdr grpshdr_mem;
1504 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1508 printf (" [%2u] %s\n",
1511 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1512 ? str : gettext ("<INVALID SECTION>"));
1518 print_scngrp (Ebl *ebl)
1520 /* Find all relocation sections and handle them. */
1521 Elf_Scn *scn = NULL;
1523 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1525 /* Handle the section if it is a symbol table. */
1527 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1529 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1531 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1533 if (elf_compress (scn, 0, 0) < 0)
1534 printf ("WARNING: %s [%zd]\n",
1535 gettext ("Couldn't uncompress section"),
1537 shdr = gelf_getshdr (scn, &shdr_mem);
1538 if (unlikely (shdr == NULL))
1539 error (EXIT_FAILURE, 0,
1540 gettext ("cannot get section [%zd] header: %s"),
1544 handle_scngrp (ebl, scn, shdr);
1550 static const struct flags
1556 { DF_ORIGIN, "ORIGIN" },
1557 { DF_SYMBOLIC, "SYMBOLIC" },
1558 { DF_TEXTREL, "TEXTREL" },
1559 { DF_BIND_NOW, "BIND_NOW" },
1560 { DF_STATIC_TLS, "STATIC_TLS" }
1562 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1564 static const struct flags dt_flags_1[] =
1566 { DF_1_NOW, "NOW" },
1567 { DF_1_GLOBAL, "GLOBAL" },
1568 { DF_1_GROUP, "GROUP" },
1569 { DF_1_NODELETE, "NODELETE" },
1570 { DF_1_LOADFLTR, "LOADFLTR" },
1571 { DF_1_INITFIRST, "INITFIRST" },
1572 { DF_1_NOOPEN, "NOOPEN" },
1573 { DF_1_ORIGIN, "ORIGIN" },
1574 { DF_1_DIRECT, "DIRECT" },
1575 { DF_1_TRANS, "TRANS" },
1576 { DF_1_INTERPOSE, "INTERPOSE" },
1577 { DF_1_NODEFLIB, "NODEFLIB" },
1578 { DF_1_NODUMP, "NODUMP" },
1579 { DF_1_CONFALT, "CONFALT" },
1580 { DF_1_ENDFILTEE, "ENDFILTEE" },
1581 { DF_1_DISPRELDNE, "DISPRELDNE" },
1582 { DF_1_DISPRELPND, "DISPRELPND" },
1584 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1586 static const struct flags dt_feature_1[] =
1588 { DTF_1_PARINIT, "PARINIT" },
1589 { DTF_1_CONFEXP, "CONFEXP" }
1591 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1592 / sizeof (dt_feature_1[0]));
1594 static const struct flags dt_posflag_1[] =
1596 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1597 { DF_P1_GROUPPERM, "GROUPPERM" }
1599 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1600 / sizeof (dt_posflag_1[0]));
1604 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1610 for (cnt = 0; cnt < nflags; ++cnt)
1611 if (d_val & flags[cnt].mask)
1614 putchar_unlocked (' ');
1615 fputs_unlocked (flags[cnt].str, stdout);
1616 d_val &= ~flags[cnt].mask;
1623 putchar_unlocked (' ');
1624 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1627 putchar_unlocked ('\n');
1632 print_dt_flags (int class, GElf_Xword d_val)
1634 print_flags (class, d_val, dt_flags, ndt_flags);
1639 print_dt_flags_1 (int class, GElf_Xword d_val)
1641 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1646 print_dt_feature_1 (int class, GElf_Xword d_val)
1648 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1653 print_dt_posflag_1 (int class, GElf_Xword d_val)
1655 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1660 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1662 int class = gelf_getclass (ebl->elf);
1663 GElf_Shdr glink_mem;
1670 /* Get the data of the section. */
1671 data = elf_getdata (scn, NULL);
1675 /* Get the section header string table index. */
1676 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1677 error (EXIT_FAILURE, 0,
1678 gettext ("cannot get section header string table index"));
1680 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1682 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1684 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1687 printf (ngettext ("\
1688 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1690 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1691 shdr->sh_size / sh_entsize),
1692 (unsigned long int) (shdr->sh_size / sh_entsize),
1693 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1695 (int) shdr->sh_link,
1696 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1697 fputs_unlocked (gettext (" Type Value\n"), stdout);
1699 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1702 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1708 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1716 /* No further output. */
1717 fputc_unlocked ('\n', stdout);
1721 printf (gettext ("Shared library: [%s]\n"),
1722 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1726 printf (gettext ("Library soname: [%s]\n"),
1727 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1731 printf (gettext ("Library rpath: [%s]\n"),
1732 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1736 printf (gettext ("Library runpath: [%s]\n"),
1737 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1750 case DT_INIT_ARRAYSZ:
1751 case DT_FINI_ARRAYSZ:
1754 case DT_GNU_CONFLICTSZ:
1755 case DT_GNU_LIBLISTSZ:
1756 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1763 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1767 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1769 puts (tagname ?: "???");
1773 print_dt_flags (class, dyn->d_un.d_val);
1777 print_dt_flags_1 (class, dyn->d_un.d_val);
1781 print_dt_feature_1 (class, dyn->d_un.d_val);
1785 print_dt_posflag_1 (class, dyn->d_un.d_val);
1789 printf ("%#0*" PRIx64 "\n",
1790 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1797 /* Print the dynamic segment. */
1799 print_dynamic (Ebl *ebl)
1801 for (size_t i = 0; i < phnum; ++i)
1804 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1806 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1808 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1810 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1811 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1812 handle_dynamic (ebl, scn, shdr);
1819 /* Print relocations. */
1821 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1823 /* Find all relocation sections and handle them. */
1824 Elf_Scn *scn = NULL;
1826 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1828 /* Handle the section if it is a symbol table. */
1830 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1832 if (likely (shdr != NULL))
1834 if (shdr->sh_type == SHT_REL)
1835 handle_relocs_rel (ebl, ehdr, scn, shdr);
1836 else if (shdr->sh_type == SHT_RELA)
1837 handle_relocs_rela (ebl, ehdr, scn, shdr);
1843 /* Handle a relocation section. */
1845 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1847 int class = gelf_getclass (ebl->elf);
1848 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1849 int nentries = shdr->sh_size / sh_entsize;
1851 /* Get the data of the section. */
1852 Elf_Data *data = elf_getdata (scn, NULL);
1856 /* Get the symbol table information. */
1857 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1858 GElf_Shdr symshdr_mem;
1859 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1860 Elf_Data *symdata = elf_getdata (symscn, NULL);
1862 /* Get the section header of the section the relocations are for. */
1863 GElf_Shdr destshdr_mem;
1864 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1867 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1869 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1874 /* Search for the optional extended section index table. */
1875 Elf_Data *xndxdata = NULL;
1876 int xndxscnidx = elf_scnshndx (scn);
1877 if (unlikely (xndxscnidx > 0))
1878 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1880 /* Get the section header string table index. */
1882 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1883 error (EXIT_FAILURE, 0,
1884 gettext ("cannot get section header string table index"));
1886 if (shdr->sh_info != 0)
1887 printf (ngettext ("\
1888 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1890 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1893 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1894 (unsigned int) shdr->sh_info,
1895 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1899 /* The .rel.dyn section does not refer to a specific section but
1900 instead of section index zero. Do not try to print a section
1902 printf (ngettext ("\
1903 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1905 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1907 (unsigned int) elf_ndxscn (scn),
1908 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1911 fputs_unlocked (class == ELFCLASS32
1913 Offset Type Value Name\n")
1915 Offset Type Value Name\n"),
1918 int is_statically_linked = 0;
1919 for (int cnt = 0; cnt < nentries; ++cnt)
1922 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1923 if (likely (rel != NULL))
1928 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1929 GELF_R_SYM (rel->r_info),
1931 if (unlikely (sym == NULL))
1933 /* As a special case we have to handle relocations in static
1934 executables. This only happens for IRELATIVE relocations
1935 (so far). There is no symbol table. */
1936 if (is_statically_linked == 0)
1938 /* Find the program header and look for a PT_INTERP entry. */
1939 is_statically_linked = -1;
1940 if (ehdr->e_type == ET_EXEC)
1942 is_statically_linked = 1;
1944 for (size_t inner = 0; inner < phnum; ++inner)
1947 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1949 if (phdr != NULL && phdr->p_type == PT_INTERP)
1951 is_statically_linked = -1;
1958 if (is_statically_linked > 0 && shdr->sh_link == 0)
1960 %#0*" PRIx64 " %-20s %*s %s\n",
1961 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1962 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1963 /* Avoid the leading R_ which isn't carrying any
1965 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1966 buf, sizeof (buf)) + 2
1967 : gettext ("<INVALID RELOC>"),
1968 class == ELFCLASS32 ? 10 : 18, "",
1969 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1971 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1972 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1973 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1974 /* Avoid the leading R_ which isn't carrying any
1976 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1977 buf, sizeof (buf)) + 2
1978 : gettext ("<INVALID RELOC>"),
1979 gettext ("INVALID SYMBOL"),
1980 (long int) GELF_R_SYM (rel->r_info));
1982 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1983 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1984 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1985 likely (ebl_reloc_type_check (ebl,
1986 GELF_R_TYPE (rel->r_info)))
1987 /* Avoid the leading R_ which isn't carrying any
1989 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1990 buf, sizeof (buf)) + 2
1991 : gettext ("<INVALID RELOC>"),
1992 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1993 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1996 /* This is a relocation against a STT_SECTION symbol. */
1997 GElf_Shdr secshdr_mem;
1999 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2000 sym->st_shndx == SHN_XINDEX
2001 ? xndx : sym->st_shndx),
2004 if (unlikely (secshdr == NULL))
2005 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2006 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2007 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2008 /* Avoid the leading R_ which isn't carrying any
2010 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2011 buf, sizeof (buf)) + 2
2012 : gettext ("<INVALID RELOC>"),
2013 gettext ("INVALID SECTION"),
2014 (long int) (sym->st_shndx == SHN_XINDEX
2015 ? xndx : sym->st_shndx));
2017 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2018 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2019 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2020 /* Avoid the leading R_ which isn't carrying any
2022 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2023 buf, sizeof (buf)) + 2
2024 : gettext ("<INVALID RELOC>"),
2025 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2026 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2033 /* Handle a relocation section. */
2035 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2037 int class = gelf_getclass (ebl->elf);
2038 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2039 int nentries = shdr->sh_size / sh_entsize;
2041 /* Get the data of the section. */
2042 Elf_Data *data = elf_getdata (scn, NULL);
2046 /* Get the symbol table information. */
2047 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2048 GElf_Shdr symshdr_mem;
2049 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2050 Elf_Data *symdata = elf_getdata (symscn, NULL);
2052 /* Get the section header of the section the relocations are for. */
2053 GElf_Shdr destshdr_mem;
2054 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2057 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2059 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2064 /* Search for the optional extended section index table. */
2065 Elf_Data *xndxdata = NULL;
2066 int xndxscnidx = elf_scnshndx (scn);
2067 if (unlikely (xndxscnidx > 0))
2068 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2070 /* Get the section header string table index. */
2072 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2073 error (EXIT_FAILURE, 0,
2074 gettext ("cannot get section header string table index"));
2076 if (shdr->sh_info != 0)
2077 printf (ngettext ("\
2078 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2080 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2083 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2084 (unsigned int) shdr->sh_info,
2085 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2089 /* The .rela.dyn section does not refer to a specific section but
2090 instead of section index zero. Do not try to print a section
2092 printf (ngettext ("\
2093 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2095 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2097 (unsigned int) elf_ndxscn (scn),
2098 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2101 fputs_unlocked (class == ELFCLASS32
2103 Offset Type Value Addend Name\n")
2105 Offset Type Value Addend Name\n"),
2108 int is_statically_linked = 0;
2109 for (int cnt = 0; cnt < nentries; ++cnt)
2112 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2113 if (likely (rel != NULL))
2118 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2119 GELF_R_SYM (rel->r_info),
2122 if (unlikely (sym == NULL))
2124 /* As a special case we have to handle relocations in static
2125 executables. This only happens for IRELATIVE relocations
2126 (so far). There is no symbol table. */
2127 if (is_statically_linked == 0)
2129 /* Find the program header and look for a PT_INTERP entry. */
2130 is_statically_linked = -1;
2131 if (ehdr->e_type == ET_EXEC)
2133 is_statically_linked = 1;
2135 for (size_t inner = 0; inner < phnum; ++inner)
2138 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2140 if (phdr != NULL && phdr->p_type == PT_INTERP)
2142 is_statically_linked = -1;
2149 if (is_statically_linked > 0 && shdr->sh_link == 0)
2151 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2152 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2153 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2154 /* Avoid the leading R_ which isn't carrying any
2156 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2157 buf, sizeof (buf)) + 2
2158 : gettext ("<INVALID RELOC>"),
2159 class == ELFCLASS32 ? 10 : 18, "",
2161 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2163 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2164 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2165 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2166 /* Avoid the leading R_ which isn't carrying any
2168 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2169 buf, sizeof (buf)) + 2
2170 : gettext ("<INVALID RELOC>"),
2171 gettext ("INVALID SYMBOL"),
2172 (long int) GELF_R_SYM (rel->r_info));
2174 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2176 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2177 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2178 likely (ebl_reloc_type_check (ebl,
2179 GELF_R_TYPE (rel->r_info)))
2180 /* Avoid the leading R_ which isn't carrying any
2182 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2183 buf, sizeof (buf)) + 2
2184 : gettext ("<INVALID RELOC>"),
2185 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2187 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2190 /* This is a relocation against a STT_SECTION symbol. */
2191 GElf_Shdr secshdr_mem;
2193 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2194 sym->st_shndx == SHN_XINDEX
2195 ? xndx : sym->st_shndx),
2198 if (unlikely (secshdr == NULL))
2199 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2200 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2201 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2202 /* Avoid the leading R_ which isn't carrying any
2204 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2205 buf, sizeof (buf)) + 2
2206 : gettext ("<INVALID RELOC>"),
2207 gettext ("INVALID SECTION"),
2208 (long int) (sym->st_shndx == SHN_XINDEX
2209 ? xndx : sym->st_shndx));
2212 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2213 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2214 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2215 /* Avoid the leading R_ which isn't carrying any
2217 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2218 buf, sizeof (buf)) + 2
2219 : gettext ("<INVALID RELOC>"),
2220 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2222 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2229 /* Print the program header. */
2231 print_symtab (Ebl *ebl, int type)
2233 /* Find the symbol table(s). For this we have to search through the
2235 Elf_Scn *scn = NULL;
2237 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2239 /* Handle the section if it is a symbol table. */
2241 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2243 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2245 if (symbol_table_section != NULL)
2247 /* Get the section header string table index. */
2250 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2251 error (EXIT_FAILURE, 0,
2252 gettext ("cannot get section header string table index"));
2253 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2254 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2258 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2260 if (elf_compress (scn, 0, 0) < 0)
2261 printf ("WARNING: %s [%zd]\n",
2262 gettext ("Couldn't uncompress section"),
2264 shdr = gelf_getshdr (scn, &shdr_mem);
2265 if (unlikely (shdr == NULL))
2266 error (EXIT_FAILURE, 0,
2267 gettext ("cannot get section [%zd] header: %s"),
2268 elf_ndxscn (scn), elf_errmsg (-1));
2270 handle_symtab (ebl, scn, shdr);
2277 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2279 Elf_Data *versym_data = NULL;
2280 Elf_Data *verneed_data = NULL;
2281 Elf_Data *verdef_data = NULL;
2282 Elf_Data *xndx_data = NULL;
2283 int class = gelf_getclass (ebl->elf);
2284 Elf32_Word verneed_stridx = 0;
2285 Elf32_Word verdef_stridx = 0;
2287 /* Get the data of the section. */
2288 Elf_Data *data = elf_getdata (scn, NULL);
2292 /* Find out whether we have other sections we might need. */
2293 Elf_Scn *runscn = NULL;
2294 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2296 GElf_Shdr runshdr_mem;
2297 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2299 if (likely (runshdr != NULL))
2301 if (runshdr->sh_type == SHT_GNU_versym
2302 && runshdr->sh_link == elf_ndxscn (scn))
2303 /* Bingo, found the version information. Now get the data. */
2304 versym_data = elf_getdata (runscn, NULL);
2305 else if (runshdr->sh_type == SHT_GNU_verneed)
2307 /* This is the information about the needed versions. */
2308 verneed_data = elf_getdata (runscn, NULL);
2309 verneed_stridx = runshdr->sh_link;
2311 else if (runshdr->sh_type == SHT_GNU_verdef)
2313 /* This is the information about the defined versions. */
2314 verdef_data = elf_getdata (runscn, NULL);
2315 verdef_stridx = runshdr->sh_link;
2317 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2318 && runshdr->sh_link == elf_ndxscn (scn))
2319 /* Extended section index. */
2320 xndx_data = elf_getdata (runscn, NULL);
2324 /* Get the section header string table index. */
2326 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2327 error (EXIT_FAILURE, 0,
2328 gettext ("cannot get section header string table index"));
2330 GElf_Shdr glink_mem;
2331 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2334 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2337 /* Now we can compute the number of entries in the section. */
2338 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2339 ? sizeof (Elf32_Sym)
2340 : sizeof (Elf64_Sym));
2342 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2343 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2345 (unsigned int) elf_ndxscn (scn),
2346 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2347 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2348 " %lu local symbols String table: [%2u] '%s'\n",
2350 (unsigned long int) shdr->sh_info,
2351 (unsigned int) shdr->sh_link,
2352 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2354 fputs_unlocked (class == ELFCLASS32
2356 Num: Value Size Type Bind Vis Ndx Name\n")
2358 Num: Value Size Type Bind Vis Ndx Name\n"),
2361 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2368 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2370 if (unlikely (sym == NULL))
2373 /* Determine the real section index. */
2374 if (likely (sym->st_shndx != SHN_XINDEX))
2375 xndx = sym->st_shndx;
2378 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2380 class == ELFCLASS32 ? 8 : 16,
2383 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2384 typebuf, sizeof (typebuf)),
2385 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2386 bindbuf, sizeof (bindbuf)),
2387 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2388 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2389 sizeof (scnbuf), NULL, shnum),
2390 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2392 if (versym_data != NULL)
2394 /* Get the version information. */
2395 GElf_Versym versym_mem;
2396 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2398 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2400 bool is_nobits = false;
2401 bool check_def = xndx != SHN_UNDEF;
2403 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2405 GElf_Shdr symshdr_mem;
2406 GElf_Shdr *symshdr =
2407 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2409 is_nobits = (symshdr != NULL
2410 && symshdr->sh_type == SHT_NOBITS);
2413 if (is_nobits || ! check_def)
2415 /* We must test both. */
2416 GElf_Vernaux vernaux_mem;
2417 GElf_Vernaux *vernaux = NULL;
2418 size_t vn_offset = 0;
2420 GElf_Verneed verneed_mem;
2421 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2423 while (verneed != NULL)
2425 size_t vna_offset = vn_offset;
2427 vernaux = gelf_getvernaux (verneed_data,
2428 vna_offset += verneed->vn_aux,
2430 while (vernaux != NULL
2431 && vernaux->vna_other != *versym
2432 && vernaux->vna_next != 0)
2434 /* Update the offset. */
2435 vna_offset += vernaux->vna_next;
2437 vernaux = (vernaux->vna_next == 0
2439 : gelf_getvernaux (verneed_data,
2444 /* Check whether we found the version. */
2445 if (vernaux != NULL && vernaux->vna_other == *versym)
2449 vn_offset += verneed->vn_next;
2450 verneed = (verneed->vn_next == 0
2452 : gelf_getverneed (verneed_data, vn_offset,
2456 if (vernaux != NULL && vernaux->vna_other == *versym)
2459 elf_strptr (ebl->elf, verneed_stridx,
2461 (unsigned int) vernaux->vna_other);
2464 else if (unlikely (! is_nobits))
2465 error (0, 0, gettext ("bad dynamic symbol"));
2470 if (check_def && *versym != 0x8001)
2472 /* We must test both. */
2473 size_t vd_offset = 0;
2475 GElf_Verdef verdef_mem;
2476 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2478 while (verdef != NULL)
2480 if (verdef->vd_ndx == (*versym & 0x7fff))
2481 /* Found the definition. */
2484 vd_offset += verdef->vd_next;
2485 verdef = (verdef->vd_next == 0
2487 : gelf_getverdef (verdef_data, vd_offset,
2493 GElf_Verdaux verdaux_mem;
2494 GElf_Verdaux *verdaux
2495 = gelf_getverdaux (verdef_data,
2496 vd_offset + verdef->vd_aux,
2499 if (verdaux != NULL)
2500 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2501 elf_strptr (ebl->elf, verdef_stridx,
2502 verdaux->vda_name));
2508 putchar_unlocked ('\n');
2513 /* Print version information. */
2515 print_verinfo (Ebl *ebl)
2517 /* Find the version information sections. For this we have to
2518 search through the section table. */
2519 Elf_Scn *scn = NULL;
2521 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2523 /* Handle the section if it is part of the versioning handling. */
2525 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2527 if (likely (shdr != NULL))
2529 if (shdr->sh_type == SHT_GNU_verneed)
2530 handle_verneed (ebl, scn, shdr);
2531 else if (shdr->sh_type == SHT_GNU_verdef)
2532 handle_verdef (ebl, scn, shdr);
2533 else if (shdr->sh_type == SHT_GNU_versym)
2534 handle_versym (ebl, scn, shdr);
2541 get_ver_flags (unsigned int flags)
2543 static char buf[32];
2547 return gettext ("none");
2549 if (flags & VER_FLG_BASE)
2550 endp = stpcpy (buf, "BASE ");
2554 if (flags & VER_FLG_WEAK)
2557 endp = stpcpy (endp, "| ");
2559 endp = stpcpy (endp, "WEAK ");
2562 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2564 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2565 buf[sizeof (buf) - 1] = '\0';
2573 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2575 int class = gelf_getclass (ebl->elf);
2577 /* Get the data of the section. */
2578 Elf_Data *data = elf_getdata (scn, NULL);
2582 /* Get the section header string table index. */
2584 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2585 error (EXIT_FAILURE, 0,
2586 gettext ("cannot get section header string table index"));
2588 GElf_Shdr glink_mem;
2589 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2592 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2595 printf (ngettext ("\
2596 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2598 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2600 (unsigned int) elf_ndxscn (scn),
2601 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2602 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2604 (unsigned int) shdr->sh_link,
2605 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2607 unsigned int offset = 0;
2608 for (int cnt = shdr->sh_info; --cnt >= 0; )
2610 /* Get the data at the next offset. */
2611 GElf_Verneed needmem;
2612 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2613 if (unlikely (need == NULL))
2616 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2617 offset, (unsigned short int) need->vn_version,
2618 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2619 (unsigned short int) need->vn_cnt);
2621 unsigned int auxoffset = offset + need->vn_aux;
2622 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2624 GElf_Vernaux auxmem;
2625 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2626 if (unlikely (aux == NULL))
2629 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2631 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2632 get_ver_flags (aux->vna_flags),
2633 (unsigned short int) aux->vna_other);
2635 if (aux->vna_next == 0)
2638 auxoffset += aux->vna_next;
2641 /* Find the next offset. */
2642 if (need->vn_next == 0)
2645 offset += need->vn_next;
2651 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2653 /* Get the data of the section. */
2654 Elf_Data *data = elf_getdata (scn, NULL);
2658 /* Get the section header string table index. */
2660 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2661 error (EXIT_FAILURE, 0,
2662 gettext ("cannot get section header string table index"));
2664 GElf_Shdr glink_mem;
2665 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2668 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2671 int class = gelf_getclass (ebl->elf);
2672 printf (ngettext ("\
2673 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2675 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2677 (unsigned int) elf_ndxscn (scn),
2678 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2680 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2682 (unsigned int) shdr->sh_link,
2683 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2685 unsigned int offset = 0;
2686 for (int cnt = shdr->sh_info; --cnt >= 0; )
2688 /* Get the data at the next offset. */
2690 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2691 if (unlikely (def == NULL))
2694 unsigned int auxoffset = offset + def->vd_aux;
2695 GElf_Verdaux auxmem;
2696 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2697 if (unlikely (aux == NULL))
2701 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2702 offset, def->vd_version,
2703 get_ver_flags (def->vd_flags),
2706 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2708 auxoffset += aux->vda_next;
2709 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2711 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2712 if (unlikely (aux == NULL))
2715 printf (gettext (" %#06x: Parent %d: %s\n"),
2717 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2719 if (aux->vda_next == 0)
2722 auxoffset += aux->vda_next;
2725 /* Find the next offset. */
2726 if (def->vd_next == 0)
2728 offset += def->vd_next;
2734 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2736 int class = gelf_getclass (ebl->elf);
2737 const char **vername;
2738 const char **filename;
2740 /* Get the data of the section. */
2741 Elf_Data *data = elf_getdata (scn, NULL);
2745 /* Get the section header string table index. */
2747 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2748 error (EXIT_FAILURE, 0,
2749 gettext ("cannot get section header string table index"));
2751 /* We have to find the version definition section and extract the
2753 Elf_Scn *defscn = NULL;
2754 Elf_Scn *needscn = NULL;
2756 Elf_Scn *verscn = NULL;
2757 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2759 GElf_Shdr vershdr_mem;
2760 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2762 if (likely (vershdr != NULL))
2764 if (vershdr->sh_type == SHT_GNU_verdef)
2766 else if (vershdr->sh_type == SHT_GNU_verneed)
2772 if (defscn != NULL || needscn != NULL)
2774 /* We have a version information (better should have). Now get
2775 the version names. First find the maximum version number. */
2779 /* Run through the version definitions and find the highest
2781 unsigned int offset = 0;
2783 GElf_Shdr defshdrmem;
2786 defdata = elf_getdata (defscn, NULL);
2787 if (unlikely (defdata == NULL))
2790 defshdr = gelf_getshdr (defscn, &defshdrmem);
2791 if (unlikely (defshdr == NULL))
2794 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2799 /* Get the data at the next offset. */
2800 def = gelf_getverdef (defdata, offset, &defmem);
2801 if (unlikely (def == NULL))
2804 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2806 if (def->vd_next == 0)
2808 offset += def->vd_next;
2811 if (needscn != NULL)
2813 unsigned int offset = 0;
2815 GElf_Shdr needshdrmem;
2816 GElf_Shdr *needshdr;
2818 needdata = elf_getdata (needscn, NULL);
2819 if (unlikely (needdata == NULL))
2822 needshdr = gelf_getshdr (needscn, &needshdrmem);
2823 if (unlikely (needshdr == NULL))
2826 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2828 GElf_Verneed needmem;
2830 unsigned int auxoffset;
2833 /* Get the data at the next offset. */
2834 need = gelf_getverneed (needdata, offset, &needmem);
2835 if (unlikely (need == NULL))
2838 /* Run through the auxiliary entries. */
2839 auxoffset = offset + need->vn_aux;
2840 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2842 GElf_Vernaux auxmem;
2845 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2846 if (unlikely (aux == NULL))
2849 nvername = MAX (nvername,
2850 (size_t) (aux->vna_other & 0x7fff));
2852 if (aux->vna_next == 0)
2854 auxoffset += aux->vna_next;
2857 if (need->vn_next == 0)
2859 offset += need->vn_next;
2863 /* This is the number of versions we know about. */
2866 /* Allocate the array. */
2867 vername = (const char **) alloca (nvername * sizeof (const char *));
2868 memset(vername, 0, nvername * sizeof (const char *));
2869 filename = (const char **) alloca (nvername * sizeof (const char *));
2870 memset(filename, 0, nvername * sizeof (const char *));
2872 /* Run through the data structures again and collect the strings. */
2875 /* Run through the version definitions and find the highest
2877 unsigned int offset = 0;
2879 GElf_Shdr defshdrmem;
2882 defdata = elf_getdata (defscn, NULL);
2883 if (unlikely (defdata == NULL))
2886 defshdr = gelf_getshdr (defscn, &defshdrmem);
2887 if (unlikely (defshdr == NULL))
2890 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2893 /* Get the data at the next offset. */
2895 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2896 if (unlikely (def == NULL))
2899 GElf_Verdaux auxmem;
2900 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2901 offset + def->vd_aux,
2903 if (unlikely (aux == NULL))
2906 vername[def->vd_ndx & 0x7fff]
2907 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2908 filename[def->vd_ndx & 0x7fff] = NULL;
2910 if (def->vd_next == 0)
2912 offset += def->vd_next;
2915 if (needscn != NULL)
2917 unsigned int offset = 0;
2919 Elf_Data *needdata = elf_getdata (needscn, NULL);
2920 GElf_Shdr needshdrmem;
2921 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2922 if (unlikely (needdata == NULL || needshdr == NULL))
2925 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2927 /* Get the data at the next offset. */
2928 GElf_Verneed needmem;
2929 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2931 if (unlikely (need == NULL))
2934 /* Run through the auxiliary entries. */
2935 unsigned int auxoffset = offset + need->vn_aux;
2936 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2938 GElf_Vernaux auxmem;
2939 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2941 if (unlikely (aux == NULL))
2944 vername[aux->vna_other & 0x7fff]
2945 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2946 filename[aux->vna_other & 0x7fff]
2947 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2949 if (aux->vna_next == 0)
2951 auxoffset += aux->vna_next;
2954 if (need->vn_next == 0)
2956 offset += need->vn_next;
2967 GElf_Shdr glink_mem;
2968 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2970 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2972 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2975 /* Print the header. */
2976 printf (ngettext ("\
2977 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2979 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2980 shdr->sh_size / sh_entsize),
2981 (unsigned int) elf_ndxscn (scn),
2982 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2983 (int) (shdr->sh_size / sh_entsize),
2984 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2986 (unsigned int) shdr->sh_link,
2987 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2989 /* Now we can finally look at the actual contents of this section. */
2990 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2993 printf ("\n %4d:", cnt);
2996 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3004 fputs_unlocked (gettext (" 0 *local* "),
3009 fputs_unlocked (gettext (" 1 *global* "),
3014 n = printf ("%4d%c%s",
3015 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3017 && (unsigned int) (*sym & 0x7fff) < nvername)
3018 ? vername[*sym & 0x7fff] : "???");
3019 if ((unsigned int) (*sym & 0x7fff) < nvername
3020 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3021 n += printf ("(%s)", filename[*sym & 0x7fff]);
3022 printf ("%*s", MAX (0, 33 - (int) n), " ");
3026 putchar_unlocked ('\n');
3031 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3032 uint_fast32_t maxlength, Elf32_Word nbucket,
3033 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3035 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3037 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3038 ++counts[lengths[cnt]];
3040 GElf_Shdr glink_mem;
3041 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3046 error (0, 0, gettext ("invalid sh_link value in section %zu"),
3051 printf (ngettext ("\
3052 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3054 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3056 (unsigned int) elf_ndxscn (scn),
3057 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3059 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3062 (unsigned int) shdr->sh_link,
3063 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3065 if (extrastr != NULL)
3066 fputs (extrastr, stdout);
3068 if (likely (nbucket > 0))
3070 uint64_t success = 0;
3072 /* xgettext:no-c-format */
3073 fputs_unlocked (gettext ("\
3074 Length Number % of total Coverage\n"), stdout);
3075 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
3076 counts[0], (counts[0] * 100.0) / nbucket);
3078 uint64_t nzero_counts = 0;
3079 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3081 nzero_counts += counts[cnt] * cnt;
3083 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3084 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3085 (nzero_counts * 100.0) / nsyms);
3089 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3092 success += counts[cnt] * acc;
3096 Average number of tests: successful lookup: %f\n\
3097 unsuccessful lookup: %f\n"),
3098 (double) success / (double) nzero_counts,
3099 (double) nzero_counts / (double) nbucket);
3106 /* This function handles the traditional System V-style hash table format. */
3108 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3110 Elf_Data *data = elf_getdata (scn, NULL);
3111 if (unlikely (data == NULL))
3113 error (0, 0, gettext ("cannot get data for section %d: %s"),
3114 (int) elf_ndxscn (scn), elf_errmsg (-1));
3118 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3121 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3122 (int) elf_ndxscn (scn));
3126 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3127 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3129 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3130 if (used_buf > data->d_size)
3133 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3134 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3136 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3138 uint_fast32_t maxlength = 0;
3139 uint_fast32_t nsyms = 0;
3140 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3142 Elf32_Word inner = bucket[cnt];
3143 while (inner > 0 && inner < nchain)
3146 if (maxlength < ++lengths[cnt])
3149 inner = chain[inner];
3153 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3160 /* This function handles the incorrect, System V-style hash table
3161 format some 64-bit architectures use. */
3163 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3165 Elf_Data *data = elf_getdata (scn, NULL);
3166 if (unlikely (data == NULL))
3168 error (0, 0, gettext ("cannot get data for section %d: %s"),
3169 (int) elf_ndxscn (scn), elf_errmsg (-1));
3173 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3176 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3177 (int) elf_ndxscn (scn));
3181 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3182 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3184 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3186 || maxwords - 2 < nbucket
3187 || maxwords - 2 - nbucket < nchain)
3190 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3191 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3193 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3195 uint_fast32_t maxlength = 0;
3196 uint_fast32_t nsyms = 0;
3197 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3199 Elf64_Xword inner = bucket[cnt];
3200 while (inner > 0 && inner < nchain)
3203 if (maxlength < ++lengths[cnt])
3206 inner = chain[inner];
3210 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3217 /* This function handles the GNU-style hash table format. */
3219 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3221 uint32_t *lengths = NULL;
3222 Elf_Data *data = elf_getdata (scn, NULL);
3223 if (unlikely (data == NULL))
3225 error (0, 0, gettext ("cannot get data for section %d: %s"),
3226 (int) elf_ndxscn (scn), elf_errmsg (-1));
3230 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3234 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3235 (int) elf_ndxscn (scn));
3239 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3240 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3242 /* Next comes the size of the bitmap. It's measured in words for
3243 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3244 64 bit archs. There is always a bloom filter present, so zero is
3245 an invalid value. */
3246 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3247 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3250 if (bitmask_words == 0)
3253 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3255 /* Is there still room for the sym chain?
3256 Use uint64_t calculation to prevent 32bit overlow. */
3257 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3258 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3259 if (used_buf > data->d_size)
3262 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3264 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3265 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3266 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3269 /* Compute distribution of chain lengths. */
3270 uint_fast32_t maxlength = 0;
3271 uint_fast32_t nsyms = 0;
3272 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3273 if (bucket[cnt] != 0)
3275 Elf32_Word inner = bucket[cnt] - symbias;
3279 if (maxlength < ++lengths[cnt])
3281 if (inner >= max_nsyms)
3284 while ((chain[inner++] & 1) == 0);
3287 /* Count bits in bitmask. */
3288 uint_fast32_t nbits = 0;
3289 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3291 uint_fast32_t word = bitmask[cnt];
3293 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3294 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3295 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3296 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3297 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3301 if (unlikely (asprintf (&str, gettext ("\
3303 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3304 (unsigned int) symbias,
3305 bitmask_words * sizeof (Elf32_Word),
3307 / (uint_fast32_t) (bitmask_words
3308 * sizeof (Elf32_Word) * 8)),
3309 (unsigned int) shift) == -1))
3310 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3312 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3320 /* Find the symbol table(s). For this we have to search through the
3323 handle_hash (Ebl *ebl)
3325 /* Get the section header string table index. */
3327 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3328 error (EXIT_FAILURE, 0,
3329 gettext ("cannot get section header string table index"));
3331 Elf_Scn *scn = NULL;
3332 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3334 /* Handle the section if it is a symbol table. */
3336 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3338 if (likely (shdr != NULL))
3340 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3341 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3343 if (elf_compress (scn, 0, 0) < 0)
3344 printf ("WARNING: %s [%zd]\n",
3345 gettext ("Couldn't uncompress section"),
3347 shdr = gelf_getshdr (scn, &shdr_mem);
3348 if (unlikely (shdr == NULL))
3349 error (EXIT_FAILURE, 0,
3350 gettext ("cannot get section [%zd] header: %s"),
3351 elf_ndxscn (scn), elf_errmsg (-1));
3354 if (shdr->sh_type == SHT_HASH)
3356 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3357 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3359 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3361 else if (shdr->sh_type == SHT_GNU_HASH)
3362 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3369 print_liblist (Ebl *ebl)
3371 /* Find the library list sections. For this we have to search
3372 through the section table. */
3373 Elf_Scn *scn = NULL;
3375 /* Get the section header string table index. */
3377 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3378 error (EXIT_FAILURE, 0,
3379 gettext ("cannot get section header string table index"));
3381 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3384 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3386 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3388 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3389 int nentries = shdr->sh_size / sh_entsize;
3390 printf (ngettext ("\
3391 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3393 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3396 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3400 Elf_Data *data = elf_getdata (scn, NULL);
3405 Library Time Stamp Checksum Version Flags"));
3407 for (int cnt = 0; cnt < nentries; ++cnt)
3410 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3411 if (unlikely (lib == NULL))
3414 time_t t = (time_t) lib->l_time_stamp;
3415 struct tm *tm = gmtime (&t);
3416 if (unlikely (tm == NULL))
3419 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3420 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3421 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3422 tm->tm_hour, tm->tm_min, tm->tm_sec,
3423 (unsigned int) lib->l_checksum,
3424 (unsigned int) lib->l_version,
3425 (unsigned int) lib->l_flags);
3432 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3434 /* Find the object attributes sections. For this we have to search
3435 through the section table. */
3436 Elf_Scn *scn = NULL;
3438 /* Get the section header string table index. */
3440 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3441 error (EXIT_FAILURE, 0,
3442 gettext ("cannot get section header string table index"));
3444 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3447 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3449 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3450 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3451 || ehdr->e_machine != EM_ARM)))
3455 \nObject attributes section [%2zu] '%s' of %" PRIu64
3456 " bytes at offset %#0" PRIx64 ":\n"),
3458 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3459 shdr->sh_size, shdr->sh_offset);
3461 Elf_Data *data = elf_rawdata (scn, NULL);
3462 if (unlikely (data == NULL || data->d_size == 0))
3465 const unsigned char *p = data->d_buf;
3467 /* There is only one 'version', A. */
3468 if (unlikely (*p++ != 'A'))
3471 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3473 inline size_t left (void)
3475 return (const unsigned char *) data->d_buf + data->d_size - p;
3478 /* Loop over the sections. */
3479 while (left () >= 4)
3481 /* Section length. */
3483 memcpy (&len, p, sizeof len);
3485 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3488 if (unlikely (len > left ()))
3491 /* Section vendor name. */
3492 const unsigned char *name = p + sizeof len;
3495 unsigned const char *q = memchr (name, '\0', len);
3496 if (unlikely (q == NULL))
3500 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3502 bool gnu_vendor = (q - name == sizeof "gnu"
3503 && !memcmp (name, "gnu", sizeof "gnu"));
3505 /* Loop over subsections. */
3506 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3510 const unsigned char *const sub = q;
3512 unsigned int subsection_tag;
3513 get_uleb128 (subsection_tag, q, p);
3514 if (unlikely (q >= p))
3517 uint32_t subsection_len;
3518 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3521 memcpy (&subsection_len, q, sizeof subsection_len);
3523 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3524 CONVERT (subsection_len);
3526 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3527 if (unlikely (subsection_len == 0
3528 || subsection_len >= (uint32_t) PTRDIFF_MAX
3529 || p - sub < (ptrdiff_t) subsection_len))
3532 const unsigned char *r = q + sizeof subsection_len;
3533 q = sub + subsection_len;
3535 switch (subsection_tag)
3538 /* Unknown subsection, print and skip. */
3539 printf (gettext (" %-4u %12" PRIu32 "\n"),
3540 subsection_tag, subsection_len);
3543 case 1: /* Tag_File */
3544 printf (gettext (" File: %11" PRIu32 "\n"),
3550 get_uleb128 (tag, r, q);
3551 if (unlikely (r >= q))
3554 /* GNU style tags have either a uleb128 value,
3555 when lowest bit is not set, or a string
3556 when the lowest bit is set.
3557 "compatibility" (32) is special. It has
3558 both a string and a uleb128 value. For
3559 non-gnu we assume 6 till 31 only take ints.
3560 XXX see arm backend, do we need a separate
3563 const char *string = NULL;
3564 if (tag == 32 || (tag & 1) == 0
3565 || (! gnu_vendor && (tag > 5 && tag < 32)))
3567 get_uleb128 (value, r, q);
3574 || (! gnu_vendor && tag > 32)))
3575 || (! gnu_vendor && tag > 3 && tag < 6))
3577 string = (const char *) r;
3578 r = memchr (r, '\0', q - r);
3584 const char *tag_name = NULL;
3585 const char *value_name = NULL;
3586 ebl_check_object_attribute (ebl, (const char *) name,
3588 &tag_name, &value_name);
3590 if (tag_name != NULL)
3593 printf (gettext (" %s: %" PRId64 ", %s\n"),
3594 tag_name, value, string);
3595 else if (string == NULL && value_name == NULL)
3596 printf (gettext (" %s: %" PRId64 "\n"),
3599 printf (gettext (" %s: %s\n"),
3600 tag_name, string ?: value_name);
3604 /* For "gnu" vendor 32 "compatibility" has
3605 already been handled above. */
3607 || strcmp ((const char *) name, "gnu"));
3609 printf (gettext (" %u: %" PRId64 "\n"),
3612 printf (gettext (" %u: %s\n"),
3624 format_dwarf_addr (Dwfl_Module *dwflmod,
3625 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3627 /* See if there is a name we can give for this address. */
3630 const char *name = (print_address_names && ! print_unresolved_addresses)
3631 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3635 if (print_unresolved_addresses)
3642 /* Relativize the address. */
3643 int n = dwfl_module_relocations (dwflmod);
3644 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3646 /* In an ET_REL file there is a section name to refer to. */
3648 : dwfl_module_relocation_info (dwflmod, i, NULL));
3655 ? (address_size == 0
3656 ? asprintf (&result,
3657 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3658 scn, address, name, off)
3659 : asprintf (&result,
3660 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3661 scn, 2 + address_size * 2, address,
3663 : (address_size == 0
3664 ? asprintf (&result,
3665 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3667 : asprintf (&result,
3668 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3669 2 + address_size * 2, address,
3672 ? (address_size == 0
3673 ? asprintf (&result,
3674 gettext ("%s+%#" PRIx64 " <%s>"),
3676 : asprintf (&result,
3677 gettext ("%s+%#0*" PRIx64 " <%s>"),
3678 scn, 2 + address_size * 2, address, name))
3679 : (address_size == 0
3680 ? asprintf (&result,
3681 gettext ("%#" PRIx64 " <%s>"),
3683 : asprintf (&result,
3684 gettext ("%#0*" PRIx64 " <%s>"),
3685 2 + address_size * 2, address, name))))
3687 ? (address_size == 0
3688 ? asprintf (&result,
3689 gettext ("%s+%#" PRIx64),
3691 : asprintf (&result,
3692 gettext ("%s+%#0*" PRIx64),
3693 scn, 2 + address_size * 2, address))
3694 : (address_size == 0
3695 ? asprintf (&result,
3698 : asprintf (&result,
3700 2 + address_size * 2, address)))) < 0)
3701 error (EXIT_FAILURE, 0, _("memory exhausted"));
3707 dwarf_tag_string (unsigned int tag)
3711 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3712 DWARF_ALL_KNOWN_DW_TAG
3713 #undef DWARF_ONE_KNOWN_DW_TAG
3721 dwarf_attr_string (unsigned int attrnum)
3725 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3726 DWARF_ALL_KNOWN_DW_AT
3727 #undef DWARF_ONE_KNOWN_DW_AT
3735 dwarf_form_string (unsigned int form)
3739 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3740 DWARF_ALL_KNOWN_DW_FORM
3741 #undef DWARF_ONE_KNOWN_DW_FORM
3749 dwarf_lang_string (unsigned int lang)
3753 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3754 DWARF_ALL_KNOWN_DW_LANG
3755 #undef DWARF_ONE_KNOWN_DW_LANG
3763 dwarf_inline_string (unsigned int code)
3765 static const char *const known[] =
3767 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3768 DWARF_ALL_KNOWN_DW_INL
3769 #undef DWARF_ONE_KNOWN_DW_INL
3772 if (likely (code < sizeof (known) / sizeof (known[0])))
3780 dwarf_encoding_string (unsigned int code)
3782 static const char *const known[] =
3784 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3785 DWARF_ALL_KNOWN_DW_ATE
3786 #undef DWARF_ONE_KNOWN_DW_ATE
3789 if (likely (code < sizeof (known) / sizeof (known[0])))
3797 dwarf_access_string (unsigned int code)
3799 static const char *const known[] =
3801 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3802 DWARF_ALL_KNOWN_DW_ACCESS
3803 #undef DWARF_ONE_KNOWN_DW_ACCESS
3806 if (likely (code < sizeof (known) / sizeof (known[0])))
3814 dwarf_defaulted_string (unsigned int code)
3816 static const char *const known[] =
3818 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3819 DWARF_ALL_KNOWN_DW_DEFAULTED
3820 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3823 if (likely (code < sizeof (known) / sizeof (known[0])))
3831 dwarf_visibility_string (unsigned int code)
3833 static const char *const known[] =
3835 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3836 DWARF_ALL_KNOWN_DW_VIS
3837 #undef DWARF_ONE_KNOWN_DW_VIS
3840 if (likely (code < sizeof (known) / sizeof (known[0])))
3848 dwarf_virtuality_string (unsigned int code)
3850 static const char *const known[] =
3852 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3853 DWARF_ALL_KNOWN_DW_VIRTUALITY
3854 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3857 if (likely (code < sizeof (known) / sizeof (known[0])))
3865 dwarf_identifier_case_string (unsigned int code)
3867 static const char *const known[] =
3869 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3870 DWARF_ALL_KNOWN_DW_ID
3871 #undef DWARF_ONE_KNOWN_DW_ID
3874 if (likely (code < sizeof (known) / sizeof (known[0])))
3882 dwarf_calling_convention_string (unsigned int code)
3884 static const char *const known[] =
3886 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3887 DWARF_ALL_KNOWN_DW_CC
3888 #undef DWARF_ONE_KNOWN_DW_CC
3891 if (likely (code < sizeof (known) / sizeof (known[0])))
3899 dwarf_ordering_string (unsigned int code)
3901 static const char *const known[] =
3903 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3904 DWARF_ALL_KNOWN_DW_ORD
3905 #undef DWARF_ONE_KNOWN_DW_ORD
3908 if (likely (code < sizeof (known) / sizeof (known[0])))
3916 dwarf_discr_list_string (unsigned int code)
3918 static const char *const known[] =
3920 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3921 DWARF_ALL_KNOWN_DW_DSC
3922 #undef DWARF_ONE_KNOWN_DW_DSC
3925 if (likely (code < sizeof (known) / sizeof (known[0])))
3933 dwarf_locexpr_opcode_string (unsigned int code)
3935 static const char *const known[] =
3937 /* Normally we can't affort building huge table of 64K entries,
3938 most of them zero, just because there are a couple defined
3939 values at the far end. In case of opcodes, it's OK. */
3940 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3941 DWARF_ALL_KNOWN_DW_OP
3942 #undef DWARF_ONE_KNOWN_DW_OP
3945 if (likely (code < sizeof (known) / sizeof (known[0])))
3952 /* Used by all dwarf_foo_name functions. */
3954 string_or_unknown (const char *known, unsigned int code,
3955 unsigned int lo_user, unsigned int hi_user,
3956 bool print_unknown_num)
3958 static char unknown_buf[20];
3960 if (likely (known != NULL))
3963 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3965 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3970 if (print_unknown_num)
3972 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3981 dwarf_tag_name (unsigned int tag)
3983 const char *ret = dwarf_tag_string (tag);
3984 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3988 dwarf_attr_name (unsigned int attr)
3990 const char *ret = dwarf_attr_string (attr);
3991 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3996 dwarf_form_name (unsigned int form)
3998 const char *ret = dwarf_form_string (form);
3999 return string_or_unknown (ret, form, 0, 0, true);
4004 dwarf_lang_name (unsigned int lang)
4006 const char *ret = dwarf_lang_string (lang);
4007 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4012 dwarf_inline_name (unsigned int code)
4014 const char *ret = dwarf_inline_string (code);
4015 return string_or_unknown (ret, code, 0, 0, false);
4020 dwarf_encoding_name (unsigned int code)
4022 const char *ret = dwarf_encoding_string (code);
4023 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4028 dwarf_access_name (unsigned int code)
4030 const char *ret = dwarf_access_string (code);
4031 return string_or_unknown (ret, code, 0, 0, false);
4036 dwarf_defaulted_name (unsigned int code)
4038 const char *ret = dwarf_defaulted_string (code);
4039 return string_or_unknown (ret, code, 0, 0, false);
4044 dwarf_visibility_name (unsigned int code)
4046 const char *ret = dwarf_visibility_string (code);
4047 return string_or_unknown (ret, code, 0, 0, false);
4052 dwarf_virtuality_name (unsigned int code)
4054 const char *ret = dwarf_virtuality_string (code);
4055 return string_or_unknown (ret, code, 0, 0, false);
4060 dwarf_identifier_case_name (unsigned int code)
4062 const char *ret = dwarf_identifier_case_string (code);
4063 return string_or_unknown (ret, code, 0, 0, false);
4068 dwarf_calling_convention_name (unsigned int code)
4070 const char *ret = dwarf_calling_convention_string (code);
4071 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4076 dwarf_ordering_name (unsigned int code)
4078 const char *ret = dwarf_ordering_string (code);
4079 return string_or_unknown (ret, code, 0, 0, false);
4084 dwarf_discr_list_name (unsigned int code)
4086 const char *ret = dwarf_discr_list_string (code);
4087 return string_or_unknown (ret, code, 0, 0, false);
4092 print_block (size_t n, const void *block)
4095 puts (_("empty block"));
4098 printf (_("%zu byte block:"), n);
4099 const unsigned char *data = block;
4101 printf (" %02x", *data++);
4108 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4109 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4110 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4112 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4116 printf ("%*s(empty)\n", indent, "");
4120 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4121 #define CONSUME(n) NEED (n); else len -= (n)
4123 Dwarf_Word offset = 0;
4126 uint_fast8_t op = *data++;
4128 const char *op_name = dwarf_locexpr_opcode_string (op);
4129 if (unlikely (op_name == NULL))
4131 static char buf[20];
4132 if (op >= DW_OP_lo_user)
4133 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4135 snprintf (buf, sizeof buf, "??? (%#x)", op);
4142 /* Address operand. */
4146 addr = read_4ubyte_unaligned (dbg, data);
4147 else if (addrsize == 8)
4148 addr = read_8ubyte_unaligned (dbg, data);
4154 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
4155 printf ("%*s[%4" PRIuMAX "] %s %s\n",
4156 indent, "", (uintmax_t) offset, op_name, a);
4159 offset += 1 + addrsize;
4162 case DW_OP_call_ref:
4163 case DW_OP_GNU_variable_value:
4164 /* Offset operand. */
4165 if (ref_size != 4 && ref_size != 8)
4166 goto invalid; /* Cannot be used in CFA. */
4169 addr = read_4ubyte_unaligned (dbg, data);
4171 addr = read_8ubyte_unaligned (dbg, data);
4174 /* addr is a DIE offset, so format it as one. */
4175 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4176 indent, "", (uintmax_t) offset,
4177 op_name, (uintmax_t) addr);
4178 offset += 1 + ref_size;
4181 case DW_OP_deref_size:
4182 case DW_OP_xderef_size:
4185 // XXX value might be modified by relocation
4187 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4188 indent, "", (uintmax_t) offset,
4189 op_name, *((uint8_t *) data));
4197 // XXX value might be modified by relocation
4198 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4199 indent, "", (uintmax_t) offset,
4200 op_name, read_2ubyte_unaligned (dbg, data));
4208 // XXX value might be modified by relocation
4209 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4210 indent, "", (uintmax_t) offset,
4211 op_name, read_4ubyte_unaligned (dbg, data));
4219 // XXX value might be modified by relocation
4220 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4221 indent, "", (uintmax_t) offset,
4222 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4230 // XXX value might be modified by relocation
4231 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4232 indent, "", (uintmax_t) offset,
4233 op_name, *((int8_t *) data));
4241 // XXX value might be modified by relocation
4242 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4243 indent, "", (uintmax_t) offset,
4244 op_name, read_2sbyte_unaligned (dbg, data));
4252 // XXX value might be modified by relocation
4253 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4254 indent, "", (uintmax_t) offset,
4255 op_name, read_4sbyte_unaligned (dbg, data));
4263 // XXX value might be modified by relocation
4264 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4265 indent, "", (uintmax_t) offset,
4266 op_name, read_8sbyte_unaligned (dbg, data));
4274 case DW_OP_plus_uconst:
4276 const unsigned char *start = data;
4279 get_uleb128 (uleb, data, data + len);
4280 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4281 indent, "", (uintmax_t) offset, op_name, uleb);
4282 CONSUME (data - start);
4283 offset += 1 + (data - start);
4286 case DW_OP_bit_piece:
4290 get_uleb128 (uleb, data, data + len);
4292 get_uleb128 (uleb2, data, data + len);
4293 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4294 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4295 CONSUME (data - start);
4296 offset += 1 + (data - start);
4300 case DW_OP_breg0 ... DW_OP_breg31:
4305 get_sleb128 (sleb, data, data + len);
4306 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4307 indent, "", (uintmax_t) offset, op_name, sleb);
4308 CONSUME (data - start);
4309 offset += 1 + (data - start);
4315 get_uleb128 (uleb, data, data + len);
4317 get_sleb128 (sleb, data, data + len);
4318 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4319 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4320 CONSUME (data - start);
4321 offset += 1 + (data - start);
4326 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4327 indent, "", (uintmax_t) offset, op_name,
4328 read_2ubyte_unaligned (dbg, data));
4335 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4336 indent, "", (uintmax_t) offset, op_name,
4337 read_4ubyte_unaligned (dbg, data));
4345 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4346 indent, "", (uintmax_t) offset, op_name,
4347 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4353 case DW_OP_implicit_value:
4356 get_uleb128 (uleb, data, data + len);
4357 printf ("%*s[%4" PRIuMAX "] %s: ",
4358 indent, "", (uintmax_t) offset, op_name);
4360 print_block (uleb, data);
4362 CONSUME (data - start);
4363 offset += 1 + (data - start);
4366 case DW_OP_GNU_implicit_pointer:
4367 /* DIE offset operand. */
4370 if (ref_size != 4 && ref_size != 8)
4371 goto invalid; /* Cannot be used in CFA. */
4373 addr = read_4ubyte_unaligned (dbg, data);
4375 addr = read_8ubyte_unaligned (dbg, data);
4377 /* Byte offset operand. */
4379 get_sleb128 (sleb, data, data + len);
4381 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4382 indent, "", (intmax_t) offset,
4383 op_name, (uintmax_t) addr, sleb);
4384 CONSUME (data - start);
4385 offset += 1 + (data - start);
4388 case DW_OP_GNU_entry_value:
4389 /* Size plus expression block. */
4392 get_uleb128 (uleb, data, data + len);
4393 printf ("%*s[%4" PRIuMAX "] %s:\n",
4394 indent, "", (uintmax_t) offset, op_name);
4396 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4397 addrsize, offset_size, cu, uleb, data);
4399 CONSUME (data - start);
4400 offset += 1 + (data - start);
4403 case DW_OP_GNU_const_type:
4404 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4405 unsigned size plus block. */
4408 get_uleb128 (uleb, data, data + len);
4409 if (! print_unresolved_addresses && cu != NULL)
4412 uint8_t usize = *(uint8_t *) data++;
4414 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4415 indent, "", (uintmax_t) offset, op_name, uleb);
4416 print_block (usize, data);
4418 CONSUME (data - start);
4419 offset += 1 + (data - start);
4422 case DW_OP_GNU_regval_type:
4423 /* uleb128 register number, uleb128 CU relative
4424 DW_TAG_base_type DIE offset. */
4427 get_uleb128 (uleb, data, data + len);
4429 get_uleb128 (uleb2, data, data + len);
4430 if (! print_unresolved_addresses && cu != NULL)
4432 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4433 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4434 CONSUME (data - start);
4435 offset += 1 + (data - start);
4438 case DW_OP_GNU_deref_type:
4439 /* 1-byte unsigned size of value, uleb128 CU relative
4440 DW_TAG_base_type DIE offset. */
4443 usize = *(uint8_t *) data++;
4445 get_uleb128 (uleb, data, data + len);
4446 if (! print_unresolved_addresses && cu != NULL)
4448 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4449 indent, "", (uintmax_t) offset,
4450 op_name, usize, uleb);
4451 CONSUME (data - start);
4452 offset += 1 + (data - start);
4455 case DW_OP_GNU_convert:
4456 case DW_OP_GNU_reinterpret:
4457 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4458 for conversion to untyped. */
4461 get_uleb128 (uleb, data, data + len);
4462 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4464 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4465 indent, "", (uintmax_t) offset, op_name, uleb);
4466 CONSUME (data - start);
4467 offset += 1 + (data - start);
4470 case DW_OP_GNU_parameter_ref:
4471 /* 4 byte CU relative reference to the abstract optimized away
4472 DW_TAG_formal_parameter. */
4474 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4475 if (! print_unresolved_addresses && cu != NULL)
4476 param_off += cu->start;
4477 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4478 indent, "", (uintmax_t) offset, op_name, param_off);
4486 printf ("%*s[%4" PRIuMAX "] %s\n",
4487 indent, "", (uintmax_t) offset, op_name);
4492 indent = indentrest;
4496 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4497 indent, "", (uintmax_t) offset, op_name);
4505 Dwarf_Off offset:(64 - 3);
4509 struct Dwarf_CU *cu;
4512 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4513 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4516 listptr_base (struct listptr *p)
4519 Dwarf_Die cu = CUDIE (p->cu);
4520 /* Find the base address of the compilation unit. It will normally
4521 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4522 address could be overridden by DW_AT_entry_pc. It's been
4523 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4524 compilation units with discontinuous ranges. */
4525 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4527 Dwarf_Attribute attr_mem;
4528 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4536 compare_listptr (const void *a, const void *b, void *arg)
4538 const char *name = arg;
4539 struct listptr *p1 = (void *) a;
4540 struct listptr *p2 = (void *) b;
4542 if (p1->offset < p2->offset)
4544 if (p1->offset > p2->offset)
4547 if (!p1->warned && !p2->warned)
4549 if (p1->addr64 != p2->addr64)
4551 p1->warned = p2->warned = true;
4553 gettext ("%s %#" PRIx64 " used with different address sizes"),
4554 name, (uint64_t) p1->offset);
4556 if (p1->dwarf64 != p2->dwarf64)
4558 p1->warned = p2->warned = true;
4560 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4561 name, (uint64_t) p1->offset);
4563 if (listptr_base (p1) != listptr_base (p2))
4565 p1->warned = p2->warned = true;
4567 gettext ("%s %#" PRIx64 " used with different base addresses"),
4568 name, (uint64_t) p1->offset);
4575 struct listptr_table
4579 struct listptr *table;
4582 static struct listptr_table known_loclistptr;
4583 static struct listptr_table known_rangelistptr;
4586 reset_listptr (struct listptr_table *table)
4588 free (table->table);
4589 table->table = NULL;
4590 table->n = table->alloc = 0;
4593 /* Returns false if offset doesn't fit. See struct listptr. */
4595 notice_listptr (enum section_e section, struct listptr_table *table,
4596 uint_fast8_t address_size, uint_fast8_t offset_size,
4597 struct Dwarf_CU *cu, Dwarf_Off offset)
4599 if (print_debug_sections & section)
4601 if (table->n == table->alloc)
4603 if (table->alloc == 0)
4607 table->table = xrealloc (table->table,
4608 table->alloc * sizeof table->table[0]);
4611 struct listptr *p = &table->table[table->n++];
4613 *p = (struct listptr)
4615 .addr64 = address_size == 8,
4616 .dwarf64 = offset_size == 8,
4621 if (p->offset != offset)
4631 sort_listptr (struct listptr_table *table, const char *name)
4634 qsort_r (table->table, table->n, sizeof table->table[0],
4635 &compare_listptr, (void *) name);
4639 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4640 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4641 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4642 unsigned char **readp, unsigned char *endp)
4647 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4650 struct listptr *p = &table->table[*idxp];
4652 if (*idxp == table->n
4653 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4656 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4661 if (p->offset != (Dwarf_Off) offset)
4663 *readp += p->offset - offset;
4664 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4665 offset, (Dwarf_Off) p->offset - offset);
4669 if (address_sizep != NULL)
4670 *address_sizep = listptr_address_size (p);
4671 if (offset_sizep != NULL)
4672 *offset_sizep = listptr_offset_size (p);
4674 *base = listptr_base (p);
4683 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4684 Ebl *ebl, GElf_Ehdr *ehdr,
4685 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4687 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4688 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4690 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4692 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4693 (uint64_t) shdr->sh_offset);
4695 Dwarf_Off offset = 0;
4696 while (offset < sh_size)
4698 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4704 Dwarf_Abbrev abbrev;
4706 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4709 if (unlikely (res < 0))
4712 *** error while reading abbreviation: %s\n"),
4717 /* This is the NUL byte at the end of the section. */
4722 /* We know these calls can never fail. */
4723 unsigned int code = dwarf_getabbrevcode (&abbrev);
4724 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4725 int has_children = dwarf_abbrevhaschildren (&abbrev);
4727 printf (gettext (" [%5u] offset: %" PRId64
4728 ", children: %s, tag: %s\n"),
4729 code, (int64_t) offset,
4730 has_children ? gettext ("yes") : gettext ("no"),
4731 dwarf_tag_name (tag));
4737 while (dwarf_getabbrevattr (&abbrev, cnt,
4738 &name, &form, &enoffset) == 0)
4740 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4741 dwarf_attr_name (name), dwarf_form_name (form),
4742 (uint64_t) enoffset);
4753 /* Print content of DWARF .debug_aranges section. We fortunately do
4754 not have to know a bit about the structure of the section, libdwarf
4755 takes care of it. */
4757 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4758 GElf_Shdr *shdr, Dwarf *dbg)
4760 Dwarf_Aranges *aranges;
4762 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4764 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4769 GElf_Shdr glink_mem;
4771 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4774 error (0, 0, gettext ("invalid sh_link value in section %zu"),
4779 printf (ngettext ("\
4780 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4782 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4784 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4785 (uint64_t) shdr->sh_offset, cnt);
4787 /* Compute floor(log16(cnt)). */
4796 for (size_t n = 0; n < cnt; ++n)
4798 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4799 if (unlikely (runp == NULL))
4801 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4809 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4810 printf (gettext (" [%*zu] ???\n"), digits, n);
4812 printf (gettext (" [%*zu] start: %0#*" PRIx64
4813 ", length: %5" PRIu64 ", CU DIE offset: %6"
4815 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4816 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4821 /* Print content of DWARF .debug_aranges section. */
4823 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4824 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4825 GElf_Shdr *shdr, Dwarf *dbg)
4829 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4833 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4835 if (unlikely (data == NULL))
4837 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4843 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4844 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4845 (uint64_t) shdr->sh_offset);
4847 const unsigned char *readp = data->d_buf;
4848 const unsigned char *readendp = readp + data->d_size;
4850 while (readp < readendp)
4852 const unsigned char *hdrstart = readp;
4853 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4855 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
4856 if (readp + 4 > readendp)
4859 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4860 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4864 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4865 unsigned int length_bytes = 4;
4866 if (length == DWARF3_LENGTH_64_BIT)
4868 if (readp + 8 > readendp)
4870 length = read_8ubyte_unaligned_inc (dbg, readp);
4874 const unsigned char *nexthdr = readp + length;
4875 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4878 if (unlikely (length > (size_t) (readendp - readp)))
4884 if (readp + 2 > readendp)
4886 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4887 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4891 error (0, 0, gettext ("unsupported aranges version"));
4896 if (readp + length_bytes > readendp)
4898 if (length_bytes == 8)
4899 offset = read_8ubyte_unaligned_inc (dbg, readp);
4901 offset = read_4ubyte_unaligned_inc (dbg, readp);
4902 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4905 if (readp + 1 > readendp)
4907 unsigned int address_size = *readp++;
4908 printf (gettext (" Address size: %6" PRIu64 "\n"),
4909 (uint64_t) address_size);
4910 if (address_size != 4 && address_size != 8)
4912 error (0, 0, gettext ("unsupported address size"));
4916 unsigned int segment_size = *readp++;
4917 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4918 (uint64_t) segment_size);
4919 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4921 error (0, 0, gettext ("unsupported segment size"));
4925 /* Round the address to the next multiple of 2*address_size. */
4926 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4927 % (2 * address_size));
4929 while (readp < nexthdr)
4931 Dwarf_Word range_address;
4932 Dwarf_Word range_length;
4933 Dwarf_Word segment = 0;
4934 if (readp + 2 * address_size + segment_size > readendp)
4936 if (address_size == 4)
4938 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4939 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4943 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4944 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4947 if (segment_size == 4)
4948 segment = read_4ubyte_unaligned_inc (dbg, readp);
4949 else if (segment_size == 8)
4950 segment = read_8ubyte_unaligned_inc (dbg, readp);
4952 if (range_address == 0 && range_length == 0 && segment == 0)
4955 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4957 char *e = format_dwarf_addr (dwflmod, address_size,
4958 range_address + range_length - 1,
4960 if (segment_size != 0)
4961 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4962 (uint64_t) segment);
4964 printf (gettext (" %s..%s\n"), b, e);
4970 if (readp != nexthdr)
4972 size_t padding = nexthdr - readp;
4973 printf (gettext (" %zu padding bytes\n"), padding);
4980 /* Print content of DWARF .debug_ranges section. */
4982 print_debug_ranges_section (Dwfl_Module *dwflmod,
4983 Ebl *ebl, GElf_Ehdr *ehdr,
4984 Elf_Scn *scn, GElf_Shdr *shdr,
4987 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4989 if (unlikely (data == NULL))
4991 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4997 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4998 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4999 (uint64_t) shdr->sh_offset);
5001 sort_listptr (&known_rangelistptr, "rangelistptr");
5002 size_t listptr_idx = 0;
5004 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5007 Dwarf_Addr base = 0;
5008 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
5009 unsigned char *readp = data->d_buf;
5010 while (readp < endp)
5012 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5014 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
5015 &address_size, NULL, &base, NULL,
5016 offset, &readp, endp))
5019 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
5021 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
5027 if (address_size == 8)
5029 begin = read_8ubyte_unaligned_inc (dbg, readp);
5030 end = read_8ubyte_unaligned_inc (dbg, readp);
5034 begin = read_4ubyte_unaligned_inc (dbg, readp);
5035 end = read_4ubyte_unaligned_inc (dbg, readp);
5036 if (begin == (Dwarf_Addr) (uint32_t) -1)
5037 begin = (Dwarf_Addr) -1l;
5040 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
5042 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
5043 printf (gettext (" [%6tx] base address %s\n"), offset, b);
5047 else if (begin == 0 && end == 0) /* End of list entry. */
5050 printf (gettext (" [%6tx] empty list\n"), offset);
5055 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
5057 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
5059 /* We have an address range entry. */
5060 if (first) /* First address range entry in a list. */
5061 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
5063 printf (gettext (" %s..%s\n"), b, e);
5072 #define REGNAMESZ 16
5074 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
5075 char name[REGNAMESZ], int *bits, int *type)
5080 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
5081 bits ?: &ignore, type ?: &ignore);
5085 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
5087 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
5089 *bits = loc != NULL ? loc->bits : 0;
5091 *type = DW_ATE_unsigned;
5092 set = "??? unrecognized";
5096 if (bits != NULL && *bits <= 0)
5097 *bits = loc != NULL ? loc->bits : 0;
5098 if (type != NULL && *type == DW_ATE_void)
5099 *type = DW_ATE_unsigned;
5105 static const unsigned char *
5106 read_encoded (unsigned int encoding, const unsigned char *readp,
5107 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5109 if ((encoding & 0xf) == DW_EH_PE_absptr)
5110 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5111 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5113 switch (encoding & 0xf)
5115 case DW_EH_PE_uleb128:
5116 get_uleb128 (*res, readp, endp);
5118 case DW_EH_PE_sleb128:
5119 get_sleb128 (*res, readp, endp);
5121 case DW_EH_PE_udata2:
5122 if (readp + 2 > endp)
5124 *res = read_2ubyte_unaligned_inc (dbg, readp);
5126 case DW_EH_PE_udata4:
5127 if (readp + 4 > endp)
5129 *res = read_4ubyte_unaligned_inc (dbg, readp);
5131 case DW_EH_PE_udata8:
5132 if (readp + 8 > endp)
5134 *res = read_8ubyte_unaligned_inc (dbg, readp);
5136 case DW_EH_PE_sdata2:
5137 if (readp + 2 > endp)
5139 *res = read_2sbyte_unaligned_inc (dbg, readp);
5141 case DW_EH_PE_sdata4:
5142 if (readp + 4 > endp)
5144 *res = read_4sbyte_unaligned_inc (dbg, readp);
5146 case DW_EH_PE_sdata8:
5147 if (readp + 8 > endp)
5149 *res = read_8sbyte_unaligned_inc (dbg, readp);
5154 gettext ("invalid encoding"));
5162 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
5163 Dwarf_Word vma_base, unsigned int code_align,
5165 unsigned int version, unsigned int ptr_size,
5166 unsigned int encoding,
5167 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
5169 char regnamebuf[REGNAMESZ];
5170 const char *regname (unsigned int regno)
5172 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
5176 puts ("\n Program:");
5177 Dwarf_Word pc = vma_base;
5178 while (readp < endp)
5180 unsigned int opcode = *readp++;
5182 if (opcode < DW_CFA_advance_loc)
5183 /* Extended opcode. */
5194 case DW_CFA_set_loc:
5195 if ((uint64_t) (endp - readp) < 1)
5197 readp = read_encoded (encoding, readp, endp, &op1, dbg);
5198 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
5199 op1, pc = vma_base + op1);
5201 case DW_CFA_advance_loc1:
5202 if ((uint64_t) (endp - readp) < 1)
5204 printf (" advance_loc1 %u to %#" PRIx64 "\n",
5205 *readp, pc += *readp * code_align);
5208 case DW_CFA_advance_loc2:
5209 if ((uint64_t) (endp - readp) < 2)
5211 op1 = read_2ubyte_unaligned_inc (dbg, readp);
5212 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
5213 op1, pc += op1 * code_align);
5215 case DW_CFA_advance_loc4:
5216 if ((uint64_t) (endp - readp) < 4)
5218 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5219 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
5220 op1, pc += op1 * code_align);
5222 case DW_CFA_offset_extended:
5223 if ((uint64_t) (endp - readp) < 1)
5225 get_uleb128 (op1, readp, endp);
5226 if ((uint64_t) (endp - readp) < 1)
5228 get_uleb128 (op2, readp, endp);
5229 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5231 op1, regname (op1), op2 * data_align);
5233 case DW_CFA_restore_extended:
5234 if ((uint64_t) (endp - readp) < 1)
5236 get_uleb128 (op1, readp, endp);
5237 printf (" restore_extended r%" PRIu64 " (%s)\n",
5238 op1, regname (op1));
5240 case DW_CFA_undefined:
5241 if ((uint64_t) (endp - readp) < 1)
5243 get_uleb128 (op1, readp, endp);
5244 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5246 case DW_CFA_same_value:
5247 if ((uint64_t) (endp - readp) < 1)
5249 get_uleb128 (op1, readp, endp);
5250 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5252 case DW_CFA_register:
5253 if ((uint64_t) (endp - readp) < 1)
5255 get_uleb128 (op1, readp, endp);
5256 if ((uint64_t) (endp - readp) < 1)
5258 get_uleb128 (op2, readp, endp);
5259 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5260 op1, regname (op1), op2, regname (op2));
5262 case DW_CFA_remember_state:
5263 puts (" remember_state");
5265 case DW_CFA_restore_state:
5266 puts (" restore_state");
5268 case DW_CFA_def_cfa:
5269 if ((uint64_t) (endp - readp) < 1)
5271 get_uleb128 (op1, readp, endp);
5272 if ((uint64_t) (endp - readp) < 1)
5274 get_uleb128 (op2, readp, endp);
5275 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5276 op1, regname (op1), op2);
5278 case DW_CFA_def_cfa_register:
5279 if ((uint64_t) (endp - readp) < 1)
5281 get_uleb128 (op1, readp, endp);
5282 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
5283 op1, regname (op1));
5285 case DW_CFA_def_cfa_offset:
5286 if ((uint64_t) (endp - readp) < 1)
5288 get_uleb128 (op1, readp, endp);
5289 printf (" def_cfa_offset %" PRIu64 "\n", op1);
5291 case DW_CFA_def_cfa_expression:
5292 if ((uint64_t) (endp - readp) < 1)
5294 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
5295 printf (" def_cfa_expression %" PRIu64 "\n", op1);
5296 if ((uint64_t) (endp - readp) < op1)
5299 fputs (gettext (" <INVALID DATA>\n"), stdout);
5302 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5306 case DW_CFA_expression:
5307 if ((uint64_t) (endp - readp) < 1)
5309 get_uleb128 (op1, readp, endp);
5310 if ((uint64_t) (endp - readp) < 1)
5312 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5313 printf (" expression r%" PRIu64 " (%s) \n",
5314 op1, regname (op1));
5315 if ((uint64_t) (endp - readp) < op2)
5317 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5321 case DW_CFA_offset_extended_sf:
5322 if ((uint64_t) (endp - readp) < 1)
5324 get_uleb128 (op1, readp, endp);
5325 if ((uint64_t) (endp - readp) < 1)
5327 get_sleb128 (sop2, readp, endp);
5328 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5330 op1, regname (op1), sop2 * data_align);
5332 case DW_CFA_def_cfa_sf:
5333 if ((uint64_t) (endp - readp) < 1)
5335 get_uleb128 (op1, readp, endp);
5336 if ((uint64_t) (endp - readp) < 1)
5338 get_sleb128 (sop2, readp, endp);
5339 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5340 op1, regname (op1), sop2 * data_align);
5342 case DW_CFA_def_cfa_offset_sf:
5343 if ((uint64_t) (endp - readp) < 1)
5345 get_sleb128 (sop1, readp, endp);
5346 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5348 case DW_CFA_val_offset:
5349 if ((uint64_t) (endp - readp) < 1)
5351 get_uleb128 (op1, readp, endp);
5352 if ((uint64_t) (endp - readp) < 1)
5354 get_uleb128 (op2, readp, endp);
5355 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5356 op1, op2 * data_align);
5358 case DW_CFA_val_offset_sf:
5359 if ((uint64_t) (endp - readp) < 1)
5361 get_uleb128 (op1, readp, endp);
5362 if ((uint64_t) (endp - readp) < 1)
5364 get_sleb128 (sop2, readp, endp);
5365 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5366 op1, sop2 * data_align);
5368 case DW_CFA_val_expression:
5369 if ((uint64_t) (endp - readp) < 1)
5371 get_uleb128 (op1, readp, endp);
5372 if ((uint64_t) (endp - readp) < 1)
5374 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5375 printf (" val_expression r%" PRIu64 " (%s)\n",
5376 op1, regname (op1));
5377 if ((uint64_t) (endp - readp) < op2)
5379 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5383 case DW_CFA_MIPS_advance_loc8:
5384 if ((uint64_t) (endp - readp) < 8)
5386 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5387 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5388 op1, pc += op1 * code_align);
5390 case DW_CFA_GNU_window_save:
5391 puts (" GNU_window_save");
5393 case DW_CFA_GNU_args_size:
5394 if ((uint64_t) (endp - readp) < 1)
5396 get_uleb128 (op1, readp, endp);
5397 printf (" args_size %" PRIu64 "\n", op1);
5400 printf (" ??? (%u)\n", opcode);
5403 else if (opcode < DW_CFA_offset)
5404 printf (" advance_loc %u to %#" PRIx64 "\n",
5405 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5406 else if (opcode < DW_CFA_restore)
5409 if ((uint64_t) (endp - readp) < 1)
5411 get_uleb128 (offset, readp, endp);
5412 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5413 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5416 printf (" restore r%u (%s)\n",
5417 opcode & 0x3f, regname (opcode & 0x3f));
5423 encoded_ptr_size (int encoding, unsigned int ptr_size)
5425 switch (encoding & 7)
5427 case DW_EH_PE_udata4:
5429 case DW_EH_PE_udata8:
5435 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5436 "assuming pointer size of %d.\n", encoding, ptr_size);
5442 print_encoding (unsigned int val)
5446 case DW_EH_PE_absptr:
5447 fputs ("absptr", stdout);
5449 case DW_EH_PE_uleb128:
5450 fputs ("uleb128", stdout);
5452 case DW_EH_PE_udata2:
5453 fputs ("udata2", stdout);
5455 case DW_EH_PE_udata4:
5456 fputs ("udata4", stdout);
5458 case DW_EH_PE_udata8:
5459 fputs ("udata8", stdout);
5461 case DW_EH_PE_sleb128:
5462 fputs ("sleb128", stdout);
5464 case DW_EH_PE_sdata2:
5465 fputs ("sdata2", stdout);
5467 case DW_EH_PE_sdata4:
5468 fputs ("sdata4", stdout);
5470 case DW_EH_PE_sdata8:
5471 fputs ("sdata8", stdout);
5474 /* We did not use any of the bits after all. */
5483 print_relinfo (unsigned int val)
5487 case DW_EH_PE_pcrel:
5488 fputs ("pcrel", stdout);
5490 case DW_EH_PE_textrel:
5491 fputs ("textrel", stdout);
5493 case DW_EH_PE_datarel:
5494 fputs ("datarel", stdout);
5496 case DW_EH_PE_funcrel:
5497 fputs ("funcrel", stdout);
5499 case DW_EH_PE_aligned:
5500 fputs ("aligned", stdout);
5511 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5513 printf ("(%s", pfx);
5515 if (fde_encoding == DW_EH_PE_omit)
5519 unsigned int w = fde_encoding;
5521 w = print_encoding (w);
5525 if (w != fde_encoding)
5526 fputc_unlocked (' ', stdout);
5528 w = print_relinfo (w);
5532 printf ("%s%x", w != fde_encoding ? " " : "", w);
5540 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5541 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5544 /* We know this call will succeed since it did in the caller. */
5545 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5546 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5548 /* Needed if we find PC-relative addresses. */
5550 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5552 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5556 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5557 Elf_Data *data = (is_eh_frame
5558 ? elf_rawdata (scn, NULL)
5559 : dbg->sectiondata[IDX_debug_frame]);
5561 if (unlikely (data == NULL))
5563 error (0, 0, gettext ("cannot get %s content: %s"),
5564 scnname, elf_errmsg (-1));
5570 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5571 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5574 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5575 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5579 ptrdiff_t cie_offset;
5580 const char *augmentation;
5581 unsigned int code_alignment_factor;
5582 unsigned int data_alignment_factor;
5583 uint8_t address_size;
5584 uint8_t fde_encoding;
5585 uint8_t lsda_encoding;
5586 struct cieinfo *next;
5589 const unsigned char *readp = data->d_buf;
5590 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5592 while (readp < dataend)
5594 if (unlikely (readp + 4 > dataend))
5597 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5598 elf_ndxscn (scn), scnname);
5602 /* At the beginning there must be a CIE. There can be multiple,
5603 hence we test tis in a loop. */
5604 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5606 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5607 unsigned int length = 4;
5608 if (unlikely (unit_length == 0xffffffff))
5610 if (unlikely (readp + 8 > dataend))
5613 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5617 if (unlikely (unit_length == 0))
5619 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5623 Dwarf_Word maxsize = dataend - readp;
5624 if (unlikely (unit_length > maxsize))
5627 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5629 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5630 const unsigned char *const cieend = readp + unit_length;
5631 if (unlikely (cieend > dataend || readp + 8 > dataend))
5637 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5638 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5639 cie_id = DW_CIE_ID_64;
5642 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5644 uint_fast8_t version = 2;
5645 unsigned int code_alignment_factor;
5646 int data_alignment_factor;
5647 unsigned int fde_encoding = 0;
5648 unsigned int lsda_encoding = 0;
5649 Dwarf_Word initial_location = 0;
5650 Dwarf_Word vma_base = 0;
5652 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5655 const char *const augmentation = (const char *) readp;
5656 readp = memchr (readp, '\0', cieend - readp);
5657 if (unlikely (readp == NULL))
5661 uint_fast8_t segment_size = 0;
5664 if (cieend - readp < 5)
5666 ptr_size = *readp++;
5667 segment_size = *readp++;
5670 if (cieend - readp < 1)
5672 get_uleb128 (code_alignment_factor, readp, cieend);
5673 if (cieend - readp < 1)
5675 get_sleb128 (data_alignment_factor, readp, cieend);
5677 /* In some variant for unwind data there is another field. */
5678 if (strcmp (augmentation, "eh") == 0)
5679 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5681 unsigned int return_address_register;
5682 if (cieend - readp < 1)
5684 if (unlikely (version == 1))
5685 return_address_register = *readp++;
5687 get_uleb128 (return_address_register, readp, cieend);
5689 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5690 " CIE_id: %" PRIu64 "\n"
5692 " augmentation: \"%s\"\n",
5693 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5694 version, augmentation);
5696 printf (" address_size: %u\n"
5697 " segment_size: %u\n",
5698 ptr_size, segment_size);
5699 printf (" code_alignment_factor: %u\n"
5700 " data_alignment_factor: %d\n"
5701 " return_address_register: %u\n",
5702 code_alignment_factor,
5703 data_alignment_factor, return_address_register);
5705 if (augmentation[0] == 'z')
5707 unsigned int augmentationlen;
5708 get_uleb128 (augmentationlen, readp, cieend);
5710 if (augmentationlen > (size_t) (cieend - readp))
5712 error (0, 0, gettext ("invalid augmentation length"));
5717 const char *hdr = "Augmentation data:";
5718 const char *cp = augmentation + 1;
5719 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5721 printf (" %-26s%#x ", hdr, *readp);
5726 fde_encoding = *readp++;
5727 print_encoding_base (gettext ("FDE address encoding: "),
5730 else if (*cp == 'L')
5732 lsda_encoding = *readp++;
5733 print_encoding_base (gettext ("LSDA pointer encoding: "),
5736 else if (*cp == 'P')
5738 /* Personality. This field usually has a relocation
5739 attached pointing to __gcc_personality_v0. */
5740 const unsigned char *startp = readp;
5741 unsigned int encoding = *readp++;
5743 readp = read_encoded (encoding, readp,
5744 readp - 1 + augmentationlen,
5747 while (++startp < readp)
5748 printf ("%#x ", *startp);
5751 print_encoding (encoding);
5753 switch (encoding & 0xf)
5755 case DW_EH_PE_sleb128:
5756 case DW_EH_PE_sdata2:
5757 case DW_EH_PE_sdata4:
5758 printf ("%" PRId64 ")\n", val);
5761 printf ("%#" PRIx64 ")\n", val);
5766 printf ("(%x)\n", *readp++);
5772 if (likely (ptr_size == 4 || ptr_size == 8))
5774 struct cieinfo *newp = alloca (sizeof (*newp));
5775 newp->cie_offset = offset;
5776 newp->augmentation = augmentation;
5777 newp->fde_encoding = fde_encoding;
5778 newp->lsda_encoding = lsda_encoding;
5779 newp->address_size = ptr_size;
5780 newp->code_alignment_factor = code_alignment_factor;
5781 newp->data_alignment_factor = data_alignment_factor;
5788 struct cieinfo *cie = cies;
5791 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
5792 : cie_id == (Dwarf_Off) cie->cie_offset)
5796 if (unlikely (cie == NULL))
5798 puts ("invalid CIE reference in FDE");
5802 /* Initialize from CIE data. */
5803 fde_encoding = cie->fde_encoding;
5804 lsda_encoding = cie->lsda_encoding;
5805 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5806 code_alignment_factor = cie->code_alignment_factor;
5807 data_alignment_factor = cie->data_alignment_factor;
5809 const unsigned char *base = readp;
5810 // XXX There are sometimes relocations for this value
5811 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5812 Dwarf_Word address_range
5813 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5815 /* pcrel for an FDE address is relative to the runtime
5816 address of the start_address field itself. Sign extend
5817 if necessary to make sure the calculation is done on the
5818 full 64 bit address even when initial_location only holds
5819 the lower 32 bits. */
5820 Dwarf_Addr pc_start = initial_location;
5822 pc_start = (uint64_t) (int32_t) pc_start;
5823 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5824 pc_start += ((uint64_t) shdr->sh_addr
5825 + (base - (const unsigned char *) data->d_buf)
5828 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5829 pc_start, initial_location);
5830 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5831 " CIE_pointer: %" PRIu64 "\n"
5832 " initial_location: %s",
5833 offset, (uint64_t) unit_length,
5834 cie->cie_offset, (uint64_t) cie_id, a);
5836 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5838 vma_base = (((uint64_t) shdr->sh_offset
5839 + (base - (const unsigned char *) data->d_buf)
5840 + (uint64_t) initial_location)
5842 ? UINT64_C (0xffffffff)
5843 : UINT64_C (0xffffffffffffffff)));
5844 printf (gettext (" (offset: %#" PRIx64 ")"),
5845 (uint64_t) vma_base);
5848 printf ("\n address_range: %#" PRIx64,
5849 (uint64_t) address_range);
5850 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5851 printf (gettext (" (end offset: %#" PRIx64 ")"),
5852 ((uint64_t) vma_base + (uint64_t) address_range)
5854 ? UINT64_C (0xffffffff)
5855 : UINT64_C (0xffffffffffffffff)));
5858 if (cie->augmentation[0] == 'z')
5860 unsigned int augmentationlen;
5861 if (cieend - readp < 1)
5863 get_uleb128 (augmentationlen, readp, cieend);
5865 if (augmentationlen > (size_t) (cieend - readp))
5867 error (0, 0, gettext ("invalid augmentation length"));
5872 if (augmentationlen > 0)
5874 const char *hdr = "Augmentation data:";
5875 const char *cp = cie->augmentation + 1;
5878 && cp < cie->augmentation + augmentationlen + 1)
5882 uint64_t lsda_pointer;
5883 const unsigned char *p
5884 = read_encoded (lsda_encoding, &readp[u],
5885 &readp[augmentationlen],
5886 &lsda_pointer, dbg);
5889 %-26sLSDA pointer: %#" PRIx64 "\n"),
5896 while (u < augmentationlen)
5898 printf (" %-26s%#x\n", hdr, readp[u++]);
5903 readp += augmentationlen;
5907 /* Handle the initialization instructions. */
5908 if (ptr_size != 4 && ptr_size !=8)
5909 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5911 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5912 data_alignment_factor, version, ptr_size,
5913 fde_encoding, dwflmod, ebl, dbg);
5921 Dwfl_Module *dwflmod;
5926 unsigned int version;
5927 unsigned int addrsize;
5928 unsigned int offset_size;
5929 struct Dwarf_CU *cu;
5934 attr_callback (Dwarf_Attribute *attrp, void *arg)
5936 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5937 const int level = cbargs->level;
5938 Dwarf_Die *die = cbargs->die;
5940 unsigned int attr = dwarf_whatattr (attrp);
5941 if (unlikely (attr == 0))
5943 if (!cbargs->silent)
5944 error (0, 0, gettext ("DIE [%" PRIx64 "] "
5945 "cannot get attribute code: %s"),
5946 dwarf_dieoffset (die), dwarf_errmsg (-1));
5947 return DWARF_CB_ABORT;
5950 unsigned int form = dwarf_whatform (attrp);
5951 if (unlikely (form == 0))
5953 if (!cbargs->silent)
5954 error (0, 0, gettext ("DIE [%" PRIx64 "] "
5955 "cannot get attribute form: %s"),
5956 dwarf_dieoffset (die), dwarf_errmsg (-1));
5957 return DWARF_CB_ABORT;
5963 if (!cbargs->silent)
5966 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5969 if (!cbargs->silent)
5970 error (0, 0, gettext ("DIE [%" PRIx64 "] "
5971 "cannot get attribute value: %s"),
5972 dwarf_dieoffset (die), dwarf_errmsg (-1));
5973 return DWARF_CB_ABORT;
5975 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5977 printf (" %*s%-20s (%s) %s\n",
5978 (int) (level * 2), "", dwarf_attr_name (attr),
5979 dwarf_form_name (form), a);
5984 case DW_FORM_indirect:
5986 case DW_FORM_string:
5987 case DW_FORM_GNU_strp_alt:
5990 const char *str = dwarf_formstring (attrp);
5991 if (unlikely (str == NULL))
5993 printf (" %*s%-20s (%s) \"%s\"\n",
5994 (int) (level * 2), "", dwarf_attr_name (attr),
5995 dwarf_form_name (form), str);
5998 case DW_FORM_ref_addr:
5999 case DW_FORM_ref_udata:
6004 case DW_FORM_GNU_ref_alt:
6008 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
6011 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
6012 (int) (level * 2), "", dwarf_attr_name (attr),
6013 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
6016 case DW_FORM_ref_sig8:
6019 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
6020 (int) (level * 2), "", dwarf_attr_name (attr),
6021 dwarf_form_name (form),
6022 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
6025 case DW_FORM_sec_offset:
6031 case DW_FORM_data1:;
6033 if (unlikely (dwarf_formudata (attrp, &num) != 0))
6036 const char *valuestr = NULL;
6039 /* This case can take either a constant or a loclistptr. */
6040 case DW_AT_data_member_location:
6041 if (form != DW_FORM_sec_offset
6042 && (cbargs->version >= 4
6043 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
6045 if (!cbargs->silent)
6046 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
6047 (int) (level * 2), "", dwarf_attr_name (attr),
6048 dwarf_form_name (form), (uintmax_t) num);
6051 /* else fallthrough */
6053 /* These cases always take a loclistptr and no constant. */
6054 case DW_AT_location:
6055 case DW_AT_data_location:
6056 case DW_AT_vtable_elem_location:
6057 case DW_AT_string_length:
6058 case DW_AT_use_location:
6059 case DW_AT_frame_base:
6060 case DW_AT_return_addr:
6061 case DW_AT_static_link:
6062 case DW_AT_GNU_call_site_value:
6063 case DW_AT_GNU_call_site_data_value:
6064 case DW_AT_GNU_call_site_target:
6065 case DW_AT_GNU_call_site_target_clobbered:
6067 bool nlpt = notice_listptr (section_loc, &known_loclistptr,
6068 cbargs->addrsize, cbargs->offset_size,
6070 if (!cbargs->silent)
6071 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
6072 (int) (level * 2), "", dwarf_attr_name (attr),
6073 dwarf_form_name (form), (uintmax_t) num,
6074 nlpt ? "" : " <WARNING offset too big>");
6080 bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
6081 cbargs->addrsize, cbargs->offset_size,
6083 if (!cbargs->silent)
6084 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
6085 (int) (level * 2), "", dwarf_attr_name (attr),
6086 dwarf_form_name (form), (uintmax_t) num,
6087 nlpt ? "" : " <WARNING offset too big>");
6091 case DW_AT_language:
6092 valuestr = dwarf_lang_name (num);
6094 case DW_AT_encoding:
6095 valuestr = dwarf_encoding_name (num);
6097 case DW_AT_accessibility:
6098 valuestr = dwarf_access_name (num);
6100 case DW_AT_defaulted:
6101 valuestr = dwarf_defaulted_name (num);
6103 case DW_AT_visibility:
6104 valuestr = dwarf_visibility_name (num);
6106 case DW_AT_virtuality:
6107 valuestr = dwarf_virtuality_name (num);
6109 case DW_AT_identifier_case:
6110 valuestr = dwarf_identifier_case_name (num);
6112 case DW_AT_calling_convention:
6113 valuestr = dwarf_calling_convention_name (num);
6116 valuestr = dwarf_inline_name (num);
6118 case DW_AT_ordering:
6119 valuestr = dwarf_ordering_name (num);
6121 case DW_AT_discr_list:
6122 valuestr = dwarf_discr_list_name (num);
6132 /* When highpc is in constant form it is relative to lowpc.
6133 In that case also show the address. */
6135 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
6137 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
6139 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
6140 (int) (level * 2), "", dwarf_attr_name (attr),
6141 dwarf_form_name (form), (uintmax_t) num, a);
6146 Dwarf_Sword snum = 0;
6147 if (form == DW_FORM_sdata)
6148 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
6151 if (valuestr == NULL)
6153 printf (" %*s%-20s (%s)",
6154 (int) (level * 2), "", dwarf_attr_name (attr),
6155 dwarf_form_name (form));
6156 if (form == DW_FORM_sdata)
6157 printf (" %" PRIdMAX "\n", (intmax_t) snum);
6159 printf (" %" PRIuMAX "\n", (uintmax_t) num);
6163 printf (" %*s%-20s (%s) %s",
6164 (int) (level * 2), "", dwarf_attr_name (attr),
6165 dwarf_form_name (form), valuestr);
6166 if (form == DW_FORM_sdata)
6167 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
6169 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6178 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6181 printf (" %*s%-20s (%s) %s\n",
6182 (int) (level * 2), "", dwarf_attr_name (attr),
6183 dwarf_form_name (form), flag ? gettext ("yes") : gettext ("no"));
6186 case DW_FORM_flag_present:
6189 printf (" %*s%-20s (%s) %s\n",
6190 (int) (level * 2), "", dwarf_attr_name (attr),
6191 dwarf_form_name (form), gettext ("yes"));
6194 case DW_FORM_exprloc:
6195 case DW_FORM_block4:
6196 case DW_FORM_block2:
6197 case DW_FORM_block1:
6202 if (unlikely (dwarf_formblock (attrp, &block) != 0))
6205 printf (" %*s%-20s (%s) ",
6206 (int) (level * 2), "", dwarf_attr_name (attr),
6207 dwarf_form_name (form));
6212 if (form != DW_FORM_exprloc)
6214 print_block (block.length, block.data);
6219 case DW_AT_location:
6220 case DW_AT_data_location:
6221 case DW_AT_data_member_location:
6222 case DW_AT_vtable_elem_location:
6223 case DW_AT_string_length:
6224 case DW_AT_use_location:
6225 case DW_AT_frame_base:
6226 case DW_AT_return_addr:
6227 case DW_AT_static_link:
6228 case DW_AT_allocated:
6229 case DW_AT_associated:
6230 case DW_AT_bit_size:
6231 case DW_AT_bit_offset:
6232 case DW_AT_bit_stride:
6233 case DW_AT_byte_size:
6234 case DW_AT_byte_stride:
6236 case DW_AT_lower_bound:
6237 case DW_AT_upper_bound:
6238 case DW_AT_GNU_call_site_value:
6239 case DW_AT_GNU_call_site_data_value:
6240 case DW_AT_GNU_call_site_target:
6241 case DW_AT_GNU_call_site_target_clobbered:
6243 print_ops (cbargs->dwflmod, cbargs->dbg,
6244 12 + level * 2, 12 + level * 2,
6245 cbargs->version, cbargs->addrsize, cbargs->offset_size,
6246 attrp->cu, block.length, block.data);
6254 printf (" %*s%-20s (form: %#x) ???\n",
6255 (int) (level * 2), "", dwarf_attr_name (attr),
6264 print_debug_units (Dwfl_Module *dwflmod,
6265 Ebl *ebl, GElf_Ehdr *ehdr,
6266 Elf_Scn *scn, GElf_Shdr *shdr,
6267 Dwarf *dbg, bool debug_types)
6269 const bool silent = !(print_debug_sections & section_info);
6270 const char *secname = section_name (ebl, ehdr, shdr);
6274 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6275 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6277 /* If the section is empty we don't have to do anything. */
6278 if (!silent && shdr->sh_size == 0)
6282 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6284 Dwarf_Off offset = 0;
6286 /* New compilation unit. */
6289 Dwarf_Off abbroffset;
6296 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6297 &abbroffset, &addrsize, &offsize,
6298 debug_types ? &typesig : NULL,
6299 debug_types ? &typeoff : NULL) != 0)
6305 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6306 " Version: %" PRIu16 ", Abbreviation section offset: %"
6307 PRIu64 ", Address size: %" PRIu8
6308 ", Offset size: %" PRIu8
6309 "\n Type signature: %#" PRIx64
6310 ", Type offset: %#" PRIx64 "\n"),
6311 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6312 typesig, (uint64_t) typeoff);
6314 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6315 " Version: %" PRIu16 ", Abbreviation section offset: %"
6316 PRIu64 ", Address size: %" PRIu8
6317 ", Offset size: %" PRIu8 "\n"),
6318 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6321 struct attrcb_args args =
6327 .addrsize = addrsize,
6328 .offset_size = offsize
6335 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6336 (dbg, offset, &dies[level]) == NULL))
6339 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6340 " in section '%s': %s"),
6341 (uint64_t) offset, secname, dwarf_errmsg (-1));
6345 args.cu = dies[0].cu;
6349 offset = dwarf_dieoffset (&dies[level]);
6350 if (unlikely (offset == ~0ul))
6353 error (0, 0, gettext ("cannot get DIE offset: %s"),
6358 int tag = dwarf_tag (&dies[level]);
6359 if (unlikely (tag == DW_TAG_invalid))
6362 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6363 " in section '%s': %s"),
6364 (uint64_t) offset, secname, dwarf_errmsg (-1));
6369 printf (" [%6" PRIx64 "] %*s%s\n",
6370 (uint64_t) offset, (int) (level * 2), "",
6371 dwarf_tag_name (tag));
6373 /* Print the attribute values. */
6375 args.die = &dies[level];
6376 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6378 /* Make room for the next level's DIE. */
6379 if (level + 1 == maxdies)
6380 dies = (Dwarf_Die *) xrealloc (dies,
6382 * sizeof (Dwarf_Die));
6384 int res = dwarf_child (&dies[level], &dies[level + 1]);
6387 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6391 if (unlikely (res == -1))
6394 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6399 else if (unlikely (res < 0))
6402 error (0, 0, gettext ("cannot get next DIE: %s"),
6420 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6421 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6423 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6427 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6428 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6430 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6435 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6436 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6439 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6440 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6441 (uint64_t) shdr->sh_offset);
6444 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6447 Dwarf_Off ncuoffset = 0;
6449 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6450 NULL, NULL, NULL) == 0)
6453 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6458 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6461 printf (" CU [%" PRIx64 "] %s\n",
6462 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6463 printf (" line:col SBPE* disc isa op address"
6464 " (Statement Block Prologue Epilogue *End)\n");
6465 const char *last_file = "";
6466 for (size_t n = 0; n < nlines; n++)
6468 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6471 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6474 Dwarf_Word mtime, length;
6475 const char *file = dwarf_linesrc (line, &mtime, &length);
6478 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6481 else if (strcmp (last_file, file) != 0)
6483 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6484 file, mtime, length);
6489 bool statement, endseq, block, prologue_end, epilogue_begin;
6490 unsigned int lineop, isa, disc;
6492 dwarf_lineaddr (line, &address);
6493 dwarf_lineno (line, &lineno);
6494 dwarf_linecol (line, &colno);
6495 dwarf_lineop_index (line, &lineop);
6496 dwarf_linebeginstatement (line, &statement);
6497 dwarf_lineendsequence (line, &endseq);
6498 dwarf_lineblock (line, &block);
6499 dwarf_lineprologueend (line, &prologue_end);
6500 dwarf_lineepiloguebegin (line, &epilogue_begin);
6501 dwarf_lineisa (line, &isa);
6502 dwarf_linediscriminator (line, &disc);
6504 /* End sequence is special, it is one byte past. */
6505 char *a = format_dwarf_addr (dwflmod, address_size,
6506 address - (endseq ? 1 : 0), address);
6507 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6509 (statement ? 'S' : ' '),
6510 (block ? 'B' : ' '),
6511 (prologue_end ? 'P' : ' '),
6512 (epilogue_begin ? 'E' : ' '),
6513 (endseq ? '*' : ' '),
6514 disc, isa, lineop, a);
6525 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6526 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6530 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6535 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6536 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6537 (uint64_t) shdr->sh_offset);
6539 if (shdr->sh_size == 0)
6542 /* There is no functionality in libdw to read the information in the
6543 way it is represented here. Hardcode the decoder. */
6544 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6545 if (unlikely (data == NULL || data->d_buf == NULL))
6547 error (0, 0, gettext ("cannot get line data section data: %s"),
6552 const unsigned char *linep = (const unsigned char *) data->d_buf;
6553 const unsigned char *lineendp;
6556 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6558 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6560 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
6562 if (unlikely (linep + 4 > lineendp))
6564 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6565 unsigned int length = 4;
6566 if (unlikely (unit_length == 0xffffffff))
6568 if (unlikely (linep + 8 > lineendp))
6571 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6572 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6575 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6579 /* Check whether we have enough room in the section. */
6580 if (unlikely (unit_length > (size_t) (lineendp - linep)
6581 || unit_length < 2 + length + 5 * 1))
6583 lineendp = linep + unit_length;
6585 /* The next element of the header is the version identifier. */
6586 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6588 /* Next comes the header length. */
6589 Dwarf_Word header_length;
6591 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6593 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6594 //const unsigned char *header_start = linep;
6596 /* Next the minimum instruction length. */
6597 uint_fast8_t minimum_instr_len = *linep++;
6599 /* Next the maximum operations per instruction, in version 4 format. */
6600 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6602 /* Then the flag determining the default value of the is_stmt
6604 uint_fast8_t default_is_stmt = *linep++;
6606 /* Now the line base. */
6607 int_fast8_t line_base = *((const int_fast8_t *) linep);
6610 /* And the line range. */
6611 uint_fast8_t line_range = *linep++;
6613 /* The opcode base. */
6614 uint_fast8_t opcode_base = *linep++;
6616 /* Print what we got so far. */
6617 printf (gettext ("\n"
6618 " Length: %" PRIu64 "\n"
6619 " DWARF version: %" PRIuFAST16 "\n"
6620 " Prologue length: %" PRIu64 "\n"
6621 " Minimum instruction length: %" PRIuFAST8 "\n"
6622 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6623 " Initial value if '%s': %" PRIuFAST8 "\n"
6624 " Line base: %" PRIdFAST8 "\n"
6625 " Line range: %" PRIuFAST8 "\n"
6626 " Opcode base: %" PRIuFAST8 "\n"
6629 (uint64_t) unit_length, version, (uint64_t) header_length,
6630 minimum_instr_len, max_ops_per_instr,
6631 "is_stmt", default_is_stmt, line_base,
6632 line_range, opcode_base);
6634 if (unlikely (linep + opcode_base - 1 >= lineendp))
6638 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6639 linep - (const unsigned char *) data->d_buf,
6640 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6644 int opcode_base_l10 = 1;
6645 unsigned int tmp = opcode_base;
6651 const uint8_t *standard_opcode_lengths = linep - 1;
6652 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6653 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6654 " [%*" PRIuFAST8 "] %hhu arguments\n",
6655 (int) linep[cnt - 1]),
6656 opcode_base_l10, cnt, linep[cnt - 1]);
6657 linep += opcode_base - 1;
6658 if (unlikely (linep >= lineendp))
6661 puts (gettext ("\nDirectory table:"));
6664 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6665 if (unlikely (endp == NULL))
6668 printf (" %s\n", (char *) linep);
6672 /* Skip the final NUL byte. */
6675 if (unlikely (linep >= lineendp))
6677 puts (gettext ("\nFile name table:\n"
6678 " Entry Dir Time Size Name"));
6679 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6681 /* First comes the file name. */
6682 char *fname = (char *) linep;
6683 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6684 if (unlikely (endp == NULL))
6688 /* Then the index. */
6689 unsigned int diridx;
6690 if (lineendp - linep < 1)
6692 get_uleb128 (diridx, linep, lineendp);
6694 /* Next comes the modification time. */
6696 if (lineendp - linep < 1)
6698 get_uleb128 (mtime, linep, lineendp);
6700 /* Finally the length of the file. */
6702 if (lineendp - linep < 1)
6704 get_uleb128 (fsize, linep, lineendp);
6706 printf (" %-5u %-5u %-9u %-9u %s\n",
6707 cnt, diridx, mtime, fsize, fname);
6709 /* Skip the final NUL byte. */
6712 puts (gettext ("\nLine number statements:"));
6713 Dwarf_Word address = 0;
6714 unsigned int op_index = 0;
6716 uint_fast8_t is_stmt = default_is_stmt;
6718 /* Default address value, in case we do not find the CU. */
6720 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6722 /* Determine the CU this block is for. */
6724 Dwarf_Off ncuoffset = 0;
6726 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6727 NULL, NULL, NULL) == 0)
6730 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6732 Dwarf_Attribute stmt_list;
6733 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6736 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6738 if (lineoff == start_offset)
6741 address_size = cudie.cu->address_size;
6746 /* Apply the "operation advance" from a special opcode
6747 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6748 unsigned int op_addr_advance;
6750 inline void advance_pc (unsigned int op_advance)
6752 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6753 / max_ops_per_instr);
6754 address += op_advance;
6755 show_op_index = (op_index > 0 ||
6756 (op_index + op_advance) % max_ops_per_instr > 0);
6757 op_index = (op_index + op_advance) % max_ops_per_instr;
6760 if (max_ops_per_instr == 0)
6763 gettext ("invalid maximum operations per instruction is zero"));
6768 while (linep < lineendp)
6770 size_t offset = linep - (const unsigned char *) data->d_buf;
6774 /* Read the opcode. */
6775 unsigned int opcode = *linep++;
6777 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6778 /* Is this a special opcode? */
6779 if (likely (opcode >= opcode_base))
6781 if (unlikely (line_range == 0))
6784 /* Yes. Handling this is quite easy since the opcode value
6787 opcode = (desired line increment - line_base)
6788 + (line_range * address advance) + opcode_base
6790 int line_increment = (line_base
6791 + (opcode - opcode_base) % line_range);
6793 /* Perform the increments. */
6794 line += line_increment;
6795 advance_pc ((opcode - opcode_base) / line_range);
6797 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6800 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6801 opcode, op_addr_advance, a, op_index,
6802 line_increment, line);
6805 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6806 opcode, op_addr_advance, a, line_increment, line);
6809 else if (opcode == 0)
6811 /* This an extended opcode. */
6812 if (unlikely (linep + 2 > lineendp))
6816 unsigned int len = *linep++;
6818 if (unlikely (linep + len > lineendp))
6821 /* The sub-opcode. */
6824 printf (gettext (" extended opcode %u: "), opcode);
6828 case DW_LNE_end_sequence:
6829 puts (gettext (" end of sequence"));
6831 /* Reset the registers we care about. */
6835 is_stmt = default_is_stmt;
6838 case DW_LNE_set_address:
6840 if (unlikely ((size_t) (lineendp - linep) < address_size))
6842 if (address_size == 4)
6843 address = read_4ubyte_unaligned_inc (dbg, linep);
6845 address = read_8ubyte_unaligned_inc (dbg, linep);
6847 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6848 printf (gettext (" set address to %s\n"), a);
6853 case DW_LNE_define_file:
6855 char *fname = (char *) linep;
6856 unsigned char *endp = memchr (linep, '\0',
6858 if (unlikely (endp == NULL))
6862 unsigned int diridx;
6863 if (lineendp - linep < 1)
6865 get_uleb128 (diridx, linep, lineendp);
6867 if (lineendp - linep < 1)
6869 get_uleb128 (mtime, linep, lineendp);
6870 Dwarf_Word filelength;
6871 if (lineendp - linep < 1)
6873 get_uleb128 (filelength, linep, lineendp);
6876 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6877 diridx, (uint64_t) mtime, (uint64_t) filelength,
6882 case DW_LNE_set_discriminator:
6883 /* Takes one ULEB128 parameter, the discriminator. */
6884 if (unlikely (standard_opcode_lengths[opcode] != 1))
6887 get_uleb128 (u128, linep, lineendp);
6888 printf (gettext (" set discriminator to %u\n"), u128);
6892 /* Unknown, ignore it. */
6893 puts (gettext (" unknown opcode"));
6898 else if (opcode <= DW_LNS_set_isa)
6900 /* This is a known standard opcode. */
6904 /* Takes no argument. */
6905 puts (gettext (" copy"));
6908 case DW_LNS_advance_pc:
6909 /* Takes one uleb128 parameter which is added to the
6911 get_uleb128 (u128, linep, lineendp);
6914 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6917 advance address by %u to %s, op_index to %u\n"),
6918 op_addr_advance, a, op_index);
6920 printf (gettext (" advance address by %u to %s\n"),
6921 op_addr_advance, a);
6926 case DW_LNS_advance_line:
6927 /* Takes one sleb128 parameter which is added to the
6929 get_sleb128 (s128, linep, lineendp);
6932 advance line by constant %d to %" PRId64 "\n"),
6933 s128, (int64_t) line);
6936 case DW_LNS_set_file:
6937 /* Takes one uleb128 parameter which is stored in file. */
6938 get_uleb128 (u128, linep, lineendp);
6939 printf (gettext (" set file to %" PRIu64 "\n"),
6943 case DW_LNS_set_column:
6944 /* Takes one uleb128 parameter which is stored in column. */
6945 if (unlikely (standard_opcode_lengths[opcode] != 1))
6948 get_uleb128 (u128, linep, lineendp);
6949 printf (gettext (" set column to %" PRIu64 "\n"),
6953 case DW_LNS_negate_stmt:
6954 /* Takes no argument. */
6955 is_stmt = 1 - is_stmt;
6956 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6957 "is_stmt", is_stmt);
6960 case DW_LNS_set_basic_block:
6961 /* Takes no argument. */
6962 puts (gettext (" set basic block flag"));
6965 case DW_LNS_const_add_pc:
6966 /* Takes no argument. */
6968 if (unlikely (line_range == 0))
6971 advance_pc ((255 - opcode_base) / line_range);
6973 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6976 advance address by constant %u to %s, op_index to %u\n"),
6977 op_addr_advance, a, op_index);
6980 advance address by constant %u to %s\n"),
6981 op_addr_advance, a);
6986 case DW_LNS_fixed_advance_pc:
6987 /* Takes one 16 bit parameter which is added to the
6989 if (unlikely (standard_opcode_lengths[opcode] != 1))
6992 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6996 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6998 advance address by fixed value %u to %s\n"),
7004 case DW_LNS_set_prologue_end:
7005 /* Takes no argument. */
7006 puts (gettext (" set prologue end flag"));
7009 case DW_LNS_set_epilogue_begin:
7010 /* Takes no argument. */
7011 puts (gettext (" set epilogue begin flag"));
7014 case DW_LNS_set_isa:
7015 /* Takes one uleb128 parameter which is stored in isa. */
7016 if (unlikely (standard_opcode_lengths[opcode] != 1))
7019 get_uleb128 (u128, linep, lineendp);
7020 printf (gettext (" set isa to %u\n"), u128);
7026 /* This is a new opcode the generator but not we know about.
7027 Read the parameters associated with it but then discard
7028 everything. Read all the parameters for this opcode. */
7029 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
7030 " unknown opcode with %" PRIu8 " parameters:",
7031 standard_opcode_lengths[opcode]),
7032 standard_opcode_lengths[opcode]);
7033 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
7035 get_uleb128 (u128, linep, lineendp);
7036 if (n != standard_opcode_lengths[opcode])
7037 putc_unlocked (',', stdout);
7038 printf (" %u", u128);
7041 /* Next round, ignore this opcode. */
7047 /* There must only be one data block. */
7048 assert (elf_getdata (scn, data) == NULL);
7053 print_debug_loc_section (Dwfl_Module *dwflmod,
7054 Ebl *ebl, GElf_Ehdr *ehdr,
7055 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7057 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
7059 if (unlikely (data == NULL))
7061 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
7067 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7068 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7069 (uint64_t) shdr->sh_offset);
7071 sort_listptr (&known_loclistptr, "loclistptr");
7072 size_t listptr_idx = 0;
7074 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7075 uint_fast8_t offset_size = 4;
7078 struct Dwarf_CU *cu = NULL;
7079 Dwarf_Addr base = 0;
7080 unsigned char *readp = data->d_buf;
7081 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
7082 while (readp < endp)
7084 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
7086 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
7087 &address_size, &offset_size, &base,
7088 &cu, offset, &readp, endp))
7091 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
7093 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
7099 if (address_size == 8)
7101 begin = read_8ubyte_unaligned_inc (dbg, readp);
7102 end = read_8ubyte_unaligned_inc (dbg, readp);
7106 begin = read_4ubyte_unaligned_inc (dbg, readp);
7107 end = read_4ubyte_unaligned_inc (dbg, readp);
7108 if (begin == (Dwarf_Addr) (uint32_t) -1)
7109 begin = (Dwarf_Addr) -1l;
7112 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
7114 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
7115 printf (gettext (" [%6tx] base address %s\n"), offset, b);
7119 else if (begin == 0 && end == 0) /* End of list entry. */
7122 printf (gettext (" [%6tx] empty list\n"), offset);
7127 /* We have a location expression entry. */
7128 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
7130 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
7132 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
7135 if (first) /* First entry in a list. */
7136 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
7138 printf (gettext (" %s..%s"), b, e);
7143 if (endp - readp <= (ptrdiff_t) len)
7145 fputs (gettext (" <INVALID DATA>\n"), stdout);
7149 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
7150 3 /*XXX*/, address_size, offset_size, cu, len, readp);
7163 struct mac_culist *next;
7168 mac_compare (const void *p1, const void *p2)
7170 struct mac_culist *m1 = (struct mac_culist *) p1;
7171 struct mac_culist *m2 = (struct mac_culist *) p2;
7173 if (m1->offset < m2->offset)
7175 if (m1->offset > m2->offset)
7182 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7183 Ebl *ebl, GElf_Ehdr *ehdr,
7184 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7187 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7188 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7189 (uint64_t) shdr->sh_offset);
7190 putc_unlocked ('\n', stdout);
7192 /* There is no function in libdw to iterate over the raw content of
7193 the section but it is easy enough to do. */
7194 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7195 if (unlikely (data == NULL || data->d_buf == NULL))
7197 error (0, 0, gettext ("cannot get macro information section data: %s"),
7202 /* Get the source file information for all CUs. */
7206 struct mac_culist *culist = NULL;
7208 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7211 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7214 Dwarf_Attribute attr;
7215 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7219 if (dwarf_formudata (&attr, &macoff) != 0)
7222 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7224 newp->offset = macoff;
7226 newp->next = culist;
7231 /* Convert the list into an array for easier consumption. */
7232 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7235 cus[nculist].offset = data->d_size;
7236 cus[nculist].files = (Dwarf_Files *) -1l;
7239 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7241 assert (cnt < nculist);
7243 culist = culist->next;
7246 /* Sort the array according to the offset in the .debug_macinfo
7247 section. Note we keep the sentinel at the end. */
7248 qsort (cus, nculist, sizeof (*cus), mac_compare);
7251 const unsigned char *readp = (const unsigned char *) data->d_buf;
7252 const unsigned char *readendp = readp + data->d_size;
7255 while (readp < readendp)
7257 unsigned int opcode = *readp++;
7259 unsigned int u128_2;
7260 const unsigned char *endp;
7264 case DW_MACINFO_define:
7265 case DW_MACINFO_undef:
7266 case DW_MACINFO_vendor_ext:
7267 /* For the first two opcodes the parameters are
7271 We can treat these cases together. */
7272 get_uleb128 (u128, readp, readendp);
7274 endp = memchr (readp, '\0', readendp - readp);
7275 if (unlikely (endp == NULL))
7278 %*s*** non-terminated string at end of section"),
7283 if (opcode == DW_MACINFO_define)
7284 printf ("%*s#define %s, line %u\n",
7285 level, "", (char *) readp, u128);
7286 else if (opcode == DW_MACINFO_undef)
7287 printf ("%*s#undef %s, line %u\n",
7288 level, "", (char *) readp, u128);
7290 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7295 case DW_MACINFO_start_file:
7296 /* The two parameters are line and file index, in this order. */
7297 get_uleb128 (u128, readp, readendp);
7298 if (readendp - readp < 1)
7301 %*s*** missing DW_MACINFO_start_file argument at end of section"),
7305 get_uleb128 (u128_2, readp, readendp);
7307 /* Find the CU DIE for this file. */
7308 size_t macoff = readp - (const unsigned char *) data->d_buf;
7309 const char *fname = "???";
7310 if (macoff >= cus[0].offset)
7312 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
7315 if (cus[0].files == NULL
7316 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7317 cus[0].files = (Dwarf_Files *) -1l;
7319 if (cus[0].files != (Dwarf_Files *) -1l)
7320 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7324 printf ("%*sstart_file %u, [%u] %s\n",
7325 level, "", u128, u128_2, fname);
7329 case DW_MACINFO_end_file:
7331 printf ("%*send_file\n", level, "");
7332 /* Nothing more to do. */
7336 // XXX gcc seems to generate files with a trailing zero.
7337 if (unlikely (opcode != 0 || readp != readendp))
7338 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7346 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7347 Ebl *ebl, GElf_Ehdr *ehdr,
7348 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7351 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7352 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7353 (uint64_t) shdr->sh_offset);
7354 putc_unlocked ('\n', stdout);
7356 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7357 if (unlikely (data == NULL || data->d_buf == NULL))
7359 error (0, 0, gettext ("cannot get macro information section data: %s"),
7364 /* Get the source file information for all CUs. Uses same
7365 datastructure as macinfo. But uses offset field to directly
7366 match .debug_line offset. And just stored in a list. */
7370 struct mac_culist *culist = NULL;
7372 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7375 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7378 Dwarf_Attribute attr;
7379 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7383 if (dwarf_formudata (&attr, &lineoff) != 0)
7386 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7388 newp->offset = lineoff;
7390 newp->next = culist;
7395 const unsigned char *readp = (const unsigned char *) data->d_buf;
7396 const unsigned char *readendp = readp + data->d_size;
7398 while (readp < readendp)
7400 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7401 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7403 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7404 // optional vendor extension macro entry table.
7405 if (readp + 2 > readendp)
7408 error (0, 0, gettext ("invalid data"));
7411 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7412 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7414 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7415 // 5 when it gets standardized.
7416 if (vers != 4 && vers != 5)
7418 printf (gettext (" unknown version, cannot parse section\n"));
7422 if (readp + 1 > readendp)
7424 const unsigned char flag = *readp++;
7425 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7427 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7428 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7429 Dwarf_Off line_offset = -1;
7432 if (offset_len == 8)
7433 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7435 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7436 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7440 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user];
7441 memset (vendor, 0, sizeof vendor);
7444 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7445 // of arguments, for each argument 1 byte form code.
7446 if (readp + 1 > readendp)
7448 unsigned int tlen = *readp++;
7449 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7451 for (unsigned int i = 0; i < tlen; i++)
7453 if (readp + 1 > readendp)
7455 unsigned int opcode = *readp++;
7456 printf (gettext (" [%" PRIx8 "]"), opcode);
7457 if (opcode < DW_MACRO_lo_user
7458 || opcode > DW_MACRO_hi_user)
7460 // Record the start of description for this vendor opcode.
7461 // uleb128 nr args, 1 byte per arg form.
7462 vendor[opcode - DW_MACRO_lo_user] = readp;
7463 if (readp + 1 > readendp)
7465 unsigned int args = *readp++;
7468 printf (gettext (" %" PRIu8 " arguments:"), args);
7471 if (readp + 1 > readendp)
7473 unsigned int form = *readp++;
7474 printf (" %s", dwarf_form_string (form));
7475 if (form != DW_FORM_data1
7476 && form != DW_FORM_data2
7477 && form != DW_FORM_data4
7478 && form != DW_FORM_data8
7479 && form != DW_FORM_sdata
7480 && form != DW_FORM_udata
7481 && form != DW_FORM_block
7482 && form != DW_FORM_block1
7483 && form != DW_FORM_block2
7484 && form != DW_FORM_block4
7485 && form != DW_FORM_flag
7486 && form != DW_FORM_string
7487 && form != DW_FORM_strp
7488 && form != DW_FORM_sec_offset)
7492 putchar_unlocked (',');
7496 printf (gettext (" no arguments."));
7497 putchar_unlocked ('\n');
7500 putchar_unlocked ('\n');
7503 if (readp + 1 > readendp)
7505 unsigned int opcode = *readp++;
7509 unsigned int u128_2;
7510 const unsigned char *endp;
7515 case DW_MACRO_start_file:
7516 get_uleb128 (u128, readp, readendp);
7517 if (readp >= readendp)
7519 get_uleb128 (u128_2, readp, readendp);
7521 /* Find the CU DIE that matches this line offset. */
7522 const char *fname = "???";
7523 if (line_offset != (Dwarf_Off) -1)
7525 struct mac_culist *cu = culist;
7526 while (cu != NULL && line_offset != cu->offset)
7530 if (cu->files == NULL
7531 && dwarf_getsrcfiles (&cu->die, &cu->files,
7533 cu->files = (Dwarf_Files *) -1l;
7535 if (cu->files != (Dwarf_Files *) -1l)
7536 fname = (dwarf_filesrc (cu->files, u128_2,
7537 NULL, NULL) ?: "???");
7540 printf ("%*sstart_file %u, [%u] %s\n",
7541 level, "", u128, u128_2, fname);
7545 case DW_MACRO_end_file:
7547 printf ("%*send_file\n", level, "");
7550 case DW_MACRO_define:
7551 get_uleb128 (u128, readp, readendp);
7552 endp = memchr (readp, '\0', readendp - readp);
7555 printf ("%*s#define %s, line %u\n",
7556 level, "", readp, u128);
7560 case DW_MACRO_undef:
7561 get_uleb128 (u128, readp, readendp);
7562 endp = memchr (readp, '\0', readendp - readp);
7565 printf ("%*s#undef %s, line %u\n",
7566 level, "", readp, u128);
7570 case DW_MACRO_define_strp:
7571 get_uleb128 (u128, readp, readendp);
7572 if (readp + offset_len > readendp)
7574 if (offset_len == 8)
7575 off = read_8ubyte_unaligned_inc (dbg, readp);
7577 off = read_4ubyte_unaligned_inc (dbg, readp);
7578 printf ("%*s#define %s, line %u (indirect)\n",
7579 level, "", dwarf_getstring (dbg, off, NULL), u128);
7582 case DW_MACRO_undef_strp:
7583 get_uleb128 (u128, readp, readendp);
7584 if (readp + offset_len > readendp)
7586 if (offset_len == 8)
7587 off = read_8ubyte_unaligned_inc (dbg, readp);
7589 off = read_4ubyte_unaligned_inc (dbg, readp);
7590 printf ("%*s#undef %s, line %u (indirect)\n",
7591 level, "", dwarf_getstring (dbg, off, NULL), u128);
7594 case DW_MACRO_import:
7595 if (readp + offset_len > readendp)
7597 if (offset_len == 8)
7598 off = read_8ubyte_unaligned_inc (dbg, readp);
7600 off = read_4ubyte_unaligned_inc (dbg, readp);
7601 printf ("%*s#include offset 0x%" PRIx64 "\n",
7605 case DW_MACRO_define_sup:
7606 get_uleb128 (u128, readp, readendp);
7607 if (readp + offset_len > readendp)
7609 if (offset_len == 8)
7610 off = read_8ubyte_unaligned_inc (dbg, readp);
7612 off = read_4ubyte_unaligned_inc (dbg, readp);
7613 // Needs support for reading from supplementary object file.
7614 printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (sup)\n",
7615 level, "", off, u128);
7618 case DW_MACRO_undef_sup:
7619 get_uleb128 (u128, readp, readendp);
7620 if (readp + offset_len > readendp)
7622 if (offset_len == 8)
7623 off = read_8ubyte_unaligned_inc (dbg, readp);
7625 off = read_4ubyte_unaligned_inc (dbg, readp);
7626 // Needs support for reading from supplementary object file.
7627 printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (sup)\n",
7628 level, "", off, u128);
7631 case DW_MACRO_import_sup:
7632 if (readp + offset_len > readendp)
7634 if (offset_len == 8)
7635 off = read_8ubyte_unaligned_inc (dbg, readp);
7637 off = read_4ubyte_unaligned_inc (dbg, readp);
7638 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
7642 case DW_MACRO_define_strx:
7643 get_uleb128 (u128, readp, readendp);
7644 if (readp + offset_len > readendp)
7646 if (offset_len == 8)
7647 off = read_8ubyte_unaligned_inc (dbg, readp);
7649 off = read_4ubyte_unaligned_inc (dbg, readp);
7650 // Needs support for reading indirect string offset table
7651 printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (strx)\n",
7652 level, "", off, u128);
7655 case DW_MACRO_undef_strx:
7656 get_uleb128 (u128, readp, readendp);
7657 if (readp + offset_len > readendp)
7659 if (offset_len == 8)
7660 off = read_8ubyte_unaligned_inc (dbg, readp);
7662 off = read_4ubyte_unaligned_inc (dbg, readp);
7663 // Needs support for reading indirect string offset table.
7664 printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (strx)\n",
7665 level, "", off, u128);
7669 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7670 if (opcode < DW_MACRO_lo_user
7671 || opcode > DW_MACRO_lo_user
7672 || vendor[opcode - DW_MACRO_lo_user] == NULL)
7675 const unsigned char *op_desc;
7676 op_desc = vendor[opcode - DW_MACRO_lo_user];
7678 // Just skip the arguments, we cannot really interpret them,
7679 // but print as much as we can.
7680 unsigned int args = *op_desc++;
7683 unsigned int form = *op_desc++;
7688 if (readp + 1 > readendp)
7691 printf (" %" PRIx8, (unsigned int) val);
7695 if (readp + 2 > readendp)
7697 val = read_2ubyte_unaligned_inc (dbg, readp);
7698 printf(" %" PRIx16, (unsigned int) val);
7702 if (readp + 4 > readendp)
7704 val = read_4ubyte_unaligned_inc (dbg, readp);
7705 printf (" %" PRIx32, (unsigned int) val);
7709 if (readp + 8 > readendp)
7711 val = read_8ubyte_unaligned_inc (dbg, readp);
7712 printf (" %" PRIx64, val);
7716 get_sleb128 (val, readp, readendp);
7717 printf (" %" PRIx64, val);
7721 get_uleb128 (val, readp, readendp);
7722 printf (" %" PRIx64, val);
7726 get_uleb128 (val, readp, readendp);
7727 printf (" block[%" PRIu64 "]", val);
7728 if (readp + val > readendp)
7733 case DW_FORM_block1:
7734 if (readp + 1 > readendp)
7737 printf (" block[%" PRIu64 "]", val);
7738 if (readp + val > readendp)
7742 case DW_FORM_block2:
7743 if (readp + 2 > readendp)
7745 val = read_2ubyte_unaligned_inc (dbg, readp);
7746 printf (" block[%" PRIu64 "]", val);
7747 if (readp + val > readendp)
7751 case DW_FORM_block4:
7752 if (readp + 2 > readendp)
7754 val =read_4ubyte_unaligned_inc (dbg, readp);
7755 printf (" block[%" PRIu64 "]", val);
7756 if (readp + val > readendp)
7761 if (readp + 1 > readendp)
7764 printf (" %s", val != 0 ? gettext ("yes") : gettext ("no"));
7767 case DW_FORM_string:
7768 endp = memchr (readp, '\0', readendp - readp);
7771 printf (" %s", readp);
7776 if (readp + offset_len > readendp)
7778 if (offset_len == 8)
7779 val = read_8ubyte_unaligned_inc (dbg, readp);
7781 val = read_4ubyte_unaligned_inc (dbg, readp);
7782 printf (" %s", dwarf_getstring (dbg, val, NULL));
7785 case DW_FORM_sec_offset:
7786 if (readp + offset_len > readendp)
7788 if (offset_len == 8)
7789 val = read_8ubyte_unaligned_inc (dbg, readp);
7791 val = read_4ubyte_unaligned_inc (dbg, readp);
7792 printf (" %" PRIx64, val);
7796 error (0, 0, gettext ("vendor opcode not verified?"));
7802 putchar_unlocked (',');
7804 putchar_unlocked ('\n');
7807 if (readp + 1 > readendp)
7811 putchar_unlocked ('\n');
7817 /* Callback for printing global names. */
7819 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7822 int *np = (int *) arg;
7824 printf (gettext (" [%5d] DIE offset: %6" PRId64
7825 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7826 (*np)++, global->die_offset, global->cu_offset, global->name);
7832 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7834 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7835 Ebl *ebl, GElf_Ehdr *ehdr,
7836 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7838 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7839 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7840 (uint64_t) shdr->sh_offset);
7843 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7846 /* Print the content of the DWARF string section '.debug_str'. */
7848 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7849 Ebl *ebl, GElf_Ehdr *ehdr,
7850 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7852 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7853 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7855 /* Compute floor(log16(shdr->sh_size)). */
7856 GElf_Addr tmp = sh_size;
7863 digits = MAX (4, digits);
7865 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7868 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7869 /* TRANS: the debugstr| prefix makes the string unique. */
7870 digits + 2, sgettext ("debugstr|Offset"));
7872 Dwarf_Off offset = 0;
7873 while (offset < sh_size)
7876 const char *str = dwarf_getstring (dbg, offset, &len);
7877 if (unlikely (str == NULL))
7879 printf (gettext (" *** error while reading strings: %s\n"),
7884 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7891 /* Print the content of the call frame search table section
7894 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7895 Ebl *ebl __attribute__ ((unused)),
7896 GElf_Ehdr *ehdr __attribute__ ((unused)),
7897 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7900 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7903 Elf_Data *data = elf_rawdata (scn, NULL);
7905 if (unlikely (data == NULL))
7907 error (0, 0, gettext ("cannot get %s content: %s"),
7908 ".eh_frame_hdr", elf_errmsg (-1));
7912 const unsigned char *readp = data->d_buf;
7913 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7916 if (unlikely (readp + 4 > dataend))
7919 error (0, 0, gettext ("invalid data"));
7923 unsigned int version = *readp++;
7924 unsigned int eh_frame_ptr_enc = *readp++;
7925 unsigned int fde_count_enc = *readp++;
7926 unsigned int table_enc = *readp++;
7928 printf (" version: %u\n"
7929 " eh_frame_ptr_enc: %#x ",
7930 version, eh_frame_ptr_enc);
7931 print_encoding_base ("", eh_frame_ptr_enc);
7932 printf (" fde_count_enc: %#x ", fde_count_enc);
7933 print_encoding_base ("", fde_count_enc);
7934 printf (" table_enc: %#x ", table_enc);
7935 print_encoding_base ("", table_enc);
7937 uint64_t eh_frame_ptr = 0;
7938 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7940 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7942 if (unlikely (readp == NULL))
7945 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7946 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7947 printf (" (offset: %#" PRIx64 ")",
7948 /* +4 because of the 4 byte header of the section. */
7949 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7951 putchar_unlocked ('\n');
7954 uint64_t fde_count = 0;
7955 if (fde_count_enc != DW_EH_PE_omit)
7957 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7958 if (unlikely (readp == NULL))
7961 printf (" fde_count: %" PRIu64 "\n", fde_count);
7964 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7969 /* Optimize for the most common case. */
7970 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7971 while (fde_count > 0 && readp + 8 <= dataend)
7973 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7974 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7975 + (int64_t) initial_location);
7976 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7977 // XXX Possibly print symbol name or section offset for initial_offset
7978 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7979 " fde=[%6" PRIx64 "]\n",
7980 initial_location, initial_offset,
7981 address, address - (eh_frame_ptr + 4));
7984 while (0 && readp < dataend)
7991 /* Print the content of the exception handling table section
7994 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7995 Ebl *ebl __attribute__ ((unused)),
7996 GElf_Ehdr *ehdr __attribute__ ((unused)),
7998 GElf_Shdr *shdr __attribute__ ((unused)),
7999 Dwarf *dbg __attribute__ ((unused)))
8002 \nException handling table section [%2zu] '.gcc_except_table':\n"),
8005 Elf_Data *data = elf_rawdata (scn, NULL);
8007 if (unlikely (data == NULL))
8009 error (0, 0, gettext ("cannot get %s content: %s"),
8010 ".gcc_except_table", elf_errmsg (-1));
8014 const unsigned char *readp = data->d_buf;
8015 const unsigned char *const dataend = readp + data->d_size;
8017 if (unlikely (readp + 1 > dataend))
8020 error (0, 0, gettext ("invalid data"));
8023 unsigned int lpstart_encoding = *readp++;
8024 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
8025 print_encoding_base ("", lpstart_encoding);
8026 if (lpstart_encoding != DW_EH_PE_omit)
8029 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
8030 printf (" LPStart: %#" PRIx64 "\n", lpstart);
8033 if (unlikely (readp + 1 > dataend))
8035 unsigned int ttype_encoding = *readp++;
8036 printf (gettext (" TType encoding: %#x "), ttype_encoding);
8037 print_encoding_base ("", ttype_encoding);
8038 const unsigned char *ttype_base = NULL;
8039 if (ttype_encoding != DW_EH_PE_omit)
8041 unsigned int ttype_base_offset;
8042 get_uleb128 (ttype_base_offset, readp, dataend);
8043 printf (" TType base offset: %#x\n", ttype_base_offset);
8044 if ((size_t) (dataend - readp) > ttype_base_offset)
8045 ttype_base = readp + ttype_base_offset;
8048 if (unlikely (readp + 1 > dataend))
8050 unsigned int call_site_encoding = *readp++;
8051 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
8052 print_encoding_base ("", call_site_encoding);
8053 unsigned int call_site_table_len;
8054 get_uleb128 (call_site_table_len, readp, dataend);
8056 const unsigned char *const action_table = readp + call_site_table_len;
8057 if (unlikely (action_table > dataend))
8060 unsigned int max_action = 0;
8061 while (readp < action_table)
8064 puts (gettext ("\n Call site table:"));
8066 uint64_t call_site_start;
8067 readp = read_encoded (call_site_encoding, readp, dataend,
8068 &call_site_start, dbg);
8069 uint64_t call_site_length;
8070 readp = read_encoded (call_site_encoding, readp, dataend,
8071 &call_site_length, dbg);
8072 uint64_t landing_pad;
8073 readp = read_encoded (call_site_encoding, readp, dataend,
8075 unsigned int action;
8076 get_uleb128 (action, readp, dataend);
8077 max_action = MAX (action, max_action);
8078 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
8079 " Call site length: %" PRIu64 "\n"
8080 " Landing pad: %#" PRIx64 "\n"
8082 u++, call_site_start, call_site_length, landing_pad, action);
8084 if (readp != action_table)
8087 unsigned int max_ar_filter = 0;
8090 puts ("\n Action table:");
8092 size_t maxdata = (size_t) (dataend - action_table);
8093 if (max_action > maxdata || maxdata - max_action < 1)
8095 invalid_action_table:
8096 fputs (gettext (" <INVALID DATA>\n"), stdout);
8100 const unsigned char *const action_table_end
8101 = action_table + max_action + 1;
8107 get_sleb128 (ar_filter, readp, action_table_end);
8108 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
8109 max_ar_filter = ar_filter;
8111 if (readp >= action_table_end)
8112 goto invalid_action_table;
8113 get_sleb128 (ar_disp, readp, action_table_end);
8115 printf (" [%4u] ar_filter: % d\n"
8117 u, ar_filter, ar_disp);
8118 if (abs (ar_disp) & 1)
8119 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
8120 else if (ar_disp != 0)
8123 putchar_unlocked ('\n');
8126 while (readp < action_table_end);
8129 if (max_ar_filter > 0 && ttype_base != NULL)
8131 unsigned char dsize;
8132 puts ("\n TType table:");
8134 // XXX Not *4, size of encoding;
8135 switch (ttype_encoding & 7)
8137 case DW_EH_PE_udata2:
8138 case DW_EH_PE_sdata2:
8141 case DW_EH_PE_udata4:
8142 case DW_EH_PE_sdata4:
8145 case DW_EH_PE_udata8:
8146 case DW_EH_PE_sdata8:
8151 error (1, 0, gettext ("invalid TType encoding"));
8155 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
8158 readp = ttype_base - max_ar_filter * dsize;
8162 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
8164 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
8166 while (readp < ttype_base);
8170 /* Print the content of the '.gdb_index' section.
8171 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
8174 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8175 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8177 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
8178 " contains %" PRId64 " bytes :\n"),
8179 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
8180 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
8182 Elf_Data *data = elf_rawdata (scn, NULL);
8184 if (unlikely (data == NULL))
8186 error (0, 0, gettext ("cannot get %s content: %s"),
8187 ".gdb_index", elf_errmsg (-1));
8191 // .gdb_index is always in little endian.
8192 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
8195 const unsigned char *readp = data->d_buf;
8196 const unsigned char *const dataend = readp + data->d_size;
8198 if (unlikely (readp + 4 > dataend))
8201 error (0, 0, gettext ("invalid data"));
8205 int32_t vers = read_4ubyte_unaligned (dbg, readp);
8206 printf (gettext (" Version: %" PRId32 "\n"), vers);
8208 // The only difference between version 4 and version 5 is the
8209 // hash used for generating the table. Version 6 contains symbols
8210 // for inlined functions, older versions didn't. Version 7 adds
8211 // symbol kinds. Version 8 just indicates that it correctly includes
8213 if (vers < 4 || vers > 8)
8215 printf (gettext (" unknown version, cannot parse section\n"));
8220 if (unlikely (readp + 4 > dataend))
8223 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
8224 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
8227 if (unlikely (readp + 4 > dataend))
8230 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
8231 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
8234 if (unlikely (readp + 4 > dataend))
8237 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
8238 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
8241 if (unlikely (readp + 4 > dataend))
8244 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8245 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
8248 if (unlikely (readp + 4 > dataend))
8251 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8252 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8254 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
8258 readp = data->d_buf + cu_off;
8260 const unsigned char *nextp = data->d_buf + tu_off;
8261 if (tu_off >= data->d_size)
8264 size_t cu_nr = (nextp - readp) / 16;
8266 printf (gettext ("\n CU list at offset %#" PRIx32
8267 " contains %zu entries:\n"),
8271 while (dataend - readp >= 16 && n < cu_nr)
8273 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8276 uint64_t len = read_8ubyte_unaligned (dbg, readp);
8279 printf (" [%4zu] start: %0#8" PRIx64
8280 ", length: %5" PRIu64 "\n", n, off, len);
8284 readp = data->d_buf + tu_off;
8285 nextp = data->d_buf + addr_off;
8286 if (addr_off >= data->d_size)
8289 size_t tu_nr = (nextp - readp) / 24;
8291 printf (gettext ("\n TU list at offset %#" PRIx32
8292 " contains %zu entries:\n"),
8296 while (dataend - readp >= 24 && n < tu_nr)
8298 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8301 uint64_t type = read_8ubyte_unaligned (dbg, readp);
8304 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8307 printf (" [%4zu] CU offset: %5" PRId64
8308 ", type offset: %5" PRId64
8309 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8313 readp = data->d_buf + addr_off;
8314 nextp = data->d_buf + sym_off;
8315 if (sym_off >= data->d_size)
8318 size_t addr_nr = (nextp - readp) / 20;
8320 printf (gettext ("\n Address list at offset %#" PRIx32
8321 " contains %zu entries:\n"),
8325 while (dataend - readp >= 20 && n < addr_nr)
8327 uint64_t low = read_8ubyte_unaligned (dbg, readp);
8330 uint64_t high = read_8ubyte_unaligned (dbg, readp);
8333 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8336 char *l = format_dwarf_addr (dwflmod, 8, low, low);
8337 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8338 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8345 const unsigned char *const_start = data->d_buf + const_off;
8346 if (const_off >= data->d_size)
8349 readp = data->d_buf + sym_off;
8350 nextp = const_start;
8351 size_t sym_nr = (nextp - readp) / 8;
8353 printf (gettext ("\n Symbol table at offset %#" PRIx32
8354 " contains %zu slots:\n"),
8358 while (dataend - readp >= 8 && n < sym_nr)
8360 uint32_t name = read_4ubyte_unaligned (dbg, readp);
8363 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8366 if (name != 0 || vector != 0)
8368 const unsigned char *sym = const_start + name;
8369 if (unlikely ((size_t) (dataend - const_start) < name
8370 || memchr (sym, '\0', dataend - sym) == NULL))
8373 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8375 const unsigned char *readcus = const_start + vector;
8376 if (unlikely ((size_t) (dataend - const_start) < vector))
8378 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8381 uint32_t cu_kind, cu, kind;
8384 if (unlikely (readcus + 4 > dataend))
8386 cu_kind = read_4ubyte_unaligned (dbg, readcus);
8387 cu = cu_kind & ((1 << 24) - 1);
8388 kind = (cu_kind >> 28) & 7;
8389 is_static = cu_kind & (1U << 31);
8391 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8393 printf ("%" PRId32, cu);
8412 printf ("unknown-0x%" PRIx32, kind);
8415 printf (":%c)", (is_static ? 'S' : 'G'));
8427 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8429 /* Before we start the real work get a debug context descriptor. */
8431 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8435 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8439 if ((print_debug_sections & ~section_exception) != 0)
8440 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8445 /* Get the section header string table index. */
8447 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8448 error (EXIT_FAILURE, 0,
8449 gettext ("cannot get section header string table index"));
8451 /* Look through all the sections for the debugging sections to print. */
8452 Elf_Scn *scn = NULL;
8453 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8456 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8458 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8463 enum section_e bitmask;
8464 void (*fp) (Dwfl_Module *, Ebl *,
8465 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8466 } debug_sections[] =
8468 #define NEW_SECTION(name) \
8469 { ".debug_" #name, section_##name, print_debug_##name##_section }
8470 NEW_SECTION (abbrev),
8471 NEW_SECTION (aranges),
8472 NEW_SECTION (frame),
8474 NEW_SECTION (types),
8477 NEW_SECTION (pubnames),
8479 NEW_SECTION (macinfo),
8480 NEW_SECTION (macro),
8481 NEW_SECTION (ranges),
8482 { ".eh_frame", section_frame | section_exception,
8483 print_debug_frame_section },
8484 { ".eh_frame_hdr", section_frame | section_exception,
8485 print_debug_frame_hdr_section },
8486 { ".gcc_except_table", section_frame | section_exception,
8487 print_debug_exception_table },
8488 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8490 const int ndebug_sections = (sizeof (debug_sections)
8491 / sizeof (debug_sections[0]));
8492 const char *name = elf_strptr (ebl->elf, shstrndx,
8498 for (n = 0; n < ndebug_sections; ++n)
8499 if (strcmp (name, debug_sections[n].name) == 0
8500 || (name[0] == '.' && name[1] == 'z'
8501 && debug_sections[n].name[1] == 'd'
8502 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8505 if ((print_debug_sections | implicit_debug_sections)
8506 & debug_sections[n].bitmask)
8507 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8513 reset_listptr (&known_loclistptr);
8514 reset_listptr (&known_rangelistptr);
8518 #define ITEM_INDENT 4
8519 #define WRAP_COLUMN 75
8521 /* Print "NAME: FORMAT", wrapping when output text would make the line
8522 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8523 but this function is also used for registers which should be printed
8524 aligned. Fortunately registers output uses fixed fields width (such
8525 as %11d) for the alignment.
8527 Line breaks should not depend on the particular values although that
8528 may happen in some cases of the core items. */
8531 __attribute__ ((format (printf, 6, 7)))
8532 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8533 size_t name_width, const char *name, const char *format, ...)
8535 size_t len = strlen (name);
8536 if (name_width < len)
8541 va_start (ap, format);
8542 int out_len = vasprintf (&out, format, ap);
8545 error (EXIT_FAILURE, 0, _("memory exhausted"));
8547 size_t n = name_width + sizeof ": " - 1 + out_len;
8551 printf ("%*s", ITEM_INDENT, "");
8552 colno = ITEM_INDENT + n;
8554 else if (colno + 2 + n < wrap)
8556 printf ("%c ", sep);
8561 printf ("\n%*s", ITEM_INDENT, "");
8562 colno = ITEM_INDENT + n;
8565 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8573 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8574 void *value, const void *data, size_t size)
8576 Elf_Data valuedata =
8580 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8581 .d_version = EV_CURRENT,
8586 .d_buf = (void *) data,
8587 .d_size = valuedata.d_size,
8588 .d_version = EV_CURRENT,
8591 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8592 ? elf32_xlatetom : elf64_xlatetom)
8593 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8595 error (EXIT_FAILURE, 0,
8596 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8598 return data + indata.d_size;
8601 typedef uint8_t GElf_Byte;
8604 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8605 unsigned int colno, size_t *repeated_size)
8607 uint_fast16_t count = item->count ?: 1;
8608 /* Ebl_Core_Item count is always a small number.
8609 Make sure the backend didn't put in some large bogus value. */
8610 assert (count < 128);
8613 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8614 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8615 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8616 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8617 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8618 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8620 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
8621 typedef union { TYPES; } value_t;
8622 void *data = alloca (count * sizeof (value_t));
8625 #define DO_TYPE(NAME, Name, hex, dec) \
8626 GElf_##Name *value_##Name __attribute__((unused)) = data
8630 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8631 size_t convsize = size;
8632 if (repeated_size != NULL)
8634 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8636 data = alloca (*repeated_size);
8637 count *= *repeated_size / size;
8638 convsize = count * size;
8639 *repeated_size -= convsize;
8641 else if (item->count != 0 || item->format != '\n')
8642 *repeated_size -= size;
8645 convert (core, item->type, count, data, desc + item->offset, convsize);
8647 Elf_Type type = item->type;
8648 if (type == ELF_T_ADDR)
8649 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8651 switch (item->format)
8654 assert (count == 1);
8657 #define DO_TYPE(NAME, Name, hex, dec) \
8658 case ELF_T_##NAME: \
8659 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8660 0, item->name, dec, value_##Name[0]); \
8670 assert (count == 1);
8673 #define DO_TYPE(NAME, Name, hex, dec) \
8674 case ELF_T_##NAME: \
8675 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8676 0, item->name, hex, value_##Name[0]); \
8687 assert (size % sizeof (unsigned int) == 0);
8688 unsigned int nbits = count * size * 8;
8689 unsigned int pop = 0;
8690 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8691 pop += __builtin_popcount (*i);
8692 bool negate = pop > nbits / 2;
8693 const unsigned int bias = item->format == 'b';
8696 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8700 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8702 assert (size == sizeof (unsigned int) * 2);
8703 for (unsigned int *i = data;
8704 (void *) i < data + count * size; i += 2)
8706 unsigned int w = i[1];
8712 unsigned int lastbit = 0;
8713 unsigned int run = 0;
8714 for (const unsigned int *i = data;
8715 (void *) i < data + count * size; ++i)
8717 unsigned int bit = ((void *) i - data) * 8;
8718 unsigned int w = negate ? ~*i : *i;
8721 /* Note that a right shift equal to (or greater than)
8722 the number of bits of w is undefined behaviour. In
8723 particular when the least significant bit is bit 32
8724 (w = 0x8000000) then w >>= n is undefined. So
8725 explicitly handle that case separately. */
8726 unsigned int n = ffs (w);
8727 if (n < sizeof (w) * 8)
8733 if (lastbit != 0 && lastbit + 1 == bit)
8738 p += sprintf (p, "%u", bit - bias);
8740 p += sprintf (p, ",%u", bit - bias);
8742 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8749 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8750 p += sprintf (p, "-%u", lastbit - bias);
8752 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8753 negate ? "~<%s>" : "<%s>", printed);
8758 case (char) ('T'|0x80):
8759 assert (count == 2);
8764 #define DO_TYPE(NAME, Name, hex, dec) \
8765 case ELF_T_##NAME: \
8766 sec = value_##Name[0]; \
8767 usec = value_##Name[1]; \
8774 if (unlikely (item->format == (char) ('T'|0x80)))
8776 /* This is a hack for an ill-considered 64-bit ABI where
8777 tv_usec is actually a 32-bit field with 32 bits of padding
8778 rounding out struct timeval. We've already converted it as
8779 a 64-bit field. For little-endian, this just means the
8780 high half is the padding; it's presumably zero, but should
8781 be ignored anyway. For big-endian, it means the 32-bit
8782 field went into the high half of USEC. */
8784 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8785 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8790 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8791 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8795 assert (count == 1);
8796 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8797 "%c", value_Byte[0]);
8801 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8802 "%.*s", (int) count, value_Byte);
8806 /* This is a list of strings separated by '\n'. */
8807 assert (item->count == 0);
8808 assert (repeated_size != NULL);
8809 assert (item->name == NULL);
8810 if (unlikely (item->offset >= *repeated_size))
8813 const char *s = desc + item->offset;
8814 size = *repeated_size - item->offset;
8818 const char *eol = memchr (s, '\n', size);
8822 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8825 size -= eol + 1 - s;
8829 colno = WRAP_COLUMN;
8836 error (0, 0, "XXX not handling format '%c' for %s",
8837 item->format, item->name);
8847 /* Sort items by group, and by layout offset within each group. */
8849 compare_core_items (const void *a, const void *b)
8851 const Ebl_Core_Item *const *p1 = a;
8852 const Ebl_Core_Item *const *p2 = b;
8853 const Ebl_Core_Item *item1 = *p1;
8854 const Ebl_Core_Item *item2 = *p2;
8856 return ((item1->group == item2->group ? 0
8857 : strcmp (item1->group, item2->group))
8858 ?: (int) item1->offset - (int) item2->offset);
8861 /* Sort item groups by layout offset of the first item in the group. */
8863 compare_core_item_groups (const void *a, const void *b)
8865 const Ebl_Core_Item *const *const *p1 = a;
8866 const Ebl_Core_Item *const *const *p2 = b;
8867 const Ebl_Core_Item *const *group1 = *p1;
8868 const Ebl_Core_Item *const *group2 = *p2;
8869 const Ebl_Core_Item *item1 = *group1;
8870 const Ebl_Core_Item *item2 = *group2;
8872 return (int) item1->offset - (int) item2->offset;
8876 handle_core_items (Elf *core, const void *desc, size_t descsz,
8877 const Ebl_Core_Item *items, size_t nitems)
8881 unsigned int colno = 0;
8883 /* FORMAT '\n' makes sense to be present only as a single item as it
8884 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8885 if present as a single item but they can be also processed with other
8887 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8888 || items[0].format == 'B'))
8890 assert (items[0].offset == 0);
8891 size_t size = descsz;
8892 colno = handle_core_item (core, items, desc, colno, &size);
8893 /* If SIZE is not zero here there is some remaining data. But we do not
8894 know how to process it anyway. */
8897 for (size_t i = 0; i < nitems; ++i)
8898 assert (items[i].format != '\n');
8900 /* Sort to collect the groups together. */
8901 const Ebl_Core_Item *sorted_items[nitems];
8902 for (size_t i = 0; i < nitems; ++i)
8903 sorted_items[i] = &items[i];
8904 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8906 /* Collect the unique groups and sort them. */
8907 const Ebl_Core_Item **groups[nitems];
8908 groups[0] = &sorted_items[0];
8910 for (size_t i = 1; i < nitems; ++i)
8911 if (sorted_items[i]->group != sorted_items[i - 1]->group
8912 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8913 groups[ngroups++] = &sorted_items[i];
8914 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8916 /* Write out all the groups. */
8917 const void *last = desc;
8920 for (size_t i = 0; i < ngroups; ++i)
8922 for (const Ebl_Core_Item **item = groups[i];
8923 (item < &sorted_items[nitems]
8924 && ((*item)->group == groups[i][0]->group
8925 || !strcmp ((*item)->group, groups[i][0]->group)));
8927 colno = handle_core_item (core, *item, desc, colno, NULL);
8929 /* Force a line break at the end of the group. */
8930 colno = WRAP_COLUMN;
8936 /* This set of items consumed a certain amount of the note's data.
8937 If there is more data there, we have another unit of the same size.
8938 Loop to print that out too. */
8939 const Ebl_Core_Item *item = &items[nitems - 1];
8940 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8941 item->count ?: 1, EV_CURRENT);
8950 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8954 /* For just one repeat, print it unabridged twice. */
8959 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8960 ITEM_INDENT, "", reps);
8970 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8973 desc += regloc->offset;
8981 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8982 const Ebl_Register_Location *regloc, const void *desc,
8985 if (regloc->bits % 8 != 0)
8986 return handle_bit_registers (regloc, desc, colno);
8988 desc += regloc->offset;
8990 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8992 char name[REGNAMESZ];
8995 register_info (ebl, reg, regloc, name, &bits, &type);
8998 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8999 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
9000 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
9001 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
9003 #define BITS(bits, xtype, sfmt, ufmt) \
9004 uint##bits##_t b##bits; int##bits##_t b##bits##s
9005 union { TYPES; uint64_t b128[2]; } value;
9010 case DW_ATE_unsigned:
9012 case DW_ATE_address:
9015 #define BITS(bits, xtype, sfmt, ufmt) \
9017 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
9018 if (type == DW_ATE_signed) \
9019 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
9021 sfmt, value.b##bits##s); \
9023 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
9025 ufmt, value.b##bits); \
9031 assert (type == DW_ATE_unsigned);
9032 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
9033 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
9034 colno = print_core_item (colno, ' ', WRAP_COLUMN,
9036 "0x%.16" PRIx64 "%.16" PRIx64,
9037 value.b128[!be], value.b128[be]);
9047 /* Print each byte in hex, the whole thing in native byte order. */
9048 assert (bits % 8 == 0);
9049 const uint8_t *bytes = desc;
9051 char hex[bits / 4 + 1];
9052 hex[bits / 4] = '\0';
9054 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
9056 bytes += bits / 8 - 1;
9060 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
9062 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
9063 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
9065 colno = print_core_item (colno, ' ', WRAP_COLUMN,
9066 maxregname, name, "0x%s", hex);
9069 desc += regloc->pad;
9078 struct register_info
9080 const Ebl_Register_Location *regloc;
9082 char name[REGNAMESZ];
9089 register_bitpos (const struct register_info *r)
9091 return (r->regloc->offset * 8
9092 + ((r->regno - r->regloc->regno)
9093 * (r->regloc->bits + r->regloc->pad * 8)));
9097 compare_sets_by_info (const struct register_info *r1,
9098 const struct register_info *r2)
9100 return ((int) r2->bits - (int) r1->bits
9101 ?: register_bitpos (r1) - register_bitpos (r2));
9104 /* Sort registers by set, and by size and layout offset within each set. */
9106 compare_registers (const void *a, const void *b)
9108 const struct register_info *r1 = a;
9109 const struct register_info *r2 = b;
9111 /* Unused elements sort last. */
9112 if (r1->regloc == NULL)
9113 return r2->regloc == NULL ? 0 : 1;
9114 if (r2->regloc == NULL)
9117 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
9118 ?: compare_sets_by_info (r1, r2));
9121 /* Sort register sets by layout offset of the first register in the set. */
9123 compare_register_sets (const void *a, const void *b)
9125 const struct register_info *const *p1 = a;
9126 const struct register_info *const *p2 = b;
9127 return compare_sets_by_info (*p1, *p2);
9131 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
9132 const Ebl_Register_Location *reglocs, size_t nregloc)
9137 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
9140 for (size_t i = 0; i < nregloc; ++i)
9141 if (maxnreg < reglocs[i].regno + reglocs[i].count)
9142 maxnreg = reglocs[i].regno + reglocs[i].count;
9143 assert (maxnreg > 0);
9146 struct register_info regs[maxnreg];
9147 memset (regs, 0, sizeof regs);
9149 /* Sort to collect the sets together. */
9151 for (size_t i = 0; i < nregloc; ++i)
9152 for (int reg = reglocs[i].regno;
9153 reg < reglocs[i].regno + reglocs[i].count;
9156 assert (reg < maxnreg);
9159 struct register_info *info = ®s[reg];
9160 info->regloc = ®locs[i];
9162 info->set = register_info (ebl, reg, ®locs[i],
9163 info->name, &info->bits, &info->type);
9165 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
9167 /* Collect the unique sets and sort them. */
9168 inline bool same_set (const struct register_info *a,
9169 const struct register_info *b)
9171 return (a < ®s[maxnreg] && a->regloc != NULL
9172 && b < ®s[maxnreg] && b->regloc != NULL
9173 && a->bits == b->bits
9174 && (a->set == b->set || !strcmp (a->set, b->set)));
9176 struct register_info *sets[maxreg + 1];
9179 for (int i = 1; i <= maxreg; ++i)
9180 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
9181 sets[nsets++] = ®s[i];
9182 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
9184 /* Write out all the sets. */
9185 unsigned int colno = 0;
9186 for (size_t i = 0; i < nsets; ++i)
9188 /* Find the longest name of a register in this set. */
9190 const struct register_info *end;
9191 for (end = sets[i]; same_set (sets[i], end); ++end)
9193 size_t len = strlen (end->name);
9198 for (const struct register_info *reg = sets[i];
9200 reg += reg->regloc->count ?: 1)
9201 colno = handle_core_register (ebl, core, maxname,
9202 reg->regloc, desc, colno);
9204 /* Force a line break at the end of the group. */
9205 colno = WRAP_COLUMN;
9212 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9214 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
9217 error (EXIT_FAILURE, 0,
9218 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9220 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
9221 for (size_t i = 0; i < nauxv; ++i)
9224 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
9230 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
9233 if (av->a_un.a_val == 0)
9234 printf (" %" PRIu64 "\n", av->a_type);
9236 printf (" %" PRIu64 ": %#" PRIx64 "\n",
9237 av->a_type, av->a_un.a_val);
9242 case '\0': /* Normally zero. */
9243 if (av->a_un.a_val == 0)
9245 printf (" %s\n", name);
9250 case 'p': /* address */
9251 case 's': /* address of string */
9252 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
9255 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
9258 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
9262 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
9264 const char *pfx = "<";
9265 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9267 if (av->a_un.a_val & bit)
9269 printf ("%s%s", pfx, p);
9284 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9286 return ptr < end && (size_t) (end - ptr) >= sz;
9290 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9293 if (! buf_has_data (*ptrp, end, 4))
9296 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9301 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9304 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9305 if (! buf_has_data (*ptrp, end, sz))
9314 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9324 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9326 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9328 error (EXIT_FAILURE, 0,
9329 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9331 unsigned char const *ptr = data->d_buf;
9332 unsigned char const *const end = data->d_buf + data->d_size;
9334 /* Siginfo head is three ints: signal number, error number, origin
9336 int si_signo, si_errno, si_code;
9337 if (! buf_read_int (core, &ptr, end, &si_signo)
9338 || ! buf_read_int (core, &ptr, end, &si_errno)
9339 || ! buf_read_int (core, &ptr, end, &si_code))
9342 printf (" Not enough data in NT_SIGINFO note.\n");
9346 /* Next is a pointer-aligned union of structures. On 64-bit
9347 machines, that implies a word of padding. */
9348 if (gelf_getclass (core) == ELFCLASS64)
9351 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
9352 si_signo, si_errno, si_code);
9363 if (! buf_read_ulong (core, &ptr, end, &addr))
9365 printf (" fault address: %#" PRIx64 "\n", addr);
9371 else if (si_code == CORE_SI_USER)
9374 if (! buf_read_int (core, &ptr, end, &pid)
9375 || ! buf_read_int (core, &ptr, end, &uid))
9377 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
9382 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9384 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9386 error (EXIT_FAILURE, 0,
9387 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9389 unsigned char const *ptr = data->d_buf;
9390 unsigned char const *const end = data->d_buf + data->d_size;
9392 uint64_t count, page_size;
9393 if (! buf_read_ulong (core, &ptr, end, &count)
9394 || ! buf_read_ulong (core, &ptr, end, &page_size))
9397 printf (" Not enough data in NT_FILE note.\n");
9401 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9402 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9403 if (count > maxcount)
9406 /* Where file names are stored. */
9407 unsigned char const *const fstart = ptr + 3 * count * addrsize;
9408 char const *fptr = (char *) fstart;
9410 printf (" %" PRId64 " files:\n", count);
9411 for (uint64_t i = 0; i < count; ++i)
9413 uint64_t mstart, mend, moffset;
9414 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9415 || ! buf_read_ulong (core, &ptr, fstart, &mend)
9416 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9419 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9423 int ct = printf (" %08" PRIx64 "-%08" PRIx64
9424 " %08" PRIx64 " %" PRId64,
9425 mstart, mend, moffset * page_size, mend - mstart);
9426 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9433 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9434 const char *name, const void *desc)
9436 GElf_Word regs_offset;
9438 const Ebl_Register_Location *reglocs;
9440 const Ebl_Core_Item *items;
9442 if (! ebl_core_note (ebl, nhdr, name,
9443 ®s_offset, &nregloc, ®locs, &nitems, &items))
9446 /* Pass 0 for DESCSZ when there are registers in the note,
9447 so that the ITEMS array does not describe the whole thing.
9448 For non-register notes, the actual descsz might be a multiple
9449 of the unit size, not just exactly the unit size. */
9450 unsigned int colno = handle_core_items (ebl->elf, desc,
9451 nregloc == 0 ? nhdr->n_descsz : 0,
9454 putchar_unlocked ('\n');
9456 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9459 putchar_unlocked ('\n');
9463 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9464 GElf_Off start, Elf_Data *data)
9466 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
9475 while (offset < data->d_size
9476 && (offset = gelf_getnote (data, offset,
9477 &nhdr, &name_offset, &desc_offset)) > 0)
9479 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
9480 const char *desc = data->d_buf + desc_offset;
9484 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
9485 (int) nhdr.n_namesz, name, nhdr.n_descsz,
9486 ehdr->e_type == ET_CORE
9487 ? ebl_core_note_type_name (ebl, nhdr.n_type,
9489 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9490 buf2, sizeof (buf2)));
9492 /* Filter out invalid entries. */
9493 if (memchr (name, '\0', nhdr.n_namesz) != NULL
9494 /* XXX For now help broken Linux kernels. */
9497 if (ehdr->e_type == ET_CORE)
9499 if (nhdr.n_type == NT_AUXV
9500 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9501 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9502 && !memcmp (name, "CORE", 4))
9503 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9504 start + desc_offset);
9505 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9506 switch (nhdr.n_type)
9509 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9510 start + desc_offset);
9514 handle_file_note (ebl->elf, nhdr.n_descsz,
9515 start + desc_offset);
9519 handle_core_note (ebl, &nhdr, name, desc);
9522 handle_core_note (ebl, &nhdr, name, desc);
9525 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9529 if (offset == data->d_size)
9533 error (EXIT_FAILURE, 0,
9534 gettext ("cannot get content of note section: %s"),
9539 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9541 /* If we have section headers, just look for SHT_NOTE sections.
9542 In a debuginfo file, the program headers are not reliable. */
9545 /* Get the section header string table index. */
9547 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9548 error (EXIT_FAILURE, 0,
9549 gettext ("cannot get section header string table index"));
9551 Elf_Scn *scn = NULL;
9552 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9555 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9557 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9558 /* Not what we are looking for. */
9562 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9564 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9565 shdr->sh_size, shdr->sh_offset);
9567 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9568 elf_getdata (scn, NULL));
9573 /* We have to look through the program header to find the note
9574 sections. There can be more than one. */
9575 for (size_t cnt = 0; cnt < phnum; ++cnt)
9578 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9580 if (phdr == NULL || phdr->p_type != PT_NOTE)
9581 /* Not what we are looking for. */
9585 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9586 phdr->p_filesz, phdr->p_offset);
9588 handle_notes_data (ebl, ehdr, phdr->p_offset,
9589 elf_getdata_rawchunk (ebl->elf,
9590 phdr->p_offset, phdr->p_filesz,
9597 hex_dump (const uint8_t *data, size_t len)
9602 printf (" 0x%08zx ", pos);
9604 const size_t chunk = MIN (len - pos, 16);
9606 for (size_t i = 0; i < chunk; ++i)
9608 printf ("%02x ", data[pos + i]);
9610 printf ("%02x", data[pos + i]);
9613 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9615 for (size_t i = 0; i < chunk; ++i)
9617 unsigned char b = data[pos + i];
9618 printf ("%c", isprint (b) ? b : '.');
9627 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9629 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9630 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
9631 elf_ndxscn (scn), name);
9634 if (print_decompress)
9636 /* We try to decompress the section, but keep the old shdr around
9637 so we can show both the original shdr size and the uncompressed
9639 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9641 if (elf_compress (scn, 0, 0) < 0)
9642 printf ("WARNING: %s [%zd]\n",
9643 gettext ("Couldn't uncompress section"),
9646 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9648 if (elf_compress_gnu (scn, 0, 0) < 0)
9649 printf ("WARNING: %s [%zd]\n",
9650 gettext ("Couldn't uncompress section"),
9655 Elf_Data *data = elf_rawdata (scn, NULL);
9657 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9658 elf_ndxscn (scn), name, elf_errmsg (-1));
9661 if (data->d_size == shdr->sh_size)
9662 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9663 " bytes at offset %#0" PRIx64 ":\n"),
9664 elf_ndxscn (scn), name,
9665 shdr->sh_size, shdr->sh_offset);
9667 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9668 " bytes (%zd uncompressed) at offset %#0"
9670 elf_ndxscn (scn), name,
9671 shdr->sh_size, data->d_size, shdr->sh_offset);
9672 hex_dump (data->d_buf, data->d_size);
9678 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9680 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9681 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
9682 elf_ndxscn (scn), name);
9685 if (print_decompress)
9687 /* We try to decompress the section, but keep the old shdr around
9688 so we can show both the original shdr size and the uncompressed
9690 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9692 if (elf_compress (scn, 0, 0) < 0)
9693 printf ("WARNING: %s [%zd]\n",
9694 gettext ("Couldn't uncompress section"),
9697 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9699 if (elf_compress_gnu (scn, 0, 0) < 0)
9700 printf ("WARNING: %s [%zd]\n",
9701 gettext ("Couldn't uncompress section"),
9706 Elf_Data *data = elf_rawdata (scn, NULL);
9708 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9709 elf_ndxscn (scn), name, elf_errmsg (-1));
9712 if (data->d_size == shdr->sh_size)
9713 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9714 " bytes at offset %#0" PRIx64 ":\n"),
9715 elf_ndxscn (scn), name,
9716 shdr->sh_size, shdr->sh_offset);
9718 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9719 " bytes (%zd uncompressed) at offset %#0"
9721 elf_ndxscn (scn), name,
9722 shdr->sh_size, data->d_size, shdr->sh_offset);
9724 const char *start = data->d_buf;
9725 const char *const limit = start + data->d_size;
9728 const char *end = memchr (start, '\0', limit - start);
9729 const size_t pos = start - (const char *) data->d_buf;
9730 if (unlikely (end == NULL))
9732 printf (" [%6zx]- %.*s\n",
9733 pos, (int) (limit - start), start);
9736 printf (" [%6zx] %s\n", pos, start);
9738 } while (start < limit);
9744 for_each_section_argument (Elf *elf, const struct section_argument *list,
9745 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9748 /* Get the section header string table index. */
9750 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9751 error (EXIT_FAILURE, 0,
9752 gettext ("cannot get section header string table index"));
9754 for (const struct section_argument *a = list; a != NULL; a = a->next)
9758 const char *name = NULL;
9761 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9762 if (endp != a->arg && *endp == '\0')
9764 scn = elf_getscn (elf, shndx);
9767 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9771 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9772 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9774 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9778 /* Need to look up the section by name. */
9781 while ((scn = elf_nextscn (elf, scn)) != NULL)
9783 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9785 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9788 if (!strcmp (name, a->arg))
9791 (*dump) (scn, &shdr_mem, name);
9795 if (unlikely (!found) && !a->implicit)
9796 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9802 dump_data (Ebl *ebl)
9804 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9808 dump_strings (Ebl *ebl)
9810 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9814 print_strings (Ebl *ebl)
9816 /* Get the section header string table index. */
9818 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9819 error (EXIT_FAILURE, 0,
9820 gettext ("cannot get section header string table index"));
9826 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9828 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9831 if (shdr_mem.sh_type != SHT_PROGBITS
9832 || !(shdr_mem.sh_flags & SHF_STRINGS))
9835 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9839 print_string_section (scn, &shdr_mem, name);
9844 dump_archive_index (Elf *elf, const char *fname)
9847 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9850 int result = elf_errno ();
9851 if (unlikely (result != ELF_E_NO_INDEX))
9852 error (EXIT_FAILURE, 0,
9853 gettext ("cannot get symbol index of archive '%s': %s"),
9854 fname, elf_errmsg (result));
9856 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9860 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
9864 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9866 if (s->as_off != as_off)
9871 if (unlikely (elf_rand (elf, as_off) == 0)
9872 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9874 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9877 error (EXIT_FAILURE, 0,
9878 gettext ("cannot extract member at offset %zu in '%s': %s"),
9879 as_off, fname, elf_errmsg (-1));
9881 const Elf_Arhdr *h = elf_getarhdr (subelf);
9883 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9888 printf ("\t%s\n", s->as_name);
9892 #include "debugpred.h"