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 (destshdr == 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 memset(vername, 0, nvername * sizeof (const char *));
2720 filename = (const char **) alloca (nvername * sizeof (const char *));
2721 memset(filename, 0, nvername * sizeof (const char *));
2723 /* Run through the data structures again and collect the strings. */
2726 /* Run through the version definitions and find the highest
2728 unsigned int offset = 0;
2730 GElf_Shdr defshdrmem;
2733 defdata = elf_getdata (defscn, NULL);
2734 if (unlikely (defdata == NULL))
2737 defshdr = gelf_getshdr (defscn, &defshdrmem);
2738 if (unlikely (defshdr == NULL))
2741 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2744 /* Get the data at the next offset. */
2746 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2747 GElf_Verdaux auxmem;
2748 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2749 offset + def->vd_aux,
2751 if (unlikely (def == NULL || aux == NULL))
2754 vername[def->vd_ndx & 0x7fff]
2755 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2756 filename[def->vd_ndx & 0x7fff] = NULL;
2758 offset += def->vd_next;
2761 if (needscn != NULL)
2763 unsigned int offset = 0;
2765 Elf_Data *needdata = elf_getdata (needscn, NULL);
2766 GElf_Shdr needshdrmem;
2767 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2768 if (unlikely (needdata == NULL || needshdr == NULL))
2771 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2773 /* Get the data at the next offset. */
2774 GElf_Verneed needmem;
2775 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2777 if (unlikely (need == NULL))
2780 /* Run through the auxiliary entries. */
2781 unsigned int auxoffset = offset + need->vn_aux;
2782 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2784 GElf_Vernaux auxmem;
2785 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2787 if (unlikely (aux == NULL))
2790 vername[aux->vna_other & 0x7fff]
2791 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2792 filename[aux->vna_other & 0x7fff]
2793 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2795 auxoffset += aux->vna_next;
2798 offset += need->vn_next;
2809 GElf_Shdr glink_mem;
2810 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2812 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2814 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2817 /* Print the header. */
2818 printf (ngettext ("\
2819 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2821 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2822 shdr->sh_size / sh_entsize),
2823 (unsigned int) elf_ndxscn (scn),
2824 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2825 (int) (shdr->sh_size / sh_entsize),
2826 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2828 (unsigned int) shdr->sh_link,
2829 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2831 /* Now we can finally look at the actual contents of this section. */
2832 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2835 printf ("\n %4d:", cnt);
2838 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2846 fputs_unlocked (gettext (" 0 *local* "),
2851 fputs_unlocked (gettext (" 1 *global* "),
2856 n = printf ("%4d%c%s",
2857 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2858 (unsigned int) (*sym & 0x7fff) < nvername
2859 ? vername[*sym & 0x7fff] : "???");
2860 if ((unsigned int) (*sym & 0x7fff) < nvername
2861 && filename[*sym & 0x7fff] != NULL)
2862 n += printf ("(%s)", filename[*sym & 0x7fff]);
2863 printf ("%*s", MAX (0, 33 - (int) n), " ");
2867 putchar_unlocked ('\n');
2872 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2873 uint_fast32_t maxlength, Elf32_Word nbucket,
2874 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2876 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2878 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2879 ++counts[lengths[cnt]];
2881 GElf_Shdr glink_mem;
2882 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2887 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2892 printf (ngettext ("\
2893 \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",
2895 \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",
2897 (unsigned int) elf_ndxscn (scn),
2898 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2900 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2903 (unsigned int) shdr->sh_link,
2904 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2906 if (extrastr != NULL)
2907 fputs (extrastr, stdout);
2909 if (likely (nbucket > 0))
2911 uint64_t success = 0;
2913 /* xgettext:no-c-format */
2914 fputs_unlocked (gettext ("\
2915 Length Number % of total Coverage\n"), stdout);
2916 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2917 counts[0], (counts[0] * 100.0) / nbucket);
2919 uint64_t nzero_counts = 0;
2920 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2922 nzero_counts += counts[cnt] * cnt;
2924 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2925 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2926 (nzero_counts * 100.0) / nsyms);
2930 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2933 success += counts[cnt] * acc;
2937 Average number of tests: successful lookup: %f\n\
2938 unsuccessful lookup: %f\n"),
2939 (double) success / (double) nzero_counts,
2940 (double) nzero_counts / (double) nbucket);
2947 /* This function handles the traditional System V-style hash table format. */
2949 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2951 Elf_Data *data = elf_getdata (scn, NULL);
2952 if (unlikely (data == NULL))
2954 error (0, 0, gettext ("cannot get data for section %d: %s"),
2955 (int) elf_ndxscn (scn), elf_errmsg (-1));
2959 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
2962 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
2963 (int) elf_ndxscn (scn));
2967 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2968 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2970 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
2971 if (used_buf > data->d_size)
2974 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2975 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2977 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2979 uint_fast32_t maxlength = 0;
2980 uint_fast32_t nsyms = 0;
2981 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2983 Elf32_Word inner = bucket[cnt];
2984 while (inner > 0 && inner < nchain)
2987 if (maxlength < ++lengths[cnt])
2990 inner = chain[inner];
2994 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3001 /* This function handles the incorrect, System V-style hash table
3002 format some 64-bit architectures use. */
3004 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3006 Elf_Data *data = elf_getdata (scn, NULL);
3007 if (unlikely (data == NULL))
3009 error (0, 0, gettext ("cannot get data for section %d: %s"),
3010 (int) elf_ndxscn (scn), elf_errmsg (-1));
3014 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3017 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3018 (int) elf_ndxscn (scn));
3022 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3023 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3025 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf64_Xword);
3026 if (used_buf > data->d_size)
3029 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3030 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3032 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3034 uint_fast32_t maxlength = 0;
3035 uint_fast32_t nsyms = 0;
3036 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3038 Elf64_Xword inner = bucket[cnt];
3039 while (inner > 0 && inner < nchain)
3042 if (maxlength < ++lengths[cnt])
3045 inner = chain[inner];
3049 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3056 /* This function handles the GNU-style hash table format. */
3058 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3060 Elf_Data *data = elf_getdata (scn, NULL);
3061 if (unlikely (data == NULL))
3063 error (0, 0, gettext ("cannot get data for section %d: %s"),
3064 (int) elf_ndxscn (scn), elf_errmsg (-1));
3068 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3071 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3072 (int) elf_ndxscn (scn));
3076 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3077 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3079 /* Next comes the size of the bitmap. It's measured in words for
3080 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3081 64 bit archs. There is always a bloom filter present, so zero is
3082 an invalid value. */
3083 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3084 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3087 if (bitmask_words == 0)
3090 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3092 /* Is there still room for the sym chain?
3093 Use uint64_t calculation to prevent 32bit overlow. */
3094 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3095 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3096 if (used_buf > data->d_size)
3099 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3101 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3102 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3103 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3106 /* Compute distribution of chain lengths. */
3107 uint_fast32_t maxlength = 0;
3108 uint_fast32_t nsyms = 0;
3109 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3110 if (bucket[cnt] != 0)
3112 Elf32_Word inner = bucket[cnt] - symbias;
3116 if (maxlength < ++lengths[cnt])
3118 if (inner > max_nsyms)
3121 while ((chain[inner++] & 1) == 0);
3124 /* Count bits in bitmask. */
3125 uint_fast32_t nbits = 0;
3126 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3128 uint_fast32_t word = bitmask[cnt];
3130 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3131 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3132 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3133 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3134 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3138 if (unlikely (asprintf (&str, gettext ("\
3140 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3141 (unsigned int) symbias,
3142 bitmask_words * sizeof (Elf32_Word),
3144 / (uint_fast32_t) (bitmask_words
3145 * sizeof (Elf32_Word) * 8)),
3146 (unsigned int) shift) == -1))
3147 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3149 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3157 /* Find the symbol table(s). For this we have to search through the
3160 handle_hash (Ebl *ebl)
3162 /* Get the section header string table index. */
3164 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3165 error (EXIT_FAILURE, 0,
3166 gettext ("cannot get section header string table index"));
3168 Elf_Scn *scn = NULL;
3169 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3171 /* Handle the section if it is a symbol table. */
3173 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3175 if (likely (shdr != NULL))
3177 if (shdr->sh_type == SHT_HASH)
3179 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3180 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3182 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3184 else if (shdr->sh_type == SHT_GNU_HASH)
3185 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3192 print_liblist (Ebl *ebl)
3194 /* Find the library list sections. For this we have to search
3195 through the section table. */
3196 Elf_Scn *scn = NULL;
3198 /* Get the section header string table index. */
3200 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3201 error (EXIT_FAILURE, 0,
3202 gettext ("cannot get section header string table index"));
3204 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3207 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3209 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3211 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3212 int nentries = shdr->sh_size / sh_entsize;
3213 printf (ngettext ("\
3214 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3216 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3219 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3223 Elf_Data *data = elf_getdata (scn, NULL);
3228 Library Time Stamp Checksum Version Flags"));
3230 for (int cnt = 0; cnt < nentries; ++cnt)
3233 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3234 if (unlikely (lib == NULL))
3237 time_t t = (time_t) lib->l_time_stamp;
3238 struct tm *tm = gmtime (&t);
3239 if (unlikely (tm == NULL))
3242 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3243 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3244 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3245 tm->tm_hour, tm->tm_min, tm->tm_sec,
3246 (unsigned int) lib->l_checksum,
3247 (unsigned int) lib->l_version,
3248 (unsigned int) lib->l_flags);
3255 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3257 /* Find the object attributes sections. For this we have to search
3258 through the section table. */
3259 Elf_Scn *scn = NULL;
3261 /* Get the section header string table index. */
3263 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3264 error (EXIT_FAILURE, 0,
3265 gettext ("cannot get section header string table index"));
3267 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3270 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3272 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3273 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3274 || ehdr->e_machine != EM_ARM)))
3278 \nObject attributes section [%2zu] '%s' of %" PRIu64
3279 " bytes at offset %#0" PRIx64 ":\n"),
3281 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3282 shdr->sh_size, shdr->sh_offset);
3284 Elf_Data *data = elf_rawdata (scn, NULL);
3288 const unsigned char *p = data->d_buf;
3290 if (unlikely (*p++ != 'A'))
3293 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3295 inline size_t left (void)
3297 return (const unsigned char *) data->d_buf + data->d_size - p;
3300 while (left () >= 4)
3303 memcpy (&len, p, sizeof len);
3305 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3308 if (unlikely (len > left ()))
3311 const unsigned char *name = p + sizeof len;
3314 unsigned const char *q = memchr (name, '\0', len);
3315 if (unlikely (q == NULL))
3319 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3321 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3322 || (q - name == sizeof "gnu"
3323 && !memcmp (name, "gnu", sizeof "gnu")))
3326 const unsigned char *const sub = q;
3328 unsigned int subsection_tag;
3329 get_uleb128 (subsection_tag, q);
3330 if (unlikely (q >= p))
3333 uint32_t subsection_len;
3334 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3337 memcpy (&subsection_len, q, sizeof subsection_len);
3339 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3340 CONVERT (subsection_len);
3342 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3345 const unsigned char *r = q + sizeof subsection_len;
3346 q = sub + subsection_len;
3348 switch (subsection_tag)
3351 printf (gettext (" %-4u %12" PRIu32 "\n"),
3352 subsection_tag, subsection_len);
3355 case 1: /* Tag_File */
3356 printf (gettext (" File: %11" PRIu32 "\n"),
3362 get_uleb128 (tag, r);
3363 if (unlikely (r >= q))
3367 const char *string = NULL;
3368 if (tag == 32 || (tag & 1) == 0)
3370 get_uleb128 (value, r);
3374 if (tag == 32 || (tag & 1) != 0)
3376 r = memchr (r, '\0', q - r);
3382 const char *tag_name = NULL;
3383 const char *value_name = NULL;
3384 ebl_check_object_attribute (ebl, (const char *) name,
3386 &tag_name, &value_name);
3388 if (tag_name != NULL)
3391 printf (gettext (" %s: %" PRId64 ", %s\n"),
3392 tag_name, value, string);
3393 else if (string == NULL && value_name == NULL)
3394 printf (gettext (" %s: %" PRId64 "\n"),
3397 printf (gettext (" %s: %s\n"),
3398 tag_name, string ?: value_name);
3404 printf (gettext (" %u: %" PRId64 "\n"),
3407 printf (gettext (" %u: %s\n"),
3419 format_dwarf_addr (Dwfl_Module *dwflmod,
3420 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3422 /* See if there is a name we can give for this address. */
3425 const char *name = (print_address_names && ! print_unresolved_addresses)
3426 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3430 if (print_unresolved_addresses)
3437 /* Relativize the address. */
3438 int n = dwfl_module_relocations (dwflmod);
3439 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3441 /* In an ET_REL file there is a section name to refer to. */
3443 : dwfl_module_relocation_info (dwflmod, i, NULL));
3450 ? (address_size == 0
3451 ? asprintf (&result,
3452 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3453 scn, address, name, off)
3454 : asprintf (&result,
3455 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3456 scn, 2 + address_size * 2, address,
3458 : (address_size == 0
3459 ? asprintf (&result,
3460 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3462 : asprintf (&result,
3463 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3464 2 + address_size * 2, address,
3467 ? (address_size == 0
3468 ? asprintf (&result,
3469 gettext ("%s+%#" PRIx64 " <%s>"),
3471 : asprintf (&result,
3472 gettext ("%s+%#0*" PRIx64 " <%s>"),
3473 scn, 2 + address_size * 2, address, name))
3474 : (address_size == 0
3475 ? asprintf (&result,
3476 gettext ("%#" PRIx64 " <%s>"),
3478 : asprintf (&result,
3479 gettext ("%#0*" PRIx64 " <%s>"),
3480 2 + address_size * 2, address, name))))
3482 ? (address_size == 0
3483 ? asprintf (&result,
3484 gettext ("%s+%#" PRIx64),
3486 : asprintf (&result,
3487 gettext ("%s+%#0*" PRIx64),
3488 scn, 2 + address_size * 2, address))
3489 : (address_size == 0
3490 ? asprintf (&result,
3493 : asprintf (&result,
3495 2 + address_size * 2, address)))) < 0)
3496 error (EXIT_FAILURE, 0, _("memory exhausted"));
3502 dwarf_tag_string (unsigned int tag)
3506 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3508 #undef ONE_KNOWN_DW_TAG
3516 dwarf_attr_string (unsigned int attrnum)
3520 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3522 #undef ONE_KNOWN_DW_AT
3530 dwarf_form_string (unsigned int form)
3534 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3535 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3537 #undef ONE_KNOWN_DW_FORM
3538 #undef ONE_KNOWN_DW_FORM_DESC
3546 dwarf_lang_string (unsigned int lang)
3550 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3552 #undef ONE_KNOWN_DW_LANG_DESC
3560 dwarf_inline_string (unsigned int code)
3562 static const char *const known[] =
3564 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3566 #undef ONE_KNOWN_DW_INL
3569 if (likely (code < sizeof (known) / sizeof (known[0])))
3577 dwarf_encoding_string (unsigned int code)
3579 static const char *const known[] =
3581 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3583 #undef ONE_KNOWN_DW_ATE
3586 if (likely (code < sizeof (known) / sizeof (known[0])))
3594 dwarf_access_string (unsigned int code)
3596 static const char *const known[] =
3598 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3600 #undef ONE_KNOWN_DW_ACCESS
3603 if (likely (code < sizeof (known) / sizeof (known[0])))
3611 dwarf_visibility_string (unsigned int code)
3613 static const char *const known[] =
3615 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3617 #undef ONE_KNOWN_DW_VIS
3620 if (likely (code < sizeof (known) / sizeof (known[0])))
3628 dwarf_virtuality_string (unsigned int code)
3630 static const char *const known[] =
3632 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3633 ALL_KNOWN_DW_VIRTUALITY
3634 #undef ONE_KNOWN_DW_VIRTUALITY
3637 if (likely (code < sizeof (known) / sizeof (known[0])))
3645 dwarf_identifier_case_string (unsigned int code)
3647 static const char *const known[] =
3649 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3651 #undef ONE_KNOWN_DW_ID
3654 if (likely (code < sizeof (known) / sizeof (known[0])))
3662 dwarf_calling_convention_string (unsigned int code)
3664 static const char *const known[] =
3666 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3668 #undef ONE_KNOWN_DW_CC
3671 if (likely (code < sizeof (known) / sizeof (known[0])))
3679 dwarf_ordering_string (unsigned int code)
3681 static const char *const known[] =
3683 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3685 #undef ONE_KNOWN_DW_ORD
3688 if (likely (code < sizeof (known) / sizeof (known[0])))
3696 dwarf_discr_list_string (unsigned int code)
3698 static const char *const known[] =
3700 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3702 #undef ONE_KNOWN_DW_DSC
3705 if (likely (code < sizeof (known) / sizeof (known[0])))
3713 dwarf_locexpr_opcode_string (unsigned int code)
3715 static const char *const known[] =
3717 /* Normally we can't affort building huge table of 64K entries,
3718 most of them zero, just because there are a couple defined
3719 values at the far end. In case of opcodes, it's OK. */
3720 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3721 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3723 #undef ONE_KNOWN_DW_OP
3724 #undef ONE_KNOWN_DW_OP_DESC
3727 if (likely (code < sizeof (known) / sizeof (known[0])))
3734 /* Used by all dwarf_foo_name functions. */
3736 string_or_unknown (const char *known, unsigned int code,
3737 unsigned int lo_user, unsigned int hi_user,
3738 bool print_unknown_num)
3740 static char unknown_buf[20];
3742 if (likely (known != NULL))
3745 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3747 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3752 if (print_unknown_num)
3754 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3763 dwarf_tag_name (unsigned int tag)
3765 const char *ret = dwarf_tag_string (tag);
3766 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3770 dwarf_attr_name (unsigned int attr)
3772 const char *ret = dwarf_attr_string (attr);
3773 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3778 dwarf_form_name (unsigned int form)
3780 const char *ret = dwarf_form_string (form);
3781 return string_or_unknown (ret, form, 0, 0, true);
3786 dwarf_lang_name (unsigned int lang)
3788 const char *ret = dwarf_lang_string (lang);
3789 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3794 dwarf_inline_name (unsigned int code)
3796 const char *ret = dwarf_inline_string (code);
3797 return string_or_unknown (ret, code, 0, 0, false);
3802 dwarf_encoding_name (unsigned int code)
3804 const char *ret = dwarf_encoding_string (code);
3805 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3810 dwarf_access_name (unsigned int code)
3812 const char *ret = dwarf_access_string (code);
3813 return string_or_unknown (ret, code, 0, 0, false);
3818 dwarf_visibility_name (unsigned int code)
3820 const char *ret = dwarf_visibility_string (code);
3821 return string_or_unknown (ret, code, 0, 0, false);
3826 dwarf_virtuality_name (unsigned int code)
3828 const char *ret = dwarf_virtuality_string (code);
3829 return string_or_unknown (ret, code, 0, 0, false);
3834 dwarf_identifier_case_name (unsigned int code)
3836 const char *ret = dwarf_identifier_case_string (code);
3837 return string_or_unknown (ret, code, 0, 0, false);
3842 dwarf_calling_convention_name (unsigned int code)
3844 const char *ret = dwarf_calling_convention_string (code);
3845 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3850 dwarf_ordering_name (unsigned int code)
3852 const char *ret = dwarf_ordering_string (code);
3853 return string_or_unknown (ret, code, 0, 0, false);
3858 dwarf_discr_list_name (unsigned int code)
3860 const char *ret = dwarf_discr_list_string (code);
3861 return string_or_unknown (ret, code, 0, 0, false);
3866 print_block (size_t n, const void *block)
3869 puts (_("empty block"));
3872 printf (_("%zu byte block:"), n);
3873 const unsigned char *data = block;
3875 printf (" %02x", *data++);
3882 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3883 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3884 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3886 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3890 printf ("%*s(empty)\n", indent, "");
3894 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3895 #define CONSUME(n) NEED (n); else len -= (n)
3897 Dwarf_Word offset = 0;
3900 uint_fast8_t op = *data++;
3902 const char *op_name = dwarf_locexpr_opcode_string (op);
3903 if (unlikely (op_name == NULL))
3905 static char buf[20];
3906 if (op >= DW_OP_lo_user)
3907 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3909 snprintf (buf, sizeof buf, "??? (%#x)", op);
3916 /* Address operand. */
3920 addr = read_4ubyte_unaligned (dbg, data);
3923 assert (addrsize == 8);
3924 addr = read_8ubyte_unaligned (dbg, data);
3929 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3930 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3931 indent, "", (uintmax_t) offset, op_name, a);
3934 offset += 1 + addrsize;
3937 case DW_OP_call_ref:
3938 /* Offset operand. */
3941 addr = read_4ubyte_unaligned (dbg, data);
3944 assert (ref_size == 8);
3945 addr = read_8ubyte_unaligned (dbg, data);
3950 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
3951 indent, "", (uintmax_t) offset,
3952 op_name, (uintmax_t) addr);
3953 offset += 1 + ref_size;
3956 case DW_OP_deref_size:
3957 case DW_OP_xderef_size:
3960 // XXX value might be modified by relocation
3962 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
3963 indent, "", (uintmax_t) offset,
3964 op_name, *((uint8_t *) data));
3972 // XXX value might be modified by relocation
3973 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3974 indent, "", (uintmax_t) offset,
3975 op_name, read_2ubyte_unaligned (dbg, data));
3983 // XXX value might be modified by relocation
3984 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3985 indent, "", (uintmax_t) offset,
3986 op_name, read_4ubyte_unaligned (dbg, data));
3994 // XXX value might be modified by relocation
3995 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3996 indent, "", (uintmax_t) offset,
3997 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4005 // XXX value might be modified by relocation
4006 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4007 indent, "", (uintmax_t) offset,
4008 op_name, *((int8_t *) data));
4016 // XXX value might be modified by relocation
4017 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4018 indent, "", (uintmax_t) offset,
4019 op_name, read_2sbyte_unaligned (dbg, data));
4027 // XXX value might be modified by relocation
4028 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4029 indent, "", (uintmax_t) offset,
4030 op_name, read_4sbyte_unaligned (dbg, data));
4038 // XXX value might be modified by relocation
4039 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4040 indent, "", (uintmax_t) offset,
4041 op_name, read_8sbyte_unaligned (dbg, data));
4049 case DW_OP_plus_uconst:
4051 const unsigned char *start = data;
4054 get_uleb128 (uleb, data); /* XXX check overrun */
4055 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4056 indent, "", (uintmax_t) offset, op_name, uleb);
4057 CONSUME (data - start);
4058 offset += 1 + (data - start);
4061 case DW_OP_bit_piece:
4065 get_uleb128 (uleb, data); /* XXX check overrun */
4066 get_uleb128 (uleb2, data); /* XXX check overrun */
4067 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4068 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4069 CONSUME (data - start);
4070 offset += 1 + (data - start);
4074 case DW_OP_breg0 ... DW_OP_breg31:
4079 get_sleb128 (sleb, data); /* XXX check overrun */
4080 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4081 indent, "", (uintmax_t) offset, op_name, sleb);
4082 CONSUME (data - start);
4083 offset += 1 + (data - start);
4089 get_uleb128 (uleb, data); /* XXX check overrun */
4090 get_sleb128 (sleb, data); /* XXX check overrun */
4091 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4092 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4093 CONSUME (data - start);
4094 offset += 1 + (data - start);
4099 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4100 indent, "", (uintmax_t) offset, op_name,
4101 read_2ubyte_unaligned (dbg, data));
4108 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4109 indent, "", (uintmax_t) offset, op_name,
4110 read_4ubyte_unaligned (dbg, data));
4118 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4119 indent, "", (uintmax_t) offset, op_name,
4120 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4126 case DW_OP_implicit_value:
4129 get_uleb128 (uleb, data); /* XXX check overrun */
4130 printf ("%*s[%4" PRIuMAX "] %s: ",
4131 indent, "", (uintmax_t) offset, op_name);
4133 print_block (uleb, data);
4135 CONSUME (data - start);
4136 offset += 1 + (data - start);
4139 case DW_OP_GNU_implicit_pointer:
4140 /* DIE offset operand. */
4142 NEED (ref_size + 1);
4144 addr = read_4ubyte_unaligned (dbg, data);
4147 assert (ref_size == 8);
4148 addr = read_8ubyte_unaligned (dbg, data);
4151 /* Byte offset operand. */
4152 get_sleb128 (sleb, data); /* XXX check overrun */
4154 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4155 indent, "", (intmax_t) offset,
4156 op_name, (uintmax_t) addr, sleb);
4157 CONSUME (data - start);
4158 offset += 1 + (data - start);
4161 case DW_OP_GNU_entry_value:
4162 /* Size plus expression block. */
4165 get_uleb128 (uleb, data); /* XXX check overrun */
4166 printf ("%*s[%4" PRIuMAX "] %s:\n",
4167 indent, "", (uintmax_t) offset, op_name);
4169 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4170 addrsize, offset_size, cu, uleb, data);
4172 CONSUME (data - start);
4173 offset += 1 + (data - start);
4176 case DW_OP_GNU_const_type:
4177 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4178 unsigned size plus block. */
4181 get_uleb128 (uleb, data); /* XXX check overrun */
4182 if (! print_unresolved_addresses && cu != NULL)
4184 uint8_t usize = *(uint8_t *) data++;
4186 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4187 indent, "", (uintmax_t) offset, op_name, uleb);
4188 print_block (usize, data);
4190 CONSUME (data - start);
4191 offset += 1 + (data - start);
4194 case DW_OP_GNU_regval_type:
4195 /* uleb128 register number, uleb128 CU relative
4196 DW_TAG_base_type DIE offset. */
4199 get_uleb128 (uleb, data); /* XXX check overrun */
4200 get_uleb128 (uleb2, data); /* XXX check overrun */
4201 if (! print_unresolved_addresses && cu != NULL)
4203 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4204 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4205 CONSUME (data - start);
4206 offset += 1 + (data - start);
4209 case DW_OP_GNU_deref_type:
4210 /* 1-byte unsigned size of value, uleb128 CU relative
4211 DW_TAG_base_type DIE offset. */
4214 usize = *(uint8_t *) data++;
4215 get_uleb128 (uleb, data); /* XXX check overrun */
4216 if (! print_unresolved_addresses && cu != NULL)
4218 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4219 indent, "", (uintmax_t) offset,
4220 op_name, usize, uleb);
4221 CONSUME (data - start);
4222 offset += 1 + (data - start);
4225 case DW_OP_GNU_convert:
4226 case DW_OP_GNU_reinterpret:
4227 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4228 for conversion to untyped. */
4231 get_uleb128 (uleb, data); /* XXX check overrun */
4232 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4234 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4235 indent, "", (uintmax_t) offset, op_name, uleb);
4236 CONSUME (data - start);
4237 offset += 1 + (data - start);
4240 case DW_OP_GNU_parameter_ref:
4241 /* 4 byte CU relative reference to the abstract optimized away
4242 DW_TAG_formal_parameter. */
4244 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4245 if (! print_unresolved_addresses && cu != NULL)
4246 param_off += cu->start;
4247 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4248 indent, "", (uintmax_t) offset, op_name, param_off);
4256 printf ("%*s[%4" PRIuMAX "] %s\n",
4257 indent, "", (uintmax_t) offset, op_name);
4262 indent = indentrest;
4266 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4267 indent, "", (uintmax_t) offset, op_name);
4275 Dwarf_Off offset:(64 - 3);
4279 struct Dwarf_CU *cu;
4282 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4283 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4286 listptr_base (struct listptr *p)
4289 Dwarf_Die cu = CUDIE (p->cu);
4290 /* Find the base address of the compilation unit. It will normally
4291 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4292 address could be overridden by DW_AT_entry_pc. It's been
4293 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4294 compilation units with discontinuous ranges. */
4295 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4297 Dwarf_Attribute attr_mem;
4298 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4306 compare_listptr (const void *a, const void *b, void *arg)
4308 const char *name = arg;
4309 struct listptr *p1 = (void *) a;
4310 struct listptr *p2 = (void *) b;
4312 if (p1->offset < p2->offset)
4314 if (p1->offset > p2->offset)
4317 if (!p1->warned && !p2->warned)
4319 if (p1->addr64 != p2->addr64)
4321 p1->warned = p2->warned = true;
4323 gettext ("%s %#" PRIx64 " used with different address sizes"),
4324 name, (uint64_t) p1->offset);
4326 if (p1->dwarf64 != p2->dwarf64)
4328 p1->warned = p2->warned = true;
4330 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4331 name, (uint64_t) p1->offset);
4333 if (listptr_base (p1) != listptr_base (p2))
4335 p1->warned = p2->warned = true;
4337 gettext ("%s %#" PRIx64 " used with different base addresses"),
4338 name, (uint64_t) p1->offset);
4345 struct listptr_table
4349 struct listptr *table;
4352 static struct listptr_table known_loclistptr;
4353 static struct listptr_table known_rangelistptr;
4356 reset_listptr (struct listptr_table *table)
4358 free (table->table);
4359 table->table = NULL;
4360 table->n = table->alloc = 0;
4364 notice_listptr (enum section_e section, struct listptr_table *table,
4365 uint_fast8_t address_size, uint_fast8_t offset_size,
4366 struct Dwarf_CU *cu, Dwarf_Off offset)
4368 if (print_debug_sections & section)
4370 if (table->n == table->alloc)
4372 if (table->alloc == 0)
4376 table->table = xrealloc (table->table,
4377 table->alloc * sizeof table->table[0]);
4380 struct listptr *p = &table->table[table->n++];
4382 *p = (struct listptr)
4384 .addr64 = address_size == 8,
4385 .dwarf64 = offset_size == 8,
4389 assert (p->offset == offset);
4394 sort_listptr (struct listptr_table *table, const char *name)
4397 qsort_r (table->table, table->n, sizeof table->table[0],
4398 &compare_listptr, (void *) name);
4402 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4403 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4404 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4405 unsigned char **readp, unsigned char *endp)
4410 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4413 struct listptr *p = &table->table[*idxp];
4415 if (*idxp == table->n
4416 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4419 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4424 if (p->offset != (Dwarf_Off) offset)
4426 *readp += p->offset - offset;
4427 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4428 offset, (Dwarf_Off) p->offset - offset);
4432 if (address_sizep != NULL)
4433 *address_sizep = listptr_address_size (p);
4434 if (offset_sizep != NULL)
4435 *offset_sizep = listptr_offset_size (p);
4437 *base = listptr_base (p);
4446 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4447 Ebl *ebl, GElf_Ehdr *ehdr,
4448 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4450 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4451 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4453 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4455 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4456 (uint64_t) shdr->sh_offset);
4458 Dwarf_Off offset = 0;
4459 while (offset < sh_size)
4461 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4467 Dwarf_Abbrev abbrev;
4469 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4472 if (unlikely (res < 0))
4475 *** error while reading abbreviation: %s\n"),
4480 /* This is the NUL byte at the end of the section. */
4485 /* We know these calls can never fail. */
4486 unsigned int code = dwarf_getabbrevcode (&abbrev);
4487 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4488 int has_children = dwarf_abbrevhaschildren (&abbrev);
4490 printf (gettext (" [%5u] offset: %" PRId64
4491 ", children: %s, tag: %s\n"),
4492 code, (int64_t) offset,
4493 has_children ? gettext ("yes") : gettext ("no"),
4494 dwarf_tag_name (tag));
4500 while (dwarf_getabbrevattr (&abbrev, cnt,
4501 &name, &form, &enoffset) == 0)
4503 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4504 dwarf_attr_name (name), dwarf_form_name (form),
4505 (uint64_t) enoffset);
4516 /* Print content of DWARF .debug_aranges section. We fortunately do
4517 not have to know a bit about the structure of the section, libdwarf
4518 takes care of it. */
4520 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4521 GElf_Shdr *shdr, Dwarf *dbg)
4523 Dwarf_Aranges *aranges;
4525 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4527 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4532 GElf_Shdr glink_mem;
4534 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4537 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4542 printf (ngettext ("\
4543 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4545 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4547 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4548 (uint64_t) shdr->sh_offset, cnt);
4550 /* Compute floor(log16(cnt)). */
4559 for (size_t n = 0; n < cnt; ++n)
4561 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4562 if (unlikely (runp == NULL))
4564 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4572 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4573 printf (gettext (" [%*zu] ???\n"), digits, n);
4575 printf (gettext (" [%*zu] start: %0#*" PRIx64
4576 ", length: %5" PRIu64 ", CU DIE offset: %6"
4578 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4579 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4584 /* Print content of DWARF .debug_aranges section. */
4586 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4587 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4588 GElf_Shdr *shdr, Dwarf *dbg)
4592 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4596 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4598 if (unlikely (data == NULL))
4600 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4606 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4607 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4608 (uint64_t) shdr->sh_offset);
4610 const unsigned char *readp = data->d_buf;
4611 const unsigned char *readendp = readp + data->d_size;
4613 while (readp < readendp)
4615 const unsigned char *hdrstart = readp;
4616 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4618 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4619 if (readp + 4 > readendp)
4622 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4623 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4627 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4628 unsigned int length_bytes = 4;
4629 if (length == DWARF3_LENGTH_64_BIT)
4631 if (readp + 8 > readendp)
4633 length = read_8ubyte_unaligned_inc (dbg, readp);
4637 const unsigned char *nexthdr = readp + length;
4638 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4641 if (nexthdr > readendp)
4647 if (readp + 2 > readendp)
4649 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4650 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4654 error (0, 0, gettext ("unsupported aranges version"));
4659 if (readp + length_bytes > readendp)
4661 if (length_bytes == 8)
4662 offset = read_8ubyte_unaligned_inc (dbg, readp);
4664 offset = read_4ubyte_unaligned_inc (dbg, readp);
4665 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4668 if (readp + 1 > readendp)
4670 unsigned int address_size = *readp++;
4671 printf (gettext (" Address size: %6" PRIu64 "\n"),
4672 (uint64_t) address_size);
4673 if (address_size != 4 && address_size != 8)
4675 error (0, 0, gettext ("unsupported address size"));
4679 unsigned int segment_size = *readp++;
4680 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4681 (uint64_t) segment_size);
4682 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4684 error (0, 0, gettext ("unsupported segment size"));
4688 /* Round the address to the next multiple of 2*address_size. */
4689 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4690 % (2 * address_size));
4692 while (readp < nexthdr)
4694 Dwarf_Word range_address;
4695 Dwarf_Word range_length;
4696 Dwarf_Word segment = 0;
4697 if (readp + 2 * address_size + segment_size > readendp)
4699 if (address_size == 4)
4701 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4702 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4706 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4707 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4710 if (segment_size == 4)
4711 segment = read_4ubyte_unaligned_inc (dbg, readp);
4712 else if (segment_size == 8)
4713 segment = read_8ubyte_unaligned_inc (dbg, readp);
4715 if (range_address == 0 && range_length == 0 && segment == 0)
4718 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4720 char *e = format_dwarf_addr (dwflmod, address_size,
4721 range_address + range_length - 1,
4723 if (segment_size != 0)
4724 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4725 (uint64_t) segment);
4727 printf (gettext (" %s..%s\n"), b, e);
4733 if (readp != nexthdr)
4735 size_t padding = nexthdr - readp;
4736 printf (gettext (" %Zu padding bytes\n"), padding);
4743 /* Print content of DWARF .debug_ranges section. */
4745 print_debug_ranges_section (Dwfl_Module *dwflmod,
4746 Ebl *ebl, GElf_Ehdr *ehdr,
4747 Elf_Scn *scn, GElf_Shdr *shdr,
4750 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4752 if (unlikely (data == NULL))
4754 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4760 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4761 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4762 (uint64_t) shdr->sh_offset);
4764 sort_listptr (&known_rangelistptr, "rangelistptr");
4765 size_t listptr_idx = 0;
4767 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4770 Dwarf_Addr base = 0;
4771 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4772 unsigned char *readp = data->d_buf;
4773 while (readp < endp)
4775 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4777 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4778 &address_size, NULL, &base, NULL,
4779 offset, &readp, endp))
4782 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4784 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4790 if (address_size == 8)
4792 begin = read_8ubyte_unaligned_inc (dbg, readp);
4793 end = read_8ubyte_unaligned_inc (dbg, readp);
4797 begin = read_4ubyte_unaligned_inc (dbg, readp);
4798 end = read_4ubyte_unaligned_inc (dbg, readp);
4799 if (begin == (Dwarf_Addr) (uint32_t) -1)
4800 begin = (Dwarf_Addr) -1l;
4803 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4805 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4806 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4810 else if (begin == 0 && end == 0) /* End of list entry. */
4813 printf (gettext (" [%6tx] empty list\n"), offset);
4818 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4820 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4822 /* We have an address range entry. */
4823 if (first) /* First address range entry in a list. */
4824 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4826 printf (gettext (" %s..%s\n"), b, e);
4835 #define REGNAMESZ 16
4837 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4838 char name[REGNAMESZ], int *bits, int *type)
4843 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4844 bits ?: &ignore, type ?: &ignore);
4848 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4850 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4852 *bits = loc != NULL ? loc->bits : 0;
4854 *type = DW_ATE_unsigned;
4855 set = "??? unrecognized";
4859 if (bits != NULL && *bits <= 0)
4860 *bits = loc != NULL ? loc->bits : 0;
4861 if (type != NULL && *type == DW_ATE_void)
4862 *type = DW_ATE_unsigned;
4869 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4870 Dwarf_Word vma_base, unsigned int code_align,
4872 unsigned int version, unsigned int ptr_size,
4873 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4875 char regnamebuf[REGNAMESZ];
4876 const char *regname (unsigned int regno)
4878 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4882 puts ("\n Program:");
4883 Dwarf_Word pc = vma_base;
4884 while (readp < endp)
4886 unsigned int opcode = *readp++;
4888 if (opcode < DW_CFA_advance_loc)
4889 /* Extended opcode. */
4900 case DW_CFA_set_loc:
4901 // XXX overflow check
4902 get_uleb128 (op1, readp);
4904 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4906 case DW_CFA_advance_loc1:
4907 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4908 *readp, pc += *readp * code_align);
4911 case DW_CFA_advance_loc2:
4912 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4913 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4914 op1, pc += op1 * code_align);
4916 case DW_CFA_advance_loc4:
4917 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4918 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4919 op1, pc += op1 * code_align);
4921 case DW_CFA_offset_extended:
4922 // XXX overflow check
4923 get_uleb128 (op1, readp);
4924 get_uleb128 (op2, readp);
4925 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4927 op1, regname (op1), op2 * data_align);
4929 case DW_CFA_restore_extended:
4930 // XXX overflow check
4931 get_uleb128 (op1, readp);
4932 printf (" restore_extended r%" PRIu64 " (%s)\n",
4933 op1, regname (op1));
4935 case DW_CFA_undefined:
4936 // XXX overflow check
4937 get_uleb128 (op1, readp);
4938 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4940 case DW_CFA_same_value:
4941 // XXX overflow check
4942 get_uleb128 (op1, readp);
4943 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4945 case DW_CFA_register:
4946 // XXX overflow check
4947 get_uleb128 (op1, readp);
4948 get_uleb128 (op2, readp);
4949 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4950 op1, regname (op1), op2, regname (op2));
4952 case DW_CFA_remember_state:
4953 puts (" remember_state");
4955 case DW_CFA_restore_state:
4956 puts (" restore_state");
4958 case DW_CFA_def_cfa:
4959 // XXX overflow check
4960 get_uleb128 (op1, readp);
4961 get_uleb128 (op2, readp);
4962 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4963 op1, regname (op1), op2);
4965 case DW_CFA_def_cfa_register:
4966 // XXX overflow check
4967 get_uleb128 (op1, readp);
4968 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
4969 op1, regname (op1));
4971 case DW_CFA_def_cfa_offset:
4972 // XXX overflow check
4973 get_uleb128 (op1, readp);
4974 printf (" def_cfa_offset %" PRIu64 "\n", op1);
4976 case DW_CFA_def_cfa_expression:
4977 // XXX overflow check
4978 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
4979 printf (" def_cfa_expression %" PRIu64 "\n", op1);
4980 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4984 case DW_CFA_expression:
4985 // XXX overflow check
4986 get_uleb128 (op1, readp);
4987 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4988 printf (" expression r%" PRIu64 " (%s) \n",
4989 op1, regname (op1));
4990 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4994 case DW_CFA_offset_extended_sf:
4995 // XXX overflow check
4996 get_uleb128 (op1, readp);
4997 get_sleb128 (sop2, readp);
4998 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5000 op1, regname (op1), sop2 * data_align);
5002 case DW_CFA_def_cfa_sf:
5003 // XXX overflow check
5004 get_uleb128 (op1, readp);
5005 get_sleb128 (sop2, readp);
5006 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5007 op1, regname (op1), sop2 * data_align);
5009 case DW_CFA_def_cfa_offset_sf:
5010 // XXX overflow check
5011 get_sleb128 (sop1, readp);
5012 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5014 case DW_CFA_val_offset:
5015 // XXX overflow check
5016 get_uleb128 (op1, readp);
5017 get_uleb128 (op2, readp);
5018 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5019 op1, op2 * data_align);
5021 case DW_CFA_val_offset_sf:
5022 // XXX overflow check
5023 get_uleb128 (op1, readp);
5024 get_sleb128 (sop2, readp);
5025 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5026 op1, sop2 * data_align);
5028 case DW_CFA_val_expression:
5029 // XXX overflow check
5030 get_uleb128 (op1, readp);
5031 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
5032 printf (" val_expression r%" PRIu64 " (%s)\n",
5033 op1, regname (op1));
5034 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5038 case DW_CFA_MIPS_advance_loc8:
5039 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5040 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5041 op1, pc += op1 * code_align);
5043 case DW_CFA_GNU_window_save:
5044 puts (" GNU_window_save");
5046 case DW_CFA_GNU_args_size:
5047 // XXX overflow check
5048 get_uleb128 (op1, readp);
5049 printf (" args_size %" PRIu64 "\n", op1);
5052 printf (" ??? (%u)\n", opcode);
5055 else if (opcode < DW_CFA_offset)
5056 printf (" advance_loc %u to %#" PRIx64 "\n",
5057 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5058 else if (opcode < DW_CFA_restore)
5061 // XXX overflow check
5062 get_uleb128 (offset, readp);
5063 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5064 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5067 printf (" restore r%u (%s)\n",
5068 opcode & 0x3f, regname (opcode & 0x3f));
5074 encoded_ptr_size (int encoding, unsigned int ptr_size)
5076 switch (encoding & 7)
5078 case DW_EH_PE_udata4:
5080 case DW_EH_PE_udata8:
5086 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5087 "assuming pointer size of %d.\n", encoding, ptr_size);
5093 print_encoding (unsigned int val)
5097 case DW_EH_PE_absptr:
5098 fputs ("absptr", stdout);
5100 case DW_EH_PE_uleb128:
5101 fputs ("uleb128", stdout);
5103 case DW_EH_PE_udata2:
5104 fputs ("udata2", stdout);
5106 case DW_EH_PE_udata4:
5107 fputs ("udata4", stdout);
5109 case DW_EH_PE_udata8:
5110 fputs ("udata8", stdout);
5112 case DW_EH_PE_sleb128:
5113 fputs ("sleb128", stdout);
5115 case DW_EH_PE_sdata2:
5116 fputs ("sdata2", stdout);
5118 case DW_EH_PE_sdata4:
5119 fputs ("sdata4", stdout);
5121 case DW_EH_PE_sdata8:
5122 fputs ("sdata8", stdout);
5125 /* We did not use any of the bits after all. */
5134 print_relinfo (unsigned int val)
5138 case DW_EH_PE_pcrel:
5139 fputs ("pcrel", stdout);
5141 case DW_EH_PE_textrel:
5142 fputs ("textrel", stdout);
5144 case DW_EH_PE_datarel:
5145 fputs ("datarel", stdout);
5147 case DW_EH_PE_funcrel:
5148 fputs ("funcrel", stdout);
5150 case DW_EH_PE_aligned:
5151 fputs ("aligned", stdout);
5162 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5164 printf ("(%s", pfx);
5166 if (fde_encoding == DW_EH_PE_omit)
5170 unsigned int w = fde_encoding;
5172 w = print_encoding (w);
5176 if (w != fde_encoding)
5177 fputc_unlocked (' ', stdout);
5179 w = print_relinfo (w);
5183 printf ("%s%x", w != fde_encoding ? " " : "", w);
5190 static const unsigned char *
5191 read_encoded (unsigned int encoding, const unsigned char *readp,
5192 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5194 if ((encoding & 0xf) == DW_EH_PE_absptr)
5195 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5196 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5198 switch (encoding & 0xf)
5200 case DW_EH_PE_uleb128:
5201 // XXX buffer overrun check
5202 get_uleb128 (*res, readp);
5204 case DW_EH_PE_sleb128:
5205 // XXX buffer overrun check
5206 get_sleb128 (*res, readp);
5208 case DW_EH_PE_udata2:
5209 if (readp + 2 > endp)
5211 *res = read_2ubyte_unaligned_inc (dbg, readp);
5213 case DW_EH_PE_udata4:
5214 if (readp + 4 > endp)
5216 *res = read_4ubyte_unaligned_inc (dbg, readp);
5218 case DW_EH_PE_udata8:
5219 if (readp + 8 > endp)
5221 *res = read_8ubyte_unaligned_inc (dbg, readp);
5223 case DW_EH_PE_sdata2:
5224 if (readp + 2 > endp)
5226 *res = read_2sbyte_unaligned_inc (dbg, readp);
5228 case DW_EH_PE_sdata4:
5229 if (readp + 4 > endp)
5231 *res = read_4sbyte_unaligned_inc (dbg, readp);
5233 case DW_EH_PE_sdata8:
5234 if (readp + 8 > endp)
5236 *res = read_8sbyte_unaligned_inc (dbg, readp);
5241 gettext ("invalid encoding"));
5249 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5250 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5253 /* We know this call will succeed since it did in the caller. */
5254 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5255 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5257 /* Needed if we find PC-relative addresses. */
5259 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5261 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5265 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5266 Elf_Data *data = (is_eh_frame
5267 ? elf_rawdata (scn, NULL)
5268 : dbg->sectiondata[IDX_debug_frame]);
5270 if (unlikely (data == NULL))
5272 error (0, 0, gettext ("cannot get %s content: %s"),
5273 scnname, elf_errmsg (-1));
5279 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5280 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5283 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5284 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5288 ptrdiff_t cie_offset;
5289 const char *augmentation;
5290 unsigned int code_alignment_factor;
5291 unsigned int data_alignment_factor;
5292 uint8_t address_size;
5293 uint8_t fde_encoding;
5294 uint8_t lsda_encoding;
5295 struct cieinfo *next;
5298 const unsigned char *readp = data->d_buf;
5299 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5301 while (readp < dataend)
5303 if (unlikely (readp + 4 > dataend))
5306 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5307 elf_ndxscn (scn), scnname);
5311 /* At the beginning there must be a CIE. There can be multiple,
5312 hence we test tis in a loop. */
5313 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5315 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5316 unsigned int length = 4;
5317 if (unlikely (unit_length == 0xffffffff))
5319 if (unlikely (readp + 8 > dataend))
5322 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5326 if (unlikely (unit_length == 0))
5328 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5332 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5334 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5335 const unsigned char *const cieend = readp + unit_length;
5336 if (unlikely (cieend > dataend || readp + 8 > dataend))
5342 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5343 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5344 cie_id = DW_CIE_ID_64;
5347 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5349 uint_fast8_t version = 2;
5350 unsigned int code_alignment_factor;
5351 int data_alignment_factor;
5352 unsigned int fde_encoding = 0;
5353 unsigned int lsda_encoding = 0;
5354 Dwarf_Word initial_location = 0;
5355 Dwarf_Word vma_base = 0;
5357 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5360 const char *const augmentation = (const char *) readp;
5361 readp = memchr (readp, '\0', cieend - readp);
5362 if (unlikely (readp == NULL))
5366 uint_fast8_t segment_size = 0;
5369 if (cieend - readp < 5)
5371 ptr_size = *readp++;
5372 segment_size = *readp++;
5375 // XXX Check overflow
5376 get_uleb128 (code_alignment_factor, readp);
5377 // XXX Check overflow
5378 get_sleb128 (data_alignment_factor, readp);
5380 /* In some variant for unwind data there is another field. */
5381 if (strcmp (augmentation, "eh") == 0)
5382 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5384 unsigned int return_address_register;
5385 if (unlikely (version == 1))
5386 return_address_register = *readp++;
5388 // XXX Check overflow
5389 get_uleb128 (return_address_register, readp);
5391 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5392 " CIE_id: %" PRIu64 "\n"
5394 " augmentation: \"%s\"\n",
5395 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5396 version, augmentation);
5398 printf (" address_size: %u\n"
5399 " segment_size: %u\n",
5400 ptr_size, segment_size);
5401 printf (" code_alignment_factor: %u\n"
5402 " data_alignment_factor: %d\n"
5403 " return_address_register: %u\n",
5404 code_alignment_factor,
5405 data_alignment_factor, return_address_register);
5407 if (augmentation[0] == 'z')
5409 unsigned int augmentationlen;
5410 get_uleb128 (augmentationlen, readp);
5412 if (augmentationlen > (size_t) (dataend - readp))
5413 error (1, 0, gettext ("invalid augmentation length"));
5415 const char *hdr = "Augmentation data:";
5416 const char *cp = augmentation + 1;
5419 printf (" %-26s%#x ", hdr, *readp);
5424 fde_encoding = *readp++;
5425 print_encoding_base (gettext ("FDE address encoding: "),
5428 else if (*cp == 'L')
5430 lsda_encoding = *readp++;
5431 print_encoding_base (gettext ("LSDA pointer encoding: "),
5434 else if (*cp == 'P')
5436 /* Personality. This field usually has a relocation
5437 attached pointing to __gcc_personality_v0. */
5438 const unsigned char *startp = readp;
5439 unsigned int encoding = *readp++;
5441 readp = read_encoded (encoding, readp,
5442 readp - 1 + augmentationlen,
5445 while (++startp < readp)
5446 printf ("%#x ", *startp);
5449 print_encoding (encoding);
5451 switch (encoding & 0xf)
5453 case DW_EH_PE_sleb128:
5454 case DW_EH_PE_sdata2:
5455 case DW_EH_PE_sdata4:
5456 printf ("%" PRId64 ")\n", val);
5459 printf ("%#" PRIx64 ")\n", val);
5464 printf ("(%x)\n", *readp++);
5470 if (likely (ptr_size == 4 || ptr_size == 8))
5472 struct cieinfo *newp = alloca (sizeof (*newp));
5473 newp->cie_offset = offset;
5474 newp->augmentation = augmentation;
5475 newp->fde_encoding = fde_encoding;
5476 newp->lsda_encoding = lsda_encoding;
5477 newp->address_size = ptr_size;
5478 newp->code_alignment_factor = code_alignment_factor;
5479 newp->data_alignment_factor = data_alignment_factor;
5486 struct cieinfo *cie = cies;
5489 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5490 : (ptrdiff_t) cie_id == cie->cie_offset)
5494 if (unlikely (cie == NULL))
5496 puts ("invalid CIE reference in FDE");
5500 /* Initialize from CIE data. */
5501 fde_encoding = cie->fde_encoding;
5502 lsda_encoding = cie->lsda_encoding;
5503 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5504 code_alignment_factor = cie->code_alignment_factor;
5505 data_alignment_factor = cie->data_alignment_factor;
5507 const unsigned char *base = readp;
5508 // XXX There are sometimes relocations for this value
5509 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5510 Dwarf_Word address_range
5511 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5513 /* pcrel for an FDE address is relative to the runtime
5514 address of the start_address field itself. Sign extend
5515 if necessary to make sure the calculation is done on the
5516 full 64 bit address even when initial_location only holds
5517 the lower 32 bits. */
5518 Dwarf_Addr pc_start = initial_location;
5520 pc_start = (uint64_t) (int32_t) pc_start;
5521 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5522 pc_start += ((uint64_t) shdr->sh_addr
5523 + (base - (const unsigned char *) data->d_buf)
5526 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5527 pc_start, initial_location);
5528 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5529 " CIE_pointer: %" PRIu64 "\n"
5530 " initial_location: %s",
5531 offset, (uint64_t) unit_length,
5532 cie->cie_offset, (uint64_t) cie_id, a);
5534 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5536 vma_base = (((uint64_t) shdr->sh_offset
5537 + (base - (const unsigned char *) data->d_buf)
5538 + (uint64_t) initial_location)
5540 ? UINT64_C (0xffffffff)
5541 : UINT64_C (0xffffffffffffffff)));
5542 printf (gettext (" (offset: %#" PRIx64 ")"),
5543 (uint64_t) vma_base);
5546 printf ("\n address_range: %#" PRIx64,
5547 (uint64_t) address_range);
5548 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5549 printf (gettext (" (end offset: %#" PRIx64 ")"),
5550 ((uint64_t) vma_base + (uint64_t) address_range)
5552 ? UINT64_C (0xffffffff)
5553 : UINT64_C (0xffffffffffffffff)));
5556 if (cie->augmentation[0] == 'z')
5558 unsigned int augmentationlen;
5559 get_uleb128 (augmentationlen, readp);
5561 if (augmentationlen > 0)
5563 const char *hdr = "Augmentation data:";
5564 const char *cp = cie->augmentation + 1;
5570 uint64_t lsda_pointer;
5571 const unsigned char *p
5572 = read_encoded (lsda_encoding, &readp[u],
5573 &readp[augmentationlen],
5574 &lsda_pointer, dbg);
5577 %-26sLSDA pointer: %#" PRIx64 "\n"),
5584 while (u < augmentationlen)
5586 printf (" %-26s%#x\n", hdr, readp[u++]);
5591 readp += augmentationlen;
5595 /* Handle the initialization instructions. */
5596 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5597 data_alignment_factor, version, ptr_size,
5606 Dwfl_Module *dwflmod;
5611 unsigned int version;
5612 unsigned int addrsize;
5613 unsigned int offset_size;
5614 struct Dwarf_CU *cu;
5619 attr_callback (Dwarf_Attribute *attrp, void *arg)
5621 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5622 const int level = cbargs->level;
5624 unsigned int attr = dwarf_whatattr (attrp);
5625 if (unlikely (attr == 0))
5627 if (!cbargs->silent)
5628 error (0, 0, gettext ("cannot get attribute code: %s"),
5630 return DWARF_CB_ABORT;
5633 unsigned int form = dwarf_whatform (attrp);
5634 if (unlikely (form == 0))
5636 if (!cbargs->silent)
5637 error (0, 0, gettext ("cannot get attribute form: %s"),
5639 return DWARF_CB_ABORT;
5645 if (!cbargs->silent)
5648 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5651 if (!cbargs->silent)
5652 error (0, 0, gettext ("cannot get attribute value: %s"),
5654 return DWARF_CB_ABORT;
5656 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5658 printf (" %*s%-20s (%s) %s\n",
5659 (int) (level * 2), "", dwarf_attr_name (attr),
5660 dwarf_form_name (form), a);
5665 case DW_FORM_indirect:
5667 case DW_FORM_string:
5668 case DW_FORM_GNU_strp_alt:
5671 const char *str = dwarf_formstring (attrp);
5672 if (unlikely (str == NULL))
5674 printf (" %*s%-20s (%s) \"%s\"\n",
5675 (int) (level * 2), "", dwarf_attr_name (attr),
5676 dwarf_form_name (form), str);
5679 case DW_FORM_ref_addr:
5680 case DW_FORM_ref_udata:
5685 case DW_FORM_GNU_ref_alt:
5689 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5692 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5693 (int) (level * 2), "", dwarf_attr_name (attr),
5694 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5697 case DW_FORM_ref_sig8:
5700 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5701 (int) (level * 2), "", dwarf_attr_name (attr),
5702 dwarf_form_name (form),
5703 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5706 case DW_FORM_sec_offset:
5712 case DW_FORM_data1:;
5714 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5717 const char *valuestr = NULL;
5720 /* This case can take either a constant or a loclistptr. */
5721 case DW_AT_data_member_location:
5722 if (form != DW_FORM_sec_offset
5723 && (cbargs->version >= 4
5724 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5726 if (!cbargs->silent)
5727 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5728 (int) (level * 2), "", dwarf_attr_name (attr),
5729 dwarf_form_name (form), (uintmax_t) num);
5732 /* else fallthrough */
5734 /* These cases always take a loclistptr and no constant. */
5735 case DW_AT_location:
5736 case DW_AT_data_location:
5737 case DW_AT_vtable_elem_location:
5738 case DW_AT_string_length:
5739 case DW_AT_use_location:
5740 case DW_AT_frame_base:
5741 case DW_AT_return_addr:
5742 case DW_AT_static_link:
5743 case DW_AT_GNU_call_site_value:
5744 case DW_AT_GNU_call_site_data_value:
5745 case DW_AT_GNU_call_site_target:
5746 case DW_AT_GNU_call_site_target_clobbered:
5747 notice_listptr (section_loc, &known_loclistptr,
5748 cbargs->addrsize, cbargs->offset_size,
5750 if (!cbargs->silent)
5751 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5752 (int) (level * 2), "", dwarf_attr_name (attr),
5753 dwarf_form_name (form), (uintmax_t) num);
5757 notice_listptr (section_ranges, &known_rangelistptr,
5758 cbargs->addrsize, cbargs->offset_size,
5760 if (!cbargs->silent)
5761 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5762 (int) (level * 2), "", dwarf_attr_name (attr),
5763 dwarf_form_name (form), (uintmax_t) num);
5766 case DW_AT_language:
5767 valuestr = dwarf_lang_name (num);
5769 case DW_AT_encoding:
5770 valuestr = dwarf_encoding_name (num);
5772 case DW_AT_accessibility:
5773 valuestr = dwarf_access_name (num);
5775 case DW_AT_visibility:
5776 valuestr = dwarf_visibility_name (num);
5778 case DW_AT_virtuality:
5779 valuestr = dwarf_virtuality_name (num);
5781 case DW_AT_identifier_case:
5782 valuestr = dwarf_identifier_case_name (num);
5784 case DW_AT_calling_convention:
5785 valuestr = dwarf_calling_convention_name (num);
5788 valuestr = dwarf_inline_name (num);
5790 case DW_AT_ordering:
5791 valuestr = dwarf_ordering_name (num);
5793 case DW_AT_discr_list:
5794 valuestr = dwarf_discr_list_name (num);
5804 /* When highpc is in constant form it is relative to lowpc.
5805 In that case also show the address. */
5807 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5809 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5811 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5812 (int) (level * 2), "", dwarf_attr_name (attr),
5813 dwarf_form_name (form), (uintmax_t) num, a);
5818 Dwarf_Sword snum = 0;
5819 if (form == DW_FORM_sdata)
5820 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5823 if (valuestr == NULL)
5825 printf (" %*s%-20s (%s)",
5826 (int) (level * 2), "", dwarf_attr_name (attr),
5827 dwarf_form_name (form));
5828 if (form == DW_FORM_sdata)
5829 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5831 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5835 printf (" %*s%-20s (%s) %s",
5836 (int) (level * 2), "", dwarf_attr_name (attr),
5837 dwarf_form_name (form), valuestr);
5838 if (form == DW_FORM_sdata)
5839 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5841 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
5850 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5853 printf (" %*s%-20s (%s) %s\n",
5854 (int) (level * 2), "", dwarf_attr_name (attr),
5855 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5858 case DW_FORM_flag_present:
5861 printf (" %*s%-20s (%s) %s\n",
5862 (int) (level * 2), "", dwarf_attr_name (attr),
5863 dwarf_form_name (form), nl_langinfo (YESSTR));
5866 case DW_FORM_exprloc:
5867 case DW_FORM_block4:
5868 case DW_FORM_block2:
5869 case DW_FORM_block1:
5874 if (unlikely (dwarf_formblock (attrp, &block) != 0))
5877 printf (" %*s%-20s (%s) ",
5878 (int) (level * 2), "", dwarf_attr_name (attr),
5879 dwarf_form_name (form));
5884 if (form != DW_FORM_exprloc)
5886 print_block (block.length, block.data);
5891 case DW_AT_location:
5892 case DW_AT_data_location:
5893 case DW_AT_data_member_location:
5894 case DW_AT_vtable_elem_location:
5895 case DW_AT_string_length:
5896 case DW_AT_use_location:
5897 case DW_AT_frame_base:
5898 case DW_AT_return_addr:
5899 case DW_AT_static_link:
5900 case DW_AT_allocated:
5901 case DW_AT_associated:
5902 case DW_AT_bit_size:
5903 case DW_AT_bit_offset:
5904 case DW_AT_bit_stride:
5905 case DW_AT_byte_size:
5906 case DW_AT_byte_stride:
5908 case DW_AT_lower_bound:
5909 case DW_AT_upper_bound:
5910 case DW_AT_GNU_call_site_value:
5911 case DW_AT_GNU_call_site_data_value:
5912 case DW_AT_GNU_call_site_target:
5913 case DW_AT_GNU_call_site_target_clobbered:
5915 print_ops (cbargs->dwflmod, cbargs->dbg,
5916 12 + level * 2, 12 + level * 2,
5917 cbargs->version, cbargs->addrsize, cbargs->offset_size,
5918 attrp->cu, block.length, block.data);
5926 printf (" %*s%-20s (form: %#x) ???\n",
5927 (int) (level * 2), "", dwarf_attr_name (attr),
5936 print_debug_units (Dwfl_Module *dwflmod,
5937 Ebl *ebl, GElf_Ehdr *ehdr,
5938 Elf_Scn *scn, GElf_Shdr *shdr,
5939 Dwarf *dbg, bool debug_types)
5941 const bool silent = !(print_debug_sections & section_info);
5942 const char *secname = section_name (ebl, ehdr, shdr);
5946 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5947 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5949 /* If the section is empty we don't have to do anything. */
5950 if (!silent && shdr->sh_size == 0)
5954 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5956 Dwarf_Off offset = 0;
5958 /* New compilation unit. */
5961 Dwarf_Off abbroffset;
5968 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5969 &abbroffset, &addrsize, &offsize,
5970 debug_types ? &typesig : NULL,
5971 debug_types ? &typeoff : NULL) != 0)
5977 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5978 " Version: %" PRIu16 ", Abbreviation section offset: %"
5979 PRIu64 ", Address size: %" PRIu8
5980 ", Offset size: %" PRIu8
5981 "\n Type signature: %#" PRIx64
5982 ", Type offset: %#" PRIx64 "\n"),
5983 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5984 typesig, (uint64_t) typeoff);
5986 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5987 " Version: %" PRIu16 ", Abbreviation section offset: %"
5988 PRIu64 ", Address size: %" PRIu8
5989 ", Offset size: %" PRIu8 "\n"),
5990 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5993 struct attrcb_args args =
5999 .addrsize = addrsize,
6000 .offset_size = offsize
6007 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6008 (dbg, offset, &dies[level]) == NULL))
6011 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6012 " in section '%s': %s"),
6013 (uint64_t) offset, secname, dwarf_errmsg (-1));
6017 args.cu = dies[0].cu;
6021 offset = dwarf_dieoffset (&dies[level]);
6022 if (unlikely (offset == ~0ul))
6025 error (0, 0, gettext ("cannot get DIE offset: %s"),
6030 int tag = dwarf_tag (&dies[level]);
6031 if (unlikely (tag == DW_TAG_invalid))
6034 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6035 " in section '%s': %s"),
6036 (uint64_t) offset, secname, dwarf_errmsg (-1));
6041 printf (" [%6" PRIx64 "] %*s%s\n",
6042 (uint64_t) offset, (int) (level * 2), "",
6043 dwarf_tag_name (tag));
6045 /* Print the attribute values. */
6047 args.die = &dies[level];
6048 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6050 /* Make room for the next level's DIE. */
6051 if (level + 1 == maxdies)
6052 dies = (Dwarf_Die *) xrealloc (dies,
6054 * sizeof (Dwarf_Die));
6056 int res = dwarf_child (&dies[level], &dies[level + 1]);
6059 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6063 if (unlikely (res == -1))
6066 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6071 else if (unlikely (res < 0))
6074 error (0, 0, gettext ("cannot get next DIE: %s"),
6092 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6093 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6095 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6099 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6100 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6102 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6107 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6108 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6111 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6112 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6113 (uint64_t) shdr->sh_offset);
6116 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6119 Dwarf_Off ncuoffset = 0;
6121 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6122 NULL, NULL, NULL) == 0)
6125 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6130 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6133 printf (" CU [%" PRIx64 "] %s\n",
6134 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6135 printf (" line:col SBPE* disc isa op address"
6136 " (Statement Block Prologue Epilogue *End)\n");
6137 const char *last_file = "";
6138 for (size_t n = 0; n < nlines; n++)
6140 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6141 Dwarf_Word mtime, length;
6142 const char *file = dwarf_linesrc (line, &mtime, &length);
6143 if (strcmp (last_file, file) != 0)
6145 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6146 file, mtime, length);
6151 bool statement, endseq, block, prologue_end, epilogue_begin;
6152 unsigned int lineop, isa, disc;
6154 dwarf_lineaddr (line, &address);
6155 dwarf_lineno (line, &lineno);
6156 dwarf_linecol (line, &colno);
6157 dwarf_lineop_index (line, &lineop);
6158 dwarf_linebeginstatement (line, &statement);
6159 dwarf_lineendsequence (line, &endseq);
6160 dwarf_lineblock (line, &block);
6161 dwarf_lineprologueend (line, &prologue_end);
6162 dwarf_lineepiloguebegin (line, &epilogue_begin);
6163 dwarf_lineisa (line, &isa);
6164 dwarf_linediscriminator (line, &disc);
6166 /* End sequence is special, it is one byte past. */
6167 char *a = format_dwarf_addr (dwflmod, address_size,
6168 address - (endseq ? 1 : 0), address);
6169 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6171 (statement ? 'S' : ' '),
6172 (block ? 'B' : ' '),
6173 (prologue_end ? 'P' : ' '),
6174 (epilogue_begin ? 'E' : ' '),
6175 (endseq ? '*' : ' '),
6176 disc, isa, lineop, a);
6187 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6188 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6192 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6197 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6198 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6199 (uint64_t) shdr->sh_offset);
6201 if (shdr->sh_size == 0)
6204 /* There is no functionality in libdw to read the information in the
6205 way it is represented here. Hardcode the decoder. */
6206 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6207 if (unlikely (data == NULL || data->d_buf == NULL))
6209 error (0, 0, gettext ("cannot get line data section data: %s"),
6214 const unsigned char *linep = (const unsigned char *) data->d_buf;
6215 const unsigned char *lineendp;
6218 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6220 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6222 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6224 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6225 unsigned int length = 4;
6226 if (unlikely (unit_length == 0xffffffff))
6228 if (unlikely (linep + 8 > lineendp))
6231 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6232 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6235 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6239 /* Check whether we have enough room in the section. */
6240 if (unit_length < 2 + length + 5 * 1
6241 || unlikely (linep + unit_length > lineendp))
6243 lineendp = linep + unit_length;
6245 /* The next element of the header is the version identifier. */
6246 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6248 /* Next comes the header length. */
6249 Dwarf_Word header_length;
6251 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6253 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6254 //const unsigned char *header_start = linep;
6256 /* Next the minimum instruction length. */
6257 uint_fast8_t minimum_instr_len = *linep++;
6259 /* Next the maximum operations per instruction, in version 4 format. */
6260 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6262 /* Then the flag determining the default value of the is_stmt
6264 uint_fast8_t default_is_stmt = *linep++;
6266 /* Now the line base. */
6267 int_fast8_t line_base = *((const int_fast8_t *) linep);
6270 /* And the line range. */
6271 uint_fast8_t line_range = *linep++;
6273 /* The opcode base. */
6274 uint_fast8_t opcode_base = *linep++;
6276 /* Print what we got so far. */
6277 printf (gettext ("\n"
6278 " Length: %" PRIu64 "\n"
6279 " DWARF version: %" PRIuFAST16 "\n"
6280 " Prologue length: %" PRIu64 "\n"
6281 " Minimum instruction length: %" PRIuFAST8 "\n"
6282 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6283 " Initial value if '%s': %" PRIuFAST8 "\n"
6284 " Line base: %" PRIdFAST8 "\n"
6285 " Line range: %" PRIuFAST8 "\n"
6286 " Opcode base: %" PRIuFAST8 "\n"
6289 (uint64_t) unit_length, version, (uint64_t) header_length,
6290 minimum_instr_len, max_ops_per_instr,
6291 "is_stmt", default_is_stmt, line_base,
6292 line_range, opcode_base);
6294 if (unlikely (linep + opcode_base - 1 >= lineendp))
6298 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6299 linep - (const unsigned char *) data->d_buf,
6300 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6304 int opcode_base_l10 = 1;
6305 unsigned int tmp = opcode_base;
6311 const uint8_t *standard_opcode_lengths = linep - 1;
6312 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6313 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6314 " [%*" PRIuFAST8 "] %hhu arguments\n",
6315 (int) linep[cnt - 1]),
6316 opcode_base_l10, cnt, linep[cnt - 1]);
6317 linep += opcode_base - 1;
6318 if (unlikely (linep >= lineendp))
6321 puts (gettext ("\nDirectory table:"));
6324 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6325 if (unlikely (endp == NULL))
6328 printf (" %s\n", (char *) linep);
6332 /* Skip the final NUL byte. */
6335 if (unlikely (linep >= lineendp))
6337 puts (gettext ("\nFile name table:\n"
6338 " Entry Dir Time Size Name"));
6339 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6341 /* First comes the file name. */
6342 char *fname = (char *) linep;
6343 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6344 if (unlikely (endp == NULL))
6348 /* Then the index. */
6349 unsigned int diridx;
6350 get_uleb128 (diridx, linep);
6352 /* Next comes the modification time. */
6354 get_uleb128 (mtime, linep);
6356 /* Finally the length of the file. */
6358 get_uleb128 (fsize, linep);
6360 printf (" %-5u %-5u %-9u %-9u %s\n",
6361 cnt, diridx, mtime, fsize, fname);
6363 /* Skip the final NUL byte. */
6366 puts (gettext ("\nLine number statements:"));
6367 Dwarf_Word address = 0;
6368 unsigned int op_index = 0;
6370 uint_fast8_t is_stmt = default_is_stmt;
6372 /* Default address value, in case we do not find the CU. */
6374 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6376 /* Determine the CU this block is for. */
6378 Dwarf_Off ncuoffset = 0;
6380 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6381 NULL, NULL, NULL) == 0)
6384 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6386 Dwarf_Attribute stmt_list;
6387 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6390 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6392 if (lineoff == start_offset)
6395 address_size = cudie.cu->address_size;
6400 /* Apply the "operation advance" from a special opcode
6401 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6402 unsigned int op_addr_advance;
6404 inline void advance_pc (unsigned int op_advance)
6406 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6407 / max_ops_per_instr);
6408 address += op_advance;
6409 show_op_index = (op_index > 0 ||
6410 (op_index + op_advance) % max_ops_per_instr > 0);
6411 op_index = (op_index + op_advance) % max_ops_per_instr;
6414 while (linep < lineendp)
6416 size_t offset = linep - (const unsigned char *) data->d_buf;
6420 /* Read the opcode. */
6421 unsigned int opcode = *linep++;
6423 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6424 /* Is this a special opcode? */
6425 if (likely (opcode >= opcode_base))
6427 /* Yes. Handling this is quite easy since the opcode value
6430 opcode = (desired line increment - line_base)
6431 + (line_range * address advance) + opcode_base
6433 int line_increment = (line_base
6434 + (opcode - opcode_base) % line_range);
6436 /* Perform the increments. */
6437 line += line_increment;
6438 advance_pc ((opcode - opcode_base) / line_range);
6440 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6443 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6444 opcode, op_addr_advance, a, op_index,
6445 line_increment, line);
6448 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6449 opcode, op_addr_advance, a, line_increment, line);
6452 else if (opcode == 0)
6454 /* This an extended opcode. */
6455 if (unlikely (linep + 2 > lineendp))
6459 unsigned int len = *linep++;
6461 if (unlikely (linep + len > lineendp))
6464 /* The sub-opcode. */
6467 printf (gettext (" extended opcode %u: "), opcode);
6471 case DW_LNE_end_sequence:
6472 puts (gettext (" end of sequence"));
6474 /* Reset the registers we care about. */
6478 is_stmt = default_is_stmt;
6481 case DW_LNE_set_address:
6483 if (address_size == 4)
6484 address = read_4ubyte_unaligned_inc (dbg, linep);
6486 address = read_8ubyte_unaligned_inc (dbg, linep);
6488 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6489 printf (gettext (" set address to %s\n"), a);
6494 case DW_LNE_define_file:
6496 char *fname = (char *) linep;
6497 unsigned char *endp = memchr (linep, '\0',
6499 if (unlikely (endp == NULL))
6503 unsigned int diridx;
6504 get_uleb128 (diridx, linep);
6506 get_uleb128 (mtime, linep);
6507 Dwarf_Word filelength;
6508 get_uleb128 (filelength, linep);
6511 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6512 diridx, (uint64_t) mtime, (uint64_t) filelength,
6517 case DW_LNE_set_discriminator:
6518 /* Takes one ULEB128 parameter, the discriminator. */
6519 if (unlikely (standard_opcode_lengths[opcode] != 1))
6522 get_uleb128 (u128, linep);
6523 printf (gettext (" set discriminator to %u\n"), u128);
6527 /* Unknown, ignore it. */
6528 puts (gettext (" unknown opcode"));
6533 else if (opcode <= DW_LNS_set_isa)
6535 /* This is a known standard opcode. */
6539 /* Takes no argument. */
6540 puts (gettext (" copy"));
6543 case DW_LNS_advance_pc:
6544 /* Takes one uleb128 parameter which is added to the
6546 get_uleb128 (u128, linep);
6549 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6552 advance address by %u to %s, op_index to %u\n"),
6553 op_addr_advance, a, op_index);
6555 printf (gettext (" advance address by %u to %s\n"),
6556 op_addr_advance, a);
6561 case DW_LNS_advance_line:
6562 /* Takes one sleb128 parameter which is added to the
6564 get_sleb128 (s128, linep);
6567 advance line by constant %d to %" PRId64 "\n"),
6568 s128, (int64_t) line);
6571 case DW_LNS_set_file:
6572 /* Takes one uleb128 parameter which is stored in file. */
6573 get_uleb128 (u128, linep);
6574 printf (gettext (" set file to %" PRIu64 "\n"),
6578 case DW_LNS_set_column:
6579 /* Takes one uleb128 parameter which is stored in column. */
6580 if (unlikely (standard_opcode_lengths[opcode] != 1))
6583 get_uleb128 (u128, linep);
6584 printf (gettext (" set column to %" PRIu64 "\n"),
6588 case DW_LNS_negate_stmt:
6589 /* Takes no argument. */
6590 is_stmt = 1 - is_stmt;
6591 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6592 "is_stmt", is_stmt);
6595 case DW_LNS_set_basic_block:
6596 /* Takes no argument. */
6597 puts (gettext (" set basic block flag"));
6600 case DW_LNS_const_add_pc:
6601 /* Takes no argument. */
6602 advance_pc ((255 - opcode_base) / line_range);
6604 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6607 advance address by constant %u to %s, op_index to %u\n"),
6608 op_addr_advance, a, op_index);
6611 advance address by constant %u to %s\n"),
6612 op_addr_advance, a);
6617 case DW_LNS_fixed_advance_pc:
6618 /* Takes one 16 bit parameter which is added to the
6620 if (unlikely (standard_opcode_lengths[opcode] != 1))
6623 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6627 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6629 advance address by fixed value %u to %s\n"),
6635 case DW_LNS_set_prologue_end:
6636 /* Takes no argument. */
6637 puts (gettext (" set prologue end flag"));
6640 case DW_LNS_set_epilogue_begin:
6641 /* Takes no argument. */
6642 puts (gettext (" set epilogue begin flag"));
6645 case DW_LNS_set_isa:
6646 /* Takes one uleb128 parameter which is stored in isa. */
6647 if (unlikely (standard_opcode_lengths[opcode] != 1))
6650 get_uleb128 (u128, linep);
6651 printf (gettext (" set isa to %u\n"), u128);
6657 /* This is a new opcode the generator but not we know about.
6658 Read the parameters associated with it but then discard
6659 everything. Read all the parameters for this opcode. */
6660 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6661 " unknown opcode with %" PRIu8 " parameters:",
6662 standard_opcode_lengths[opcode]),
6663 standard_opcode_lengths[opcode]);
6664 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6666 get_uleb128 (u128, linep);
6667 if (n != standard_opcode_lengths[opcode])
6668 putc_unlocked (',', stdout);
6669 printf (" %u", u128);
6672 /* Next round, ignore this opcode. */
6678 /* There must only be one data block. */
6679 assert (elf_getdata (scn, data) == NULL);
6684 print_debug_loc_section (Dwfl_Module *dwflmod,
6685 Ebl *ebl, GElf_Ehdr *ehdr,
6686 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6688 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6690 if (unlikely (data == NULL))
6692 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6698 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6699 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6700 (uint64_t) shdr->sh_offset);
6702 sort_listptr (&known_loclistptr, "loclistptr");
6703 size_t listptr_idx = 0;
6705 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6706 uint_fast8_t offset_size = 4;
6709 struct Dwarf_CU *cu = NULL;
6710 Dwarf_Addr base = 0;
6711 unsigned char *readp = data->d_buf;
6712 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6713 while (readp < endp)
6715 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6717 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6718 &address_size, &offset_size, &base,
6719 &cu, offset, &readp, endp))
6722 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6724 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6730 if (address_size == 8)
6732 begin = read_8ubyte_unaligned_inc (dbg, readp);
6733 end = read_8ubyte_unaligned_inc (dbg, readp);
6737 begin = read_4ubyte_unaligned_inc (dbg, readp);
6738 end = read_4ubyte_unaligned_inc (dbg, readp);
6739 if (begin == (Dwarf_Addr) (uint32_t) -1)
6740 begin = (Dwarf_Addr) -1l;
6743 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6745 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6746 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6750 else if (begin == 0 && end == 0) /* End of list entry. */
6753 printf (gettext (" [%6tx] empty list\n"), offset);
6758 /* We have a location expression entry. */
6759 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6761 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6763 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6766 if (first) /* First entry in a list. */
6767 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6769 printf (gettext (" %s..%s"), b, e);
6774 if (endp - readp <= (ptrdiff_t) len)
6776 fputs (gettext (" <INVALID DATA>\n"), stdout);
6780 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6781 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6794 struct mac_culist *next;
6799 mac_compare (const void *p1, const void *p2)
6801 struct mac_culist *m1 = (struct mac_culist *) p1;
6802 struct mac_culist *m2 = (struct mac_culist *) p2;
6804 if (m1->offset < m2->offset)
6806 if (m1->offset > m2->offset)
6813 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6814 Ebl *ebl, GElf_Ehdr *ehdr,
6815 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6818 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6819 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6820 (uint64_t) shdr->sh_offset);
6821 putc_unlocked ('\n', stdout);
6823 /* There is no function in libdw to iterate over the raw content of
6824 the section but it is easy enough to do. */
6825 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
6826 if (unlikely (data == NULL || data->d_buf == NULL))
6828 error (0, 0, gettext ("cannot get macro information section data: %s"),
6833 /* Get the source file information for all CUs. */
6837 struct mac_culist *culist = NULL;
6839 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6842 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6845 Dwarf_Attribute attr;
6846 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6850 if (dwarf_formudata (&attr, &macoff) != 0)
6853 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6855 newp->offset = macoff;
6857 newp->next = culist;
6862 /* Convert the list into an array for easier consumption. */
6863 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6866 cus[nculist].offset = data->d_size;
6869 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6871 assert (cnt < nculist);
6873 culist = culist->next;
6876 /* Sort the array according to the offset in the .debug_macinfo
6877 section. Note we keep the sentinel at the end. */
6878 qsort (cus, nculist, sizeof (*cus), mac_compare);
6881 const unsigned char *readp = (const unsigned char *) data->d_buf;
6882 const unsigned char *readendp = readp + data->d_size;
6885 while (readp < readendp)
6887 unsigned int opcode = *readp++;
6889 unsigned int u128_2;
6890 const unsigned char *endp;
6894 case DW_MACINFO_define:
6895 case DW_MACINFO_undef:
6896 case DW_MACINFO_vendor_ext:
6897 /* For the first two opcodes the parameters are
6901 We can treat these cases together. */
6902 get_uleb128 (u128, readp);
6904 endp = memchr (readp, '\0', readendp - readp);
6905 if (unlikely (endp == NULL))
6908 %*s*** non-terminated string at end of section"),
6913 if (opcode == DW_MACINFO_define)
6914 printf ("%*s#define %s, line %u\n",
6915 level, "", (char *) readp, u128);
6916 else if (opcode == DW_MACINFO_undef)
6917 printf ("%*s#undef %s, line %u\n",
6918 level, "", (char *) readp, u128);
6920 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6925 case DW_MACINFO_start_file:
6926 /* The two parameters are line and file index, in this order. */
6927 get_uleb128 (u128, readp);
6928 get_uleb128 (u128_2, readp);
6930 /* Find the CU DIE for this file. */
6931 size_t macoff = readp - (const unsigned char *) data->d_buf;
6932 const char *fname = "???";
6933 if (macoff >= cus[0].offset)
6935 while (macoff >= cus[1].offset)
6938 if (cus[0].files == NULL
6939 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6940 cus[0].files = (Dwarf_Files *) -1l;
6942 if (cus[0].files != (Dwarf_Files *) -1l)
6943 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6947 printf ("%*sstart_file %u, [%u] %s\n",
6948 level, "", u128, u128_2, fname);
6952 case DW_MACINFO_end_file:
6954 printf ("%*send_file\n", level, "");
6955 /* Nothing more to do. */
6959 // XXX gcc seems to generate files with a trailing zero.
6960 if (unlikely (opcode != 0 || readp != readendp))
6961 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6969 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6970 Ebl *ebl, GElf_Ehdr *ehdr,
6971 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6974 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6975 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6976 (uint64_t) shdr->sh_offset);
6977 putc_unlocked ('\n', stdout);
6979 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
6980 if (unlikely (data == NULL || data->d_buf == NULL))
6982 error (0, 0, gettext ("cannot get macro information section data: %s"),
6987 /* Get the source file information for all CUs. Uses same
6988 datastructure as macinfo. But uses offset field to directly
6989 match .debug_line offset. And just stored in a list. */
6993 struct mac_culist *culist = NULL;
6995 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6998 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7001 Dwarf_Attribute attr;
7002 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7006 if (dwarf_formudata (&attr, &lineoff) != 0)
7009 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7011 newp->offset = lineoff;
7013 newp->next = culist;
7018 const unsigned char *readp = (const unsigned char *) data->d_buf;
7019 const unsigned char *readendp = readp + data->d_size;
7021 while (readp < readendp)
7023 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7024 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7026 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7027 // optional vendor extension macro entry table.
7028 if (readp + 2 > readendp)
7031 error (0, 0, gettext ("invalid data"));
7034 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7035 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7037 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7038 // 5 when it gets standardized.
7041 printf (gettext (" unknown version, cannot parse section\n"));
7045 if (readp + 1 > readendp)
7047 const unsigned char flag = *readp++;
7048 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7050 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7051 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7052 Dwarf_Off line_offset = -1;
7055 if (offset_len == 8)
7056 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7058 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7059 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7063 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7064 memset (vendor, 0, sizeof vendor);
7067 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7068 // of arguments, for each argument 1 byte form code.
7069 if (readp + 1 > readendp)
7071 unsigned int tlen = *readp++;
7072 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7074 for (unsigned int i = 0; i < tlen; i++)
7076 if (readp + 1 > readendp)
7078 unsigned int opcode = *readp++;
7079 printf (gettext (" [%" PRIx8 "]"), opcode);
7080 if (opcode < DW_MACRO_GNU_lo_user
7081 || opcode > DW_MACRO_GNU_hi_user)
7083 // Record the start of description for this vendor opcode.
7084 // uleb128 nr args, 1 byte per arg form.
7085 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7086 if (readp + 1 > readendp)
7088 unsigned int args = *readp++;
7091 printf (gettext (" %" PRIu8 " arguments:"), args);
7094 if (readp + 1 > readendp)
7096 unsigned int form = *readp++;
7097 printf (" %s", dwarf_form_string (form));
7098 if (form != DW_FORM_data1
7099 && form != DW_FORM_data2
7100 && form != DW_FORM_data4
7101 && form != DW_FORM_data8
7102 && form != DW_FORM_sdata
7103 && form != DW_FORM_udata
7104 && form != DW_FORM_block
7105 && form != DW_FORM_block1
7106 && form != DW_FORM_block2
7107 && form != DW_FORM_block4
7108 && form != DW_FORM_flag
7109 && form != DW_FORM_string
7110 && form != DW_FORM_strp
7111 && form != DW_FORM_sec_offset)
7115 putchar_unlocked (',');
7119 printf (gettext (" no arguments."));
7120 putchar_unlocked ('\n');
7123 putchar_unlocked ('\n');
7126 if (readp + 1 > readendp)
7128 unsigned int opcode = *readp++;
7132 unsigned int u128_2;
7133 const unsigned char *endp;
7138 case DW_MACRO_GNU_start_file:
7139 get_uleb128 (u128, readp);
7140 get_uleb128 (u128_2, readp);
7142 /* Find the CU DIE that matches this line offset. */
7143 const char *fname = "???";
7144 if (line_offset != (Dwarf_Off) -1)
7146 struct mac_culist *cu = culist;
7147 while (cu != NULL && line_offset != cu->offset)
7151 if (cu->files == NULL
7152 && dwarf_getsrcfiles (&cu->die, &cu->files,
7154 cu->files = (Dwarf_Files *) -1l;
7156 if (cu->files != (Dwarf_Files *) -1l)
7157 fname = (dwarf_filesrc (cu->files, u128_2,
7158 NULL, NULL) ?: "???");
7161 printf ("%*sstart_file %u, [%u] %s\n",
7162 level, "", u128, u128_2, fname);
7166 case DW_MACRO_GNU_end_file:
7168 printf ("%*send_file\n", level, "");
7171 case DW_MACRO_GNU_define:
7172 get_uleb128 (u128, readp);
7173 endp = memchr (readp, '\0', readendp - readp);
7176 printf ("%*s#define %s, line %u\n",
7177 level, "", readp, u128);
7181 case DW_MACRO_GNU_undef:
7182 get_uleb128 (u128, readp);
7183 endp = memchr (readp, '\0', readendp - readp);
7186 printf ("%*s#undef %s, line %u\n",
7187 level, "", readp, u128);
7191 case DW_MACRO_GNU_define_indirect:
7192 get_uleb128 (u128, readp);
7193 if (readp + offset_len > readendp)
7195 if (offset_len == 8)
7196 off = read_8ubyte_unaligned_inc (dbg, readp);
7198 off = read_4ubyte_unaligned_inc (dbg, readp);
7199 printf ("%*s#define %s, line %u (indirect)\n",
7200 level, "", dwarf_getstring (dbg, off, NULL), u128);
7203 case DW_MACRO_GNU_undef_indirect:
7204 get_uleb128 (u128, readp);
7205 if (readp + offset_len > readendp)
7207 if (offset_len == 8)
7208 off = read_8ubyte_unaligned_inc (dbg, readp);
7210 off = read_4ubyte_unaligned_inc (dbg, readp);
7211 printf ("%*s#undef %s, line %u (indirect)\n",
7212 level, "", dwarf_getstring (dbg, off, NULL), u128);
7215 case DW_MACRO_GNU_transparent_include:
7216 if (readp + offset_len > readendp)
7218 if (offset_len == 8)
7219 off = read_8ubyte_unaligned_inc (dbg, readp);
7221 off = read_4ubyte_unaligned_inc (dbg, readp);
7222 printf ("%*s#include offset 0x%" PRIx64 "\n",
7227 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7228 if (opcode < DW_MACRO_GNU_lo_user
7229 || opcode > DW_MACRO_GNU_lo_user
7230 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7233 const unsigned char *op_desc;
7234 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7236 // Just skip the arguments, we cannot really interpret them,
7237 // but print as much as we can.
7238 unsigned int args = *op_desc++;
7241 unsigned int form = *op_desc++;
7246 if (readp + 1 > readendp)
7249 printf (" %" PRIx8, (unsigned int) val);
7253 if (readp + 2 > readendp)
7255 val = read_2ubyte_unaligned_inc (dbg, readp);
7256 printf(" %" PRIx16, (unsigned int) val);
7260 if (readp + 4 > readendp)
7262 val = read_4ubyte_unaligned_inc (dbg, readp);
7263 printf (" %" PRIx32, (unsigned int) val);
7267 if (readp + 8 > readendp)
7269 val = read_8ubyte_unaligned_inc (dbg, readp);
7270 printf (" %" PRIx64, val);
7274 get_sleb128 (val, readp);
7275 printf (" %" PRIx64, val);
7279 get_uleb128 (val, readp);
7280 printf (" %" PRIx64, val);
7284 get_uleb128 (val, readp);
7285 printf (" block[%" PRIu64 "]", val);
7286 if (readp + val > readendp)
7291 case DW_FORM_block1:
7292 if (readp + 1 > readendp)
7295 printf (" block[%" PRIu64 "]", val);
7296 if (readp + val > readendp)
7300 case DW_FORM_block2:
7301 if (readp + 2 > readendp)
7303 val = read_2ubyte_unaligned_inc (dbg, readp);
7304 printf (" block[%" PRIu64 "]", val);
7305 if (readp + val > readendp)
7309 case DW_FORM_block4:
7310 if (readp + 2 > readendp)
7312 val =read_4ubyte_unaligned_inc (dbg, readp);
7313 printf (" block[%" PRIu64 "]", val);
7314 if (readp + val > readendp)
7319 if (readp + 1 > readendp)
7322 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7325 case DW_FORM_string:
7326 endp = memchr (readp, '\0', readendp - readp);
7329 printf (" %s", readp);
7334 if (readp + offset_len > readendp)
7336 if (offset_len == 8)
7337 val = read_8ubyte_unaligned_inc (dbg, readp);
7339 val = read_4ubyte_unaligned_inc (dbg, readp);
7340 printf (" %s", dwarf_getstring (dbg, val, NULL));
7343 case DW_FORM_sec_offset:
7344 if (readp + offset_len > readendp)
7346 if (offset_len == 8)
7347 val = read_8ubyte_unaligned_inc (dbg, readp);
7349 val = read_4ubyte_unaligned_inc (dbg, readp);
7350 printf (" %" PRIx64, val);
7354 error (0, 0, gettext ("vendor opcode not verified?"));
7360 putchar_unlocked (',');
7362 putchar_unlocked ('\n');
7365 if (readp + 1 > readendp)
7369 putchar_unlocked ('\n');
7375 /* Callback for printing global names. */
7377 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7380 int *np = (int *) arg;
7382 printf (gettext (" [%5d] DIE offset: %6" PRId64
7383 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7384 (*np)++, global->die_offset, global->cu_offset, global->name);
7390 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7392 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7393 Ebl *ebl, GElf_Ehdr *ehdr,
7394 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7396 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7397 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7398 (uint64_t) shdr->sh_offset);
7401 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7404 /* Print the content of the DWARF string section '.debug_str'. */
7406 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7407 Ebl *ebl, GElf_Ehdr *ehdr,
7408 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7410 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7411 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7413 /* Compute floor(log16(shdr->sh_size)). */
7414 GElf_Addr tmp = sh_size;
7421 digits = MAX (4, digits);
7423 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7426 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7427 /* TRANS: the debugstr| prefix makes the string unique. */
7428 digits + 2, sgettext ("debugstr|Offset"));
7430 Dwarf_Off offset = 0;
7431 while (offset < sh_size)
7434 const char *str = dwarf_getstring (dbg, offset, &len);
7435 if (unlikely (str == NULL))
7437 printf (gettext (" *** error while reading strings: %s\n"),
7442 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7449 /* Print the content of the call frame search table section
7452 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7453 Ebl *ebl __attribute__ ((unused)),
7454 GElf_Ehdr *ehdr __attribute__ ((unused)),
7455 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7458 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7461 Elf_Data *data = elf_rawdata (scn, NULL);
7463 if (unlikely (data == NULL))
7465 error (0, 0, gettext ("cannot get %s content: %s"),
7466 ".eh_frame_hdr", elf_errmsg (-1));
7470 const unsigned char *readp = data->d_buf;
7471 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7474 if (unlikely (readp + 4 > dataend))
7477 error (0, 0, gettext ("invalid data"));
7481 unsigned int version = *readp++;
7482 unsigned int eh_frame_ptr_enc = *readp++;
7483 unsigned int fde_count_enc = *readp++;
7484 unsigned int table_enc = *readp++;
7486 printf (" version: %u\n"
7487 " eh_frame_ptr_enc: %#x ",
7488 version, eh_frame_ptr_enc);
7489 print_encoding_base ("", eh_frame_ptr_enc);
7490 printf (" fde_count_enc: %#x ", fde_count_enc);
7491 print_encoding_base ("", fde_count_enc);
7492 printf (" table_enc: %#x ", table_enc);
7493 print_encoding_base ("", table_enc);
7495 uint64_t eh_frame_ptr = 0;
7496 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7498 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7500 if (unlikely (readp == NULL))
7503 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7504 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7505 printf (" (offset: %#" PRIx64 ")",
7506 /* +4 because of the 4 byte header of the section. */
7507 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7509 putchar_unlocked ('\n');
7512 uint64_t fde_count = 0;
7513 if (fde_count_enc != DW_EH_PE_omit)
7515 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7516 if (unlikely (readp == NULL))
7519 printf (" fde_count: %" PRIu64 "\n", fde_count);
7522 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7527 /* Optimize for the most common case. */
7528 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7529 while (fde_count > 0 && readp + 8 <= dataend)
7531 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7532 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7533 + (int64_t) initial_location);
7534 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7535 // XXX Possibly print symbol name or section offset for initial_offset
7536 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7537 " fde=[%6" PRIx64 "]\n",
7538 initial_location, initial_offset,
7539 address, address - (eh_frame_ptr + 4));
7542 while (0 && readp < dataend)
7549 /* Print the content of the exception handling table section
7552 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7553 Ebl *ebl __attribute__ ((unused)),
7554 GElf_Ehdr *ehdr __attribute__ ((unused)),
7556 GElf_Shdr *shdr __attribute__ ((unused)),
7557 Dwarf *dbg __attribute__ ((unused)))
7560 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7563 Elf_Data *data = elf_rawdata (scn, NULL);
7565 if (unlikely (data == NULL))
7567 error (0, 0, gettext ("cannot get %s content: %s"),
7568 ".gcc_except_table", elf_errmsg (-1));
7572 const unsigned char *readp = data->d_buf;
7573 const unsigned char *const dataend = readp + data->d_size;
7575 if (unlikely (readp + 1 > dataend))
7578 error (0, 0, gettext ("invalid data"));
7581 unsigned int lpstart_encoding = *readp++;
7582 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7583 print_encoding_base ("", lpstart_encoding);
7584 if (lpstart_encoding != DW_EH_PE_omit)
7587 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7588 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7591 if (unlikely (readp + 1 > dataend))
7593 unsigned int ttype_encoding = *readp++;
7594 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7595 print_encoding_base ("", ttype_encoding);
7596 const unsigned char *ttype_base = NULL;
7597 if (ttype_encoding != DW_EH_PE_omit)
7599 unsigned int ttype_base_offset;
7600 get_uleb128 (ttype_base_offset, readp);
7601 printf (" TType base offset: %#x\n", ttype_base_offset);
7602 ttype_base = readp + ttype_base_offset;
7605 if (unlikely (readp + 1 > dataend))
7607 unsigned int call_site_encoding = *readp++;
7608 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7609 print_encoding_base ("", call_site_encoding);
7610 unsigned int call_site_table_len;
7611 get_uleb128 (call_site_table_len, readp);
7613 const unsigned char *const action_table = readp + call_site_table_len;
7614 if (unlikely (action_table > dataend))
7617 unsigned int max_action = 0;
7618 while (readp < action_table)
7621 puts (gettext ("\n Call site table:"));
7623 uint64_t call_site_start;
7624 readp = read_encoded (call_site_encoding, readp, dataend,
7625 &call_site_start, dbg);
7626 uint64_t call_site_length;
7627 readp = read_encoded (call_site_encoding, readp, dataend,
7628 &call_site_length, dbg);
7629 uint64_t landing_pad;
7630 readp = read_encoded (call_site_encoding, readp, dataend,
7632 unsigned int action;
7633 get_uleb128 (action, readp);
7634 max_action = MAX (action, max_action);
7635 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7636 " Call site length: %" PRIu64 "\n"
7637 " Landing pad: %#" PRIx64 "\n"
7639 u++, call_site_start, call_site_length, landing_pad, action);
7641 assert (readp == action_table);
7643 unsigned int max_ar_filter = 0;
7646 puts ("\n Action table:");
7648 const unsigned char *const action_table_end
7649 = action_table + max_action + 1;
7655 get_sleb128 (ar_filter, readp);
7656 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7657 max_ar_filter = ar_filter;
7659 get_sleb128 (ar_disp, readp);
7661 printf (" [%4u] ar_filter: % d\n"
7663 u, ar_filter, ar_disp);
7664 if (abs (ar_disp) & 1)
7665 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7666 else if (ar_disp != 0)
7669 putchar_unlocked ('\n');
7672 while (readp < action_table_end);
7675 if (max_ar_filter > 0)
7677 puts ("\n TType table:");
7679 // XXX Not *4, size of encoding;
7680 switch (ttype_encoding & 7)
7682 case DW_EH_PE_udata2:
7683 case DW_EH_PE_sdata2:
7684 readp = ttype_base - max_ar_filter * 2;
7686 case DW_EH_PE_udata4:
7687 case DW_EH_PE_sdata4:
7688 readp = ttype_base - max_ar_filter * 4;
7690 case DW_EH_PE_udata8:
7691 case DW_EH_PE_sdata8:
7692 readp = ttype_base - max_ar_filter * 8;
7695 error (1, 0, gettext ("invalid TType encoding"));
7701 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7703 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7705 while (readp < ttype_base);
7709 /* Print the content of the '.gdb_index' section.
7710 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7713 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7714 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7716 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7717 " contains %" PRId64 " bytes :\n"),
7718 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7719 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7721 Elf_Data *data = elf_rawdata (scn, NULL);
7723 if (unlikely (data == NULL))
7725 error (0, 0, gettext ("cannot get %s content: %s"),
7726 ".gdb_index", elf_errmsg (-1));
7730 // .gdb_index is always in little endian.
7731 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7734 const unsigned char *readp = data->d_buf;
7735 const unsigned char *const dataend = readp + data->d_size;
7737 if (unlikely (readp + 4 > dataend))
7740 error (0, 0, gettext ("invalid data"));
7744 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7745 printf (gettext (" Version: %" PRId32 "\n"), vers);
7747 // The only difference between version 4 and version 5 is the
7748 // hash used for generating the table. Version 6 contains symbols
7749 // for inlined functions, older versions didn't. Version 7 adds
7750 // symbol kinds. Version 8 just indicates that it correctly includes
7752 if (vers < 4 || vers > 8)
7754 printf (gettext (" unknown version, cannot parse section\n"));
7759 if (unlikely (readp + 4 > dataend))
7762 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7763 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7766 if (unlikely (readp + 4 > dataend))
7769 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7770 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7773 if (unlikely (readp + 4 > dataend))
7776 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7777 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
7780 if (unlikely (readp + 4 > dataend))
7783 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7784 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
7787 if (unlikely (readp + 4 > dataend))
7790 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7791 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7793 readp = data->d_buf + cu_off;
7795 const unsigned char *nextp = data->d_buf + tu_off;
7796 size_t cu_nr = (nextp - readp) / 16;
7798 printf (gettext ("\n CU list at offset %#" PRIx32
7799 " contains %zu entries:\n"),
7803 while (readp + 16 <= dataend && n < cu_nr)
7805 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7808 uint64_t len = read_8ubyte_unaligned (dbg, readp);
7811 printf (" [%4zu] start: %0#8" PRIx64
7812 ", length: %5" PRIu64 "\n", n, off, len);
7816 readp = data->d_buf + tu_off;
7817 nextp = data->d_buf + addr_off;
7818 size_t tu_nr = (nextp - readp) / 24;
7820 printf (gettext ("\n TU list at offset %#" PRIx32
7821 " contains %zu entries:\n"),
7825 while (readp + 24 <= dataend && n < tu_nr)
7827 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7830 uint64_t type = read_8ubyte_unaligned (dbg, readp);
7833 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7836 printf (" [%4zu] CU offset: %5" PRId64
7837 ", type offset: %5" PRId64
7838 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7842 readp = data->d_buf + addr_off;
7843 nextp = data->d_buf + sym_off;
7844 size_t addr_nr = (nextp - readp) / 20;
7846 printf (gettext ("\n Address list at offset %#" PRIx32
7847 " contains %zu entries:\n"),
7851 while (readp + 20 <= dataend && n < addr_nr)
7853 uint64_t low = read_8ubyte_unaligned (dbg, readp);
7856 uint64_t high = read_8ubyte_unaligned (dbg, readp);
7859 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7862 char *l = format_dwarf_addr (dwflmod, 8, low, low);
7863 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7864 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7871 readp = data->d_buf + sym_off;
7872 nextp = data->d_buf + const_off;
7873 size_t sym_nr = (nextp - readp) / 8;
7875 printf (gettext ("\n Symbol table at offset %#" PRIx32
7876 " contains %zu slots:\n"),
7880 while (readp + 8 <= dataend && n < sym_nr)
7882 uint32_t name = read_4ubyte_unaligned (dbg, readp);
7885 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7888 if (name != 0 || vector != 0)
7890 const unsigned char *sym = data->d_buf + const_off + name;
7891 if (unlikely (sym > dataend))
7894 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7896 const unsigned char *readcus = data->d_buf + const_off + vector;
7897 if (unlikely (readcus + 8 > dataend))
7900 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7903 uint32_t cu_kind, cu, kind;
7906 cu_kind = read_4ubyte_unaligned (dbg, readcus);
7907 cu = cu_kind & ((1 << 24) - 1);
7908 kind = (cu_kind >> 28) & 7;
7909 is_static = cu_kind & (1U << 31);
7911 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
7913 printf ("%" PRId32, cu);
7932 printf ("unknown-0x%" PRIx32, kind);
7935 printf (":%c)", (is_static ? 'S' : 'G'));
7947 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7949 /* Before we start the real work get a debug context descriptor. */
7951 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7955 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7959 if ((print_debug_sections & ~section_exception) != 0)
7960 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7962 if ((print_debug_sections & section_exception) == 0)
7967 /* Get the section header string table index. */
7969 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7970 error (EXIT_FAILURE, 0,
7971 gettext ("cannot get section header string table index"));
7973 /* Look through all the sections for the debugging sections to print. */
7974 Elf_Scn *scn = NULL;
7975 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7978 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7980 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7985 enum section_e bitmask;
7986 void (*fp) (Dwfl_Module *, Ebl *,
7987 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7988 } debug_sections[] =
7990 #define NEW_SECTION(name) \
7991 { ".debug_" #name, section_##name, print_debug_##name##_section }
7992 NEW_SECTION (abbrev),
7993 NEW_SECTION (aranges),
7994 NEW_SECTION (frame),
7996 NEW_SECTION (types),
7999 NEW_SECTION (pubnames),
8001 NEW_SECTION (macinfo),
8002 NEW_SECTION (macro),
8003 NEW_SECTION (ranges),
8004 { ".eh_frame", section_frame | section_exception,
8005 print_debug_frame_section },
8006 { ".eh_frame_hdr", section_frame | section_exception,
8007 print_debug_frame_hdr_section },
8008 { ".gcc_except_table", section_frame | section_exception,
8009 print_debug_exception_table },
8010 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8012 const int ndebug_sections = (sizeof (debug_sections)
8013 / sizeof (debug_sections[0]));
8014 const char *name = elf_strptr (ebl->elf, shstrndx,
8020 for (n = 0; n < ndebug_sections; ++n)
8021 if (strcmp (name, debug_sections[n].name) == 0
8023 || (name[0] == '.' && name[1] == 'z'
8024 && debug_sections[n].name[1] == 'd'
8025 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8029 if ((print_debug_sections | implicit_debug_sections)
8030 & debug_sections[n].bitmask)
8031 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8037 reset_listptr (&known_loclistptr);
8038 reset_listptr (&known_rangelistptr);
8042 #define ITEM_INDENT 4
8043 #define WRAP_COLUMN 75
8045 /* Print "NAME: FORMAT", wrapping when output text would make the line
8046 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8047 but this function is also used for registers which should be printed
8048 aligned. Fortunately registers output uses fixed fields width (such
8049 as %11d) for the alignment.
8051 Line breaks should not depend on the particular values although that
8052 may happen in some cases of the core items. */
8055 __attribute__ ((format (printf, 6, 7)))
8056 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8057 size_t name_width, const char *name, const char *format, ...)
8059 size_t len = strlen (name);
8060 if (name_width < len)
8065 va_start (ap, format);
8066 int out_len = vasprintf (&out, format, ap);
8069 error (EXIT_FAILURE, 0, _("memory exhausted"));
8071 size_t n = name_width + sizeof ": " - 1 + out_len;
8075 printf ("%*s", ITEM_INDENT, "");
8076 colno = ITEM_INDENT + n;
8078 else if (colno + 2 + n < wrap)
8080 printf ("%c ", sep);
8085 printf ("\n%*s", ITEM_INDENT, "");
8086 colno = ITEM_INDENT + n;
8089 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8097 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8098 void *value, const void *data, size_t size)
8100 Elf_Data valuedata =
8104 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8105 .d_version = EV_CURRENT,
8110 .d_buf = (void *) data,
8111 .d_size = valuedata.d_size,
8112 .d_version = EV_CURRENT,
8115 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8116 ? elf32_xlatetom : elf64_xlatetom)
8117 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8119 error (EXIT_FAILURE, 0,
8120 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8122 return data + indata.d_size;
8125 typedef uint8_t GElf_Byte;
8128 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8129 unsigned int colno, size_t *repeated_size)
8131 uint_fast16_t count = item->count ?: 1;
8134 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8135 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8136 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8137 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8138 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8139 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8141 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8142 union { TYPES; } value;
8145 void *data = &value;
8146 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8147 size_t convsize = size;
8148 if (repeated_size != NULL)
8150 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8152 data = alloca (*repeated_size);
8153 count *= *repeated_size / size;
8154 convsize = count * size;
8155 *repeated_size -= convsize;
8157 else if (item->count != 0 || item->format != '\n')
8158 *repeated_size -= size;
8161 convert (core, item->type, count, data, desc + item->offset, convsize);
8163 Elf_Type type = item->type;
8164 if (type == ELF_T_ADDR)
8165 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8167 switch (item->format)
8170 assert (count == 1);
8173 #define DO_TYPE(NAME, Name, hex, dec) \
8174 case ELF_T_##NAME: \
8175 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8176 0, item->name, dec, value.Name[0]); \
8186 assert (count == 1);
8189 #define DO_TYPE(NAME, Name, hex, dec) \
8190 case ELF_T_##NAME: \
8191 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8192 0, item->name, hex, value.Name[0]); \
8203 assert (size % sizeof (unsigned int) == 0);
8204 unsigned int nbits = count * size * 8;
8205 unsigned int pop = 0;
8206 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8207 pop += __builtin_popcount (*i);
8208 bool negate = pop > nbits / 2;
8209 const unsigned int bias = item->format == 'b';
8212 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8216 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8218 assert (size == sizeof (unsigned int) * 2);
8219 for (unsigned int *i = data;
8220 (void *) i < data + count * size; i += 2)
8222 unsigned int w = i[1];
8228 unsigned int lastbit = 0;
8229 unsigned int run = 0;
8230 for (const unsigned int *i = data;
8231 (void *) i < data + count * size; ++i)
8233 unsigned int bit = ((void *) i - data) * 8;
8234 unsigned int w = negate ? ~*i : *i;
8241 if (lastbit != 0 && lastbit + 1 == bit)
8246 p += sprintf (p, "%u", bit - bias);
8248 p += sprintf (p, ",%u", bit - bias);
8250 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8257 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8258 p += sprintf (p, "-%u", lastbit - bias);
8260 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8261 negate ? "~<%s>" : "<%s>", printed);
8266 case (char) ('T'|0x80):
8267 assert (count == 2);
8272 #define DO_TYPE(NAME, Name, hex, dec) \
8273 case ELF_T_##NAME: \
8274 sec = value.Name[0]; \
8275 usec = value.Name[1]; \
8282 if (unlikely (item->format == (char) ('T'|0x80)))
8284 /* This is a hack for an ill-considered 64-bit ABI where
8285 tv_usec is actually a 32-bit field with 32 bits of padding
8286 rounding out struct timeval. We've already converted it as
8287 a 64-bit field. For little-endian, this just means the
8288 high half is the padding; it's presumably zero, but should
8289 be ignored anyway. For big-endian, it means the 32-bit
8290 field went into the high half of USEC. */
8292 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8293 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8298 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8299 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8303 assert (count == 1);
8304 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8305 "%c", value.Byte[0]);
8309 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8310 "%.*s", (int) count, value.Byte);
8314 /* This is a list of strings separated by '\n'. */
8315 assert (item->count == 0);
8316 assert (repeated_size != NULL);
8317 assert (item->name == NULL);
8318 if (unlikely (item->offset >= *repeated_size))
8321 const char *s = desc + item->offset;
8322 size = *repeated_size - item->offset;
8326 const char *eol = memchr (s, '\n', size);
8330 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8333 size -= eol + 1 - s;
8337 colno = WRAP_COLUMN;
8344 error (0, 0, "XXX not handling format '%c' for %s",
8345 item->format, item->name);
8355 /* Sort items by group, and by layout offset within each group. */
8357 compare_core_items (const void *a, const void *b)
8359 const Ebl_Core_Item *const *p1 = a;
8360 const Ebl_Core_Item *const *p2 = b;
8361 const Ebl_Core_Item *item1 = *p1;
8362 const Ebl_Core_Item *item2 = *p2;
8364 return ((item1->group == item2->group ? 0
8365 : strcmp (item1->group, item2->group))
8366 ?: (int) item1->offset - (int) item2->offset);
8369 /* Sort item groups by layout offset of the first item in the group. */
8371 compare_core_item_groups (const void *a, const void *b)
8373 const Ebl_Core_Item *const *const *p1 = a;
8374 const Ebl_Core_Item *const *const *p2 = b;
8375 const Ebl_Core_Item *const *group1 = *p1;
8376 const Ebl_Core_Item *const *group2 = *p2;
8377 const Ebl_Core_Item *item1 = *group1;
8378 const Ebl_Core_Item *item2 = *group2;
8380 return (int) item1->offset - (int) item2->offset;
8384 handle_core_items (Elf *core, const void *desc, size_t descsz,
8385 const Ebl_Core_Item *items, size_t nitems)
8389 unsigned int colno = 0;
8391 /* FORMAT '\n' makes sense to be present only as a single item as it
8392 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8393 if present as a single item but they can be also processed with other
8395 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8396 || items[0].format == 'B'))
8398 assert (items[0].offset == 0);
8399 size_t size = descsz;
8400 colno = handle_core_item (core, items, desc, colno, &size);
8401 /* If SIZE is not zero here there is some remaining data. But we do not
8402 know how to process it anyway. */
8405 for (size_t i = 0; i < nitems; ++i)
8406 assert (items[i].format != '\n');
8408 /* Sort to collect the groups together. */
8409 const Ebl_Core_Item *sorted_items[nitems];
8410 for (size_t i = 0; i < nitems; ++i)
8411 sorted_items[i] = &items[i];
8412 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8414 /* Collect the unique groups and sort them. */
8415 const Ebl_Core_Item **groups[nitems];
8416 groups[0] = &sorted_items[0];
8418 for (size_t i = 1; i < nitems; ++i)
8419 if (sorted_items[i]->group != sorted_items[i - 1]->group
8420 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8421 groups[ngroups++] = &sorted_items[i];
8422 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8424 /* Write out all the groups. */
8425 const void *last = desc;
8428 for (size_t i = 0; i < ngroups; ++i)
8430 for (const Ebl_Core_Item **item = groups[i];
8431 (item < &sorted_items[nitems]
8432 && ((*item)->group == groups[i][0]->group
8433 || !strcmp ((*item)->group, groups[i][0]->group)));
8435 colno = handle_core_item (core, *item, desc, colno, NULL);
8437 /* Force a line break at the end of the group. */
8438 colno = WRAP_COLUMN;
8444 /* This set of items consumed a certain amount of the note's data.
8445 If there is more data there, we have another unit of the same size.
8446 Loop to print that out too. */
8447 const Ebl_Core_Item *item = &items[nitems - 1];
8448 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8449 item->count ?: 1, EV_CURRENT);
8458 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8462 /* For just one repeat, print it unabridged twice. */
8467 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8468 ITEM_INDENT, "", reps);
8478 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8481 desc += regloc->offset;
8489 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8490 const Ebl_Register_Location *regloc, const void *desc,
8493 if (regloc->bits % 8 != 0)
8494 return handle_bit_registers (regloc, desc, colno);
8496 desc += regloc->offset;
8498 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8500 char name[REGNAMESZ];
8503 register_info (ebl, reg, regloc, name, &bits, &type);
8506 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8507 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8508 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8509 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8511 #define BITS(bits, xtype, sfmt, ufmt) \
8512 uint##bits##_t b##bits; int##bits##_t b##bits##s
8513 union { TYPES; uint64_t b128[2]; } value;
8518 case DW_ATE_unsigned:
8520 case DW_ATE_address:
8523 #define BITS(bits, xtype, sfmt, ufmt) \
8525 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8526 if (type == DW_ATE_signed) \
8527 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8529 sfmt, value.b##bits##s); \
8531 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8533 ufmt, value.b##bits); \
8539 assert (type == DW_ATE_unsigned);
8540 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8541 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8542 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8544 "0x%.16" PRIx64 "%.16" PRIx64,
8545 value.b128[!be], value.b128[be]);
8555 /* Print each byte in hex, the whole thing in native byte order. */
8556 assert (bits % 8 == 0);
8557 const uint8_t *bytes = desc;
8559 char hex[bits / 4 + 1];
8560 hex[bits / 4] = '\0';
8562 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8564 bytes += bits / 8 - 1;
8568 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8570 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8571 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8573 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8574 maxregname, name, "0x%s", hex);
8577 desc += regloc->pad;
8586 struct register_info
8588 const Ebl_Register_Location *regloc;
8590 char name[REGNAMESZ];
8597 register_bitpos (const struct register_info *r)
8599 return (r->regloc->offset * 8
8600 + ((r->regno - r->regloc->regno)
8601 * (r->regloc->bits + r->regloc->pad * 8)));
8605 compare_sets_by_info (const struct register_info *r1,
8606 const struct register_info *r2)
8608 return ((int) r2->bits - (int) r1->bits
8609 ?: register_bitpos (r1) - register_bitpos (r2));
8612 /* Sort registers by set, and by size and layout offset within each set. */
8614 compare_registers (const void *a, const void *b)
8616 const struct register_info *r1 = a;
8617 const struct register_info *r2 = b;
8619 /* Unused elements sort last. */
8620 if (r1->regloc == NULL)
8621 return r2->regloc == NULL ? 0 : 1;
8622 if (r2->regloc == NULL)
8625 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8626 ?: compare_sets_by_info (r1, r2));
8629 /* Sort register sets by layout offset of the first register in the set. */
8631 compare_register_sets (const void *a, const void *b)
8633 const struct register_info *const *p1 = a;
8634 const struct register_info *const *p2 = b;
8635 return compare_sets_by_info (*p1, *p2);
8639 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8640 const Ebl_Register_Location *reglocs, size_t nregloc)
8645 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8648 for (size_t i = 0; i < nregloc; ++i)
8649 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8650 maxnreg = reglocs[i].regno + reglocs[i].count;
8651 assert (maxnreg > 0);
8654 struct register_info regs[maxnreg];
8655 memset (regs, 0, sizeof regs);
8657 /* Sort to collect the sets together. */
8659 for (size_t i = 0; i < nregloc; ++i)
8660 for (int reg = reglocs[i].regno;
8661 reg < reglocs[i].regno + reglocs[i].count;
8664 assert (reg < maxnreg);
8667 struct register_info *info = ®s[reg];
8668 info->regloc = ®locs[i];
8670 info->set = register_info (ebl, reg, ®locs[i],
8671 info->name, &info->bits, &info->type);
8673 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8675 /* Collect the unique sets and sort them. */
8676 inline bool same_set (const struct register_info *a,
8677 const struct register_info *b)
8679 return (a < ®s[maxnreg] && a->regloc != NULL
8680 && b < ®s[maxnreg] && b->regloc != NULL
8681 && a->bits == b->bits
8682 && (a->set == b->set || !strcmp (a->set, b->set)));
8684 struct register_info *sets[maxreg + 1];
8687 for (int i = 1; i <= maxreg; ++i)
8688 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8689 sets[nsets++] = ®s[i];
8690 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8692 /* Write out all the sets. */
8693 unsigned int colno = 0;
8694 for (size_t i = 0; i < nsets; ++i)
8696 /* Find the longest name of a register in this set. */
8698 const struct register_info *end;
8699 for (end = sets[i]; same_set (sets[i], end); ++end)
8701 size_t len = strlen (end->name);
8706 for (const struct register_info *reg = sets[i];
8708 reg += reg->regloc->count ?: 1)
8709 colno = handle_core_register (ebl, core, maxname,
8710 reg->regloc, desc, colno);
8712 /* Force a line break at the end of the group. */
8713 colno = WRAP_COLUMN;
8720 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8722 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8725 error (EXIT_FAILURE, 0,
8726 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8728 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8729 for (size_t i = 0; i < nauxv; ++i)
8732 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8738 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8741 if (av->a_un.a_val == 0)
8742 printf (" %" PRIu64 "\n", av->a_type);
8744 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8745 av->a_type, av->a_un.a_val);
8750 case '\0': /* Normally zero. */
8751 if (av->a_un.a_val == 0)
8753 printf (" %s\n", name);
8758 case 'p': /* address */
8759 case 's': /* address of string */
8760 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8763 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8766 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8770 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8772 const char *pfx = "<";
8773 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8775 if (av->a_un.a_val & bit)
8777 printf ("%s%s", pfx, p);
8792 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8794 return ptr < end && (size_t) (end - ptr) >= sz;
8798 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8801 if (! buf_has_data (*ptrp, end, 4))
8804 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8809 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8812 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8813 if (! buf_has_data (*ptrp, end, sz))
8822 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
8832 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8834 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8836 error (EXIT_FAILURE, 0,
8837 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8839 unsigned char const *ptr = data->d_buf;
8840 unsigned char const *const end = data->d_buf + data->d_size;
8842 /* Siginfo head is three ints: signal number, error number, origin
8844 int si_signo, si_errno, si_code;
8845 if (! buf_read_int (core, &ptr, end, &si_signo)
8846 || ! buf_read_int (core, &ptr, end, &si_errno)
8847 || ! buf_read_int (core, &ptr, end, &si_code))
8850 printf (" Not enough data in NT_SIGINFO note.\n");
8854 /* Next is a pointer-aligned union of structures. On 64-bit
8855 machines, that implies a word of padding. */
8856 if (gelf_getclass (core) == ELFCLASS64)
8859 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
8860 si_signo, si_errno, si_code);
8871 if (! buf_read_ulong (core, &ptr, end, &addr))
8873 printf (" fault address: %#" PRIx64 "\n", addr);
8879 else if (si_code == SI_USER)
8882 if (! buf_read_int (core, &ptr, end, &pid)
8883 || ! buf_read_int (core, &ptr, end, &uid))
8885 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
8890 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8892 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8894 error (EXIT_FAILURE, 0,
8895 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8897 unsigned char const *ptr = data->d_buf;
8898 unsigned char const *const end = data->d_buf + data->d_size;
8900 uint64_t count, page_size;
8901 if (! buf_read_ulong (core, &ptr, end, &count)
8902 || ! buf_read_ulong (core, &ptr, end, &page_size))
8905 printf (" Not enough data in NT_FILE note.\n");
8909 /* Where file names are stored. */
8910 unsigned char const *const fstart
8911 = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8912 char const *fptr = (char *) fstart;
8914 printf (" %" PRId64 " files:\n", count);
8915 for (uint64_t i = 0; i < count; ++i)
8917 uint64_t mstart, mend, moffset;
8918 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
8919 || ! buf_read_ulong (core, &ptr, fstart, &mend)
8920 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
8923 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
8927 int ct = printf (" %08" PRIx64 "-%08" PRIx64
8928 " %08" PRIx64 " %" PRId64,
8929 mstart, mend, moffset * page_size, mend - mstart);
8930 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
8937 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8938 const char *name, const void *desc)
8940 GElf_Word regs_offset;
8942 const Ebl_Register_Location *reglocs;
8944 const Ebl_Core_Item *items;
8946 if (! ebl_core_note (ebl, nhdr, name,
8947 ®s_offset, &nregloc, ®locs, &nitems, &items))
8950 /* Pass 0 for DESCSZ when there are registers in the note,
8951 so that the ITEMS array does not describe the whole thing.
8952 For non-register notes, the actual descsz might be a multiple
8953 of the unit size, not just exactly the unit size. */
8954 unsigned int colno = handle_core_items (ebl->elf, desc,
8955 nregloc == 0 ? nhdr->n_descsz : 0,
8958 putchar_unlocked ('\n');
8960 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8963 putchar_unlocked ('\n');
8967 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8968 GElf_Off start, Elf_Data *data)
8970 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
8979 while (offset < data->d_size
8980 && (offset = gelf_getnote (data, offset,
8981 &nhdr, &name_offset, &desc_offset)) > 0)
8983 const char *name = data->d_buf + name_offset;
8984 const char *desc = data->d_buf + desc_offset;
8988 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
8989 (int) nhdr.n_namesz, name, nhdr.n_descsz,
8990 ehdr->e_type == ET_CORE
8991 ? ebl_core_note_type_name (ebl, nhdr.n_type,
8993 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8994 buf2, sizeof (buf2)));
8996 /* Filter out invalid entries. */
8997 if (memchr (name, '\0', nhdr.n_namesz) != NULL
8998 /* XXX For now help broken Linux kernels. */
9001 if (ehdr->e_type == ET_CORE)
9003 if (nhdr.n_type == NT_AUXV
9004 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9005 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9006 && !memcmp (name, "CORE", 4))
9007 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9008 start + desc_offset);
9009 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9010 switch (nhdr.n_type)
9013 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9014 start + desc_offset);
9018 handle_file_note (ebl->elf, nhdr.n_descsz,
9019 start + desc_offset);
9023 handle_core_note (ebl, &nhdr, name, desc);
9026 handle_core_note (ebl, &nhdr, name, desc);
9029 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9033 if (offset == data->d_size)
9037 error (EXIT_FAILURE, 0,
9038 gettext ("cannot get content of note section: %s"),
9043 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9045 /* If we have section headers, just look for SHT_NOTE sections.
9046 In a debuginfo file, the program headers are not reliable. */
9049 /* Get the section header string table index. */
9051 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9052 error (EXIT_FAILURE, 0,
9053 gettext ("cannot get section header string table index"));
9055 Elf_Scn *scn = NULL;
9056 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9059 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9061 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9062 /* Not what we are looking for. */
9066 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9068 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9069 shdr->sh_size, shdr->sh_offset);
9071 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9072 elf_getdata (scn, NULL));
9077 /* We have to look through the program header to find the note
9078 sections. There can be more than one. */
9079 for (size_t cnt = 0; cnt < phnum; ++cnt)
9082 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9084 if (phdr == NULL || phdr->p_type != PT_NOTE)
9085 /* Not what we are looking for. */
9089 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9090 phdr->p_filesz, phdr->p_offset);
9092 handle_notes_data (ebl, ehdr, phdr->p_offset,
9093 elf_getdata_rawchunk (ebl->elf,
9094 phdr->p_offset, phdr->p_filesz,
9101 hex_dump (const uint8_t *data, size_t len)
9106 printf (" 0x%08Zx ", pos);
9108 const size_t chunk = MIN (len - pos, 16);
9110 for (size_t i = 0; i < chunk; ++i)
9112 printf ("%02x ", data[pos + i]);
9114 printf ("%02x", data[pos + i]);
9117 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9119 for (size_t i = 0; i < chunk; ++i)
9121 unsigned char b = data[pos + i];
9122 printf ("%c", isprint (b) ? b : '.');
9131 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9133 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9134 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9135 elf_ndxscn (scn), name);
9138 Elf_Data *data = elf_rawdata (scn, NULL);
9140 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9141 elf_ndxscn (scn), name, elf_errmsg (-1));
9144 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9145 " bytes at offset %#0" PRIx64 ":\n"),
9146 elf_ndxscn (scn), name,
9147 shdr->sh_size, shdr->sh_offset);
9148 hex_dump (data->d_buf, data->d_size);
9154 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9156 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9157 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9158 elf_ndxscn (scn), name);
9161 Elf_Data *data = elf_rawdata (scn, NULL);
9163 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9164 elf_ndxscn (scn), name, elf_errmsg (-1));
9167 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9168 " bytes at offset %#0" PRIx64 ":\n"),
9169 elf_ndxscn (scn), name,
9170 shdr->sh_size, shdr->sh_offset);
9172 const char *start = data->d_buf;
9173 const char *const limit = start + data->d_size;
9176 const char *end = memchr (start, '\0', limit - start);
9177 const size_t pos = start - (const char *) data->d_buf;
9178 if (unlikely (end == NULL))
9180 printf (" [%6Zx]- %.*s\n",
9181 pos, (int) (limit - start), start);
9184 printf (" [%6Zx] %s\n", pos, start);
9186 } while (start < limit);
9192 for_each_section_argument (Elf *elf, const struct section_argument *list,
9193 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9196 /* Get the section header string table index. */
9198 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9199 error (EXIT_FAILURE, 0,
9200 gettext ("cannot get section header string table index"));
9202 for (const struct section_argument *a = list; a != NULL; a = a->next)
9206 const char *name = NULL;
9209 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9210 if (endp != a->arg && *endp == '\0')
9212 scn = elf_getscn (elf, shndx);
9215 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9219 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9220 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9222 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9226 /* Need to look up the section by name. */
9229 while ((scn = elf_nextscn (elf, scn)) != NULL)
9231 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9233 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9236 if (!strcmp (name, a->arg))
9239 (*dump) (scn, &shdr_mem, name);
9243 if (unlikely (!found) && !a->implicit)
9244 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9250 dump_data (Ebl *ebl)
9252 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9256 dump_strings (Ebl *ebl)
9258 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9262 print_strings (Ebl *ebl)
9264 /* Get the section header string table index. */
9266 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9267 error (EXIT_FAILURE, 0,
9268 gettext ("cannot get section header string table index"));
9274 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9276 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9279 if (shdr_mem.sh_type != SHT_PROGBITS
9280 || !(shdr_mem.sh_flags & SHF_STRINGS))
9283 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9287 print_string_section (scn, &shdr_mem, name);
9292 dump_archive_index (Elf *elf, const char *fname)
9295 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9298 int result = elf_errno ();
9299 if (unlikely (result != ELF_E_NO_INDEX))
9300 error (EXIT_FAILURE, 0,
9301 gettext ("cannot get symbol index of archive '%s': %s"),
9302 fname, elf_errmsg (result));
9304 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9308 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9312 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9314 if (s->as_off != as_off)
9319 if (unlikely (elf_rand (elf, as_off) == 0)
9320 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9322 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9325 error (EXIT_FAILURE, 0,
9326 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9327 as_off, fname, elf_errmsg (-1));
9329 const Elf_Arhdr *h = elf_getarhdr (subelf);
9331 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9336 printf ("\t%s\n", s->as_name);
9340 #include "debugpred.h"