1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2014 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/>. */
43 #include <sys/param.h>
48 #include "../libelf/libelfP.h"
49 #include "../libelf/common.h"
50 #include "../libebl/libeblP.h"
51 #include "../libdw/libdwP.h"
52 #include "../libdwfl/libdwflP.h"
53 #include "../libdw/memory-access.h"
55 #include "../libdw/known-dwarf.h"
58 /* Name and version of program. */
59 static void print_version (FILE *stream, struct argp_state *state);
60 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
62 /* Bug report address. */
63 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
65 /* argp key value for --elf-section, non-ascii. */
66 #define ELF_INPUT_SECTION 256
68 /* Definitions of arguments for argp functions. */
69 static const struct argp_option options[] =
71 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
72 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
73 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
75 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
76 { "all", 'a', NULL, 0,
77 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
78 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
79 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
80 { "histogram", 'I', NULL, 0,
81 N_("Display histogram of bucket list lengths"), 0 },
82 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
83 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
84 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
85 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
86 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
87 { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
88 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
89 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
90 { "arch-specific", 'A', NULL, 0,
91 N_("Display architecture specific information, if any"), 0 },
92 { "exception", 'e', NULL, 0,
93 N_("Display sections for exception handling"), 0 },
95 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
96 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
97 N_("Display DWARF section content. SECTION can be one of abbrev, "
98 "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
99 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
100 { "hex-dump", 'x', "SECTION", 0,
101 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
102 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
103 N_("Print string contents of sections"), 0 },
104 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
105 { "archive-index", 'c', NULL, 0,
106 N_("Display the symbol index of an archive"), 0 },
108 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
109 { "numeric-addresses", 'N', NULL, 0,
110 N_("Do not find symbol names for addresses in DWARF data"), 0 },
111 { "unresolved-address-offsets", 'U', NULL, 0,
112 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
113 { "wide", 'W', NULL, 0,
114 N_("Ignored for compatibility (lines always wide)"), 0 },
115 { NULL, 0, NULL, 0, NULL, 0 }
118 /* Short description of program. */
119 static const char doc[] = N_("\
120 Print information from ELF file in human-readable form.");
122 /* Strings for arguments in help texts. */
123 static const char args_doc[] = N_("FILE...");
125 /* Prototype for option handler. */
126 static error_t parse_opt (int key, char *arg, struct argp_state *state);
128 /* Data structure to communicate with argp functions. */
129 static struct argp argp =
131 options, parse_opt, args_doc, doc, NULL, NULL, NULL
134 /* If non-null, the section from which we should read to (compressed) ELF. */
135 static const char *elf_input_section = NULL;
137 /* Flags set by the option controlling the output. */
139 /* True if dynamic segment should be printed. */
140 static bool print_dynamic_table;
142 /* True if the file header should be printed. */
143 static bool print_file_header;
145 /* True if the program headers should be printed. */
146 static bool print_program_header;
148 /* True if relocations should be printed. */
149 static bool print_relocations;
151 /* True if the section headers should be printed. */
152 static bool print_section_header;
154 /* True if the symbol table should be printed. */
155 static bool print_symbol_table;
157 /* True if the version information should be printed. */
158 static bool print_version_info;
160 /* True if section groups should be printed. */
161 static bool print_section_groups;
163 /* True if bucket list length histogram should be printed. */
164 static bool print_histogram;
166 /* True if the architecture specific data should be printed. */
167 static bool print_arch;
169 /* True if note section content should be printed. */
170 static bool print_notes;
172 /* True if SHF_STRINGS section content should be printed. */
173 static bool print_string_sections;
175 /* True if archive index should be printed. */
176 static bool print_archive_index;
178 /* True if any of the control options except print_archive_index is set. */
179 static bool any_control_option;
181 /* True if we should print addresses from DWARF in symbolic form. */
182 static bool print_address_names = true;
184 /* True if we should print raw values instead of relativized addresses. */
185 static bool print_unresolved_addresses = false;
187 /* True if we should print the .debug_aranges section using libdw. */
188 static bool decodedaranges = false;
190 /* True if we should print the .debug_aranges section using libdw. */
191 static bool decodedline = false;
193 /* Select printing of debugging sections. */
194 static enum section_e
196 section_abbrev = 1, /* .debug_abbrev */
197 section_aranges = 2, /* .debug_aranges */
198 section_frame = 4, /* .debug_frame or .eh_frame & al. */
199 section_info = 8, /* .debug_info, .debug_types */
200 section_types = section_info,
201 section_line = 16, /* .debug_line */
202 section_loc = 32, /* .debug_loc */
203 section_pubnames = 64, /* .debug_pubnames */
204 section_str = 128, /* .debug_str */
205 section_macinfo = 256, /* .debug_macinfo */
206 section_ranges = 512, /* .debug_ranges */
207 section_exception = 1024, /* .eh_frame & al. */
208 section_gdb_index = 2048, /* .gdb_index */
209 section_macro = 4096, /* .debug_macro */
210 section_all = (section_abbrev | section_aranges | section_frame
211 | section_info | section_line | section_loc
212 | section_pubnames | section_str | section_macinfo
213 | section_ranges | section_exception | section_gdb_index
215 } print_debug_sections, implicit_debug_sections;
217 /* Select hex dumping of sections. */
218 static struct section_argument *dump_data_sections;
219 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
221 /* Select string dumping of sections. */
222 static struct section_argument *string_sections;
223 static struct section_argument **string_sections_tail = &string_sections;
225 struct section_argument
227 struct section_argument *next;
232 /* Numbers of sections and program headers in the file. */
237 /* Declarations of local functions. */
238 static void process_file (int fd, const char *fname, bool only_one);
239 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
240 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
241 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
242 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
243 static void print_scngrp (Ebl *ebl);
244 static void print_dynamic (Ebl *ebl);
245 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
246 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
248 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
250 static void print_symtab (Ebl *ebl, int type);
251 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
252 static void print_verinfo (Ebl *ebl);
253 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
254 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
255 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
257 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
258 static void handle_hash (Ebl *ebl);
259 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
260 static void print_liblist (Ebl *ebl);
261 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
262 static void dump_data (Ebl *ebl);
263 static void dump_strings (Ebl *ebl);
264 static void print_strings (Ebl *ebl);
265 static void dump_archive_index (Elf *, const char *);
269 main (int argc, char *argv[])
272 setlocale (LC_ALL, "");
274 /* Initialize the message catalog. */
275 textdomain (PACKAGE_TARNAME);
277 /* Parse and process arguments. */
279 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
281 /* Before we start tell the ELF library which version we are using. */
282 elf_version (EV_CURRENT);
284 /* Now process all the files given at the command line. */
285 bool only_one = remaining + 1 == argc;
289 int fd = open (argv[remaining], O_RDONLY);
292 error (0, errno, gettext ("cannot open input file"));
296 process_file (fd, argv[remaining], only_one);
300 while (++remaining < argc);
302 return error_message_count != 0;
306 /* Handle program arguments. */
308 parse_opt (int key, char *arg,
309 struct argp_state *state __attribute__ ((unused)))
311 void add_dump_section (const char *name, bool implicit)
313 struct section_argument *a = xmalloc (sizeof *a);
316 a->implicit = implicit;
317 struct section_argument ***tailp
318 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
326 print_file_header = true;
327 print_program_header = true;
328 print_relocations = true;
329 print_section_header = true;
330 print_symbol_table = true;
331 print_version_info = true;
332 print_dynamic_table = true;
333 print_section_groups = true;
334 print_histogram = true;
337 implicit_debug_sections |= section_exception;
338 add_dump_section (".strtab", true);
339 add_dump_section (".dynstr", true);
340 add_dump_section (".comment", true);
341 any_control_option = true;
345 any_control_option = true;
348 print_dynamic_table = true;
349 any_control_option = true;
352 print_debug_sections |= section_exception;
353 any_control_option = true;
356 print_section_groups = true;
357 any_control_option = true;
360 print_file_header = true;
361 any_control_option = true;
364 print_histogram = true;
365 any_control_option = true;
368 print_program_header = true;
369 any_control_option = true;
373 any_control_option = true;
376 print_relocations = true;
377 any_control_option = true;
380 print_section_header = true;
381 any_control_option = true;
384 print_symbol_table = true;
385 any_control_option = true;
388 print_version_info = true;
389 any_control_option = true;
392 print_archive_index = true;
396 print_debug_sections = section_all;
397 else if (strcmp (arg, "abbrev") == 0)
398 print_debug_sections |= section_abbrev;
399 else if (strcmp (arg, "aranges") == 0)
400 print_debug_sections |= section_aranges;
401 else if (strcmp (arg, "decodedaranges") == 0)
403 print_debug_sections |= section_aranges;
404 decodedaranges = true;
406 else if (strcmp (arg, "ranges") == 0)
408 print_debug_sections |= section_ranges;
409 implicit_debug_sections |= section_info;
411 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
412 print_debug_sections |= section_frame;
413 else if (strcmp (arg, "info") == 0)
414 print_debug_sections |= section_info;
415 else if (strcmp (arg, "loc") == 0)
417 print_debug_sections |= section_loc;
418 implicit_debug_sections |= section_info;
420 else if (strcmp (arg, "line") == 0)
421 print_debug_sections |= section_line;
422 else if (strcmp (arg, "decodedline") == 0)
424 print_debug_sections |= section_line;
427 else if (strcmp (arg, "pubnames") == 0)
428 print_debug_sections |= section_pubnames;
429 else if (strcmp (arg, "str") == 0)
430 print_debug_sections |= section_str;
431 else if (strcmp (arg, "macinfo") == 0)
432 print_debug_sections |= section_macinfo;
433 else if (strcmp (arg, "macro") == 0)
434 print_debug_sections |= section_macro;
435 else if (strcmp (arg, "exception") == 0)
436 print_debug_sections |= section_exception;
437 else if (strcmp (arg, "gdb_index") == 0)
438 print_debug_sections |= section_gdb_index;
441 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
443 argp_help (&argp, stderr, ARGP_HELP_SEE,
444 program_invocation_short_name);
447 any_control_option = true;
450 any_control_option = true;
453 print_string_sections = true;
458 add_dump_section (arg, false);
459 any_control_option = true;
462 print_address_names = false;
465 print_unresolved_addresses = true;
467 case ARGP_KEY_NO_ARGS:
468 fputs (gettext ("Missing file name.\n"), stderr);
471 if (! any_control_option && ! print_archive_index)
473 fputs (gettext ("No operation specified.\n"), stderr);
475 argp_help (&argp, stderr, ARGP_HELP_SEE,
476 program_invocation_short_name);
480 case 'W': /* Ignored. */
482 case ELF_INPUT_SECTION:
484 elf_input_section = ".gnu_debugdata";
486 elf_input_section = arg;
489 return ARGP_ERR_UNKNOWN;
495 /* Print the version information. */
497 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
499 fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
500 fprintf (stream, gettext ("\
501 Copyright (C) %s Red Hat, Inc.\n\
502 This is free software; see the source for copying conditions. There is NO\n\
503 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
505 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
509 /* Create a file descriptor to read the data from the
510 elf_input_section given a file descriptor to an ELF file. */
512 open_input_section (int fd)
517 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
520 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
525 if (elf_getshdrnum (elf, &shnums) < 0)
527 error (0, 0, gettext ("cannot determine number of sections: %s"),
534 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
536 error (0, 0, gettext ("cannot get section header string table index"));
540 for (cnt = 0; cnt < shnums; ++cnt)
542 Elf_Scn *scn = elf_getscn (elf, cnt);
545 error (0, 0, gettext ("cannot get section: %s"),
551 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
552 if (unlikely (shdr == NULL))
554 error (0, 0, gettext ("cannot get section header: %s"),
559 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
562 error (0, 0, gettext ("cannot get section name"));
566 if (strcmp (sname, elf_input_section) == 0)
568 Elf_Data *data = elf_rawdata (scn, NULL);
571 error (0, 0, gettext ("cannot get %s content: %s"),
572 sname, elf_errmsg (-1));
576 /* Create (and immediately unlink) a temporary file to store
577 section data in to create a file descriptor for it. */
578 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
579 static const char suffix[] = "/readelfXXXXXX";
580 int tmplen = strlen (tmpdir) + sizeof (suffix);
581 char *tempname = alloca (tmplen);
582 sprintf (tempname, "%s%s", tmpdir, suffix);
584 int sfd = mkstemp (tempname);
587 error (0, 0, gettext ("cannot create temp file '%s'"),
593 ssize_t size = data->d_size;
594 if (write_retry (sfd, data->d_buf, size) != size)
596 error (0, 0, gettext ("cannot write section data"));
600 if (elf_end (elf) != 0)
602 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
607 if (lseek (sfd, 0, SEEK_SET) == -1)
609 error (0, 0, gettext ("error while rewinding file descriptor"));
617 /* Named section not found. */
618 if (elf_end (elf) != 0)
619 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
624 /* Check if the file is an archive, and if so dump its index. */
626 check_archive_index (int fd, const char *fname, bool only_one)
628 /* Create an `Elf' descriptor. */
629 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
631 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
635 if (elf_kind (elf) == ELF_K_AR)
638 printf ("\n%s:\n\n", fname);
639 dump_archive_index (elf, fname);
643 gettext ("'%s' is not an archive, cannot print archive index"),
646 /* Now we can close the descriptor. */
647 if (elf_end (elf) != 0)
648 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
653 /* Trivial callback used for checking if we opened an archive. */
655 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
656 void **userdata __attribute__ ((unused)),
657 const char *name __attribute__ ((unused)),
658 Dwarf_Addr base __attribute__ ((unused)),
662 return DWARF_CB_ABORT;
663 *(bool *) arg = true;
667 struct process_dwflmod_args
674 process_dwflmod (Dwfl_Module *dwflmod,
675 void **userdata __attribute__ ((unused)),
676 const char *name __attribute__ ((unused)),
677 Dwarf_Addr base __attribute__ ((unused)),
680 const struct process_dwflmod_args *a = arg;
682 /* Print the file name. */
686 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
688 printf ("\n%s:\n\n", fname);
691 process_elf_file (dwflmod, a->fd);
696 /* Stub libdwfl callback, only the ELF handle already open is ever used.
697 Only used for finding the alternate debug file if the Dwarf comes from
698 the main file. We are not interested in separate debuginfo. */
700 find_no_debuginfo (Dwfl_Module *mod,
704 const char *file_name,
705 const char *debuglink_file,
706 GElf_Word debuglink_crc,
707 char **debuginfo_file_name)
710 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
712 /* We are only interested if the Dwarf has been setup on the main
713 elf file but is only missing the alternate debug link. If dwbias
714 hasn't even been setup, this is searching for separate debuginfo
715 for the main elf. We don't care in that case. */
716 if (dwbias == (Dwarf_Addr) -1)
719 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
720 file_name, debuglink_file,
721 debuglink_crc, debuginfo_file_name);
724 /* Process one input file. */
726 process_file (int fd, const char *fname, bool only_one)
728 if (print_archive_index)
729 check_archive_index (fd, fname, only_one);
731 if (!any_control_option)
734 if (elf_input_section != NULL)
736 /* Replace fname and fd with section content. */
737 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
738 sprintf (fnname, "%s:%s", fname, elf_input_section);
739 fd = open_input_section (fd);
742 error (0, 0, gettext ("No such section '%s' in '%s'"),
743 elf_input_section, fname);
749 /* Duplicate an fd for dwfl_report_offline to swallow. */
750 int dwfl_fd = dup (fd);
751 if (unlikely (dwfl_fd < 0))
752 error (EXIT_FAILURE, errno, "dup");
754 /* Use libdwfl in a trivial way to open the libdw handle for us.
755 This takes care of applying relocations to DWARF data in ET_REL files. */
756 static const Dwfl_Callbacks callbacks =
758 .section_address = dwfl_offline_section_address,
759 .find_debuginfo = find_no_debuginfo
761 Dwfl *dwfl = dwfl_begin (&callbacks);
762 if (likely (dwfl != NULL))
763 /* Let 0 be the logical address of the file (or first in archive). */
764 dwfl->offline_next_address = 0;
765 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
768 if (fstat64 (dwfl_fd, &st) != 0)
769 error (0, errno, gettext ("cannot stat input file"));
770 else if (unlikely (st.st_size == 0))
771 error (0, 0, gettext ("input file is empty"));
773 error (0, 0, gettext ("failed reading '%s': %s"),
774 fname, dwfl_errmsg (-1));
775 close (dwfl_fd); /* Consumed on success, not on failure. */
779 dwfl_report_end (dwfl, NULL, NULL);
783 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
785 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
788 /* Process the one or more modules gleaned from this file. */
789 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
790 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
794 /* Need to close the replaced fd if we created it. Caller takes
796 if (elf_input_section != NULL)
801 /* Process one ELF file. */
803 process_elf_file (Dwfl_Module *dwflmod, int fd)
806 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
809 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
814 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
818 Ebl *ebl = ebl_openbackend (elf);
819 if (unlikely (ebl == NULL))
822 error (0, errno, gettext ("cannot create EBL handle"));
826 /* Determine the number of sections. */
827 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
828 error (EXIT_FAILURE, 0,
829 gettext ("cannot determine number of sections: %s"),
832 /* Determine the number of phdrs. */
833 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
834 error (EXIT_FAILURE, 0,
835 gettext ("cannot determine number of program headers: %s"),
838 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs
839 and may have applied relocation to some sections.
840 So we need to get a fresh Elf handle on the file to display those. */
841 bool print_unrelocated = (print_section_header
843 || dump_data_sections != NULL
846 Elf *pure_elf = NULL;
848 if (ehdr->e_type == ET_REL && print_unrelocated)
850 /* Read the file afresh. */
851 off64_t aroff = elf_getaroff (elf);
852 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
855 /* Archive member. */
856 (void) elf_rand (pure_elf, aroff);
857 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
861 if (pure_elf == NULL)
863 pure_ebl = ebl_openbackend (pure_elf);
864 if (pure_ebl == NULL)
868 if (print_file_header)
869 print_ehdr (ebl, ehdr);
870 if (print_section_header)
871 print_shdr (pure_ebl, ehdr);
872 if (print_program_header)
873 print_phdr (ebl, ehdr);
874 if (print_section_groups)
876 if (print_dynamic_table)
878 if (print_relocations)
879 print_relocs (pure_ebl, ehdr);
882 if (print_symbol_table)
883 print_symtab (ebl, SHT_DYNSYM);
884 if (print_version_info)
886 if (print_symbol_table)
887 print_symtab (ebl, SHT_SYMTAB);
891 print_attributes (ebl, ehdr);
892 if (dump_data_sections != NULL)
893 dump_data (pure_ebl);
894 if (string_sections != NULL)
896 if ((print_debug_sections | implicit_debug_sections) != 0)
897 print_debug (dwflmod, ebl, ehdr);
899 handle_notes (pure_ebl, ehdr);
900 if (print_string_sections)
903 ebl_closebackend (ebl);
907 ebl_closebackend (pure_ebl);
913 /* Print file type. */
915 print_file_type (unsigned short int e_type)
917 if (likely (e_type <= ET_CORE))
919 static const char *const knowntypes[] =
922 N_("REL (Relocatable file)"),
923 N_("EXEC (Executable file)"),
924 N_("DYN (Shared object file)"),
925 N_("CORE (Core file)")
927 puts (gettext (knowntypes[e_type]));
929 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
930 printf (gettext ("OS Specific: (%x)\n"), e_type);
931 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
932 printf (gettext ("Processor Specific: (%x)\n"), e_type);
938 /* Print ELF header. */
940 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
942 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
943 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
944 printf (" %02hhx", ehdr->e_ident[cnt]);
946 printf (gettext ("\n Class: %s\n"),
947 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
948 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
951 printf (gettext (" Data: %s\n"),
952 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
953 ? "2's complement, little endian"
954 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
955 ? "2's complement, big endian" : "\?\?\?");
957 printf (gettext (" Ident Version: %hhd %s\n"),
958 ehdr->e_ident[EI_VERSION],
959 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
963 printf (gettext (" OS/ABI: %s\n"),
964 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
966 printf (gettext (" ABI Version: %hhd\n"),
967 ehdr->e_ident[EI_ABIVERSION]);
969 fputs_unlocked (gettext (" Type: "), stdout);
970 print_file_type (ehdr->e_type);
972 printf (gettext (" Machine: %s\n"), ebl->name);
974 printf (gettext (" Version: %d %s\n"),
976 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
978 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
981 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
982 ehdr->e_phoff, gettext ("(bytes into file)"));
984 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
985 ehdr->e_shoff, gettext ("(bytes into file)"));
987 printf (gettext (" Flags: %s\n"),
988 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
990 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
991 ehdr->e_ehsize, gettext ("(bytes)"));
993 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
994 ehdr->e_phentsize, gettext ("(bytes)"));
996 printf (gettext (" Number of program headers entries: %" PRId16),
998 if (ehdr->e_phnum == PN_XNUM)
1001 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1003 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1004 (uint32_t) shdr->sh_info);
1006 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1008 fputc_unlocked ('\n', stdout);
1010 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1011 ehdr->e_shentsize, gettext ("(bytes)"));
1013 printf (gettext (" Number of section headers entries: %" PRId16),
1015 if (ehdr->e_shnum == 0)
1018 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1020 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1021 (uint32_t) shdr->sh_size);
1023 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1025 fputc_unlocked ('\n', stdout);
1027 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1030 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1032 /* We managed to get the zeroth section. */
1033 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1034 (uint32_t) shdr->sh_link);
1037 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1038 buf[sizeof (buf) - 1] = '\0';
1041 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1045 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1051 get_visibility_type (int value)
1069 /* Print the section headers. */
1071 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1076 if (! print_file_header)
1078 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1080 ehdr->e_shnum, ehdr->e_shoff);
1082 /* Get the section header string table index. */
1083 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1084 error (EXIT_FAILURE, 0,
1085 gettext ("cannot get section header string table index"));
1087 puts (gettext ("Section Headers:"));
1089 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1090 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1092 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1094 for (cnt = 0; cnt < shnum; ++cnt)
1096 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1098 if (unlikely (scn == NULL))
1099 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1102 /* Get the section header. */
1104 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1105 if (unlikely (shdr == NULL))
1106 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1111 if (shdr->sh_flags & SHF_WRITE)
1113 if (shdr->sh_flags & SHF_ALLOC)
1115 if (shdr->sh_flags & SHF_EXECINSTR)
1117 if (shdr->sh_flags & SHF_MERGE)
1119 if (shdr->sh_flags & SHF_STRINGS)
1121 if (shdr->sh_flags & SHF_INFO_LINK)
1123 if (shdr->sh_flags & SHF_LINK_ORDER)
1125 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1127 if (shdr->sh_flags & SHF_GROUP)
1129 if (shdr->sh_flags & SHF_TLS)
1131 if (shdr->sh_flags & SHF_ORDERED)
1133 if (shdr->sh_flags & SHF_EXCLUDE)
1138 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1139 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1142 elf_strptr (ebl->elf, shstrndx, shdr->sh_name)
1144 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1145 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1146 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1147 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1148 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1149 shdr->sh_addralign);
1152 fputc_unlocked ('\n', stdout);
1156 /* Print the program header. */
1158 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1160 if (ehdr->e_phnum == 0)
1161 /* No program header, this is OK in relocatable objects. */
1164 puts (gettext ("Program Headers:"));
1165 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1167 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1170 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1172 /* Process all program headers. */
1173 bool has_relro = false;
1174 GElf_Addr relro_from = 0;
1175 GElf_Addr relro_to = 0;
1176 for (size_t cnt = 0; cnt < phnum; ++cnt)
1180 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1182 /* If for some reason the header cannot be returned show this. */
1183 if (unlikely (phdr == NULL))
1189 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1190 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1191 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1193 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1194 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1197 phdr->p_flags & PF_R ? 'R' : ' ',
1198 phdr->p_flags & PF_W ? 'W' : ' ',
1199 phdr->p_flags & PF_X ? 'E' : ' ',
1202 if (phdr->p_type == PT_INTERP)
1204 /* If we are sure the file offset is valid then we can show
1205 the user the name of the interpreter. We check whether
1206 there is a section at the file offset. Normally there
1207 would be a section called ".interp". But in separate
1208 .debug files it is a NOBITS section (and so doesn't match
1209 with gelf_offscn). Which probably means the offset is
1210 not valid another reason could be because the ELF file
1211 just doesn't contain any section headers, in that case
1212 just play it safe and don't display anything. */
1214 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1216 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1219 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1221 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1222 && filedata != NULL && phdr->p_offset < maxsize
1223 && phdr->p_filesz <= maxsize - phdr->p_offset
1224 && memchr (filedata + phdr->p_offset, '\0',
1225 phdr->p_filesz) != NULL)
1226 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1227 filedata + phdr->p_offset);
1229 else if (phdr->p_type == PT_GNU_RELRO)
1232 relro_from = phdr->p_vaddr;
1233 relro_to = relro_from + phdr->p_memsz;
1237 if (ehdr->e_shnum == 0)
1238 /* No sections in the file. Punt. */
1241 /* Get the section header string table index. */
1243 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1244 error (EXIT_FAILURE, 0,
1245 gettext ("cannot get section header string table index"));
1247 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1249 for (size_t cnt = 0; cnt < phnum; ++cnt)
1251 /* Print the segment number. */
1252 printf (" %2.2zu ", cnt);
1255 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1256 /* This must not happen. */
1257 if (unlikely (phdr == NULL))
1258 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1261 /* Iterate over the sections. */
1262 bool in_relro = false;
1264 for (size_t inner = 1; inner < shnum; ++inner)
1266 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1267 /* This should not happen. */
1268 if (unlikely (scn == NULL))
1269 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1272 /* Get the section header. */
1274 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1275 if (unlikely (shdr == NULL))
1276 error (EXIT_FAILURE, 0,
1277 gettext ("cannot get section header: %s"),
1280 if (shdr->sh_size > 0
1281 /* Compare allocated sections by VMA, unallocated
1282 sections by file offset. */
1283 && (shdr->sh_flags & SHF_ALLOC
1284 ? (shdr->sh_addr >= phdr->p_vaddr
1285 && (shdr->sh_addr + shdr->sh_size
1286 <= phdr->p_vaddr + phdr->p_memsz))
1287 : (shdr->sh_offset >= phdr->p_offset
1288 && (shdr->sh_offset + shdr->sh_size
1289 <= phdr->p_offset + phdr->p_filesz))))
1291 if (has_relro && !in_relro
1292 && shdr->sh_addr >= relro_from
1293 && shdr->sh_addr + shdr->sh_size <= relro_to)
1295 fputs_unlocked (" [RELRO:", stdout);
1298 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1300 fputs_unlocked ("]", stdout);
1303 else if (has_relro && in_relro
1304 && shdr->sh_addr + shdr->sh_size > relro_to)
1305 fputs_unlocked ("] <RELRO:", stdout);
1306 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1310 fputs_unlocked (" [RO:", stdout);
1316 /* Determine the segment this section is part of. */
1318 GElf_Phdr *phdr2 = NULL;
1319 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1321 GElf_Phdr phdr2_mem;
1322 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1324 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1325 && shdr->sh_addr >= phdr2->p_vaddr
1326 && (shdr->sh_addr + shdr->sh_size
1327 <= phdr2->p_vaddr + phdr2->p_memsz))
1333 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1335 fputs_unlocked (" [RO:", stdout);
1338 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1340 fputs_unlocked ("]", stdout);
1347 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1349 /* Signal that this sectin is only partially covered. */
1350 if (has_relro && in_relro
1351 && shdr->sh_addr + shdr->sh_size > relro_to)
1353 fputs_unlocked (">", stdout);
1358 if (in_relro || in_ro)
1359 fputs_unlocked ("]", stdout);
1361 /* Finish the line. */
1362 fputc_unlocked ('\n', stdout);
1368 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1370 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1375 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1377 /* Get the data of the section. */
1378 Elf_Data *data = elf_getdata (scn, NULL);
1380 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1381 GElf_Shdr symshdr_mem;
1382 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1383 Elf_Data *symdata = elf_getdata (symscn, NULL);
1385 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1389 /* Get the section header string table index. */
1391 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1392 error (EXIT_FAILURE, 0,
1393 gettext ("cannot get section header string table index"));
1395 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1398 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1400 printf ((grpref[0] & GRP_COMDAT)
1402 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1404 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1405 data->d_size / sizeof (Elf32_Word) - 1)
1407 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1408 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1409 data->d_size / sizeof (Elf32_Word) - 1),
1411 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1413 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1414 ?: gettext ("<INVALID SYMBOL>"),
1415 data->d_size / sizeof (Elf32_Word) - 1);
1417 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1419 GElf_Shdr grpshdr_mem;
1420 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1424 printf (" [%2u] %s\n",
1427 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1428 ? str : gettext ("<INVALID SECTION>"));
1434 print_scngrp (Ebl *ebl)
1436 /* Find all relocation sections and handle them. */
1437 Elf_Scn *scn = NULL;
1439 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1441 /* Handle the section if it is a symbol table. */
1443 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1445 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1446 handle_scngrp (ebl, scn, shdr);
1451 static const struct flags
1457 { DF_ORIGIN, "ORIGIN" },
1458 { DF_SYMBOLIC, "SYMBOLIC" },
1459 { DF_TEXTREL, "TEXTREL" },
1460 { DF_BIND_NOW, "BIND_NOW" },
1461 { DF_STATIC_TLS, "STATIC_TLS" }
1463 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1465 static const struct flags dt_flags_1[] =
1467 { DF_1_NOW, "NOW" },
1468 { DF_1_GLOBAL, "GLOBAL" },
1469 { DF_1_GROUP, "GROUP" },
1470 { DF_1_NODELETE, "NODELETE" },
1471 { DF_1_LOADFLTR, "LOADFLTR" },
1472 { DF_1_INITFIRST, "INITFIRST" },
1473 { DF_1_NOOPEN, "NOOPEN" },
1474 { DF_1_ORIGIN, "ORIGIN" },
1475 { DF_1_DIRECT, "DIRECT" },
1476 { DF_1_TRANS, "TRANS" },
1477 { DF_1_INTERPOSE, "INTERPOSE" },
1478 { DF_1_NODEFLIB, "NODEFLIB" },
1479 { DF_1_NODUMP, "NODUMP" },
1480 { DF_1_CONFALT, "CONFALT" },
1481 { DF_1_ENDFILTEE, "ENDFILTEE" },
1482 { DF_1_DISPRELDNE, "DISPRELDNE" },
1483 { DF_1_DISPRELPND, "DISPRELPND" },
1485 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1487 static const struct flags dt_feature_1[] =
1489 { DTF_1_PARINIT, "PARINIT" },
1490 { DTF_1_CONFEXP, "CONFEXP" }
1492 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1493 / sizeof (dt_feature_1[0]));
1495 static const struct flags dt_posflag_1[] =
1497 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1498 { DF_P1_GROUPPERM, "GROUPPERM" }
1500 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1501 / sizeof (dt_posflag_1[0]));
1505 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1511 for (cnt = 0; cnt < nflags; ++cnt)
1512 if (d_val & flags[cnt].mask)
1515 putchar_unlocked (' ');
1516 fputs_unlocked (flags[cnt].str, stdout);
1517 d_val &= ~flags[cnt].mask;
1524 putchar_unlocked (' ');
1525 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1528 putchar_unlocked ('\n');
1533 print_dt_flags (int class, GElf_Xword d_val)
1535 print_flags (class, d_val, dt_flags, ndt_flags);
1540 print_dt_flags_1 (int class, GElf_Xword d_val)
1542 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1547 print_dt_feature_1 (int class, GElf_Xword d_val)
1549 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1554 print_dt_posflag_1 (int class, GElf_Xword d_val)
1556 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1561 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1563 int class = gelf_getclass (ebl->elf);
1564 GElf_Shdr glink_mem;
1571 /* Get the data of the section. */
1572 data = elf_getdata (scn, NULL);
1576 /* Get the section header string table index. */
1577 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1578 error (EXIT_FAILURE, 0,
1579 gettext ("cannot get section header string table index"));
1581 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1583 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1585 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1588 printf (ngettext ("\
1589 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1591 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1592 shdr->sh_size / sh_entsize),
1593 (unsigned long int) (shdr->sh_size / sh_entsize),
1594 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1596 (int) shdr->sh_link,
1597 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1598 fputs_unlocked (gettext (" Type Value\n"), stdout);
1600 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1603 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1609 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1617 /* No further output. */
1618 fputc_unlocked ('\n', stdout);
1622 printf (gettext ("Shared library: [%s]\n"),
1623 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1627 printf (gettext ("Library soname: [%s]\n"),
1628 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1632 printf (gettext ("Library rpath: [%s]\n"),
1633 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1637 printf (gettext ("Library runpath: [%s]\n"),
1638 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1651 case DT_INIT_ARRAYSZ:
1652 case DT_FINI_ARRAYSZ:
1655 case DT_GNU_CONFLICTSZ:
1656 case DT_GNU_LIBLISTSZ:
1657 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1664 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1668 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1670 puts (tagname ?: "???");
1674 print_dt_flags (class, dyn->d_un.d_val);
1678 print_dt_flags_1 (class, dyn->d_un.d_val);
1682 print_dt_feature_1 (class, dyn->d_un.d_val);
1686 print_dt_posflag_1 (class, dyn->d_un.d_val);
1690 printf ("%#0*" PRIx64 "\n",
1691 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1698 /* Print the dynamic segment. */
1700 print_dynamic (Ebl *ebl)
1702 for (size_t i = 0; i < phnum; ++i)
1705 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1707 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1709 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1711 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1712 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1713 handle_dynamic (ebl, scn, shdr);
1720 /* Print relocations. */
1722 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1724 /* Find all relocation sections and handle them. */
1725 Elf_Scn *scn = NULL;
1727 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1729 /* Handle the section if it is a symbol table. */
1731 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1733 if (likely (shdr != NULL))
1735 if (shdr->sh_type == SHT_REL)
1736 handle_relocs_rel (ebl, ehdr, scn, shdr);
1737 else if (shdr->sh_type == SHT_RELA)
1738 handle_relocs_rela (ebl, ehdr, scn, shdr);
1744 /* Handle a relocation section. */
1746 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1748 int class = gelf_getclass (ebl->elf);
1749 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1750 int nentries = shdr->sh_size / sh_entsize;
1752 /* Get the data of the section. */
1753 Elf_Data *data = elf_getdata (scn, NULL);
1757 /* Get the symbol table information. */
1758 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1759 GElf_Shdr symshdr_mem;
1760 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1761 Elf_Data *symdata = elf_getdata (symscn, NULL);
1763 /* Get the section header of the section the relocations are for. */
1764 GElf_Shdr destshdr_mem;
1765 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1768 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1770 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1775 /* Search for the optional extended section index table. */
1776 Elf_Data *xndxdata = NULL;
1777 int xndxscnidx = elf_scnshndx (scn);
1778 if (unlikely (xndxscnidx > 0))
1779 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1781 /* Get the section header string table index. */
1783 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1784 error (EXIT_FAILURE, 0,
1785 gettext ("cannot get section header string table index"));
1787 if (shdr->sh_info != 0)
1788 printf (ngettext ("\
1789 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1791 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1794 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1795 (unsigned int) shdr->sh_info,
1796 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1800 /* The .rel.dyn section does not refer to a specific section but
1801 instead of section index zero. Do not try to print a section
1803 printf (ngettext ("\
1804 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1806 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1808 (unsigned int) elf_ndxscn (scn),
1809 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1812 fputs_unlocked (class == ELFCLASS32
1814 Offset Type Value Name\n")
1816 Offset Type Value Name\n"),
1819 int is_statically_linked = 0;
1820 for (int cnt = 0; cnt < nentries; ++cnt)
1823 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1824 if (likely (rel != NULL))
1829 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1830 GELF_R_SYM (rel->r_info),
1832 if (unlikely (sym == NULL))
1834 /* As a special case we have to handle relocations in static
1835 executables. This only happens for IRELATIVE relocations
1836 (so far). There is no symbol table. */
1837 if (is_statically_linked == 0)
1839 /* Find the program header and look for a PT_INTERP entry. */
1840 is_statically_linked = -1;
1841 if (ehdr->e_type == ET_EXEC)
1843 is_statically_linked = 1;
1845 for (size_t inner = 0; inner < phnum; ++inner)
1848 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1850 if (phdr != NULL && phdr->p_type == PT_INTERP)
1852 is_statically_linked = -1;
1859 if (is_statically_linked > 0 && shdr->sh_link == 0)
1861 %#0*" PRIx64 " %-20s %*s %s\n",
1862 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1863 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1864 /* Avoid the leading R_ which isn't carrying any
1866 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1867 buf, sizeof (buf)) + 2
1868 : gettext ("<INVALID RELOC>"),
1869 class == ELFCLASS32 ? 10 : 18, "",
1870 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1872 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1873 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1874 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1875 /* Avoid the leading R_ which isn't carrying any
1877 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1878 buf, sizeof (buf)) + 2
1879 : gettext ("<INVALID RELOC>"),
1880 gettext ("INVALID SYMBOL"),
1881 (long int) GELF_R_SYM (rel->r_info));
1883 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1884 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1885 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1886 likely (ebl_reloc_type_check (ebl,
1887 GELF_R_TYPE (rel->r_info)))
1888 /* Avoid the leading R_ which isn't carrying any
1890 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1891 buf, sizeof (buf)) + 2
1892 : gettext ("<INVALID RELOC>"),
1893 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1894 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1897 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
1898 sym->st_shndx == SHN_XINDEX
1899 ? xndx : sym->st_shndx),
1902 if (unlikely (destshdr == NULL))
1903 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1904 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1905 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1906 /* Avoid the leading R_ which isn't carrying any
1908 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1909 buf, sizeof (buf)) + 2
1910 : gettext ("<INVALID RELOC>"),
1911 gettext ("INVALID SECTION"),
1912 (long int) (sym->st_shndx == SHN_XINDEX
1913 ? xndx : sym->st_shndx));
1915 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1916 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1917 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1918 /* Avoid the leading R_ which isn't carrying any
1920 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1921 buf, sizeof (buf)) + 2
1922 : gettext ("<INVALID RELOC>"),
1923 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1924 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1931 /* Handle a relocation section. */
1933 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1935 int class = gelf_getclass (ebl->elf);
1936 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1937 int nentries = shdr->sh_size / sh_entsize;
1939 /* Get the data of the section. */
1940 Elf_Data *data = elf_getdata (scn, NULL);
1944 /* Get the symbol table information. */
1945 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1946 GElf_Shdr symshdr_mem;
1947 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1948 Elf_Data *symdata = elf_getdata (symscn, NULL);
1950 /* Get the section header of the section the relocations are for. */
1951 GElf_Shdr destshdr_mem;
1952 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1955 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1957 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1962 /* Search for the optional extended section index table. */
1963 Elf_Data *xndxdata = NULL;
1964 int xndxscnidx = elf_scnshndx (scn);
1965 if (unlikely (xndxscnidx > 0))
1966 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1968 /* Get the section header string table index. */
1970 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1971 error (EXIT_FAILURE, 0,
1972 gettext ("cannot get section header string table index"));
1974 if (shdr->sh_info != 0)
1975 printf (ngettext ("\
1976 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1978 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1981 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1982 (unsigned int) shdr->sh_info,
1983 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1987 /* The .rela.dyn section does not refer to a specific section but
1988 instead of section index zero. Do not try to print a section
1990 printf (ngettext ("\
1991 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1993 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1995 (unsigned int) elf_ndxscn (scn),
1996 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1999 fputs_unlocked (class == ELFCLASS32
2001 Offset Type Value Addend Name\n")
2003 Offset Type Value Addend Name\n"),
2006 int is_statically_linked = 0;
2007 for (int cnt = 0; cnt < nentries; ++cnt)
2010 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2011 if (likely (rel != NULL))
2016 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2017 GELF_R_SYM (rel->r_info),
2020 if (unlikely (sym == NULL))
2022 /* As a special case we have to handle relocations in static
2023 executables. This only happens for IRELATIVE relocations
2024 (so far). There is no symbol table. */
2025 if (is_statically_linked == 0)
2027 /* Find the program header and look for a PT_INTERP entry. */
2028 is_statically_linked = -1;
2029 if (ehdr->e_type == ET_EXEC)
2031 is_statically_linked = 1;
2033 for (size_t inner = 0; inner < phnum; ++inner)
2036 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2038 if (phdr != NULL && phdr->p_type == PT_INTERP)
2040 is_statically_linked = -1;
2047 if (is_statically_linked > 0 && shdr->sh_link == 0)
2049 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2050 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2051 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2052 /* Avoid the leading R_ which isn't carrying any
2054 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2055 buf, sizeof (buf)) + 2
2056 : gettext ("<INVALID RELOC>"),
2057 class == ELFCLASS32 ? 10 : 18, "",
2059 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2061 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2062 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2063 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2064 /* Avoid the leading R_ which isn't carrying any
2066 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2067 buf, sizeof (buf)) + 2
2068 : gettext ("<INVALID RELOC>"),
2069 gettext ("INVALID SYMBOL"),
2070 (long int) GELF_R_SYM (rel->r_info));
2072 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2074 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2075 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2076 likely (ebl_reloc_type_check (ebl,
2077 GELF_R_TYPE (rel->r_info)))
2078 /* Avoid the leading R_ which isn't carrying any
2080 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2081 buf, sizeof (buf)) + 2
2082 : gettext ("<INVALID RELOC>"),
2083 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2085 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2088 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
2089 sym->st_shndx == SHN_XINDEX
2090 ? xndx : sym->st_shndx),
2093 if (unlikely (shdr == NULL))
2094 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2095 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2096 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2097 /* Avoid the leading R_ which isn't carrying any
2099 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2100 buf, sizeof (buf)) + 2
2101 : gettext ("<INVALID RELOC>"),
2102 gettext ("INVALID SECTION"),
2103 (long int) (sym->st_shndx == SHN_XINDEX
2104 ? xndx : sym->st_shndx));
2107 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2108 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2109 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2110 /* Avoid the leading R_ which isn't carrying any
2112 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2113 buf, sizeof (buf)) + 2
2114 : gettext ("<INVALID RELOC>"),
2115 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2117 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2124 /* Print the program header. */
2126 print_symtab (Ebl *ebl, int type)
2128 /* Find the symbol table(s). For this we have to search through the
2130 Elf_Scn *scn = NULL;
2132 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2134 /* Handle the section if it is a symbol table. */
2136 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2138 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2139 handle_symtab (ebl, scn, shdr);
2145 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2147 Elf_Data *versym_data = NULL;
2148 Elf_Data *verneed_data = NULL;
2149 Elf_Data *verdef_data = NULL;
2150 Elf_Data *xndx_data = NULL;
2151 int class = gelf_getclass (ebl->elf);
2152 Elf32_Word verneed_stridx = 0;
2153 Elf32_Word verdef_stridx = 0;
2155 /* Get the data of the section. */
2156 Elf_Data *data = elf_getdata (scn, NULL);
2160 /* Find out whether we have other sections we might need. */
2161 Elf_Scn *runscn = NULL;
2162 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2164 GElf_Shdr runshdr_mem;
2165 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2167 if (likely (runshdr != NULL))
2169 if (runshdr->sh_type == SHT_GNU_versym
2170 && runshdr->sh_link == elf_ndxscn (scn))
2171 /* Bingo, found the version information. Now get the data. */
2172 versym_data = elf_getdata (runscn, NULL);
2173 else if (runshdr->sh_type == SHT_GNU_verneed)
2175 /* This is the information about the needed versions. */
2176 verneed_data = elf_getdata (runscn, NULL);
2177 verneed_stridx = runshdr->sh_link;
2179 else if (runshdr->sh_type == SHT_GNU_verdef)
2181 /* This is the information about the defined versions. */
2182 verdef_data = elf_getdata (runscn, NULL);
2183 verdef_stridx = runshdr->sh_link;
2185 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2186 && runshdr->sh_link == elf_ndxscn (scn))
2187 /* Extended section index. */
2188 xndx_data = elf_getdata (runscn, NULL);
2192 /* Get the section header string table index. */
2194 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2195 error (EXIT_FAILURE, 0,
2196 gettext ("cannot get section header string table index"));
2198 GElf_Shdr glink_mem;
2199 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2202 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2205 /* Now we can compute the number of entries in the section. */
2206 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2207 ? sizeof (Elf32_Sym)
2208 : sizeof (Elf64_Sym));
2210 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2211 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2213 (unsigned int) elf_ndxscn (scn),
2214 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2215 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2216 " %lu local symbols String table: [%2u] '%s'\n",
2218 (unsigned long int) shdr->sh_info,
2219 (unsigned int) shdr->sh_link,
2220 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2222 fputs_unlocked (class == ELFCLASS32
2224 Num: Value Size Type Bind Vis Ndx Name\n")
2226 Num: Value Size Type Bind Vis Ndx Name\n"),
2229 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2236 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2238 if (unlikely (sym == NULL))
2241 /* Determine the real section index. */
2242 if (likely (sym->st_shndx != SHN_XINDEX))
2243 xndx = sym->st_shndx;
2246 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2248 class == ELFCLASS32 ? 8 : 16,
2251 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2252 typebuf, sizeof (typebuf)),
2253 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2254 bindbuf, sizeof (bindbuf)),
2255 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2256 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2257 sizeof (scnbuf), NULL, shnum),
2258 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2260 if (versym_data != NULL)
2262 /* Get the version information. */
2263 GElf_Versym versym_mem;
2264 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2266 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2268 bool is_nobits = false;
2269 bool check_def = xndx != SHN_UNDEF;
2271 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2273 GElf_Shdr symshdr_mem;
2274 GElf_Shdr *symshdr =
2275 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2277 is_nobits = (symshdr != NULL
2278 && symshdr->sh_type == SHT_NOBITS);
2281 if (is_nobits || ! check_def)
2283 /* We must test both. */
2284 GElf_Vernaux vernaux_mem;
2285 GElf_Vernaux *vernaux = NULL;
2286 size_t vn_offset = 0;
2288 GElf_Verneed verneed_mem;
2289 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2291 while (verneed != NULL)
2293 size_t vna_offset = vn_offset;
2295 vernaux = gelf_getvernaux (verneed_data,
2296 vna_offset += verneed->vn_aux,
2298 while (vernaux != NULL
2299 && vernaux->vna_other != *versym
2300 && vernaux->vna_next != 0)
2302 /* Update the offset. */
2303 vna_offset += vernaux->vna_next;
2305 vernaux = (vernaux->vna_next == 0
2307 : gelf_getvernaux (verneed_data,
2312 /* Check whether we found the version. */
2313 if (vernaux != NULL && vernaux->vna_other == *versym)
2317 vn_offset += verneed->vn_next;
2318 verneed = (verneed->vn_next == 0
2320 : gelf_getverneed (verneed_data, vn_offset,
2324 if (vernaux != NULL && vernaux->vna_other == *versym)
2327 elf_strptr (ebl->elf, verneed_stridx,
2329 (unsigned int) vernaux->vna_other);
2332 else if (unlikely (! is_nobits))
2333 error (0, 0, gettext ("bad dynamic symbol"));
2338 if (check_def && *versym != 0x8001)
2340 /* We must test both. */
2341 size_t vd_offset = 0;
2343 GElf_Verdef verdef_mem;
2344 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2346 while (verdef != NULL)
2348 if (verdef->vd_ndx == (*versym & 0x7fff))
2349 /* Found the definition. */
2352 vd_offset += verdef->vd_next;
2353 verdef = (verdef->vd_next == 0
2355 : gelf_getverdef (verdef_data, vd_offset,
2361 GElf_Verdaux verdaux_mem;
2362 GElf_Verdaux *verdaux
2363 = gelf_getverdaux (verdef_data,
2364 vd_offset + verdef->vd_aux,
2367 if (verdaux != NULL)
2368 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2369 elf_strptr (ebl->elf, verdef_stridx,
2370 verdaux->vda_name));
2376 putchar_unlocked ('\n');
2381 /* Print version information. */
2383 print_verinfo (Ebl *ebl)
2385 /* Find the version information sections. For this we have to
2386 search through the section table. */
2387 Elf_Scn *scn = NULL;
2389 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2391 /* Handle the section if it is part of the versioning handling. */
2393 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2395 if (likely (shdr != NULL))
2397 if (shdr->sh_type == SHT_GNU_verneed)
2398 handle_verneed (ebl, scn, shdr);
2399 else if (shdr->sh_type == SHT_GNU_verdef)
2400 handle_verdef (ebl, scn, shdr);
2401 else if (shdr->sh_type == SHT_GNU_versym)
2402 handle_versym (ebl, scn, shdr);
2409 get_ver_flags (unsigned int flags)
2411 static char buf[32];
2415 return gettext ("none");
2417 if (flags & VER_FLG_BASE)
2418 endp = stpcpy (buf, "BASE ");
2422 if (flags & VER_FLG_WEAK)
2425 endp = stpcpy (endp, "| ");
2427 endp = stpcpy (endp, "WEAK ");
2430 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2432 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2433 buf[sizeof (buf) - 1] = '\0';
2441 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2443 int class = gelf_getclass (ebl->elf);
2445 /* Get the data of the section. */
2446 Elf_Data *data = elf_getdata (scn, NULL);
2450 /* Get the section header string table index. */
2452 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2453 error (EXIT_FAILURE, 0,
2454 gettext ("cannot get section header string table index"));
2456 GElf_Shdr glink_mem;
2457 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2460 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2463 printf (ngettext ("\
2464 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2466 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2468 (unsigned int) elf_ndxscn (scn),
2469 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2470 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2472 (unsigned int) shdr->sh_link,
2473 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2475 unsigned int offset = 0;
2476 for (int cnt = shdr->sh_info; --cnt >= 0; )
2478 /* Get the data at the next offset. */
2479 GElf_Verneed needmem;
2480 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2481 if (unlikely (need == NULL))
2484 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2485 offset, (unsigned short int) need->vn_version,
2486 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2487 (unsigned short int) need->vn_cnt);
2489 unsigned int auxoffset = offset + need->vn_aux;
2490 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2492 GElf_Vernaux auxmem;
2493 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2494 if (unlikely (aux == NULL))
2497 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2499 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2500 get_ver_flags (aux->vna_flags),
2501 (unsigned short int) aux->vna_other);
2503 auxoffset += aux->vna_next;
2506 /* Find the next offset. */
2507 offset += need->vn_next;
2513 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2515 /* Get the data of the section. */
2516 Elf_Data *data = elf_getdata (scn, NULL);
2520 /* Get the section header string table index. */
2522 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2523 error (EXIT_FAILURE, 0,
2524 gettext ("cannot get section header string table index"));
2526 GElf_Shdr glink_mem;
2527 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2530 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2533 int class = gelf_getclass (ebl->elf);
2534 printf (ngettext ("\
2535 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2537 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2539 (unsigned int) elf_ndxscn (scn),
2540 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2542 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2544 (unsigned int) shdr->sh_link,
2545 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2547 unsigned int offset = 0;
2548 for (int cnt = shdr->sh_info; --cnt >= 0; )
2550 /* Get the data at the next offset. */
2552 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2553 if (unlikely (def == NULL))
2556 unsigned int auxoffset = offset + def->vd_aux;
2557 GElf_Verdaux auxmem;
2558 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2559 if (unlikely (aux == NULL))
2563 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2564 offset, def->vd_version,
2565 get_ver_flags (def->vd_flags),
2568 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2570 auxoffset += aux->vda_next;
2571 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2573 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2574 if (unlikely (aux == NULL))
2577 printf (gettext (" %#06x: Parent %d: %s\n"),
2579 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2581 auxoffset += aux->vda_next;
2584 /* Find the next offset. */
2585 offset += def->vd_next;
2591 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2593 int class = gelf_getclass (ebl->elf);
2594 const char **vername;
2595 const char **filename;
2597 /* Get the data of the section. */
2598 Elf_Data *data = elf_getdata (scn, NULL);
2602 /* Get the section header string table index. */
2604 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2605 error (EXIT_FAILURE, 0,
2606 gettext ("cannot get section header string table index"));
2608 /* We have to find the version definition section and extract the
2610 Elf_Scn *defscn = NULL;
2611 Elf_Scn *needscn = NULL;
2613 Elf_Scn *verscn = NULL;
2614 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2616 GElf_Shdr vershdr_mem;
2617 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2619 if (likely (vershdr != NULL))
2621 if (vershdr->sh_type == SHT_GNU_verdef)
2623 else if (vershdr->sh_type == SHT_GNU_verneed)
2629 if (defscn != NULL || needscn != NULL)
2631 /* We have a version information (better should have). Now get
2632 the version names. First find the maximum version number. */
2636 /* Run through the version definitions and find the highest
2638 unsigned int offset = 0;
2640 GElf_Shdr defshdrmem;
2643 defdata = elf_getdata (defscn, NULL);
2644 if (unlikely (defdata == NULL))
2647 defshdr = gelf_getshdr (defscn, &defshdrmem);
2648 if (unlikely (defshdr == NULL))
2651 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2656 /* Get the data at the next offset. */
2657 def = gelf_getverdef (defdata, offset, &defmem);
2658 if (unlikely (def == NULL))
2661 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2663 offset += def->vd_next;
2666 if (needscn != NULL)
2668 unsigned int offset = 0;
2670 GElf_Shdr needshdrmem;
2671 GElf_Shdr *needshdr;
2673 needdata = elf_getdata (needscn, NULL);
2674 if (unlikely (needdata == NULL))
2677 needshdr = gelf_getshdr (needscn, &needshdrmem);
2678 if (unlikely (needshdr == NULL))
2681 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2683 GElf_Verneed needmem;
2685 unsigned int auxoffset;
2688 /* Get the data at the next offset. */
2689 need = gelf_getverneed (needdata, offset, &needmem);
2690 if (unlikely (need == NULL))
2693 /* Run through the auxiliary entries. */
2694 auxoffset = offset + need->vn_aux;
2695 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2697 GElf_Vernaux auxmem;
2700 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2701 if (unlikely (aux == NULL))
2704 nvername = MAX (nvername,
2705 (size_t) (aux->vna_other & 0x7fff));
2707 auxoffset += aux->vna_next;
2710 offset += need->vn_next;
2714 /* This is the number of versions we know about. */
2717 /* Allocate the array. */
2718 vername = (const char **) alloca (nvername * sizeof (const char *));
2719 filename = (const char **) alloca (nvername * sizeof (const char *));
2721 /* Run through the data structures again and collect the strings. */
2724 /* Run through the version definitions and find the highest
2726 unsigned int offset = 0;
2728 GElf_Shdr defshdrmem;
2731 defdata = elf_getdata (defscn, NULL);
2732 if (unlikely (defdata == NULL))
2735 defshdr = gelf_getshdr (defscn, &defshdrmem);
2736 if (unlikely (defshdr == NULL))
2739 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2742 /* Get the data at the next offset. */
2744 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2745 GElf_Verdaux auxmem;
2746 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2747 offset + def->vd_aux,
2749 if (unlikely (def == NULL || aux == NULL))
2752 vername[def->vd_ndx & 0x7fff]
2753 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2754 filename[def->vd_ndx & 0x7fff] = NULL;
2756 offset += def->vd_next;
2759 if (needscn != NULL)
2761 unsigned int offset = 0;
2763 Elf_Data *needdata = elf_getdata (needscn, NULL);
2764 GElf_Shdr needshdrmem;
2765 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2766 if (unlikely (needdata == NULL || needshdr == NULL))
2769 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2771 /* Get the data at the next offset. */
2772 GElf_Verneed needmem;
2773 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2775 if (unlikely (need == NULL))
2778 /* Run through the auxiliary entries. */
2779 unsigned int auxoffset = offset + need->vn_aux;
2780 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2782 GElf_Vernaux auxmem;
2783 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2785 if (unlikely (aux == NULL))
2788 vername[aux->vna_other & 0x7fff]
2789 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2790 filename[aux->vna_other & 0x7fff]
2791 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2793 auxoffset += aux->vna_next;
2796 offset += need->vn_next;
2807 GElf_Shdr glink_mem;
2808 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2810 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2812 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2815 /* Print the header. */
2816 printf (ngettext ("\
2817 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2819 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2820 shdr->sh_size / sh_entsize),
2821 (unsigned int) elf_ndxscn (scn),
2822 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2823 (int) (shdr->sh_size / sh_entsize),
2824 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2826 (unsigned int) shdr->sh_link,
2827 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2829 /* Now we can finally look at the actual contents of this section. */
2830 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2833 printf ("\n %4d:", cnt);
2836 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2844 fputs_unlocked (gettext (" 0 *local* "),
2849 fputs_unlocked (gettext (" 1 *global* "),
2854 n = printf ("%4d%c%s",
2855 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2856 (unsigned int) (*sym & 0x7fff) < nvername
2857 ? vername[*sym & 0x7fff] : "???");
2858 if ((unsigned int) (*sym & 0x7fff) < nvername
2859 && filename[*sym & 0x7fff] != NULL)
2860 n += printf ("(%s)", filename[*sym & 0x7fff]);
2861 printf ("%*s", MAX (0, 33 - (int) n), " ");
2865 putchar_unlocked ('\n');
2870 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2871 uint_fast32_t maxlength, Elf32_Word nbucket,
2872 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2874 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2876 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2877 ++counts[lengths[cnt]];
2879 GElf_Shdr glink_mem;
2880 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2885 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2890 printf (ngettext ("\
2891 \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",
2893 \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",
2895 (unsigned int) elf_ndxscn (scn),
2896 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2898 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2901 (unsigned int) shdr->sh_link,
2902 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2904 if (extrastr != NULL)
2905 fputs (extrastr, stdout);
2907 if (likely (nbucket > 0))
2909 uint64_t success = 0;
2911 /* xgettext:no-c-format */
2912 fputs_unlocked (gettext ("\
2913 Length Number % of total Coverage\n"), stdout);
2914 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2915 counts[0], (counts[0] * 100.0) / nbucket);
2917 uint64_t nzero_counts = 0;
2918 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2920 nzero_counts += counts[cnt] * cnt;
2922 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2923 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2924 (nzero_counts * 100.0) / nsyms);
2928 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2931 success += counts[cnt] * acc;
2935 Average number of tests: successful lookup: %f\n\
2936 unsuccessful lookup: %f\n"),
2937 (double) success / (double) nzero_counts,
2938 (double) nzero_counts / (double) nbucket);
2945 /* This function handles the traditional System V-style hash table format. */
2947 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2949 Elf_Data *data = elf_getdata (scn, NULL);
2950 if (unlikely (data == NULL))
2952 error (0, 0, gettext ("cannot get data for section %d: %s"),
2953 (int) elf_ndxscn (scn), elf_errmsg (-1));
2957 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2958 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2959 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2960 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2962 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2964 uint_fast32_t maxlength = 0;
2965 uint_fast32_t nsyms = 0;
2966 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2968 Elf32_Word inner = bucket[cnt];
2969 while (inner > 0 && inner < nchain)
2972 if (maxlength < ++lengths[cnt])
2975 inner = chain[inner];
2979 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2986 /* This function handles the incorrect, System V-style hash table
2987 format some 64-bit architectures use. */
2989 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2991 Elf_Data *data = elf_getdata (scn, NULL);
2992 if (unlikely (data == NULL))
2994 error (0, 0, gettext ("cannot get data for section %d: %s"),
2995 (int) elf_ndxscn (scn), elf_errmsg (-1));
2999 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3000 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3001 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3002 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3004 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3006 uint_fast32_t maxlength = 0;
3007 uint_fast32_t nsyms = 0;
3008 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3010 Elf64_Xword inner = bucket[cnt];
3011 while (inner > 0 && inner < nchain)
3014 if (maxlength < ++lengths[cnt])
3017 inner = chain[inner];
3021 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3028 /* This function handles the GNU-style hash table format. */
3030 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3032 Elf_Data *data = elf_getdata (scn, NULL);
3033 if (unlikely (data == NULL))
3035 error (0, 0, gettext ("cannot get data for section %d: %s"),
3036 (int) elf_ndxscn (scn), elf_errmsg (-1));
3040 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3041 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3043 /* Next comes the size of the bitmap. It's measured in words for
3044 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3046 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3047 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3050 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3052 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3054 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3055 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3056 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3059 /* Compute distribution of chain lengths. */
3060 uint_fast32_t maxlength = 0;
3061 uint_fast32_t nsyms = 0;
3062 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3063 if (bucket[cnt] != 0)
3065 Elf32_Word inner = bucket[cnt] - symbias;
3069 if (maxlength < ++lengths[cnt])
3072 while ((chain[inner++] & 1) == 0);
3075 /* Count bits in bitmask. */
3076 uint_fast32_t nbits = 0;
3077 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3079 uint_fast32_t word = bitmask[cnt];
3081 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3082 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3083 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3084 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3085 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3089 if (unlikely (asprintf (&str, gettext ("\
3091 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3092 (unsigned int) symbias,
3093 bitmask_words * sizeof (Elf32_Word),
3095 / (uint_fast32_t) (bitmask_words
3096 * sizeof (Elf32_Word) * 8)),
3097 (unsigned int) shift) == -1))
3098 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3100 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3108 /* Find the symbol table(s). For this we have to search through the
3111 handle_hash (Ebl *ebl)
3113 /* Get the section header string table index. */
3115 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3116 error (EXIT_FAILURE, 0,
3117 gettext ("cannot get section header string table index"));
3119 Elf_Scn *scn = NULL;
3120 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3122 /* Handle the section if it is a symbol table. */
3124 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3126 if (likely (shdr != NULL))
3128 if (shdr->sh_type == SHT_HASH)
3130 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3131 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3133 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3135 else if (shdr->sh_type == SHT_GNU_HASH)
3136 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3143 print_liblist (Ebl *ebl)
3145 /* Find the library list sections. For this we have to search
3146 through the section table. */
3147 Elf_Scn *scn = NULL;
3149 /* Get the section header string table index. */
3151 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3152 error (EXIT_FAILURE, 0,
3153 gettext ("cannot get section header string table index"));
3155 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3158 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3160 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3162 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3163 int nentries = shdr->sh_size / sh_entsize;
3164 printf (ngettext ("\
3165 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3167 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3170 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3174 Elf_Data *data = elf_getdata (scn, NULL);
3179 Library Time Stamp Checksum Version Flags"));
3181 for (int cnt = 0; cnt < nentries; ++cnt)
3184 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3185 if (unlikely (lib == NULL))
3188 time_t t = (time_t) lib->l_time_stamp;
3189 struct tm *tm = gmtime (&t);
3190 if (unlikely (tm == NULL))
3193 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3194 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3195 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3196 tm->tm_hour, tm->tm_min, tm->tm_sec,
3197 (unsigned int) lib->l_checksum,
3198 (unsigned int) lib->l_version,
3199 (unsigned int) lib->l_flags);
3206 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3208 /* Find the object attributes sections. For this we have to search
3209 through the section table. */
3210 Elf_Scn *scn = NULL;
3212 /* Get the section header string table index. */
3214 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3215 error (EXIT_FAILURE, 0,
3216 gettext ("cannot get section header string table index"));
3218 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3221 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3223 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3224 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3225 || ehdr->e_machine != EM_ARM)))
3229 \nObject attributes section [%2zu] '%s' of %" PRIu64
3230 " bytes at offset %#0" PRIx64 ":\n"),
3232 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3233 shdr->sh_size, shdr->sh_offset);
3235 Elf_Data *data = elf_rawdata (scn, NULL);
3239 const unsigned char *p = data->d_buf;
3241 if (unlikely (*p++ != 'A'))
3244 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3246 inline size_t left (void)
3248 return (const unsigned char *) data->d_buf + data->d_size - p;
3251 while (left () >= 4)
3254 memcpy (&len, p, sizeof len);
3256 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3259 if (unlikely (len > left ()))
3262 const unsigned char *name = p + sizeof len;
3265 unsigned const char *q = memchr (name, '\0', len);
3266 if (unlikely (q == NULL))
3270 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3272 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3273 || (q - name == sizeof "gnu"
3274 && !memcmp (name, "gnu", sizeof "gnu")))
3277 const unsigned char *const sub = q;
3279 unsigned int subsection_tag;
3280 get_uleb128 (subsection_tag, q);
3281 if (unlikely (q >= p))
3284 uint32_t subsection_len;
3285 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3288 memcpy (&subsection_len, q, sizeof subsection_len);
3290 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3291 CONVERT (subsection_len);
3293 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3296 const unsigned char *r = q + sizeof subsection_len;
3297 q = sub + subsection_len;
3299 switch (subsection_tag)
3302 printf (gettext (" %-4u %12" PRIu32 "\n"),
3303 subsection_tag, subsection_len);
3306 case 1: /* Tag_File */
3307 printf (gettext (" File: %11" PRIu32 "\n"),
3313 get_uleb128 (tag, r);
3314 if (unlikely (r >= q))
3318 const char *string = NULL;
3319 if (tag == 32 || (tag & 1) == 0)
3321 get_uleb128 (value, r);
3325 if (tag == 32 || (tag & 1) != 0)
3327 r = memchr (r, '\0', q - r);
3333 const char *tag_name = NULL;
3334 const char *value_name = NULL;
3335 ebl_check_object_attribute (ebl, (const char *) name,
3337 &tag_name, &value_name);
3339 if (tag_name != NULL)
3342 printf (gettext (" %s: %" PRId64 ", %s\n"),
3343 tag_name, value, string);
3344 else if (string == NULL && value_name == NULL)
3345 printf (gettext (" %s: %" PRId64 "\n"),
3348 printf (gettext (" %s: %s\n"),
3349 tag_name, string ?: value_name);
3355 printf (gettext (" %u: %" PRId64 "\n"),
3358 printf (gettext (" %u: %s\n"),
3370 format_dwarf_addr (Dwfl_Module *dwflmod,
3371 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3373 /* See if there is a name we can give for this address. */
3376 const char *name = (print_address_names && ! print_unresolved_addresses)
3377 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3381 if (print_unresolved_addresses)
3388 /* Relativize the address. */
3389 int n = dwfl_module_relocations (dwflmod);
3390 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3392 /* In an ET_REL file there is a section name to refer to. */
3394 : dwfl_module_relocation_info (dwflmod, i, NULL));
3401 ? (address_size == 0
3402 ? asprintf (&result,
3403 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3404 scn, address, name, off)
3405 : asprintf (&result,
3406 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3407 scn, 2 + address_size * 2, address,
3409 : (address_size == 0
3410 ? asprintf (&result,
3411 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3413 : asprintf (&result,
3414 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3415 2 + address_size * 2, address,
3418 ? (address_size == 0
3419 ? asprintf (&result,
3420 gettext ("%s+%#" PRIx64 " <%s>"),
3422 : asprintf (&result,
3423 gettext ("%s+%#0*" PRIx64 " <%s>"),
3424 scn, 2 + address_size * 2, address, name))
3425 : (address_size == 0
3426 ? asprintf (&result,
3427 gettext ("%#" PRIx64 " <%s>"),
3429 : asprintf (&result,
3430 gettext ("%#0*" PRIx64 " <%s>"),
3431 2 + address_size * 2, address, name))))
3433 ? (address_size == 0
3434 ? asprintf (&result,
3435 gettext ("%s+%#" PRIx64),
3437 : asprintf (&result,
3438 gettext ("%s+%#0*" PRIx64),
3439 scn, 2 + address_size * 2, address))
3440 : (address_size == 0
3441 ? asprintf (&result,
3444 : asprintf (&result,
3446 2 + address_size * 2, address)))) < 0)
3447 error (EXIT_FAILURE, 0, _("memory exhausted"));
3453 dwarf_tag_string (unsigned int tag)
3457 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3459 #undef ONE_KNOWN_DW_TAG
3467 dwarf_attr_string (unsigned int attrnum)
3471 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3473 #undef ONE_KNOWN_DW_AT
3481 dwarf_form_string (unsigned int form)
3485 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3486 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3488 #undef ONE_KNOWN_DW_FORM
3489 #undef ONE_KNOWN_DW_FORM_DESC
3497 dwarf_lang_string (unsigned int lang)
3501 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3503 #undef ONE_KNOWN_DW_LANG_DESC
3511 dwarf_inline_string (unsigned int code)
3513 static const char *const known[] =
3515 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3517 #undef ONE_KNOWN_DW_INL
3520 if (likely (code < sizeof (known) / sizeof (known[0])))
3528 dwarf_encoding_string (unsigned int code)
3530 static const char *const known[] =
3532 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3534 #undef ONE_KNOWN_DW_ATE
3537 if (likely (code < sizeof (known) / sizeof (known[0])))
3545 dwarf_access_string (unsigned int code)
3547 static const char *const known[] =
3549 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3551 #undef ONE_KNOWN_DW_ACCESS
3554 if (likely (code < sizeof (known) / sizeof (known[0])))
3562 dwarf_visibility_string (unsigned int code)
3564 static const char *const known[] =
3566 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3568 #undef ONE_KNOWN_DW_VIS
3571 if (likely (code < sizeof (known) / sizeof (known[0])))
3579 dwarf_virtuality_string (unsigned int code)
3581 static const char *const known[] =
3583 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3584 ALL_KNOWN_DW_VIRTUALITY
3585 #undef ONE_KNOWN_DW_VIRTUALITY
3588 if (likely (code < sizeof (known) / sizeof (known[0])))
3596 dwarf_identifier_case_string (unsigned int code)
3598 static const char *const known[] =
3600 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3602 #undef ONE_KNOWN_DW_ID
3605 if (likely (code < sizeof (known) / sizeof (known[0])))
3613 dwarf_calling_convention_string (unsigned int code)
3615 static const char *const known[] =
3617 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3619 #undef ONE_KNOWN_DW_CC
3622 if (likely (code < sizeof (known) / sizeof (known[0])))
3630 dwarf_ordering_string (unsigned int code)
3632 static const char *const known[] =
3634 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3636 #undef ONE_KNOWN_DW_ORD
3639 if (likely (code < sizeof (known) / sizeof (known[0])))
3647 dwarf_discr_list_string (unsigned int code)
3649 static const char *const known[] =
3651 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3653 #undef ONE_KNOWN_DW_DSC
3656 if (likely (code < sizeof (known) / sizeof (known[0])))
3664 dwarf_locexpr_opcode_string (unsigned int code)
3666 static const char *const known[] =
3668 /* Normally we can't affort building huge table of 64K entries,
3669 most of them zero, just because there are a couple defined
3670 values at the far end. In case of opcodes, it's OK. */
3671 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3672 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3674 #undef ONE_KNOWN_DW_OP
3675 #undef ONE_KNOWN_DW_OP_DESC
3678 if (likely (code < sizeof (known) / sizeof (known[0])))
3685 /* Used by all dwarf_foo_name functions. */
3687 string_or_unknown (const char *known, unsigned int code,
3688 unsigned int lo_user, unsigned int hi_user,
3689 bool print_unknown_num)
3691 static char unknown_buf[20];
3693 if (likely (known != NULL))
3696 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3698 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3703 if (print_unknown_num)
3705 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3714 dwarf_tag_name (unsigned int tag)
3716 const char *ret = dwarf_tag_string (tag);
3717 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3721 dwarf_attr_name (unsigned int attr)
3723 const char *ret = dwarf_attr_string (attr);
3724 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3729 dwarf_form_name (unsigned int form)
3731 const char *ret = dwarf_form_string (form);
3732 return string_or_unknown (ret, form, 0, 0, true);
3737 dwarf_lang_name (unsigned int lang)
3739 const char *ret = dwarf_lang_string (lang);
3740 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3745 dwarf_inline_name (unsigned int code)
3747 const char *ret = dwarf_inline_string (code);
3748 return string_or_unknown (ret, code, 0, 0, false);
3753 dwarf_encoding_name (unsigned int code)
3755 const char *ret = dwarf_encoding_string (code);
3756 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3761 dwarf_access_name (unsigned int code)
3763 const char *ret = dwarf_access_string (code);
3764 return string_or_unknown (ret, code, 0, 0, false);
3769 dwarf_visibility_name (unsigned int code)
3771 const char *ret = dwarf_visibility_string (code);
3772 return string_or_unknown (ret, code, 0, 0, false);
3777 dwarf_virtuality_name (unsigned int code)
3779 const char *ret = dwarf_virtuality_string (code);
3780 return string_or_unknown (ret, code, 0, 0, false);
3785 dwarf_identifier_case_name (unsigned int code)
3787 const char *ret = dwarf_identifier_case_string (code);
3788 return string_or_unknown (ret, code, 0, 0, false);
3793 dwarf_calling_convention_name (unsigned int code)
3795 const char *ret = dwarf_calling_convention_string (code);
3796 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3801 dwarf_ordering_name (unsigned int code)
3803 const char *ret = dwarf_ordering_string (code);
3804 return string_or_unknown (ret, code, 0, 0, false);
3809 dwarf_discr_list_name (unsigned int code)
3811 const char *ret = dwarf_discr_list_string (code);
3812 return string_or_unknown (ret, code, 0, 0, false);
3817 print_block (size_t n, const void *block)
3820 puts (_("empty block"));
3823 printf (_("%zu byte block:"), n);
3824 const unsigned char *data = block;
3826 printf (" %02x", *data++);
3833 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3834 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3835 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3837 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3841 printf ("%*s(empty)\n", indent, "");
3845 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3846 #define CONSUME(n) NEED (n); else len -= (n)
3848 Dwarf_Word offset = 0;
3851 uint_fast8_t op = *data++;
3853 const char *op_name = dwarf_locexpr_opcode_string (op);
3854 if (unlikely (op_name == NULL))
3856 static char buf[20];
3857 if (op >= DW_OP_lo_user)
3858 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3860 snprintf (buf, sizeof buf, "??? (%#x)", op);
3867 /* Address operand. */
3871 addr = read_4ubyte_unaligned (dbg, data);
3874 assert (addrsize == 8);
3875 addr = read_8ubyte_unaligned (dbg, data);
3880 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3881 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3882 indent, "", (uintmax_t) offset, op_name, a);
3885 offset += 1 + addrsize;
3888 case DW_OP_call_ref:
3889 /* Offset operand. */
3892 addr = read_4ubyte_unaligned (dbg, data);
3895 assert (ref_size == 8);
3896 addr = read_8ubyte_unaligned (dbg, data);
3901 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
3902 indent, "", (uintmax_t) offset,
3903 op_name, (uintmax_t) addr);
3904 offset += 1 + ref_size;
3907 case DW_OP_deref_size:
3908 case DW_OP_xderef_size:
3911 // XXX value might be modified by relocation
3913 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
3914 indent, "", (uintmax_t) offset,
3915 op_name, *((uint8_t *) data));
3923 // XXX value might be modified by relocation
3924 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3925 indent, "", (uintmax_t) offset,
3926 op_name, read_2ubyte_unaligned (dbg, data));
3934 // XXX value might be modified by relocation
3935 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3936 indent, "", (uintmax_t) offset,
3937 op_name, read_4ubyte_unaligned (dbg, data));
3945 // XXX value might be modified by relocation
3946 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3947 indent, "", (uintmax_t) offset,
3948 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
3956 // XXX value might be modified by relocation
3957 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
3958 indent, "", (uintmax_t) offset,
3959 op_name, *((int8_t *) data));
3967 // XXX value might be modified by relocation
3968 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
3969 indent, "", (uintmax_t) offset,
3970 op_name, read_2sbyte_unaligned (dbg, data));
3978 // XXX value might be modified by relocation
3979 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
3980 indent, "", (uintmax_t) offset,
3981 op_name, read_4sbyte_unaligned (dbg, data));
3989 // XXX value might be modified by relocation
3990 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3991 indent, "", (uintmax_t) offset,
3992 op_name, read_8sbyte_unaligned (dbg, data));
4000 case DW_OP_plus_uconst:
4002 const unsigned char *start = data;
4005 get_uleb128 (uleb, data); /* XXX check overrun */
4006 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4007 indent, "", (uintmax_t) offset, op_name, uleb);
4008 CONSUME (data - start);
4009 offset += 1 + (data - start);
4012 case DW_OP_bit_piece:
4016 get_uleb128 (uleb, data); /* XXX check overrun */
4017 get_uleb128 (uleb2, data); /* XXX check overrun */
4018 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4019 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4020 CONSUME (data - start);
4021 offset += 1 + (data - start);
4025 case DW_OP_breg0 ... DW_OP_breg31:
4030 get_sleb128 (sleb, data); /* XXX check overrun */
4031 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4032 indent, "", (uintmax_t) offset, op_name, sleb);
4033 CONSUME (data - start);
4034 offset += 1 + (data - start);
4040 get_uleb128 (uleb, data); /* XXX check overrun */
4041 get_sleb128 (sleb, data); /* XXX check overrun */
4042 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4043 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4044 CONSUME (data - start);
4045 offset += 1 + (data - start);
4050 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4051 indent, "", (uintmax_t) offset, op_name,
4052 read_2ubyte_unaligned (dbg, data));
4059 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4060 indent, "", (uintmax_t) offset, op_name,
4061 read_4ubyte_unaligned (dbg, data));
4069 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4070 indent, "", (uintmax_t) offset, op_name,
4071 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4077 case DW_OP_implicit_value:
4080 get_uleb128 (uleb, data); /* XXX check overrun */
4081 printf ("%*s[%4" PRIuMAX "] %s: ",
4082 indent, "", (uintmax_t) offset, op_name);
4084 print_block (uleb, data);
4086 CONSUME (data - start);
4087 offset += 1 + (data - start);
4090 case DW_OP_GNU_implicit_pointer:
4091 /* DIE offset operand. */
4093 NEED (ref_size + 1);
4095 addr = read_4ubyte_unaligned (dbg, data);
4098 assert (ref_size == 8);
4099 addr = read_8ubyte_unaligned (dbg, data);
4102 /* Byte offset operand. */
4103 get_sleb128 (sleb, data); /* XXX check overrun */
4105 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4106 indent, "", (intmax_t) offset,
4107 op_name, (uintmax_t) addr, sleb);
4108 CONSUME (data - start);
4109 offset += 1 + (data - start);
4112 case DW_OP_GNU_entry_value:
4113 /* Size plus expression block. */
4116 get_uleb128 (uleb, data); /* XXX check overrun */
4117 printf ("%*s[%4" PRIuMAX "] %s:\n",
4118 indent, "", (uintmax_t) offset, op_name);
4120 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4121 addrsize, offset_size, cu, uleb, data);
4123 CONSUME (data - start);
4124 offset += 1 + (data - start);
4127 case DW_OP_GNU_const_type:
4128 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4129 unsigned size plus block. */
4132 get_uleb128 (uleb, data); /* XXX check overrun */
4133 if (! print_unresolved_addresses && cu != NULL)
4135 uint8_t usize = *(uint8_t *) data++;
4137 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4138 indent, "", (uintmax_t) offset, op_name, uleb);
4139 print_block (usize, data);
4141 CONSUME (data - start);
4142 offset += 1 + (data - start);
4145 case DW_OP_GNU_regval_type:
4146 /* uleb128 register number, uleb128 CU relative
4147 DW_TAG_base_type DIE offset. */
4150 get_uleb128 (uleb, data); /* XXX check overrun */
4151 get_uleb128 (uleb2, data); /* XXX check overrun */
4152 if (! print_unresolved_addresses && cu != NULL)
4154 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4155 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4156 CONSUME (data - start);
4157 offset += 1 + (data - start);
4160 case DW_OP_GNU_deref_type:
4161 /* 1-byte unsigned size of value, uleb128 CU relative
4162 DW_TAG_base_type DIE offset. */
4165 usize = *(uint8_t *) data++;
4166 get_uleb128 (uleb, data); /* XXX check overrun */
4167 if (! print_unresolved_addresses && cu != NULL)
4169 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4170 indent, "", (uintmax_t) offset,
4171 op_name, usize, uleb);
4172 CONSUME (data - start);
4173 offset += 1 + (data - start);
4176 case DW_OP_GNU_convert:
4177 case DW_OP_GNU_reinterpret:
4178 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4179 for conversion to untyped. */
4182 get_uleb128 (uleb, data); /* XXX check overrun */
4183 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4185 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4186 indent, "", (uintmax_t) offset, op_name, uleb);
4187 CONSUME (data - start);
4188 offset += 1 + (data - start);
4191 case DW_OP_GNU_parameter_ref:
4192 /* 4 byte CU relative reference to the abstract optimized away
4193 DW_TAG_formal_parameter. */
4195 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4196 if (! print_unresolved_addresses && cu != NULL)
4197 param_off += cu->start;
4198 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4199 indent, "", (uintmax_t) offset, op_name, param_off);
4207 printf ("%*s[%4" PRIuMAX "] %s\n",
4208 indent, "", (uintmax_t) offset, op_name);
4213 indent = indentrest;
4217 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4218 indent, "", (uintmax_t) offset, op_name);
4226 Dwarf_Off offset:(64 - 3);
4230 struct Dwarf_CU *cu;
4233 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4234 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4237 listptr_base (struct listptr *p)
4240 Dwarf_Die cu = CUDIE (p->cu);
4241 /* Find the base address of the compilation unit. It will normally
4242 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4243 address could be overridden by DW_AT_entry_pc. It's been
4244 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4245 compilation units with discontinuous ranges. */
4246 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4248 Dwarf_Attribute attr_mem;
4249 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4257 compare_listptr (const void *a, const void *b, void *arg)
4259 const char *name = arg;
4260 struct listptr *p1 = (void *) a;
4261 struct listptr *p2 = (void *) b;
4263 if (p1->offset < p2->offset)
4265 if (p1->offset > p2->offset)
4268 if (!p1->warned && !p2->warned)
4270 if (p1->addr64 != p2->addr64)
4272 p1->warned = p2->warned = true;
4274 gettext ("%s %#" PRIx64 " used with different address sizes"),
4275 name, (uint64_t) p1->offset);
4277 if (p1->dwarf64 != p2->dwarf64)
4279 p1->warned = p2->warned = true;
4281 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4282 name, (uint64_t) p1->offset);
4284 if (listptr_base (p1) != listptr_base (p2))
4286 p1->warned = p2->warned = true;
4288 gettext ("%s %#" PRIx64 " used with different base addresses"),
4289 name, (uint64_t) p1->offset);
4296 struct listptr_table
4300 struct listptr *table;
4303 static struct listptr_table known_loclistptr;
4304 static struct listptr_table known_rangelistptr;
4307 reset_listptr (struct listptr_table *table)
4309 free (table->table);
4310 table->table = NULL;
4311 table->n = table->alloc = 0;
4315 notice_listptr (enum section_e section, struct listptr_table *table,
4316 uint_fast8_t address_size, uint_fast8_t offset_size,
4317 struct Dwarf_CU *cu, Dwarf_Off offset)
4319 if (print_debug_sections & section)
4321 if (table->n == table->alloc)
4323 if (table->alloc == 0)
4327 table->table = xrealloc (table->table,
4328 table->alloc * sizeof table->table[0]);
4331 struct listptr *p = &table->table[table->n++];
4333 *p = (struct listptr)
4335 .addr64 = address_size == 8,
4336 .dwarf64 = offset_size == 8,
4340 assert (p->offset == offset);
4345 sort_listptr (struct listptr_table *table, const char *name)
4348 qsort_r (table->table, table->n, sizeof table->table[0],
4349 &compare_listptr, (void *) name);
4353 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4354 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4355 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4356 unsigned char **readp, unsigned char *endp)
4361 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4364 struct listptr *p = &table->table[*idxp];
4366 if (*idxp == table->n
4367 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4370 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4375 if (p->offset != (Dwarf_Off) offset)
4377 *readp += p->offset - offset;
4378 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4379 offset, (Dwarf_Off) p->offset - offset);
4383 if (address_sizep != NULL)
4384 *address_sizep = listptr_address_size (p);
4385 if (offset_sizep != NULL)
4386 *offset_sizep = listptr_offset_size (p);
4388 *base = listptr_base (p);
4397 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4398 Ebl *ebl, GElf_Ehdr *ehdr,
4399 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4401 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4402 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4404 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4406 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4407 (uint64_t) shdr->sh_offset);
4409 Dwarf_Off offset = 0;
4410 while (offset < sh_size)
4412 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4418 Dwarf_Abbrev abbrev;
4420 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4423 if (unlikely (res < 0))
4426 *** error while reading abbreviation: %s\n"),
4431 /* This is the NUL byte at the end of the section. */
4436 /* We know these calls can never fail. */
4437 unsigned int code = dwarf_getabbrevcode (&abbrev);
4438 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4439 int has_children = dwarf_abbrevhaschildren (&abbrev);
4441 printf (gettext (" [%5u] offset: %" PRId64
4442 ", children: %s, tag: %s\n"),
4443 code, (int64_t) offset,
4444 has_children ? gettext ("yes") : gettext ("no"),
4445 dwarf_tag_name (tag));
4451 while (dwarf_getabbrevattr (&abbrev, cnt,
4452 &name, &form, &enoffset) == 0)
4454 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4455 dwarf_attr_name (name), dwarf_form_name (form),
4456 (uint64_t) enoffset);
4467 /* Print content of DWARF .debug_aranges section. We fortunately do
4468 not have to know a bit about the structure of the section, libdwarf
4469 takes care of it. */
4471 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4472 GElf_Shdr *shdr, Dwarf *dbg)
4474 Dwarf_Aranges *aranges;
4476 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4478 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4483 GElf_Shdr glink_mem;
4485 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4488 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4493 printf (ngettext ("\
4494 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4496 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4498 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4499 (uint64_t) shdr->sh_offset, cnt);
4501 /* Compute floor(log16(cnt)). */
4510 for (size_t n = 0; n < cnt; ++n)
4512 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4513 if (unlikely (runp == NULL))
4515 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4523 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4524 printf (gettext (" [%*zu] ???\n"), digits, n);
4526 printf (gettext (" [%*zu] start: %0#*" PRIx64
4527 ", length: %5" PRIu64 ", CU DIE offset: %6"
4529 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4530 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4535 /* Print content of DWARF .debug_aranges section. */
4537 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4538 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4539 GElf_Shdr *shdr, Dwarf *dbg)
4543 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4547 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4549 if (unlikely (data == NULL))
4551 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4557 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4558 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4559 (uint64_t) shdr->sh_offset);
4561 const unsigned char *readp = data->d_buf;
4562 const unsigned char *readendp = readp + data->d_size;
4564 while (readp < readendp)
4566 const unsigned char *hdrstart = readp;
4567 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4569 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4570 if (readp + 4 > readendp)
4573 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4574 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4578 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4579 unsigned int length_bytes = 4;
4580 if (length == DWARF3_LENGTH_64_BIT)
4582 if (readp + 8 > readendp)
4584 length = read_8ubyte_unaligned_inc (dbg, readp);
4588 const unsigned char *nexthdr = readp + length;
4589 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4592 if (nexthdr > readendp)
4598 if (readp + 2 > readendp)
4600 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4601 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4605 error (0, 0, gettext ("unsupported aranges version"));
4610 if (readp + length_bytes > readendp)
4612 if (length_bytes == 8)
4613 offset = read_8ubyte_unaligned_inc (dbg, readp);
4615 offset = read_4ubyte_unaligned_inc (dbg, readp);
4616 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4619 if (readp + 1 > readendp)
4621 unsigned int address_size = *readp++;
4622 printf (gettext (" Address size: %6" PRIu64 "\n"),
4623 (uint64_t) address_size);
4624 if (address_size != 4 && address_size != 8)
4626 error (0, 0, gettext ("unsupported address size"));
4630 unsigned int segment_size = *readp++;
4631 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4632 (uint64_t) segment_size);
4633 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4635 error (0, 0, gettext ("unsupported segment size"));
4639 /* Round the address to the next multiple of 2*address_size. */
4640 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4641 % (2 * address_size));
4643 while (readp < nexthdr)
4645 Dwarf_Word range_address;
4646 Dwarf_Word range_length;
4647 Dwarf_Word segment = 0;
4648 if (readp + 2 * address_size + segment_size > readendp)
4650 if (address_size == 4)
4652 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4653 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4657 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4658 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4661 if (segment_size == 4)
4662 segment = read_4ubyte_unaligned_inc (dbg, readp);
4663 else if (segment_size == 8)
4664 segment = read_8ubyte_unaligned_inc (dbg, readp);
4666 if (range_address == 0 && range_length == 0 && segment == 0)
4669 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4671 char *e = format_dwarf_addr (dwflmod, address_size,
4672 range_address + range_length - 1,
4674 if (segment_size != 0)
4675 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4676 (uint64_t) segment);
4678 printf (gettext (" %s..%s\n"), b, e);
4684 if (readp != nexthdr)
4686 size_t padding = nexthdr - readp;
4687 printf (gettext (" %Zu padding bytes\n"), padding);
4694 /* Print content of DWARF .debug_ranges section. */
4696 print_debug_ranges_section (Dwfl_Module *dwflmod,
4697 Ebl *ebl, GElf_Ehdr *ehdr,
4698 Elf_Scn *scn, GElf_Shdr *shdr,
4701 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4703 if (unlikely (data == NULL))
4705 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4711 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4712 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4713 (uint64_t) shdr->sh_offset);
4715 sort_listptr (&known_rangelistptr, "rangelistptr");
4716 size_t listptr_idx = 0;
4718 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4721 Dwarf_Addr base = 0;
4722 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4723 unsigned char *readp = data->d_buf;
4724 while (readp < endp)
4726 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4728 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4729 &address_size, NULL, &base, NULL,
4730 offset, &readp, endp))
4733 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4735 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4741 if (address_size == 8)
4743 begin = read_8ubyte_unaligned_inc (dbg, readp);
4744 end = read_8ubyte_unaligned_inc (dbg, readp);
4748 begin = read_4ubyte_unaligned_inc (dbg, readp);
4749 end = read_4ubyte_unaligned_inc (dbg, readp);
4750 if (begin == (Dwarf_Addr) (uint32_t) -1)
4751 begin = (Dwarf_Addr) -1l;
4754 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4756 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4757 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4761 else if (begin == 0 && end == 0) /* End of list entry. */
4764 printf (gettext (" [%6tx] empty list\n"), offset);
4769 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4771 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4773 /* We have an address range entry. */
4774 if (first) /* First address range entry in a list. */
4775 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4777 printf (gettext (" %s..%s\n"), b, e);
4786 #define REGNAMESZ 16
4788 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4789 char name[REGNAMESZ], int *bits, int *type)
4794 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4795 bits ?: &ignore, type ?: &ignore);
4799 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4801 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4803 *bits = loc != NULL ? loc->bits : 0;
4805 *type = DW_ATE_unsigned;
4806 set = "??? unrecognized";
4810 if (bits != NULL && *bits <= 0)
4811 *bits = loc != NULL ? loc->bits : 0;
4812 if (type != NULL && *type == DW_ATE_void)
4813 *type = DW_ATE_unsigned;
4820 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4821 Dwarf_Word vma_base, unsigned int code_align,
4823 unsigned int version, unsigned int ptr_size,
4824 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4826 char regnamebuf[REGNAMESZ];
4827 const char *regname (unsigned int regno)
4829 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4833 puts ("\n Program:");
4834 Dwarf_Word pc = vma_base;
4835 while (readp < endp)
4837 unsigned int opcode = *readp++;
4839 if (opcode < DW_CFA_advance_loc)
4840 /* Extended opcode. */
4851 case DW_CFA_set_loc:
4852 // XXX overflow check
4853 get_uleb128 (op1, readp);
4855 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4857 case DW_CFA_advance_loc1:
4858 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4859 *readp, pc += *readp * code_align);
4862 case DW_CFA_advance_loc2:
4863 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4864 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4865 op1, pc += op1 * code_align);
4867 case DW_CFA_advance_loc4:
4868 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4869 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4870 op1, pc += op1 * code_align);
4872 case DW_CFA_offset_extended:
4873 // XXX overflow check
4874 get_uleb128 (op1, readp);
4875 get_uleb128 (op2, readp);
4876 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4878 op1, regname (op1), op2 * data_align);
4880 case DW_CFA_restore_extended:
4881 // XXX overflow check
4882 get_uleb128 (op1, readp);
4883 printf (" restore_extended r%" PRIu64 " (%s)\n",
4884 op1, regname (op1));
4886 case DW_CFA_undefined:
4887 // XXX overflow check
4888 get_uleb128 (op1, readp);
4889 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4891 case DW_CFA_same_value:
4892 // XXX overflow check
4893 get_uleb128 (op1, readp);
4894 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4896 case DW_CFA_register:
4897 // XXX overflow check
4898 get_uleb128 (op1, readp);
4899 get_uleb128 (op2, readp);
4900 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4901 op1, regname (op1), op2, regname (op2));
4903 case DW_CFA_remember_state:
4904 puts (" remember_state");
4906 case DW_CFA_restore_state:
4907 puts (" restore_state");
4909 case DW_CFA_def_cfa:
4910 // XXX overflow check
4911 get_uleb128 (op1, readp);
4912 get_uleb128 (op2, readp);
4913 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4914 op1, regname (op1), op2);
4916 case DW_CFA_def_cfa_register:
4917 // XXX overflow check
4918 get_uleb128 (op1, readp);
4919 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
4920 op1, regname (op1));
4922 case DW_CFA_def_cfa_offset:
4923 // XXX overflow check
4924 get_uleb128 (op1, readp);
4925 printf (" def_cfa_offset %" PRIu64 "\n", op1);
4927 case DW_CFA_def_cfa_expression:
4928 // XXX overflow check
4929 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
4930 printf (" def_cfa_expression %" PRIu64 "\n", op1);
4931 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4935 case DW_CFA_expression:
4936 // XXX overflow check
4937 get_uleb128 (op1, readp);
4938 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4939 printf (" expression r%" PRIu64 " (%s) \n",
4940 op1, regname (op1));
4941 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4945 case DW_CFA_offset_extended_sf:
4946 // XXX overflow check
4947 get_uleb128 (op1, readp);
4948 get_sleb128 (sop2, readp);
4949 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
4951 op1, regname (op1), sop2 * data_align);
4953 case DW_CFA_def_cfa_sf:
4954 // XXX overflow check
4955 get_uleb128 (op1, readp);
4956 get_sleb128 (sop2, readp);
4957 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
4958 op1, regname (op1), sop2 * data_align);
4960 case DW_CFA_def_cfa_offset_sf:
4961 // XXX overflow check
4962 get_sleb128 (sop1, readp);
4963 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
4965 case DW_CFA_val_offset:
4966 // XXX overflow check
4967 get_uleb128 (op1, readp);
4968 get_uleb128 (op2, readp);
4969 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
4970 op1, op2 * data_align);
4972 case DW_CFA_val_offset_sf:
4973 // XXX overflow check
4974 get_uleb128 (op1, readp);
4975 get_sleb128 (sop2, readp);
4976 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
4977 op1, sop2 * data_align);
4979 case DW_CFA_val_expression:
4980 // XXX overflow check
4981 get_uleb128 (op1, readp);
4982 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4983 printf (" val_expression r%" PRIu64 " (%s)\n",
4984 op1, regname (op1));
4985 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
4989 case DW_CFA_MIPS_advance_loc8:
4990 op1 = read_8ubyte_unaligned_inc (dbg, readp);
4991 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
4992 op1, pc += op1 * code_align);
4994 case DW_CFA_GNU_window_save:
4995 puts (" GNU_window_save");
4997 case DW_CFA_GNU_args_size:
4998 // XXX overflow check
4999 get_uleb128 (op1, readp);
5000 printf (" args_size %" PRIu64 "\n", op1);
5003 printf (" ??? (%u)\n", opcode);
5006 else if (opcode < DW_CFA_offset)
5007 printf (" advance_loc %u to %#" PRIx64 "\n",
5008 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5009 else if (opcode < DW_CFA_restore)
5012 // XXX overflow check
5013 get_uleb128 (offset, readp);
5014 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5015 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5018 printf (" restore r%u (%s)\n",
5019 opcode & 0x3f, regname (opcode & 0x3f));
5025 encoded_ptr_size (int encoding, unsigned int ptr_size)
5027 switch (encoding & 7)
5042 print_encoding (unsigned int val)
5046 case DW_EH_PE_absptr:
5047 fputs ("absptr", stdout);
5049 case DW_EH_PE_uleb128:
5050 fputs ("uleb128", stdout);
5052 case DW_EH_PE_udata2:
5053 fputs ("udata2", stdout);
5055 case DW_EH_PE_udata4:
5056 fputs ("udata4", stdout);
5058 case DW_EH_PE_udata8:
5059 fputs ("udata8", stdout);
5061 case DW_EH_PE_sleb128:
5062 fputs ("sleb128", stdout);
5064 case DW_EH_PE_sdata2:
5065 fputs ("sdata2", stdout);
5067 case DW_EH_PE_sdata4:
5068 fputs ("sdata4", stdout);
5070 case DW_EH_PE_sdata8:
5071 fputs ("sdata8", stdout);
5074 /* We did not use any of the bits after all. */
5083 print_relinfo (unsigned int val)
5087 case DW_EH_PE_pcrel:
5088 fputs ("pcrel", stdout);
5090 case DW_EH_PE_textrel:
5091 fputs ("textrel", stdout);
5093 case DW_EH_PE_datarel:
5094 fputs ("datarel", stdout);
5096 case DW_EH_PE_funcrel:
5097 fputs ("funcrel", stdout);
5099 case DW_EH_PE_aligned:
5100 fputs ("aligned", stdout);
5111 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5113 printf ("(%s", pfx);
5115 if (fde_encoding == DW_EH_PE_omit)
5119 unsigned int w = fde_encoding;
5121 w = print_encoding (w);
5125 if (w != fde_encoding)
5126 fputc_unlocked (' ', stdout);
5128 w = print_relinfo (w);
5132 printf ("%s%x", w != fde_encoding ? " " : "", w);
5139 static const unsigned char *
5140 read_encoded (unsigned int encoding, const unsigned char *readp,
5141 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5143 if ((encoding & 0xf) == DW_EH_PE_absptr)
5144 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5145 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5147 switch (encoding & 0xf)
5149 case DW_EH_PE_uleb128:
5150 // XXX buffer overrun check
5151 get_uleb128 (*res, readp);
5153 case DW_EH_PE_sleb128:
5154 // XXX buffer overrun check
5155 get_sleb128 (*res, readp);
5157 case DW_EH_PE_udata2:
5158 if (readp + 2 > endp)
5160 *res = read_2ubyte_unaligned_inc (dbg, readp);
5162 case DW_EH_PE_udata4:
5163 if (readp + 4 > endp)
5165 *res = read_4ubyte_unaligned_inc (dbg, readp);
5167 case DW_EH_PE_udata8:
5168 if (readp + 8 > endp)
5170 *res = read_8ubyte_unaligned_inc (dbg, readp);
5172 case DW_EH_PE_sdata2:
5173 if (readp + 2 > endp)
5175 *res = read_2sbyte_unaligned_inc (dbg, readp);
5177 case DW_EH_PE_sdata4:
5178 if (readp + 4 > endp)
5180 *res = read_4sbyte_unaligned_inc (dbg, readp);
5182 case DW_EH_PE_sdata8:
5183 if (readp + 8 > endp)
5185 *res = read_8sbyte_unaligned_inc (dbg, readp);
5190 gettext ("invalid encoding"));
5198 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5199 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5202 /* We know this call will succeed since it did in the caller. */
5203 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5204 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5206 /* Needed if we find PC-relative addresses. */
5208 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5210 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5214 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5215 Elf_Data *data = (is_eh_frame
5216 ? elf_rawdata (scn, NULL)
5217 : dbg->sectiondata[IDX_debug_frame]);
5219 if (unlikely (data == NULL))
5221 error (0, 0, gettext ("cannot get %s content: %s"),
5222 scnname, elf_errmsg (-1));
5228 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5229 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5232 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5233 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5237 ptrdiff_t cie_offset;
5238 const char *augmentation;
5239 unsigned int code_alignment_factor;
5240 unsigned int data_alignment_factor;
5241 uint8_t address_size;
5242 uint8_t fde_encoding;
5243 uint8_t lsda_encoding;
5244 struct cieinfo *next;
5247 const unsigned char *readp = data->d_buf;
5248 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5250 while (readp < dataend)
5252 if (unlikely (readp + 4 > dataend))
5255 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5256 elf_ndxscn (scn), scnname);
5260 /* At the beginning there must be a CIE. There can be multiple,
5261 hence we test tis in a loop. */
5262 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5264 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5265 unsigned int length = 4;
5266 if (unlikely (unit_length == 0xffffffff))
5268 if (unlikely (readp + 8 > dataend))
5271 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5275 if (unlikely (unit_length == 0))
5277 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5281 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5283 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5284 const unsigned char *const cieend = readp + unit_length;
5285 if (unlikely (cieend > dataend || readp + 8 > dataend))
5291 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5292 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5293 cie_id = DW_CIE_ID_64;
5296 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5298 uint_fast8_t version = 2;
5299 unsigned int code_alignment_factor;
5300 int data_alignment_factor;
5301 unsigned int fde_encoding = 0;
5302 unsigned int lsda_encoding = 0;
5303 Dwarf_Word initial_location = 0;
5304 Dwarf_Word vma_base = 0;
5306 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5309 const char *const augmentation = (const char *) readp;
5310 readp = memchr (readp, '\0', cieend - readp);
5311 if (unlikely (readp == NULL))
5315 uint_fast8_t segment_size = 0;
5318 if (cieend - readp < 5)
5320 ptr_size = *readp++;
5321 segment_size = *readp++;
5324 // XXX Check overflow
5325 get_uleb128 (code_alignment_factor, readp);
5326 // XXX Check overflow
5327 get_sleb128 (data_alignment_factor, readp);
5329 /* In some variant for unwind data there is another field. */
5330 if (strcmp (augmentation, "eh") == 0)
5331 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5333 unsigned int return_address_register;
5334 if (unlikely (version == 1))
5335 return_address_register = *readp++;
5337 // XXX Check overflow
5338 get_uleb128 (return_address_register, readp);
5340 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5341 " CIE_id: %" PRIu64 "\n"
5343 " augmentation: \"%s\"\n",
5344 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5345 version, augmentation);
5347 printf (" address_size: %u\n"
5348 " segment_size: %u\n",
5349 ptr_size, segment_size);
5350 printf (" code_alignment_factor: %u\n"
5351 " data_alignment_factor: %d\n"
5352 " return_address_register: %u\n",
5353 code_alignment_factor,
5354 data_alignment_factor, return_address_register);
5356 if (augmentation[0] == 'z')
5358 unsigned int augmentationlen;
5359 get_uleb128 (augmentationlen, readp);
5361 if (augmentationlen > (size_t) (dataend - readp))
5362 error (1, 0, gettext ("invalid augmentation length"));
5364 const char *hdr = "Augmentation data:";
5365 const char *cp = augmentation + 1;
5368 printf (" %-26s%#x ", hdr, *readp);
5373 fde_encoding = *readp++;
5374 print_encoding_base (gettext ("FDE address encoding: "),
5377 else if (*cp == 'L')
5379 lsda_encoding = *readp++;
5380 print_encoding_base (gettext ("LSDA pointer encoding: "),
5383 else if (*cp == 'P')
5385 /* Personality. This field usually has a relocation
5386 attached pointing to __gcc_personality_v0. */
5387 const unsigned char *startp = readp;
5388 unsigned int encoding = *readp++;
5390 readp = read_encoded (encoding, readp,
5391 readp - 1 + augmentationlen,
5394 while (++startp < readp)
5395 printf ("%#x ", *startp);
5398 print_encoding (encoding);
5400 switch (encoding & 0xf)
5402 case DW_EH_PE_sleb128:
5403 case DW_EH_PE_sdata2:
5404 case DW_EH_PE_sdata4:
5405 printf ("%" PRId64 ")\n", val);
5408 printf ("%#" PRIx64 ")\n", val);
5413 printf ("(%x)\n", *readp++);
5419 if (likely (ptr_size == 4 || ptr_size == 8))
5421 struct cieinfo *newp = alloca (sizeof (*newp));
5422 newp->cie_offset = offset;
5423 newp->augmentation = augmentation;
5424 newp->fde_encoding = fde_encoding;
5425 newp->lsda_encoding = lsda_encoding;
5426 newp->address_size = ptr_size;
5427 newp->code_alignment_factor = code_alignment_factor;
5428 newp->data_alignment_factor = data_alignment_factor;
5435 struct cieinfo *cie = cies;
5438 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5439 : (ptrdiff_t) cie_id == cie->cie_offset)
5443 if (unlikely (cie == NULL))
5445 puts ("invalid CIE reference in FDE");
5449 /* Initialize from CIE data. */
5450 fde_encoding = cie->fde_encoding;
5451 lsda_encoding = cie->lsda_encoding;
5452 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5453 code_alignment_factor = cie->code_alignment_factor;
5454 data_alignment_factor = cie->data_alignment_factor;
5456 const unsigned char *base = readp;
5457 // XXX There are sometimes relocations for this value
5458 initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5459 Dwarf_Word address_range
5460 = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5462 /* pcrel for an FDE address is relative to the runtime
5463 address of the start_address field itself. Sign extend
5464 if necessary to make sure the calculation is done on the
5465 full 64 bit address even when initial_location only holds
5466 the lower 32 bits. */
5467 Dwarf_Addr pc_start = initial_location;
5469 pc_start = (uint64_t) (int32_t) pc_start;
5470 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5471 pc_start += ((uint64_t) shdr->sh_addr
5472 + (base - (const unsigned char *) data->d_buf)
5475 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5476 pc_start, initial_location);
5477 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5478 " CIE_pointer: %" PRIu64 "\n"
5479 " initial_location: %s",
5480 offset, (uint64_t) unit_length,
5481 cie->cie_offset, (uint64_t) cie_id, a);
5483 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5485 vma_base = (((uint64_t) shdr->sh_offset
5486 + (base - (const unsigned char *) data->d_buf)
5487 + (uint64_t) initial_location)
5489 ? UINT64_C (0xffffffff)
5490 : UINT64_C (0xffffffffffffffff)));
5491 printf (gettext (" (offset: %#" PRIx64 ")"),
5492 (uint64_t) vma_base);
5495 printf ("\n address_range: %#" PRIx64,
5496 (uint64_t) address_range);
5497 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5498 printf (gettext (" (end offset: %#" PRIx64 ")"),
5499 ((uint64_t) vma_base + (uint64_t) address_range)
5501 ? UINT64_C (0xffffffff)
5502 : UINT64_C (0xffffffffffffffff)));
5505 if (cie->augmentation[0] == 'z')
5507 unsigned int augmentationlen;
5508 get_uleb128 (augmentationlen, readp);
5510 if (augmentationlen > 0)
5512 const char *hdr = "Augmentation data:";
5513 const char *cp = cie->augmentation + 1;
5519 uint64_t lsda_pointer;
5520 const unsigned char *p
5521 = read_encoded (lsda_encoding, &readp[u],
5522 &readp[augmentationlen],
5523 &lsda_pointer, dbg);
5526 %-26sLSDA pointer: %#" PRIx64 "\n"),
5533 while (u < augmentationlen)
5535 printf (" %-26s%#x\n", hdr, readp[u++]);
5540 readp += augmentationlen;
5544 /* Handle the initialization instructions. */
5545 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5546 data_alignment_factor, version, ptr_size,
5555 Dwfl_Module *dwflmod;
5560 unsigned int version;
5561 unsigned int addrsize;
5562 unsigned int offset_size;
5563 struct Dwarf_CU *cu;
5568 attr_callback (Dwarf_Attribute *attrp, void *arg)
5570 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5571 const int level = cbargs->level;
5573 unsigned int attr = dwarf_whatattr (attrp);
5574 if (unlikely (attr == 0))
5576 if (!cbargs->silent)
5577 error (0, 0, gettext ("cannot get attribute code: %s"),
5579 return DWARF_CB_ABORT;
5582 unsigned int form = dwarf_whatform (attrp);
5583 if (unlikely (form == 0))
5585 if (!cbargs->silent)
5586 error (0, 0, gettext ("cannot get attribute form: %s"),
5588 return DWARF_CB_ABORT;
5594 if (!cbargs->silent)
5597 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5600 if (!cbargs->silent)
5601 error (0, 0, gettext ("cannot get attribute value: %s"),
5603 return DWARF_CB_ABORT;
5605 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5607 printf (" %*s%-20s (%s) %s\n",
5608 (int) (level * 2), "", dwarf_attr_name (attr),
5609 dwarf_form_name (form), a);
5614 case DW_FORM_indirect:
5616 case DW_FORM_string:
5617 case DW_FORM_GNU_strp_alt:
5620 const char *str = dwarf_formstring (attrp);
5621 if (unlikely (str == NULL))
5623 printf (" %*s%-20s (%s) \"%s\"\n",
5624 (int) (level * 2), "", dwarf_attr_name (attr),
5625 dwarf_form_name (form), str);
5628 case DW_FORM_ref_addr:
5629 case DW_FORM_ref_udata:
5634 case DW_FORM_GNU_ref_alt:
5638 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5641 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5642 (int) (level * 2), "", dwarf_attr_name (attr),
5643 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5646 case DW_FORM_ref_sig8:
5649 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5650 (int) (level * 2), "", dwarf_attr_name (attr),
5651 dwarf_form_name (form),
5652 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5655 case DW_FORM_sec_offset:
5661 case DW_FORM_data1:;
5663 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5666 const char *valuestr = NULL;
5669 /* This case can take either a constant or a loclistptr. */
5670 case DW_AT_data_member_location:
5671 if (form != DW_FORM_sec_offset
5672 && (cbargs->version >= 4
5673 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5675 if (!cbargs->silent)
5676 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5677 (int) (level * 2), "", dwarf_attr_name (attr),
5678 dwarf_form_name (form), (uintmax_t) num);
5681 /* else fallthrough */
5683 /* These cases always take a loclistptr and no constant. */
5684 case DW_AT_location:
5685 case DW_AT_data_location:
5686 case DW_AT_vtable_elem_location:
5687 case DW_AT_string_length:
5688 case DW_AT_use_location:
5689 case DW_AT_frame_base:
5690 case DW_AT_return_addr:
5691 case DW_AT_static_link:
5692 case DW_AT_GNU_call_site_value:
5693 case DW_AT_GNU_call_site_data_value:
5694 case DW_AT_GNU_call_site_target:
5695 case DW_AT_GNU_call_site_target_clobbered:
5696 notice_listptr (section_loc, &known_loclistptr,
5697 cbargs->addrsize, cbargs->offset_size,
5699 if (!cbargs->silent)
5700 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5701 (int) (level * 2), "", dwarf_attr_name (attr),
5702 dwarf_form_name (form), (uintmax_t) num);
5706 notice_listptr (section_ranges, &known_rangelistptr,
5707 cbargs->addrsize, cbargs->offset_size,
5709 if (!cbargs->silent)
5710 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5711 (int) (level * 2), "", dwarf_attr_name (attr),
5712 dwarf_form_name (form), (uintmax_t) num);
5715 case DW_AT_language:
5716 valuestr = dwarf_lang_name (num);
5718 case DW_AT_encoding:
5719 valuestr = dwarf_encoding_name (num);
5721 case DW_AT_accessibility:
5722 valuestr = dwarf_access_name (num);
5724 case DW_AT_visibility:
5725 valuestr = dwarf_visibility_name (num);
5727 case DW_AT_virtuality:
5728 valuestr = dwarf_virtuality_name (num);
5730 case DW_AT_identifier_case:
5731 valuestr = dwarf_identifier_case_name (num);
5733 case DW_AT_calling_convention:
5734 valuestr = dwarf_calling_convention_name (num);
5737 valuestr = dwarf_inline_name (num);
5739 case DW_AT_ordering:
5740 valuestr = dwarf_ordering_name (num);
5742 case DW_AT_discr_list:
5743 valuestr = dwarf_discr_list_name (num);
5753 /* When highpc is in constant form it is relative to lowpc.
5754 In that case also show the address. */
5756 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5758 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5760 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5761 (int) (level * 2), "", dwarf_attr_name (attr),
5762 dwarf_form_name (form), (uintmax_t) num, a);
5767 Dwarf_Sword snum = 0;
5768 if (form == DW_FORM_sdata)
5769 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5772 if (valuestr == NULL)
5774 printf (" %*s%-20s (%s)",
5775 (int) (level * 2), "", dwarf_attr_name (attr),
5776 dwarf_form_name (form));
5777 if (form == DW_FORM_sdata)
5778 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5780 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5784 printf (" %*s%-20s (%s) %s",
5785 (int) (level * 2), "", dwarf_attr_name (attr),
5786 dwarf_form_name (form), valuestr);
5787 if (form == DW_FORM_sdata)
5788 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5790 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
5799 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5802 printf (" %*s%-20s (%s) %s\n",
5803 (int) (level * 2), "", dwarf_attr_name (attr),
5804 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5807 case DW_FORM_flag_present:
5810 printf (" %*s%-20s (%s) %s\n",
5811 (int) (level * 2), "", dwarf_attr_name (attr),
5812 dwarf_form_name (form), nl_langinfo (YESSTR));
5815 case DW_FORM_exprloc:
5816 case DW_FORM_block4:
5817 case DW_FORM_block2:
5818 case DW_FORM_block1:
5823 if (unlikely (dwarf_formblock (attrp, &block) != 0))
5826 printf (" %*s%-20s (%s) ",
5827 (int) (level * 2), "", dwarf_attr_name (attr),
5828 dwarf_form_name (form));
5833 if (form != DW_FORM_exprloc)
5835 print_block (block.length, block.data);
5840 case DW_AT_location:
5841 case DW_AT_data_location:
5842 case DW_AT_data_member_location:
5843 case DW_AT_vtable_elem_location:
5844 case DW_AT_string_length:
5845 case DW_AT_use_location:
5846 case DW_AT_frame_base:
5847 case DW_AT_return_addr:
5848 case DW_AT_static_link:
5849 case DW_AT_allocated:
5850 case DW_AT_associated:
5851 case DW_AT_bit_size:
5852 case DW_AT_bit_offset:
5853 case DW_AT_bit_stride:
5854 case DW_AT_byte_size:
5855 case DW_AT_byte_stride:
5857 case DW_AT_lower_bound:
5858 case DW_AT_upper_bound:
5859 case DW_AT_GNU_call_site_value:
5860 case DW_AT_GNU_call_site_data_value:
5861 case DW_AT_GNU_call_site_target:
5862 case DW_AT_GNU_call_site_target_clobbered:
5864 print_ops (cbargs->dwflmod, cbargs->dbg,
5865 12 + level * 2, 12 + level * 2,
5866 cbargs->version, cbargs->addrsize, cbargs->offset_size,
5867 attrp->cu, block.length, block.data);
5875 printf (" %*s%-20s (form: %#x) ???\n",
5876 (int) (level * 2), "", dwarf_attr_name (attr),
5885 print_debug_units (Dwfl_Module *dwflmod,
5886 Ebl *ebl, GElf_Ehdr *ehdr,
5887 Elf_Scn *scn, GElf_Shdr *shdr,
5888 Dwarf *dbg, bool debug_types)
5890 const bool silent = !(print_debug_sections & section_info);
5891 const char *secname = section_name (ebl, ehdr, shdr);
5895 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5896 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5898 /* If the section is empty we don't have to do anything. */
5899 if (!silent && shdr->sh_size == 0)
5903 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5905 Dwarf_Off offset = 0;
5907 /* New compilation unit. */
5910 Dwarf_Off abbroffset;
5917 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5918 &abbroffset, &addrsize, &offsize,
5919 debug_types ? &typesig : NULL,
5920 debug_types ? &typeoff : NULL) != 0)
5926 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5927 " Version: %" PRIu16 ", Abbreviation section offset: %"
5928 PRIu64 ", Address size: %" PRIu8
5929 ", Offset size: %" PRIu8
5930 "\n Type signature: %#" PRIx64
5931 ", Type offset: %#" PRIx64 "\n"),
5932 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5933 typesig, (uint64_t) typeoff);
5935 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5936 " Version: %" PRIu16 ", Abbreviation section offset: %"
5937 PRIu64 ", Address size: %" PRIu8
5938 ", Offset size: %" PRIu8 "\n"),
5939 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5942 struct attrcb_args args =
5948 .addrsize = addrsize,
5949 .offset_size = offsize
5956 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
5957 (dbg, offset, &dies[level]) == NULL))
5960 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
5961 " in section '%s': %s"),
5962 (uint64_t) offset, secname, dwarf_errmsg (-1));
5966 args.cu = dies[0].cu;
5970 offset = dwarf_dieoffset (&dies[level]);
5971 if (unlikely (offset == ~0ul))
5974 error (0, 0, gettext ("cannot get DIE offset: %s"),
5979 int tag = dwarf_tag (&dies[level]);
5980 if (unlikely (tag == DW_TAG_invalid))
5983 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
5984 " in section '%s': %s"),
5985 (uint64_t) offset, secname, dwarf_errmsg (-1));
5990 printf (" [%6" PRIx64 "] %*s%s\n",
5991 (uint64_t) offset, (int) (level * 2), "",
5992 dwarf_tag_name (tag));
5994 /* Print the attribute values. */
5996 args.die = &dies[level];
5997 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
5999 /* Make room for the next level's DIE. */
6000 if (level + 1 == maxdies)
6001 dies = (Dwarf_Die *) xrealloc (dies,
6003 * sizeof (Dwarf_Die));
6005 int res = dwarf_child (&dies[level], &dies[level + 1]);
6008 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6012 if (unlikely (res == -1))
6015 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6020 else if (unlikely (res < 0))
6023 error (0, 0, gettext ("cannot get next DIE: %s"),
6041 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6042 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6044 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6048 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6049 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6051 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6056 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6057 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6060 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6061 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6062 (uint64_t) shdr->sh_offset);
6065 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6068 Dwarf_Off ncuoffset = 0;
6070 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6071 NULL, NULL, NULL) == 0)
6074 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6079 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6082 printf (" CU [%" PRIx64 "] %s\n",
6083 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6084 printf (" line:col SBPE* disc isa op address"
6085 " (Statement Block Prologue Epilogue *End)\n");
6086 const char *last_file = "";
6087 for (size_t n = 0; n < nlines; n++)
6089 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6090 Dwarf_Word mtime, length;
6091 const char *file = dwarf_linesrc (line, &mtime, &length);
6092 if (strcmp (last_file, file) != 0)
6094 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6095 file, mtime, length);
6100 bool statement, endseq, block, prologue_end, epilogue_begin;
6101 unsigned int lineop, isa, disc;
6103 dwarf_lineaddr (line, &address);
6104 dwarf_lineno (line, &lineno);
6105 dwarf_linecol (line, &colno);
6106 dwarf_lineop_index (line, &lineop);
6107 dwarf_linebeginstatement (line, &statement);
6108 dwarf_lineendsequence (line, &endseq);
6109 dwarf_lineblock (line, &block);
6110 dwarf_lineprologueend (line, &prologue_end);
6111 dwarf_lineepiloguebegin (line, &epilogue_begin);
6112 dwarf_lineisa (line, &isa);
6113 dwarf_linediscriminator (line, &disc);
6115 /* End sequence is special, it is one byte past. */
6116 char *a = format_dwarf_addr (dwflmod, address_size,
6117 address - (endseq ? 1 : 0), address);
6118 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6120 (statement ? 'S' : ' '),
6121 (block ? 'B' : ' '),
6122 (prologue_end ? 'P' : ' '),
6123 (epilogue_begin ? 'E' : ' '),
6124 (endseq ? '*' : ' '),
6125 disc, isa, lineop, a);
6136 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6137 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6141 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6146 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6147 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6148 (uint64_t) shdr->sh_offset);
6150 if (shdr->sh_size == 0)
6153 /* There is no functionality in libdw to read the information in the
6154 way it is represented here. Hardcode the decoder. */
6155 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6156 if (unlikely (data == NULL || data->d_buf == NULL))
6158 error (0, 0, gettext ("cannot get line data section data: %s"),
6163 const unsigned char *linep = (const unsigned char *) data->d_buf;
6164 const unsigned char *lineendp;
6167 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6169 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6171 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6173 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6174 unsigned int length = 4;
6175 if (unlikely (unit_length == 0xffffffff))
6177 if (unlikely (linep + 8 > lineendp))
6180 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6181 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6184 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6188 /* Check whether we have enough room in the section. */
6189 if (unit_length < 2 + length + 5 * 1
6190 || unlikely (linep + unit_length > lineendp))
6192 lineendp = linep + unit_length;
6194 /* The next element of the header is the version identifier. */
6195 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6197 /* Next comes the header length. */
6198 Dwarf_Word header_length;
6200 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6202 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6203 //const unsigned char *header_start = linep;
6205 /* Next the minimum instruction length. */
6206 uint_fast8_t minimum_instr_len = *linep++;
6208 /* Next the maximum operations per instruction, in version 4 format. */
6209 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6211 /* Then the flag determining the default value of the is_stmt
6213 uint_fast8_t default_is_stmt = *linep++;
6215 /* Now the line base. */
6216 int_fast8_t line_base = *((const int_fast8_t *) linep);
6219 /* And the line range. */
6220 uint_fast8_t line_range = *linep++;
6222 /* The opcode base. */
6223 uint_fast8_t opcode_base = *linep++;
6225 /* Print what we got so far. */
6226 printf (gettext ("\n"
6227 " Length: %" PRIu64 "\n"
6228 " DWARF version: %" PRIuFAST16 "\n"
6229 " Prologue length: %" PRIu64 "\n"
6230 " Minimum instruction length: %" PRIuFAST8 "\n"
6231 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6232 " Initial value if '%s': %" PRIuFAST8 "\n"
6233 " Line base: %" PRIdFAST8 "\n"
6234 " Line range: %" PRIuFAST8 "\n"
6235 " Opcode base: %" PRIuFAST8 "\n"
6238 (uint64_t) unit_length, version, (uint64_t) header_length,
6239 minimum_instr_len, max_ops_per_instr,
6240 "is_stmt", default_is_stmt, line_base,
6241 line_range, opcode_base);
6243 if (unlikely (linep + opcode_base - 1 >= lineendp))
6247 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6248 linep - (const unsigned char *) data->d_buf,
6249 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6253 int opcode_base_l10 = 1;
6254 unsigned int tmp = opcode_base;
6260 const uint8_t *standard_opcode_lengths = linep - 1;
6261 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6262 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6263 " [%*" PRIuFAST8 "] %hhu arguments\n",
6264 (int) linep[cnt - 1]),
6265 opcode_base_l10, cnt, linep[cnt - 1]);
6266 linep += opcode_base - 1;
6267 if (unlikely (linep >= lineendp))
6270 puts (gettext ("\nDirectory table:"));
6273 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6274 if (unlikely (endp == NULL))
6277 printf (" %s\n", (char *) linep);
6281 /* Skip the final NUL byte. */
6284 if (unlikely (linep >= lineendp))
6286 puts (gettext ("\nFile name table:\n"
6287 " Entry Dir Time Size Name"));
6288 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6290 /* First comes the file name. */
6291 char *fname = (char *) linep;
6292 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6293 if (unlikely (endp == NULL))
6297 /* Then the index. */
6298 unsigned int diridx;
6299 get_uleb128 (diridx, linep);
6301 /* Next comes the modification time. */
6303 get_uleb128 (mtime, linep);
6305 /* Finally the length of the file. */
6307 get_uleb128 (fsize, linep);
6309 printf (" %-5u %-5u %-9u %-9u %s\n",
6310 cnt, diridx, mtime, fsize, fname);
6312 /* Skip the final NUL byte. */
6315 puts (gettext ("\nLine number statements:"));
6316 Dwarf_Word address = 0;
6317 unsigned int op_index = 0;
6319 uint_fast8_t is_stmt = default_is_stmt;
6321 /* Default address value, in case we do not find the CU. */
6323 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6325 /* Determine the CU this block is for. */
6327 Dwarf_Off ncuoffset = 0;
6329 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6330 NULL, NULL, NULL) == 0)
6333 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6335 Dwarf_Attribute stmt_list;
6336 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6339 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6341 if (lineoff == start_offset)
6344 address_size = cudie.cu->address_size;
6349 /* Apply the "operation advance" from a special opcode
6350 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6351 unsigned int op_addr_advance;
6353 inline void advance_pc (unsigned int op_advance)
6355 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6356 / max_ops_per_instr);
6357 address += op_advance;
6358 show_op_index = (op_index > 0 ||
6359 (op_index + op_advance) % max_ops_per_instr > 0);
6360 op_index = (op_index + op_advance) % max_ops_per_instr;
6363 while (linep < lineendp)
6365 size_t offset = linep - (const unsigned char *) data->d_buf;
6369 /* Read the opcode. */
6370 unsigned int opcode = *linep++;
6372 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6373 /* Is this a special opcode? */
6374 if (likely (opcode >= opcode_base))
6376 /* Yes. Handling this is quite easy since the opcode value
6379 opcode = (desired line increment - line_base)
6380 + (line_range * address advance) + opcode_base
6382 int line_increment = (line_base
6383 + (opcode - opcode_base) % line_range);
6385 /* Perform the increments. */
6386 line += line_increment;
6387 advance_pc ((opcode - opcode_base) / line_range);
6389 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6392 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6393 opcode, op_addr_advance, a, op_index,
6394 line_increment, line);
6397 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6398 opcode, op_addr_advance, a, line_increment, line);
6401 else if (opcode == 0)
6403 /* This an extended opcode. */
6404 if (unlikely (linep + 2 > lineendp))
6408 unsigned int len = *linep++;
6410 if (unlikely (linep + len > lineendp))
6413 /* The sub-opcode. */
6416 printf (gettext (" extended opcode %u: "), opcode);
6420 case DW_LNE_end_sequence:
6421 puts (gettext (" end of sequence"));
6423 /* Reset the registers we care about. */
6427 is_stmt = default_is_stmt;
6430 case DW_LNE_set_address:
6432 if (address_size == 4)
6433 address = read_4ubyte_unaligned_inc (dbg, linep);
6435 address = read_8ubyte_unaligned_inc (dbg, linep);
6437 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6438 printf (gettext (" set address to %s\n"), a);
6443 case DW_LNE_define_file:
6445 char *fname = (char *) linep;
6446 unsigned char *endp = memchr (linep, '\0',
6448 if (unlikely (endp == NULL))
6452 unsigned int diridx;
6453 get_uleb128 (diridx, linep);
6455 get_uleb128 (mtime, linep);
6456 Dwarf_Word filelength;
6457 get_uleb128 (filelength, linep);
6460 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6461 diridx, (uint64_t) mtime, (uint64_t) filelength,
6466 case DW_LNE_set_discriminator:
6467 /* Takes one ULEB128 parameter, the discriminator. */
6468 if (unlikely (standard_opcode_lengths[opcode] != 1))
6471 get_uleb128 (u128, linep);
6472 printf (gettext (" set discriminator to %u\n"), u128);
6476 /* Unknown, ignore it. */
6477 puts (gettext (" unknown opcode"));
6482 else if (opcode <= DW_LNS_set_isa)
6484 /* This is a known standard opcode. */
6488 /* Takes no argument. */
6489 puts (gettext (" copy"));
6492 case DW_LNS_advance_pc:
6493 /* Takes one uleb128 parameter which is added to the
6495 get_uleb128 (u128, linep);
6498 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6501 advance address by %u to %s, op_index to %u\n"),
6502 op_addr_advance, a, op_index);
6504 printf (gettext (" advance address by %u to %s\n"),
6505 op_addr_advance, a);
6510 case DW_LNS_advance_line:
6511 /* Takes one sleb128 parameter which is added to the
6513 get_sleb128 (s128, linep);
6516 advance line by constant %d to %" PRId64 "\n"),
6517 s128, (int64_t) line);
6520 case DW_LNS_set_file:
6521 /* Takes one uleb128 parameter which is stored in file. */
6522 get_uleb128 (u128, linep);
6523 printf (gettext (" set file to %" PRIu64 "\n"),
6527 case DW_LNS_set_column:
6528 /* Takes one uleb128 parameter which is stored in column. */
6529 if (unlikely (standard_opcode_lengths[opcode] != 1))
6532 get_uleb128 (u128, linep);
6533 printf (gettext (" set column to %" PRIu64 "\n"),
6537 case DW_LNS_negate_stmt:
6538 /* Takes no argument. */
6539 is_stmt = 1 - is_stmt;
6540 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6541 "is_stmt", is_stmt);
6544 case DW_LNS_set_basic_block:
6545 /* Takes no argument. */
6546 puts (gettext (" set basic block flag"));
6549 case DW_LNS_const_add_pc:
6550 /* Takes no argument. */
6551 advance_pc ((255 - opcode_base) / line_range);
6553 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6556 advance address by constant %u to %s, op_index to %u\n"),
6557 op_addr_advance, a, op_index);
6560 advance address by constant %u to %s\n"),
6561 op_addr_advance, a);
6566 case DW_LNS_fixed_advance_pc:
6567 /* Takes one 16 bit parameter which is added to the
6569 if (unlikely (standard_opcode_lengths[opcode] != 1))
6572 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6576 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6578 advance address by fixed value %u to %s\n"),
6584 case DW_LNS_set_prologue_end:
6585 /* Takes no argument. */
6586 puts (gettext (" set prologue end flag"));
6589 case DW_LNS_set_epilogue_begin:
6590 /* Takes no argument. */
6591 puts (gettext (" set epilogue begin flag"));
6594 case DW_LNS_set_isa:
6595 /* Takes one uleb128 parameter which is stored in isa. */
6596 if (unlikely (standard_opcode_lengths[opcode] != 1))
6599 get_uleb128 (u128, linep);
6600 printf (gettext (" set isa to %u\n"), u128);
6606 /* This is a new opcode the generator but not we know about.
6607 Read the parameters associated with it but then discard
6608 everything. Read all the parameters for this opcode. */
6609 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6610 " unknown opcode with %" PRIu8 " parameters:",
6611 standard_opcode_lengths[opcode]),
6612 standard_opcode_lengths[opcode]);
6613 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6615 get_uleb128 (u128, linep);
6616 if (n != standard_opcode_lengths[opcode])
6617 putc_unlocked (',', stdout);
6618 printf (" %u", u128);
6621 /* Next round, ignore this opcode. */
6627 /* There must only be one data block. */
6628 assert (elf_getdata (scn, data) == NULL);
6633 print_debug_loc_section (Dwfl_Module *dwflmod,
6634 Ebl *ebl, GElf_Ehdr *ehdr,
6635 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6637 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6639 if (unlikely (data == NULL))
6641 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6647 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6648 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6649 (uint64_t) shdr->sh_offset);
6651 sort_listptr (&known_loclistptr, "loclistptr");
6652 size_t listptr_idx = 0;
6654 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6655 uint_fast8_t offset_size = 4;
6658 struct Dwarf_CU *cu = NULL;
6659 Dwarf_Addr base = 0;
6660 unsigned char *readp = data->d_buf;
6661 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6662 while (readp < endp)
6664 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6666 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6667 &address_size, &offset_size, &base,
6668 &cu, offset, &readp, endp))
6671 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6673 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6679 if (address_size == 8)
6681 begin = read_8ubyte_unaligned_inc (dbg, readp);
6682 end = read_8ubyte_unaligned_inc (dbg, readp);
6686 begin = read_4ubyte_unaligned_inc (dbg, readp);
6687 end = read_4ubyte_unaligned_inc (dbg, readp);
6688 if (begin == (Dwarf_Addr) (uint32_t) -1)
6689 begin = (Dwarf_Addr) -1l;
6692 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6694 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6695 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6699 else if (begin == 0 && end == 0) /* End of list entry. */
6702 printf (gettext (" [%6tx] empty list\n"), offset);
6707 /* We have a location expression entry. */
6708 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6710 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6712 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6715 if (first) /* First entry in a list. */
6716 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6718 printf (gettext (" %s..%s"), b, e);
6723 if (endp - readp <= (ptrdiff_t) len)
6725 fputs (gettext (" <INVALID DATA>\n"), stdout);
6729 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6730 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6743 struct mac_culist *next;
6748 mac_compare (const void *p1, const void *p2)
6750 struct mac_culist *m1 = (struct mac_culist *) p1;
6751 struct mac_culist *m2 = (struct mac_culist *) p2;
6753 if (m1->offset < m2->offset)
6755 if (m1->offset > m2->offset)
6762 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6763 Ebl *ebl, GElf_Ehdr *ehdr,
6764 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6767 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6768 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6769 (uint64_t) shdr->sh_offset);
6770 putc_unlocked ('\n', stdout);
6772 /* There is no function in libdw to iterate over the raw content of
6773 the section but it is easy enough to do. */
6774 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
6775 if (unlikely (data == NULL || data->d_buf == NULL))
6777 error (0, 0, gettext ("cannot get macro information section data: %s"),
6782 /* Get the source file information for all CUs. */
6786 struct mac_culist *culist = NULL;
6788 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6791 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6794 Dwarf_Attribute attr;
6795 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6799 if (dwarf_formudata (&attr, &macoff) != 0)
6802 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6804 newp->offset = macoff;
6806 newp->next = culist;
6811 /* Convert the list into an array for easier consumption. */
6812 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6815 cus[nculist].offset = data->d_size;
6818 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6820 assert (cnt < nculist);
6822 culist = culist->next;
6825 /* Sort the array according to the offset in the .debug_macinfo
6826 section. Note we keep the sentinel at the end. */
6827 qsort (cus, nculist, sizeof (*cus), mac_compare);
6830 const unsigned char *readp = (const unsigned char *) data->d_buf;
6831 const unsigned char *readendp = readp + data->d_size;
6834 while (readp < readendp)
6836 unsigned int opcode = *readp++;
6838 unsigned int u128_2;
6839 const unsigned char *endp;
6843 case DW_MACINFO_define:
6844 case DW_MACINFO_undef:
6845 case DW_MACINFO_vendor_ext:
6846 /* For the first two opcodes the parameters are
6850 We can treat these cases together. */
6851 get_uleb128 (u128, readp);
6853 endp = memchr (readp, '\0', readendp - readp);
6854 if (unlikely (endp == NULL))
6857 %*s*** non-terminated string at end of section"),
6862 if (opcode == DW_MACINFO_define)
6863 printf ("%*s#define %s, line %u\n",
6864 level, "", (char *) readp, u128);
6865 else if (opcode == DW_MACINFO_undef)
6866 printf ("%*s#undef %s, line %u\n",
6867 level, "", (char *) readp, u128);
6869 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6874 case DW_MACINFO_start_file:
6875 /* The two parameters are line and file index, in this order. */
6876 get_uleb128 (u128, readp);
6877 get_uleb128 (u128_2, readp);
6879 /* Find the CU DIE for this file. */
6880 size_t macoff = readp - (const unsigned char *) data->d_buf;
6881 const char *fname = "???";
6882 if (macoff >= cus[0].offset)
6884 while (macoff >= cus[1].offset)
6887 if (cus[0].files == NULL
6888 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6889 cus[0].files = (Dwarf_Files *) -1l;
6891 if (cus[0].files != (Dwarf_Files *) -1l)
6892 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6896 printf ("%*sstart_file %u, [%u] %s\n",
6897 level, "", u128, u128_2, fname);
6901 case DW_MACINFO_end_file:
6903 printf ("%*send_file\n", level, "");
6904 /* Nothing more to do. */
6908 // XXX gcc seems to generate files with a trailing zero.
6909 if (unlikely (opcode != 0 || readp != readendp))
6910 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6918 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6919 Ebl *ebl, GElf_Ehdr *ehdr,
6920 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6923 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6924 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6925 (uint64_t) shdr->sh_offset);
6926 putc_unlocked ('\n', stdout);
6928 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
6929 if (unlikely (data == NULL || data->d_buf == NULL))
6931 error (0, 0, gettext ("cannot get macro information section data: %s"),
6936 /* Get the source file information for all CUs. Uses same
6937 datastructure as macinfo. But uses offset field to directly
6938 match .debug_line offset. And just stored in a list. */
6942 struct mac_culist *culist = NULL;
6944 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6947 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6950 Dwarf_Attribute attr;
6951 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
6955 if (dwarf_formudata (&attr, &lineoff) != 0)
6958 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6960 newp->offset = lineoff;
6962 newp->next = culist;
6967 const unsigned char *readp = (const unsigned char *) data->d_buf;
6968 const unsigned char *readendp = readp + data->d_size;
6970 while (readp < readendp)
6972 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
6973 (uint64_t) (readp - (const unsigned char *) data->d_buf));
6975 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
6976 // optional vendor extension macro entry table.
6977 if (readp + 2 > readendp)
6980 error (0, 0, gettext ("invalid data"));
6983 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
6984 printf (gettext (" Version: %" PRIu16 "\n"), vers);
6986 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
6987 // 5 when it gets standardized.
6990 printf (gettext (" unknown version, cannot parse section\n"));
6994 if (readp + 1 > readendp)
6996 const unsigned char flag = *readp++;
6997 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
6999 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7000 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7001 Dwarf_Off line_offset = -1;
7004 if (offset_len == 8)
7005 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7007 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7008 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7012 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7013 memset (vendor, 0, sizeof vendor);
7016 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7017 // of arguments, for each argument 1 byte form code.
7018 if (readp + 1 > readendp)
7020 unsigned int tlen = *readp++;
7021 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7023 for (unsigned int i = 0; i < tlen; i++)
7025 if (readp + 1 > readendp)
7027 unsigned int opcode = *readp++;
7028 printf (gettext (" [%" PRIx8 "]"), opcode);
7029 if (opcode < DW_MACRO_GNU_lo_user
7030 || opcode > DW_MACRO_GNU_hi_user)
7032 // Record the start of description for this vendor opcode.
7033 // uleb128 nr args, 1 byte per arg form.
7034 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7035 if (readp + 1 > readendp)
7037 unsigned int args = *readp++;
7040 printf (gettext (" %" PRIu8 " arguments:"), args);
7043 if (readp + 1 > readendp)
7045 unsigned int form = *readp++;
7046 printf (" %s", dwarf_form_string (form));
7047 if (form != DW_FORM_data1
7048 && form != DW_FORM_data2
7049 && form != DW_FORM_data4
7050 && form != DW_FORM_data8
7051 && form != DW_FORM_sdata
7052 && form != DW_FORM_udata
7053 && form != DW_FORM_block
7054 && form != DW_FORM_block1
7055 && form != DW_FORM_block2
7056 && form != DW_FORM_block4
7057 && form != DW_FORM_flag
7058 && form != DW_FORM_string
7059 && form != DW_FORM_strp
7060 && form != DW_FORM_sec_offset)
7064 putchar_unlocked (',');
7068 printf (gettext (" no arguments."));
7069 putchar_unlocked ('\n');
7072 putchar_unlocked ('\n');
7075 if (readp + 1 > readendp)
7077 unsigned int opcode = *readp++;
7081 unsigned int u128_2;
7082 const unsigned char *endp;
7087 case DW_MACRO_GNU_start_file:
7088 get_uleb128 (u128, readp);
7089 get_uleb128 (u128_2, readp);
7091 /* Find the CU DIE that matches this line offset. */
7092 const char *fname = "???";
7093 if (line_offset != (Dwarf_Off) -1)
7095 struct mac_culist *cu = culist;
7096 while (cu != NULL && line_offset != cu->offset)
7100 if (cu->files == NULL
7101 && dwarf_getsrcfiles (&cu->die, &cu->files,
7103 cu->files = (Dwarf_Files *) -1l;
7105 if (cu->files != (Dwarf_Files *) -1l)
7106 fname = (dwarf_filesrc (cu->files, u128_2,
7107 NULL, NULL) ?: "???");
7110 printf ("%*sstart_file %u, [%u] %s\n",
7111 level, "", u128, u128_2, fname);
7115 case DW_MACRO_GNU_end_file:
7117 printf ("%*send_file\n", level, "");
7120 case DW_MACRO_GNU_define:
7121 get_uleb128 (u128, readp);
7122 endp = memchr (readp, '\0', readendp - readp);
7125 printf ("%*s#define %s, line %u\n",
7126 level, "", readp, u128);
7130 case DW_MACRO_GNU_undef:
7131 get_uleb128 (u128, readp);
7132 endp = memchr (readp, '\0', readendp - readp);
7135 printf ("%*s#undef %s, line %u\n",
7136 level, "", readp, u128);
7140 case DW_MACRO_GNU_define_indirect:
7141 get_uleb128 (u128, readp);
7142 if (readp + offset_len > readendp)
7144 if (offset_len == 8)
7145 off = read_8ubyte_unaligned_inc (dbg, readp);
7147 off = read_4ubyte_unaligned_inc (dbg, readp);
7148 printf ("%*s#define %s, line %u (indirect)\n",
7149 level, "", dwarf_getstring (dbg, off, NULL), u128);
7152 case DW_MACRO_GNU_undef_indirect:
7153 get_uleb128 (u128, readp);
7154 if (readp + offset_len > readendp)
7156 if (offset_len == 8)
7157 off = read_8ubyte_unaligned_inc (dbg, readp);
7159 off = read_4ubyte_unaligned_inc (dbg, readp);
7160 printf ("%*s#undef %s, line %u (indirect)\n",
7161 level, "", dwarf_getstring (dbg, off, NULL), u128);
7164 case DW_MACRO_GNU_transparent_include:
7165 if (readp + offset_len > readendp)
7167 if (offset_len == 8)
7168 off = read_8ubyte_unaligned_inc (dbg, readp);
7170 off = read_4ubyte_unaligned_inc (dbg, readp);
7171 printf ("%*s#include offset 0x%" PRIx64 "\n",
7176 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7177 if (opcode < DW_MACRO_GNU_lo_user
7178 || opcode > DW_MACRO_GNU_lo_user
7179 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7182 const unsigned char *op_desc;
7183 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7185 // Just skip the arguments, we cannot really interpret them,
7186 // but print as much as we can.
7187 unsigned int args = *op_desc++;
7190 unsigned int form = *op_desc++;
7195 if (readp + 1 > readendp)
7198 printf (" %" PRIx8, (unsigned int) val);
7202 if (readp + 2 > readendp)
7204 val = read_2ubyte_unaligned_inc (dbg, readp);
7205 printf(" %" PRIx16, (unsigned int) val);
7209 if (readp + 4 > readendp)
7211 val = read_4ubyte_unaligned_inc (dbg, readp);
7212 printf (" %" PRIx32, (unsigned int) val);
7216 if (readp + 8 > readendp)
7218 val = read_8ubyte_unaligned_inc (dbg, readp);
7219 printf (" %" PRIx64, val);
7223 get_sleb128 (val, readp);
7224 printf (" %" PRIx64, val);
7228 get_uleb128 (val, readp);
7229 printf (" %" PRIx64, val);
7233 get_uleb128 (val, readp);
7234 printf (" block[%" PRIu64 "]", val);
7235 if (readp + val > readendp)
7240 case DW_FORM_block1:
7241 if (readp + 1 > readendp)
7244 printf (" block[%" PRIu64 "]", val);
7245 if (readp + val > readendp)
7249 case DW_FORM_block2:
7250 if (readp + 2 > readendp)
7252 val = read_2ubyte_unaligned_inc (dbg, readp);
7253 printf (" block[%" PRIu64 "]", val);
7254 if (readp + val > readendp)
7258 case DW_FORM_block4:
7259 if (readp + 2 > readendp)
7261 val =read_4ubyte_unaligned_inc (dbg, readp);
7262 printf (" block[%" PRIu64 "]", val);
7263 if (readp + val > readendp)
7268 if (readp + 1 > readendp)
7271 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7274 case DW_FORM_string:
7275 endp = memchr (readp, '\0', readendp - readp);
7278 printf (" %s", readp);
7283 if (readp + offset_len > readendp)
7285 if (offset_len == 8)
7286 val = read_8ubyte_unaligned_inc (dbg, readp);
7288 val = read_4ubyte_unaligned_inc (dbg, readp);
7289 printf (" %s", dwarf_getstring (dbg, val, NULL));
7292 case DW_FORM_sec_offset:
7293 if (readp + offset_len > readendp)
7295 if (offset_len == 8)
7296 val = read_8ubyte_unaligned_inc (dbg, readp);
7298 val = read_4ubyte_unaligned_inc (dbg, readp);
7299 printf (" %" PRIx64, val);
7303 error (0, 0, gettext ("vendor opcode not verified?"));
7309 putchar_unlocked (',');
7311 putchar_unlocked ('\n');
7314 if (readp + 1 > readendp)
7318 putchar_unlocked ('\n');
7324 /* Callback for printing global names. */
7326 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7329 int *np = (int *) arg;
7331 printf (gettext (" [%5d] DIE offset: %6" PRId64
7332 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7333 (*np)++, global->die_offset, global->cu_offset, global->name);
7339 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7341 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7342 Ebl *ebl, GElf_Ehdr *ehdr,
7343 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7345 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7346 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7347 (uint64_t) shdr->sh_offset);
7350 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7353 /* Print the content of the DWARF string section '.debug_str'. */
7355 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7356 Ebl *ebl, GElf_Ehdr *ehdr,
7357 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7359 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7360 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7362 /* Compute floor(log16(shdr->sh_size)). */
7363 GElf_Addr tmp = sh_size;
7370 digits = MAX (4, digits);
7372 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7375 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7376 /* TRANS: the debugstr| prefix makes the string unique. */
7377 digits + 2, sgettext ("debugstr|Offset"));
7379 Dwarf_Off offset = 0;
7380 while (offset < sh_size)
7383 const char *str = dwarf_getstring (dbg, offset, &len);
7384 if (unlikely (str == NULL))
7386 printf (gettext (" *** error while reading strings: %s\n"),
7391 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7398 /* Print the content of the call frame search table section
7401 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7402 Ebl *ebl __attribute__ ((unused)),
7403 GElf_Ehdr *ehdr __attribute__ ((unused)),
7404 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7407 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7410 Elf_Data *data = elf_rawdata (scn, NULL);
7412 if (unlikely (data == NULL))
7414 error (0, 0, gettext ("cannot get %s content: %s"),
7415 ".eh_frame_hdr", elf_errmsg (-1));
7419 const unsigned char *readp = data->d_buf;
7420 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7423 if (unlikely (readp + 4 > dataend))
7426 error (0, 0, gettext ("invalid data"));
7430 unsigned int version = *readp++;
7431 unsigned int eh_frame_ptr_enc = *readp++;
7432 unsigned int fde_count_enc = *readp++;
7433 unsigned int table_enc = *readp++;
7435 printf (" version: %u\n"
7436 " eh_frame_ptr_enc: %#x ",
7437 version, eh_frame_ptr_enc);
7438 print_encoding_base ("", eh_frame_ptr_enc);
7439 printf (" fde_count_enc: %#x ", fde_count_enc);
7440 print_encoding_base ("", fde_count_enc);
7441 printf (" table_enc: %#x ", table_enc);
7442 print_encoding_base ("", table_enc);
7444 uint64_t eh_frame_ptr = 0;
7445 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7447 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7449 if (unlikely (readp == NULL))
7452 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7453 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7454 printf (" (offset: %#" PRIx64 ")",
7455 /* +4 because of the 4 byte header of the section. */
7456 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7458 putchar_unlocked ('\n');
7461 uint64_t fde_count = 0;
7462 if (fde_count_enc != DW_EH_PE_omit)
7464 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7465 if (unlikely (readp == NULL))
7468 printf (" fde_count: %" PRIu64 "\n", fde_count);
7471 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7476 /* Optimize for the most common case. */
7477 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7478 while (fde_count > 0 && readp + 8 <= dataend)
7480 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7481 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7482 + (int64_t) initial_location);
7483 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7484 // XXX Possibly print symbol name or section offset for initial_offset
7485 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7486 " fde=[%6" PRIx64 "]\n",
7487 initial_location, initial_offset,
7488 address, address - (eh_frame_ptr + 4));
7491 while (0 && readp < dataend)
7498 /* Print the content of the exception handling table section
7501 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7502 Ebl *ebl __attribute__ ((unused)),
7503 GElf_Ehdr *ehdr __attribute__ ((unused)),
7505 GElf_Shdr *shdr __attribute__ ((unused)),
7506 Dwarf *dbg __attribute__ ((unused)))
7509 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7512 Elf_Data *data = elf_rawdata (scn, NULL);
7514 if (unlikely (data == NULL))
7516 error (0, 0, gettext ("cannot get %s content: %s"),
7517 ".gcc_except_table", elf_errmsg (-1));
7521 const unsigned char *readp = data->d_buf;
7522 const unsigned char *const dataend = readp + data->d_size;
7524 if (unlikely (readp + 1 > dataend))
7527 error (0, 0, gettext ("invalid data"));
7530 unsigned int lpstart_encoding = *readp++;
7531 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7532 print_encoding_base ("", lpstart_encoding);
7533 if (lpstart_encoding != DW_EH_PE_omit)
7536 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7537 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7540 if (unlikely (readp + 1 > dataend))
7542 unsigned int ttype_encoding = *readp++;
7543 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7544 print_encoding_base ("", ttype_encoding);
7545 const unsigned char *ttype_base = NULL;
7546 if (ttype_encoding != DW_EH_PE_omit)
7548 unsigned int ttype_base_offset;
7549 get_uleb128 (ttype_base_offset, readp);
7550 printf (" TType base offset: %#x\n", ttype_base_offset);
7551 ttype_base = readp + ttype_base_offset;
7554 if (unlikely (readp + 1 > dataend))
7556 unsigned int call_site_encoding = *readp++;
7557 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7558 print_encoding_base ("", call_site_encoding);
7559 unsigned int call_site_table_len;
7560 get_uleb128 (call_site_table_len, readp);
7562 const unsigned char *const action_table = readp + call_site_table_len;
7563 if (unlikely (action_table > dataend))
7566 unsigned int max_action = 0;
7567 while (readp < action_table)
7570 puts (gettext ("\n Call site table:"));
7572 uint64_t call_site_start;
7573 readp = read_encoded (call_site_encoding, readp, dataend,
7574 &call_site_start, dbg);
7575 uint64_t call_site_length;
7576 readp = read_encoded (call_site_encoding, readp, dataend,
7577 &call_site_length, dbg);
7578 uint64_t landing_pad;
7579 readp = read_encoded (call_site_encoding, readp, dataend,
7581 unsigned int action;
7582 get_uleb128 (action, readp);
7583 max_action = MAX (action, max_action);
7584 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7585 " Call site length: %" PRIu64 "\n"
7586 " Landing pad: %#" PRIx64 "\n"
7588 u++, call_site_start, call_site_length, landing_pad, action);
7590 assert (readp == action_table);
7592 unsigned int max_ar_filter = 0;
7595 puts ("\n Action table:");
7597 const unsigned char *const action_table_end
7598 = action_table + max_action + 1;
7604 get_sleb128 (ar_filter, readp);
7605 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7606 max_ar_filter = ar_filter;
7608 get_sleb128 (ar_disp, readp);
7610 printf (" [%4u] ar_filter: % d\n"
7612 u, ar_filter, ar_disp);
7613 if (abs (ar_disp) & 1)
7614 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7615 else if (ar_disp != 0)
7618 putchar_unlocked ('\n');
7621 while (readp < action_table_end);
7624 if (max_ar_filter > 0)
7626 puts ("\n TType table:");
7628 // XXX Not *4, size of encoding;
7629 switch (ttype_encoding & 7)
7631 case DW_EH_PE_udata2:
7632 case DW_EH_PE_sdata2:
7633 readp = ttype_base - max_ar_filter * 2;
7635 case DW_EH_PE_udata4:
7636 case DW_EH_PE_sdata4:
7637 readp = ttype_base - max_ar_filter * 4;
7639 case DW_EH_PE_udata8:
7640 case DW_EH_PE_sdata8:
7641 readp = ttype_base - max_ar_filter * 8;
7644 error (1, 0, gettext ("invalid TType encoding"));
7650 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7652 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7654 while (readp < ttype_base);
7658 /* Print the content of the '.gdb_index' section.
7659 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7662 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7663 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7665 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7666 " contains %" PRId64 " bytes :\n"),
7667 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7668 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7670 Elf_Data *data = elf_rawdata (scn, NULL);
7672 if (unlikely (data == NULL))
7674 error (0, 0, gettext ("cannot get %s content: %s"),
7675 ".gdb_index", elf_errmsg (-1));
7679 // .gdb_index is always in little endian.
7680 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7683 const unsigned char *readp = data->d_buf;
7684 const unsigned char *const dataend = readp + data->d_size;
7686 if (unlikely (readp + 4 > dataend))
7689 error (0, 0, gettext ("invalid data"));
7693 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7694 printf (gettext (" Version: %" PRId32 "\n"), vers);
7696 // The only difference between version 4 and version 5 is the
7697 // hash used for generating the table. Version 6 contains symbols
7698 // for inlined functions, older versions didn't. Version 7 adds
7699 // symbol kinds. Version 8 just indicates that it correctly includes
7701 if (vers < 4 || vers > 8)
7703 printf (gettext (" unknown version, cannot parse section\n"));
7708 if (unlikely (readp + 4 > dataend))
7711 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7712 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7715 if (unlikely (readp + 4 > dataend))
7718 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7719 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7722 if (unlikely (readp + 4 > dataend))
7725 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7726 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
7729 if (unlikely (readp + 4 > dataend))
7732 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7733 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
7736 if (unlikely (readp + 4 > dataend))
7739 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7740 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7742 readp = data->d_buf + cu_off;
7744 const unsigned char *nextp = data->d_buf + tu_off;
7745 size_t cu_nr = (nextp - readp) / 16;
7747 printf (gettext ("\n CU list at offset %#" PRIx32
7748 " contains %zu entries:\n"),
7752 while (readp + 16 <= dataend && n < cu_nr)
7754 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7757 uint64_t len = read_8ubyte_unaligned (dbg, readp);
7760 printf (" [%4zu] start: %0#8" PRIx64
7761 ", length: %5" PRIu64 "\n", n, off, len);
7765 readp = data->d_buf + tu_off;
7766 nextp = data->d_buf + addr_off;
7767 size_t tu_nr = (nextp - readp) / 24;
7769 printf (gettext ("\n TU list at offset %#" PRIx32
7770 " contains %zu entries:\n"),
7774 while (readp + 24 <= dataend && n < tu_nr)
7776 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7779 uint64_t type = read_8ubyte_unaligned (dbg, readp);
7782 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7785 printf (" [%4zu] CU offset: %5" PRId64
7786 ", type offset: %5" PRId64
7787 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7791 readp = data->d_buf + addr_off;
7792 nextp = data->d_buf + sym_off;
7793 size_t addr_nr = (nextp - readp) / 20;
7795 printf (gettext ("\n Address list at offset %#" PRIx32
7796 " contains %zu entries:\n"),
7800 while (readp + 20 <= dataend && n < addr_nr)
7802 uint64_t low = read_8ubyte_unaligned (dbg, readp);
7805 uint64_t high = read_8ubyte_unaligned (dbg, readp);
7808 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7811 char *l = format_dwarf_addr (dwflmod, 8, low, low);
7812 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7813 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7820 readp = data->d_buf + sym_off;
7821 nextp = data->d_buf + const_off;
7822 size_t sym_nr = (nextp - readp) / 8;
7824 printf (gettext ("\n Symbol table at offset %#" PRIx32
7825 " contains %zu slots:\n"),
7829 while (readp + 8 <= dataend && n < sym_nr)
7831 uint32_t name = read_4ubyte_unaligned (dbg, readp);
7834 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7837 if (name != 0 || vector != 0)
7839 const unsigned char *sym = data->d_buf + const_off + name;
7840 if (unlikely (sym > dataend))
7843 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7845 const unsigned char *readcus = data->d_buf + const_off + vector;
7846 if (unlikely (readcus + 8 > dataend))
7849 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7852 uint32_t cu_kind, cu, kind;
7855 cu_kind = read_4ubyte_unaligned (dbg, readcus);
7856 cu = cu_kind & ((1 << 24) - 1);
7857 kind = (cu_kind >> 28) & 7;
7858 is_static = cu_kind & (1U << 31);
7860 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
7862 printf ("%" PRId32, cu);
7881 printf ("unknown-0x%" PRIx32, kind);
7884 printf (":%c)", (is_static ? 'S' : 'G'));
7896 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7898 /* Before we start the real work get a debug context descriptor. */
7900 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7904 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7908 if ((print_debug_sections & ~section_exception) != 0)
7909 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7911 if ((print_debug_sections & section_exception) == 0)
7916 /* Get the section header string table index. */
7918 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7919 error (EXIT_FAILURE, 0,
7920 gettext ("cannot get section header string table index"));
7922 /* Look through all the sections for the debugging sections to print. */
7923 Elf_Scn *scn = NULL;
7924 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7927 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7929 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7934 enum section_e bitmask;
7935 void (*fp) (Dwfl_Module *, Ebl *,
7936 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7937 } debug_sections[] =
7939 #define NEW_SECTION(name) \
7940 { ".debug_" #name, section_##name, print_debug_##name##_section }
7941 NEW_SECTION (abbrev),
7942 NEW_SECTION (aranges),
7943 NEW_SECTION (frame),
7945 NEW_SECTION (types),
7948 NEW_SECTION (pubnames),
7950 NEW_SECTION (macinfo),
7951 NEW_SECTION (macro),
7952 NEW_SECTION (ranges),
7953 { ".eh_frame", section_frame | section_exception,
7954 print_debug_frame_section },
7955 { ".eh_frame_hdr", section_frame | section_exception,
7956 print_debug_frame_hdr_section },
7957 { ".gcc_except_table", section_frame | section_exception,
7958 print_debug_exception_table },
7959 { ".gdb_index", section_gdb_index, print_gdb_index_section }
7961 const int ndebug_sections = (sizeof (debug_sections)
7962 / sizeof (debug_sections[0]));
7963 const char *name = elf_strptr (ebl->elf, shstrndx,
7967 for (n = 0; n < ndebug_sections; ++n)
7968 if (strcmp (name, debug_sections[n].name) == 0
7970 || (name[0] == '.' && name[1] == 'z'
7971 && debug_sections[n].name[1] == 'd'
7972 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
7976 if ((print_debug_sections | implicit_debug_sections)
7977 & debug_sections[n].bitmask)
7978 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
7984 reset_listptr (&known_loclistptr);
7985 reset_listptr (&known_rangelistptr);
7989 #define ITEM_INDENT 4
7990 #define WRAP_COLUMN 75
7992 /* Print "NAME: FORMAT", wrapping when output text would make the line
7993 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
7994 but this function is also used for registers which should be printed
7995 aligned. Fortunately registers output uses fixed fields width (such
7996 as %11d) for the alignment.
7998 Line breaks should not depend on the particular values although that
7999 may happen in some cases of the core items. */
8002 __attribute__ ((format (printf, 6, 7)))
8003 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8004 size_t name_width, const char *name, const char *format, ...)
8006 size_t len = strlen (name);
8007 if (name_width < len)
8012 va_start (ap, format);
8013 int out_len = vasprintf (&out, format, ap);
8016 error (EXIT_FAILURE, 0, _("memory exhausted"));
8018 size_t n = name_width + sizeof ": " - 1 + out_len;
8022 printf ("%*s", ITEM_INDENT, "");
8023 colno = ITEM_INDENT + n;
8025 else if (colno + 2 + n < wrap)
8027 printf ("%c ", sep);
8032 printf ("\n%*s", ITEM_INDENT, "");
8033 colno = ITEM_INDENT + n;
8036 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8044 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8045 void *value, const void *data, size_t size)
8047 Elf_Data valuedata =
8051 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8052 .d_version = EV_CURRENT,
8057 .d_buf = (void *) data,
8058 .d_size = valuedata.d_size,
8059 .d_version = EV_CURRENT,
8062 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8063 ? elf32_xlatetom : elf64_xlatetom)
8064 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8066 error (EXIT_FAILURE, 0,
8067 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8069 return data + indata.d_size;
8072 typedef uint8_t GElf_Byte;
8075 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8076 unsigned int colno, size_t *repeated_size)
8078 uint_fast16_t count = item->count ?: 1;
8081 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8082 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8083 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8084 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8085 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8086 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8088 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8089 union { TYPES; } value;
8092 void *data = &value;
8093 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8094 size_t convsize = size;
8095 if (repeated_size != NULL)
8097 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8099 data = alloca (*repeated_size);
8100 count *= *repeated_size / size;
8101 convsize = count * size;
8102 *repeated_size -= convsize;
8104 else if (item->count != 0 || item->format != '\n')
8105 *repeated_size -= size;
8108 convert (core, item->type, count, data, desc + item->offset, convsize);
8110 Elf_Type type = item->type;
8111 if (type == ELF_T_ADDR)
8112 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8114 switch (item->format)
8117 assert (count == 1);
8120 #define DO_TYPE(NAME, Name, hex, dec) \
8121 case ELF_T_##NAME: \
8122 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8123 0, item->name, dec, value.Name[0]); \
8133 assert (count == 1);
8136 #define DO_TYPE(NAME, Name, hex, dec) \
8137 case ELF_T_##NAME: \
8138 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8139 0, item->name, hex, value.Name[0]); \
8150 assert (size % sizeof (unsigned int) == 0);
8151 unsigned int nbits = count * size * 8;
8152 unsigned int pop = 0;
8153 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8154 pop += __builtin_popcount (*i);
8155 bool negate = pop > nbits / 2;
8156 const unsigned int bias = item->format == 'b';
8159 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8163 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8165 assert (size == sizeof (unsigned int) * 2);
8166 for (unsigned int *i = data;
8167 (void *) i < data + count * size; i += 2)
8169 unsigned int w = i[1];
8175 unsigned int lastbit = 0;
8176 unsigned int run = 0;
8177 for (const unsigned int *i = data;
8178 (void *) i < data + count * size; ++i)
8180 unsigned int bit = ((void *) i - data) * 8;
8181 unsigned int w = negate ? ~*i : *i;
8188 if (lastbit != 0 && lastbit + 1 == bit)
8193 p += sprintf (p, "%u", bit - bias);
8195 p += sprintf (p, ",%u", bit - bias);
8197 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8204 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8205 p += sprintf (p, "-%u", lastbit - bias);
8207 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8208 negate ? "~<%s>" : "<%s>", printed);
8213 case (char) ('T'|0x80):
8214 assert (count == 2);
8219 #define DO_TYPE(NAME, Name, hex, dec) \
8220 case ELF_T_##NAME: \
8221 sec = value.Name[0]; \
8222 usec = value.Name[1]; \
8229 if (unlikely (item->format == (char) ('T'|0x80)))
8231 /* This is a hack for an ill-considered 64-bit ABI where
8232 tv_usec is actually a 32-bit field with 32 bits of padding
8233 rounding out struct timeval. We've already converted it as
8234 a 64-bit field. For little-endian, this just means the
8235 high half is the padding; it's presumably zero, but should
8236 be ignored anyway. For big-endian, it means the 32-bit
8237 field went into the high half of USEC. */
8239 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8240 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8245 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8246 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8250 assert (count == 1);
8251 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8252 "%c", value.Byte[0]);
8256 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8257 "%.*s", (int) count, value.Byte);
8261 /* This is a list of strings separated by '\n'. */
8262 assert (item->count == 0);
8263 assert (repeated_size != NULL);
8264 assert (item->name == NULL);
8265 if (unlikely (item->offset >= *repeated_size))
8268 const char *s = desc + item->offset;
8269 size = *repeated_size - item->offset;
8273 const char *eol = memchr (s, '\n', size);
8277 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8280 size -= eol + 1 - s;
8284 colno = WRAP_COLUMN;
8291 error (0, 0, "XXX not handling format '%c' for %s",
8292 item->format, item->name);
8302 /* Sort items by group, and by layout offset within each group. */
8304 compare_core_items (const void *a, const void *b)
8306 const Ebl_Core_Item *const *p1 = a;
8307 const Ebl_Core_Item *const *p2 = b;
8308 const Ebl_Core_Item *item1 = *p1;
8309 const Ebl_Core_Item *item2 = *p2;
8311 return ((item1->group == item2->group ? 0
8312 : strcmp (item1->group, item2->group))
8313 ?: (int) item1->offset - (int) item2->offset);
8316 /* Sort item groups by layout offset of the first item in the group. */
8318 compare_core_item_groups (const void *a, const void *b)
8320 const Ebl_Core_Item *const *const *p1 = a;
8321 const Ebl_Core_Item *const *const *p2 = b;
8322 const Ebl_Core_Item *const *group1 = *p1;
8323 const Ebl_Core_Item *const *group2 = *p2;
8324 const Ebl_Core_Item *item1 = *group1;
8325 const Ebl_Core_Item *item2 = *group2;
8327 return (int) item1->offset - (int) item2->offset;
8331 handle_core_items (Elf *core, const void *desc, size_t descsz,
8332 const Ebl_Core_Item *items, size_t nitems)
8336 unsigned int colno = 0;
8338 /* FORMAT '\n' makes sense to be present only as a single item as it
8339 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8340 if present as a single item but they can be also processed with other
8342 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8343 || items[0].format == 'B'))
8345 assert (items[0].offset == 0);
8346 size_t size = descsz;
8347 colno = handle_core_item (core, items, desc, colno, &size);
8348 /* If SIZE is not zero here there is some remaining data. But we do not
8349 know how to process it anyway. */
8352 for (size_t i = 0; i < nitems; ++i)
8353 assert (items[i].format != '\n');
8355 /* Sort to collect the groups together. */
8356 const Ebl_Core_Item *sorted_items[nitems];
8357 for (size_t i = 0; i < nitems; ++i)
8358 sorted_items[i] = &items[i];
8359 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8361 /* Collect the unique groups and sort them. */
8362 const Ebl_Core_Item **groups[nitems];
8363 groups[0] = &sorted_items[0];
8365 for (size_t i = 1; i < nitems; ++i)
8366 if (sorted_items[i]->group != sorted_items[i - 1]->group
8367 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8368 groups[ngroups++] = &sorted_items[i];
8369 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8371 /* Write out all the groups. */
8372 const void *last = desc;
8375 for (size_t i = 0; i < ngroups; ++i)
8377 for (const Ebl_Core_Item **item = groups[i];
8378 (item < &sorted_items[nitems]
8379 && ((*item)->group == groups[i][0]->group
8380 || !strcmp ((*item)->group, groups[i][0]->group)));
8382 colno = handle_core_item (core, *item, desc, colno, NULL);
8384 /* Force a line break at the end of the group. */
8385 colno = WRAP_COLUMN;
8391 /* This set of items consumed a certain amount of the note's data.
8392 If there is more data there, we have another unit of the same size.
8393 Loop to print that out too. */
8394 const Ebl_Core_Item *item = &items[nitems - 1];
8395 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8396 item->count ?: 1, EV_CURRENT);
8405 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8409 /* For just one repeat, print it unabridged twice. */
8414 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8415 ITEM_INDENT, "", reps);
8425 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8428 desc += regloc->offset;
8436 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8437 const Ebl_Register_Location *regloc, const void *desc,
8440 if (regloc->bits % 8 != 0)
8441 return handle_bit_registers (regloc, desc, colno);
8443 desc += regloc->offset;
8445 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8447 char name[REGNAMESZ];
8450 register_info (ebl, reg, regloc, name, &bits, &type);
8453 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8454 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8455 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8456 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8458 #define BITS(bits, xtype, sfmt, ufmt) \
8459 uint##bits##_t b##bits; int##bits##_t b##bits##s
8460 union { TYPES; uint64_t b128[2]; } value;
8465 case DW_ATE_unsigned:
8467 case DW_ATE_address:
8470 #define BITS(bits, xtype, sfmt, ufmt) \
8472 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8473 if (type == DW_ATE_signed) \
8474 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8476 sfmt, value.b##bits##s); \
8478 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8480 ufmt, value.b##bits); \
8486 assert (type == DW_ATE_unsigned);
8487 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8488 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8489 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8491 "0x%.16" PRIx64 "%.16" PRIx64,
8492 value.b128[!be], value.b128[be]);
8502 /* Print each byte in hex, the whole thing in native byte order. */
8503 assert (bits % 8 == 0);
8504 const uint8_t *bytes = desc;
8506 char hex[bits / 4 + 1];
8507 hex[bits / 4] = '\0';
8509 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8511 bytes += bits / 8 - 1;
8515 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8517 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8518 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8520 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8521 maxregname, name, "0x%s", hex);
8524 desc += regloc->pad;
8533 struct register_info
8535 const Ebl_Register_Location *regloc;
8537 char name[REGNAMESZ];
8544 register_bitpos (const struct register_info *r)
8546 return (r->regloc->offset * 8
8547 + ((r->regno - r->regloc->regno)
8548 * (r->regloc->bits + r->regloc->pad * 8)));
8552 compare_sets_by_info (const struct register_info *r1,
8553 const struct register_info *r2)
8555 return ((int) r2->bits - (int) r1->bits
8556 ?: register_bitpos (r1) - register_bitpos (r2));
8559 /* Sort registers by set, and by size and layout offset within each set. */
8561 compare_registers (const void *a, const void *b)
8563 const struct register_info *r1 = a;
8564 const struct register_info *r2 = b;
8566 /* Unused elements sort last. */
8567 if (r1->regloc == NULL)
8568 return r2->regloc == NULL ? 0 : 1;
8569 if (r2->regloc == NULL)
8572 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8573 ?: compare_sets_by_info (r1, r2));
8576 /* Sort register sets by layout offset of the first register in the set. */
8578 compare_register_sets (const void *a, const void *b)
8580 const struct register_info *const *p1 = a;
8581 const struct register_info *const *p2 = b;
8582 return compare_sets_by_info (*p1, *p2);
8586 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8587 const Ebl_Register_Location *reglocs, size_t nregloc)
8592 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8595 for (size_t i = 0; i < nregloc; ++i)
8596 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8597 maxnreg = reglocs[i].regno + reglocs[i].count;
8598 assert (maxnreg > 0);
8601 struct register_info regs[maxnreg];
8602 memset (regs, 0, sizeof regs);
8604 /* Sort to collect the sets together. */
8606 for (size_t i = 0; i < nregloc; ++i)
8607 for (int reg = reglocs[i].regno;
8608 reg < reglocs[i].regno + reglocs[i].count;
8611 assert (reg < maxnreg);
8614 struct register_info *info = ®s[reg];
8615 info->regloc = ®locs[i];
8617 info->set = register_info (ebl, reg, ®locs[i],
8618 info->name, &info->bits, &info->type);
8620 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8622 /* Collect the unique sets and sort them. */
8623 inline bool same_set (const struct register_info *a,
8624 const struct register_info *b)
8626 return (a < ®s[maxnreg] && a->regloc != NULL
8627 && b < ®s[maxnreg] && b->regloc != NULL
8628 && a->bits == b->bits
8629 && (a->set == b->set || !strcmp (a->set, b->set)));
8631 struct register_info *sets[maxreg + 1];
8634 for (int i = 1; i <= maxreg; ++i)
8635 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8636 sets[nsets++] = ®s[i];
8637 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8639 /* Write out all the sets. */
8640 unsigned int colno = 0;
8641 for (size_t i = 0; i < nsets; ++i)
8643 /* Find the longest name of a register in this set. */
8645 const struct register_info *end;
8646 for (end = sets[i]; same_set (sets[i], end); ++end)
8648 size_t len = strlen (end->name);
8653 for (const struct register_info *reg = sets[i];
8655 reg += reg->regloc->count ?: 1)
8656 colno = handle_core_register (ebl, core, maxname,
8657 reg->regloc, desc, colno);
8659 /* Force a line break at the end of the group. */
8660 colno = WRAP_COLUMN;
8667 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8669 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8672 error (EXIT_FAILURE, 0,
8673 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8675 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8676 for (size_t i = 0; i < nauxv; ++i)
8679 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8685 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8688 if (av->a_un.a_val == 0)
8689 printf (" %" PRIu64 "\n", av->a_type);
8691 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8692 av->a_type, av->a_un.a_val);
8697 case '\0': /* Normally zero. */
8698 if (av->a_un.a_val == 0)
8700 printf (" %s\n", name);
8705 case 'p': /* address */
8706 case 's': /* address of string */
8707 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8710 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8713 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8717 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8719 const char *pfx = "<";
8720 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8722 if (av->a_un.a_val & bit)
8724 printf ("%s%s", pfx, p);
8739 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8741 return ptr < end && (size_t) (end - ptr) >= sz;
8745 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8748 if (! buf_has_data (*ptrp, end, 4))
8751 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8756 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8759 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8760 if (! buf_has_data (*ptrp, end, sz))
8769 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
8779 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8781 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8783 error (EXIT_FAILURE, 0,
8784 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8786 unsigned char const *ptr = data->d_buf;
8787 unsigned char const *const end = data->d_buf + data->d_size;
8789 /* Siginfo head is three ints: signal number, error number, origin
8791 int si_signo, si_errno, si_code;
8792 if (! buf_read_int (core, &ptr, end, &si_signo)
8793 || ! buf_read_int (core, &ptr, end, &si_errno)
8794 || ! buf_read_int (core, &ptr, end, &si_code))
8797 printf (" Not enough data in NT_SIGINFO note.\n");
8801 /* Next is a pointer-aligned union of structures. On 64-bit
8802 machines, that implies a word of padding. */
8803 if (gelf_getclass (core) == ELFCLASS64)
8806 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
8807 si_signo, si_errno, si_code);
8818 if (! buf_read_ulong (core, &ptr, end, &addr))
8820 printf (" fault address: %#" PRIx64 "\n", addr);
8826 else if (si_code == SI_USER)
8829 if (! buf_read_int (core, &ptr, end, &pid)
8830 || ! buf_read_int (core, &ptr, end, &uid))
8832 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
8837 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8839 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8841 error (EXIT_FAILURE, 0,
8842 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8844 unsigned char const *ptr = data->d_buf;
8845 unsigned char const *const end = data->d_buf + data->d_size;
8847 uint64_t count, page_size;
8848 if (! buf_read_ulong (core, &ptr, end, &count)
8849 || ! buf_read_ulong (core, &ptr, end, &page_size))
8852 printf (" Not enough data in NT_FILE note.\n");
8856 /* Where file names are stored. */
8857 unsigned char const *const fstart
8858 = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8859 char const *fptr = (char *) fstart;
8861 printf (" %" PRId64 " files:\n", count);
8862 for (uint64_t i = 0; i < count; ++i)
8864 uint64_t mstart, mend, moffset;
8865 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
8866 || ! buf_read_ulong (core, &ptr, fstart, &mend)
8867 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
8870 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
8874 int ct = printf (" %08" PRIx64 "-%08" PRIx64
8875 " %08" PRIx64 " %" PRId64,
8876 mstart, mend, moffset * page_size, mend - mstart);
8877 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
8884 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8885 const char *name, const void *desc)
8887 GElf_Word regs_offset;
8889 const Ebl_Register_Location *reglocs;
8891 const Ebl_Core_Item *items;
8893 if (! ebl_core_note (ebl, nhdr, name,
8894 ®s_offset, &nregloc, ®locs, &nitems, &items))
8897 /* Pass 0 for DESCSZ when there are registers in the note,
8898 so that the ITEMS array does not describe the whole thing.
8899 For non-register notes, the actual descsz might be a multiple
8900 of the unit size, not just exactly the unit size. */
8901 unsigned int colno = handle_core_items (ebl->elf, desc,
8902 nregloc == 0 ? nhdr->n_descsz : 0,
8905 putchar_unlocked ('\n');
8907 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8910 putchar_unlocked ('\n');
8914 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8915 GElf_Off start, Elf_Data *data)
8917 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
8926 while (offset < data->d_size
8927 && (offset = gelf_getnote (data, offset,
8928 &nhdr, &name_offset, &desc_offset)) > 0)
8930 const char *name = data->d_buf + name_offset;
8931 const char *desc = data->d_buf + desc_offset;
8935 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
8936 (int) nhdr.n_namesz, name, nhdr.n_descsz,
8937 ehdr->e_type == ET_CORE
8938 ? ebl_core_note_type_name (ebl, nhdr.n_type,
8940 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8941 buf2, sizeof (buf2)));
8943 /* Filter out invalid entries. */
8944 if (memchr (name, '\0', nhdr.n_namesz) != NULL
8945 /* XXX For now help broken Linux kernels. */
8948 if (ehdr->e_type == ET_CORE)
8950 if (nhdr.n_type == NT_AUXV
8951 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
8952 || (nhdr.n_namesz == 5 && name[4] == '\0'))
8953 && !memcmp (name, "CORE", 4))
8954 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
8955 start + desc_offset);
8956 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
8957 switch (nhdr.n_type)
8960 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
8961 start + desc_offset);
8965 handle_file_note (ebl->elf, nhdr.n_descsz,
8966 start + desc_offset);
8970 handle_core_note (ebl, &nhdr, name, desc);
8973 handle_core_note (ebl, &nhdr, name, desc);
8976 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
8980 if (offset == data->d_size)
8984 error (EXIT_FAILURE, 0,
8985 gettext ("cannot get content of note section: %s"),
8990 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
8992 /* If we have section headers, just look for SHT_NOTE sections.
8993 In a debuginfo file, the program headers are not reliable. */
8996 /* Get the section header string table index. */
8998 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
8999 error (EXIT_FAILURE, 0,
9000 gettext ("cannot get section header string table index"));
9002 Elf_Scn *scn = NULL;
9003 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9006 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9008 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9009 /* Not what we are looking for. */
9013 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9015 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9016 shdr->sh_size, shdr->sh_offset);
9018 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9019 elf_getdata (scn, NULL));
9024 /* We have to look through the program header to find the note
9025 sections. There can be more than one. */
9026 for (size_t cnt = 0; cnt < phnum; ++cnt)
9029 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9031 if (phdr == NULL || phdr->p_type != PT_NOTE)
9032 /* Not what we are looking for. */
9036 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9037 phdr->p_filesz, phdr->p_offset);
9039 handle_notes_data (ebl, ehdr, phdr->p_offset,
9040 elf_getdata_rawchunk (ebl->elf,
9041 phdr->p_offset, phdr->p_filesz,
9048 hex_dump (const uint8_t *data, size_t len)
9053 printf (" 0x%08Zx ", pos);
9055 const size_t chunk = MIN (len - pos, 16);
9057 for (size_t i = 0; i < chunk; ++i)
9059 printf ("%02x ", data[pos + i]);
9061 printf ("%02x", data[pos + i]);
9064 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9066 for (size_t i = 0; i < chunk; ++i)
9068 unsigned char b = data[pos + i];
9069 printf ("%c", isprint (b) ? b : '.');
9078 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9080 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9081 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9082 elf_ndxscn (scn), name);
9085 Elf_Data *data = elf_rawdata (scn, NULL);
9087 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9088 elf_ndxscn (scn), name, elf_errmsg (-1));
9091 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9092 " bytes at offset %#0" PRIx64 ":\n"),
9093 elf_ndxscn (scn), name,
9094 shdr->sh_size, shdr->sh_offset);
9095 hex_dump (data->d_buf, data->d_size);
9101 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9103 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9104 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9105 elf_ndxscn (scn), name);
9108 Elf_Data *data = elf_rawdata (scn, NULL);
9110 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9111 elf_ndxscn (scn), name, elf_errmsg (-1));
9114 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9115 " bytes at offset %#0" PRIx64 ":\n"),
9116 elf_ndxscn (scn), name,
9117 shdr->sh_size, shdr->sh_offset);
9119 const char *start = data->d_buf;
9120 const char *const limit = start + data->d_size;
9123 const char *end = memchr (start, '\0', limit - start);
9124 const size_t pos = start - (const char *) data->d_buf;
9125 if (unlikely (end == NULL))
9127 printf (" [%6Zx]- %.*s\n",
9128 pos, (int) (limit - start), start);
9131 printf (" [%6Zx] %s\n", pos, start);
9133 } while (start < limit);
9139 for_each_section_argument (Elf *elf, const struct section_argument *list,
9140 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9143 /* Get the section header string table index. */
9145 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9146 error (EXIT_FAILURE, 0,
9147 gettext ("cannot get section header string table index"));
9149 for (const struct section_argument *a = list; a != NULL; a = a->next)
9153 const char *name = NULL;
9156 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9157 if (endp != a->arg && *endp == '\0')
9159 scn = elf_getscn (elf, shndx);
9162 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9166 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9167 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9169 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9173 /* Need to look up the section by name. */
9176 while ((scn = elf_nextscn (elf, scn)) != NULL)
9178 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9180 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9183 if (!strcmp (name, a->arg))
9186 (*dump) (scn, &shdr_mem, name);
9190 if (unlikely (!found) && !a->implicit)
9191 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9197 dump_data (Ebl *ebl)
9199 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9203 dump_strings (Ebl *ebl)
9205 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9209 print_strings (Ebl *ebl)
9211 /* Get the section header string table index. */
9213 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9214 error (EXIT_FAILURE, 0,
9215 gettext ("cannot get section header string table index"));
9221 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9223 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9226 if (shdr_mem.sh_type != SHT_PROGBITS
9227 || !(shdr_mem.sh_flags & SHF_STRINGS))
9230 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9234 print_string_section (scn, &shdr_mem, name);
9239 dump_archive_index (Elf *elf, const char *fname)
9242 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9245 int result = elf_errno ();
9246 if (unlikely (result != ELF_E_NO_INDEX))
9247 error (EXIT_FAILURE, 0,
9248 gettext ("cannot get symbol index of archive '%s': %s"),
9249 fname, elf_errmsg (result));
9251 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9255 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9259 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9261 if (s->as_off != as_off)
9266 if (unlikely (elf_rand (elf, as_off) == 0)
9267 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9269 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9272 error (EXIT_FAILURE, 0,
9273 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9274 as_off, fname, elf_errmsg (-1));
9276 const Elf_Arhdr *h = elf_getarhdr (subelf);
9278 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9283 printf ("\t%s\n", s->as_name);
9287 #include "debugpred.h"