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 printf (ngettext ("\
1975 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1977 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1980 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1981 (unsigned int) shdr->sh_info,
1982 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1985 fputs_unlocked (class == ELFCLASS32
1987 Offset Type Value Addend Name\n")
1989 Offset Type Value Addend Name\n"),
1992 int is_statically_linked = 0;
1993 for (int cnt = 0; cnt < nentries; ++cnt)
1996 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
1997 if (likely (rel != NULL))
2002 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2003 GELF_R_SYM (rel->r_info),
2006 if (unlikely (sym == NULL))
2008 /* As a special case we have to handle relocations in static
2009 executables. This only happens for IRELATIVE relocations
2010 (so far). There is no symbol table. */
2011 if (is_statically_linked == 0)
2013 /* Find the program header and look for a PT_INTERP entry. */
2014 is_statically_linked = -1;
2015 if (ehdr->e_type == ET_EXEC)
2017 is_statically_linked = 1;
2019 for (size_t inner = 0; inner < phnum; ++inner)
2022 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2024 if (phdr != NULL && phdr->p_type == PT_INTERP)
2026 is_statically_linked = -1;
2033 if (is_statically_linked > 0 && shdr->sh_link == 0)
2035 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2036 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2037 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2038 /* Avoid the leading R_ which isn't carrying any
2040 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2041 buf, sizeof (buf)) + 2
2042 : gettext ("<INVALID RELOC>"),
2043 class == ELFCLASS32 ? 10 : 18, "",
2045 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2047 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2048 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2049 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2050 /* Avoid the leading R_ which isn't carrying any
2052 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2053 buf, sizeof (buf)) + 2
2054 : gettext ("<INVALID RELOC>"),
2055 gettext ("INVALID SYMBOL"),
2056 (long int) GELF_R_SYM (rel->r_info));
2058 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2060 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2061 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2062 likely (ebl_reloc_type_check (ebl,
2063 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 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2071 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2074 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
2075 sym->st_shndx == SHN_XINDEX
2076 ? xndx : sym->st_shndx),
2079 if (unlikely (shdr == NULL))
2080 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2081 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2082 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2083 /* Avoid the leading R_ which isn't carrying any
2085 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2086 buf, sizeof (buf)) + 2
2087 : gettext ("<INVALID RELOC>"),
2088 gettext ("INVALID SECTION"),
2089 (long int) (sym->st_shndx == SHN_XINDEX
2090 ? xndx : sym->st_shndx));
2093 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2094 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2095 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2096 /* Avoid the leading R_ which isn't carrying any
2098 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2099 buf, sizeof (buf)) + 2
2100 : gettext ("<INVALID RELOC>"),
2101 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2103 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2110 /* Print the program header. */
2112 print_symtab (Ebl *ebl, int type)
2114 /* Find the symbol table(s). For this we have to search through the
2116 Elf_Scn *scn = NULL;
2118 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2120 /* Handle the section if it is a symbol table. */
2122 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2124 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2125 handle_symtab (ebl, scn, shdr);
2131 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2133 Elf_Data *versym_data = NULL;
2134 Elf_Data *verneed_data = NULL;
2135 Elf_Data *verdef_data = NULL;
2136 Elf_Data *xndx_data = NULL;
2137 int class = gelf_getclass (ebl->elf);
2138 Elf32_Word verneed_stridx = 0;
2139 Elf32_Word verdef_stridx = 0;
2141 /* Get the data of the section. */
2142 Elf_Data *data = elf_getdata (scn, NULL);
2146 /* Find out whether we have other sections we might need. */
2147 Elf_Scn *runscn = NULL;
2148 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2150 GElf_Shdr runshdr_mem;
2151 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2153 if (likely (runshdr != NULL))
2155 if (runshdr->sh_type == SHT_GNU_versym
2156 && runshdr->sh_link == elf_ndxscn (scn))
2157 /* Bingo, found the version information. Now get the data. */
2158 versym_data = elf_getdata (runscn, NULL);
2159 else if (runshdr->sh_type == SHT_GNU_verneed)
2161 /* This is the information about the needed versions. */
2162 verneed_data = elf_getdata (runscn, NULL);
2163 verneed_stridx = runshdr->sh_link;
2165 else if (runshdr->sh_type == SHT_GNU_verdef)
2167 /* This is the information about the defined versions. */
2168 verdef_data = elf_getdata (runscn, NULL);
2169 verdef_stridx = runshdr->sh_link;
2171 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2172 && runshdr->sh_link == elf_ndxscn (scn))
2173 /* Extended section index. */
2174 xndx_data = elf_getdata (runscn, NULL);
2178 /* Get the section header string table index. */
2180 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2181 error (EXIT_FAILURE, 0,
2182 gettext ("cannot get section header string table index"));
2184 GElf_Shdr glink_mem;
2185 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2188 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2191 /* Now we can compute the number of entries in the section. */
2192 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2193 ? sizeof (Elf32_Sym)
2194 : sizeof (Elf64_Sym));
2196 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2197 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2199 (unsigned int) elf_ndxscn (scn),
2200 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2201 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2202 " %lu local symbols String table: [%2u] '%s'\n",
2204 (unsigned long int) shdr->sh_info,
2205 (unsigned int) shdr->sh_link,
2206 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2208 fputs_unlocked (class == ELFCLASS32
2210 Num: Value Size Type Bind Vis Ndx Name\n")
2212 Num: Value Size Type Bind Vis Ndx Name\n"),
2215 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2222 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2224 if (unlikely (sym == NULL))
2227 /* Determine the real section index. */
2228 if (likely (sym->st_shndx != SHN_XINDEX))
2229 xndx = sym->st_shndx;
2232 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2234 class == ELFCLASS32 ? 8 : 16,
2237 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2238 typebuf, sizeof (typebuf)),
2239 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2240 bindbuf, sizeof (bindbuf)),
2241 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2242 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2243 sizeof (scnbuf), NULL, shnum),
2244 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2246 if (versym_data != NULL)
2248 /* Get the version information. */
2249 GElf_Versym versym_mem;
2250 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2252 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2254 bool is_nobits = false;
2255 bool check_def = xndx != SHN_UNDEF;
2257 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2259 GElf_Shdr symshdr_mem;
2260 GElf_Shdr *symshdr =
2261 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2263 is_nobits = (symshdr != NULL
2264 && symshdr->sh_type == SHT_NOBITS);
2267 if (is_nobits || ! check_def)
2269 /* We must test both. */
2270 GElf_Vernaux vernaux_mem;
2271 GElf_Vernaux *vernaux = NULL;
2272 size_t vn_offset = 0;
2274 GElf_Verneed verneed_mem;
2275 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2277 while (verneed != NULL)
2279 size_t vna_offset = vn_offset;
2281 vernaux = gelf_getvernaux (verneed_data,
2282 vna_offset += verneed->vn_aux,
2284 while (vernaux != NULL
2285 && vernaux->vna_other != *versym
2286 && vernaux->vna_next != 0)
2288 /* Update the offset. */
2289 vna_offset += vernaux->vna_next;
2291 vernaux = (vernaux->vna_next == 0
2293 : gelf_getvernaux (verneed_data,
2298 /* Check whether we found the version. */
2299 if (vernaux != NULL && vernaux->vna_other == *versym)
2303 vn_offset += verneed->vn_next;
2304 verneed = (verneed->vn_next == 0
2306 : gelf_getverneed (verneed_data, vn_offset,
2310 if (vernaux != NULL && vernaux->vna_other == *versym)
2313 elf_strptr (ebl->elf, verneed_stridx,
2315 (unsigned int) vernaux->vna_other);
2318 else if (unlikely (! is_nobits))
2319 error (0, 0, gettext ("bad dynamic symbol"));
2324 if (check_def && *versym != 0x8001)
2326 /* We must test both. */
2327 size_t vd_offset = 0;
2329 GElf_Verdef verdef_mem;
2330 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2332 while (verdef != NULL)
2334 if (verdef->vd_ndx == (*versym & 0x7fff))
2335 /* Found the definition. */
2338 vd_offset += verdef->vd_next;
2339 verdef = (verdef->vd_next == 0
2341 : gelf_getverdef (verdef_data, vd_offset,
2347 GElf_Verdaux verdaux_mem;
2348 GElf_Verdaux *verdaux
2349 = gelf_getverdaux (verdef_data,
2350 vd_offset + verdef->vd_aux,
2353 if (verdaux != NULL)
2354 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2355 elf_strptr (ebl->elf, verdef_stridx,
2356 verdaux->vda_name));
2362 putchar_unlocked ('\n');
2367 /* Print version information. */
2369 print_verinfo (Ebl *ebl)
2371 /* Find the version information sections. For this we have to
2372 search through the section table. */
2373 Elf_Scn *scn = NULL;
2375 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2377 /* Handle the section if it is part of the versioning handling. */
2379 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2381 if (likely (shdr != NULL))
2383 if (shdr->sh_type == SHT_GNU_verneed)
2384 handle_verneed (ebl, scn, shdr);
2385 else if (shdr->sh_type == SHT_GNU_verdef)
2386 handle_verdef (ebl, scn, shdr);
2387 else if (shdr->sh_type == SHT_GNU_versym)
2388 handle_versym (ebl, scn, shdr);
2395 get_ver_flags (unsigned int flags)
2397 static char buf[32];
2401 return gettext ("none");
2403 if (flags & VER_FLG_BASE)
2404 endp = stpcpy (buf, "BASE ");
2408 if (flags & VER_FLG_WEAK)
2411 endp = stpcpy (endp, "| ");
2413 endp = stpcpy (endp, "WEAK ");
2416 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2418 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2419 buf[sizeof (buf) - 1] = '\0';
2427 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2429 int class = gelf_getclass (ebl->elf);
2431 /* Get the data of the section. */
2432 Elf_Data *data = elf_getdata (scn, NULL);
2436 /* Get the section header string table index. */
2438 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2439 error (EXIT_FAILURE, 0,
2440 gettext ("cannot get section header string table index"));
2442 GElf_Shdr glink_mem;
2443 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2446 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2449 printf (ngettext ("\
2450 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2452 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2454 (unsigned int) elf_ndxscn (scn),
2455 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2456 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2458 (unsigned int) shdr->sh_link,
2459 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2461 unsigned int offset = 0;
2462 for (int cnt = shdr->sh_info; --cnt >= 0; )
2464 /* Get the data at the next offset. */
2465 GElf_Verneed needmem;
2466 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2467 if (unlikely (need == NULL))
2470 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2471 offset, (unsigned short int) need->vn_version,
2472 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2473 (unsigned short int) need->vn_cnt);
2475 unsigned int auxoffset = offset + need->vn_aux;
2476 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2478 GElf_Vernaux auxmem;
2479 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2480 if (unlikely (aux == NULL))
2483 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2485 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2486 get_ver_flags (aux->vna_flags),
2487 (unsigned short int) aux->vna_other);
2489 auxoffset += aux->vna_next;
2492 /* Find the next offset. */
2493 offset += need->vn_next;
2499 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2501 /* Get the data of the section. */
2502 Elf_Data *data = elf_getdata (scn, NULL);
2506 /* Get the section header string table index. */
2508 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2509 error (EXIT_FAILURE, 0,
2510 gettext ("cannot get section header string table index"));
2512 GElf_Shdr glink_mem;
2513 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2516 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2519 int class = gelf_getclass (ebl->elf);
2520 printf (ngettext ("\
2521 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2523 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2525 (unsigned int) elf_ndxscn (scn),
2526 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2528 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2530 (unsigned int) shdr->sh_link,
2531 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2533 unsigned int offset = 0;
2534 for (int cnt = shdr->sh_info; --cnt >= 0; )
2536 /* Get the data at the next offset. */
2538 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2539 if (unlikely (def == NULL))
2542 unsigned int auxoffset = offset + def->vd_aux;
2543 GElf_Verdaux auxmem;
2544 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2545 if (unlikely (aux == NULL))
2549 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2550 offset, def->vd_version,
2551 get_ver_flags (def->vd_flags),
2554 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2556 auxoffset += aux->vda_next;
2557 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2559 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2560 if (unlikely (aux == NULL))
2563 printf (gettext (" %#06x: Parent %d: %s\n"),
2565 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2567 auxoffset += aux->vda_next;
2570 /* Find the next offset. */
2571 offset += def->vd_next;
2577 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2579 int class = gelf_getclass (ebl->elf);
2580 const char **vername;
2581 const char **filename;
2583 /* Get the data of the section. */
2584 Elf_Data *data = elf_getdata (scn, NULL);
2588 /* Get the section header string table index. */
2590 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2591 error (EXIT_FAILURE, 0,
2592 gettext ("cannot get section header string table index"));
2594 /* We have to find the version definition section and extract the
2596 Elf_Scn *defscn = NULL;
2597 Elf_Scn *needscn = NULL;
2599 Elf_Scn *verscn = NULL;
2600 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2602 GElf_Shdr vershdr_mem;
2603 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2605 if (likely (vershdr != NULL))
2607 if (vershdr->sh_type == SHT_GNU_verdef)
2609 else if (vershdr->sh_type == SHT_GNU_verneed)
2615 if (defscn != NULL || needscn != NULL)
2617 /* We have a version information (better should have). Now get
2618 the version names. First find the maximum version number. */
2622 /* Run through the version definitions and find the highest
2624 unsigned int offset = 0;
2626 GElf_Shdr defshdrmem;
2629 defdata = elf_getdata (defscn, NULL);
2630 if (unlikely (defdata == NULL))
2633 defshdr = gelf_getshdr (defscn, &defshdrmem);
2634 if (unlikely (defshdr == NULL))
2637 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2642 /* Get the data at the next offset. */
2643 def = gelf_getverdef (defdata, offset, &defmem);
2644 if (unlikely (def == NULL))
2647 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2649 offset += def->vd_next;
2652 if (needscn != NULL)
2654 unsigned int offset = 0;
2656 GElf_Shdr needshdrmem;
2657 GElf_Shdr *needshdr;
2659 needdata = elf_getdata (needscn, NULL);
2660 if (unlikely (needdata == NULL))
2663 needshdr = gelf_getshdr (needscn, &needshdrmem);
2664 if (unlikely (needshdr == NULL))
2667 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2669 GElf_Verneed needmem;
2671 unsigned int auxoffset;
2674 /* Get the data at the next offset. */
2675 need = gelf_getverneed (needdata, offset, &needmem);
2676 if (unlikely (need == NULL))
2679 /* Run through the auxiliary entries. */
2680 auxoffset = offset + need->vn_aux;
2681 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2683 GElf_Vernaux auxmem;
2686 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2687 if (unlikely (aux == NULL))
2690 nvername = MAX (nvername,
2691 (size_t) (aux->vna_other & 0x7fff));
2693 auxoffset += aux->vna_next;
2696 offset += need->vn_next;
2700 /* This is the number of versions we know about. */
2703 /* Allocate the array. */
2704 vername = (const char **) alloca (nvername * sizeof (const char *));
2705 filename = (const char **) alloca (nvername * sizeof (const char *));
2707 /* Run through the data structures again and collect the strings. */
2710 /* Run through the version definitions and find the highest
2712 unsigned int offset = 0;
2714 GElf_Shdr defshdrmem;
2717 defdata = elf_getdata (defscn, NULL);
2718 if (unlikely (defdata == NULL))
2721 defshdr = gelf_getshdr (defscn, &defshdrmem);
2722 if (unlikely (defshdr == NULL))
2725 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2728 /* Get the data at the next offset. */
2730 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2731 GElf_Verdaux auxmem;
2732 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2733 offset + def->vd_aux,
2735 if (unlikely (def == NULL || aux == NULL))
2738 vername[def->vd_ndx & 0x7fff]
2739 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2740 filename[def->vd_ndx & 0x7fff] = NULL;
2742 offset += def->vd_next;
2745 if (needscn != NULL)
2747 unsigned int offset = 0;
2749 Elf_Data *needdata = elf_getdata (needscn, NULL);
2750 GElf_Shdr needshdrmem;
2751 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2752 if (unlikely (needdata == NULL || needshdr == NULL))
2755 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2757 /* Get the data at the next offset. */
2758 GElf_Verneed needmem;
2759 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2761 if (unlikely (need == NULL))
2764 /* Run through the auxiliary entries. */
2765 unsigned int auxoffset = offset + need->vn_aux;
2766 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2768 GElf_Vernaux auxmem;
2769 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2771 if (unlikely (aux == NULL))
2774 vername[aux->vna_other & 0x7fff]
2775 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2776 filename[aux->vna_other & 0x7fff]
2777 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2779 auxoffset += aux->vna_next;
2782 offset += need->vn_next;
2793 GElf_Shdr glink_mem;
2794 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2796 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2798 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2801 /* Print the header. */
2802 printf (ngettext ("\
2803 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2805 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2806 shdr->sh_size / sh_entsize),
2807 (unsigned int) elf_ndxscn (scn),
2808 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2809 (int) (shdr->sh_size / sh_entsize),
2810 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2812 (unsigned int) shdr->sh_link,
2813 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2815 /* Now we can finally look at the actual contents of this section. */
2816 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2819 printf ("\n %4d:", cnt);
2822 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2830 fputs_unlocked (gettext (" 0 *local* "),
2835 fputs_unlocked (gettext (" 1 *global* "),
2840 n = printf ("%4d%c%s",
2841 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2842 (unsigned int) (*sym & 0x7fff) < nvername
2843 ? vername[*sym & 0x7fff] : "???");
2844 if ((unsigned int) (*sym & 0x7fff) < nvername
2845 && filename[*sym & 0x7fff] != NULL)
2846 n += printf ("(%s)", filename[*sym & 0x7fff]);
2847 printf ("%*s", MAX (0, 33 - (int) n), " ");
2851 putchar_unlocked ('\n');
2856 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2857 uint_fast32_t maxlength, Elf32_Word nbucket,
2858 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2860 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2862 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2863 ++counts[lengths[cnt]];
2865 GElf_Shdr glink_mem;
2866 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2871 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2876 printf (ngettext ("\
2877 \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",
2879 \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",
2881 (unsigned int) elf_ndxscn (scn),
2882 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2884 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2887 (unsigned int) shdr->sh_link,
2888 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2890 if (extrastr != NULL)
2891 fputs (extrastr, stdout);
2893 if (likely (nbucket > 0))
2895 uint64_t success = 0;
2897 /* xgettext:no-c-format */
2898 fputs_unlocked (gettext ("\
2899 Length Number % of total Coverage\n"), stdout);
2900 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2901 counts[0], (counts[0] * 100.0) / nbucket);
2903 uint64_t nzero_counts = 0;
2904 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2906 nzero_counts += counts[cnt] * cnt;
2908 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2909 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2910 (nzero_counts * 100.0) / nsyms);
2914 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2917 success += counts[cnt] * acc;
2921 Average number of tests: successful lookup: %f\n\
2922 unsuccessful lookup: %f\n"),
2923 (double) success / (double) nzero_counts,
2924 (double) nzero_counts / (double) nbucket);
2931 /* This function handles the traditional System V-style hash table format. */
2933 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2935 Elf_Data *data = elf_getdata (scn, NULL);
2936 if (unlikely (data == NULL))
2938 error (0, 0, gettext ("cannot get data for section %d: %s"),
2939 (int) elf_ndxscn (scn), elf_errmsg (-1));
2943 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2944 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2945 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2946 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2948 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2950 uint_fast32_t maxlength = 0;
2951 uint_fast32_t nsyms = 0;
2952 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2954 Elf32_Word inner = bucket[cnt];
2955 while (inner > 0 && inner < nchain)
2958 if (maxlength < ++lengths[cnt])
2961 inner = chain[inner];
2965 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2972 /* This function handles the incorrect, System V-style hash table
2973 format some 64-bit architectures use. */
2975 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2977 Elf_Data *data = elf_getdata (scn, NULL);
2978 if (unlikely (data == NULL))
2980 error (0, 0, gettext ("cannot get data for section %d: %s"),
2981 (int) elf_ndxscn (scn), elf_errmsg (-1));
2985 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
2986 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
2987 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
2988 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
2990 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2992 uint_fast32_t maxlength = 0;
2993 uint_fast32_t nsyms = 0;
2994 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
2996 Elf64_Xword inner = bucket[cnt];
2997 while (inner > 0 && inner < nchain)
3000 if (maxlength < ++lengths[cnt])
3003 inner = chain[inner];
3007 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3014 /* This function handles the GNU-style hash table format. */
3016 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3018 Elf_Data *data = elf_getdata (scn, NULL);
3019 if (unlikely (data == NULL))
3021 error (0, 0, gettext ("cannot get data for section %d: %s"),
3022 (int) elf_ndxscn (scn), elf_errmsg (-1));
3026 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3027 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3029 /* Next comes the size of the bitmap. It's measured in words for
3030 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3032 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3033 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3036 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3038 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3040 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3041 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3042 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3045 /* Compute distribution of chain lengths. */
3046 uint_fast32_t maxlength = 0;
3047 uint_fast32_t nsyms = 0;
3048 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3049 if (bucket[cnt] != 0)
3051 Elf32_Word inner = bucket[cnt] - symbias;
3055 if (maxlength < ++lengths[cnt])
3058 while ((chain[inner++] & 1) == 0);
3061 /* Count bits in bitmask. */
3062 uint_fast32_t nbits = 0;
3063 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3065 uint_fast32_t word = bitmask[cnt];
3067 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3068 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3069 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3070 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3071 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3075 if (unlikely (asprintf (&str, gettext ("\
3077 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3078 (unsigned int) symbias,
3079 bitmask_words * sizeof (Elf32_Word),
3081 / (uint_fast32_t) (bitmask_words
3082 * sizeof (Elf32_Word) * 8)),
3083 (unsigned int) shift) == -1))
3084 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3086 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3094 /* Find the symbol table(s). For this we have to search through the
3097 handle_hash (Ebl *ebl)
3099 /* Get the section header string table index. */
3101 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3102 error (EXIT_FAILURE, 0,
3103 gettext ("cannot get section header string table index"));
3105 Elf_Scn *scn = NULL;
3106 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3108 /* Handle the section if it is a symbol table. */
3110 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3112 if (likely (shdr != NULL))
3114 if (shdr->sh_type == SHT_HASH)
3116 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3117 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3119 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3121 else if (shdr->sh_type == SHT_GNU_HASH)
3122 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3129 print_liblist (Ebl *ebl)
3131 /* Find the library list sections. For this we have to search
3132 through the section table. */
3133 Elf_Scn *scn = NULL;
3135 /* Get the section header string table index. */
3137 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3138 error (EXIT_FAILURE, 0,
3139 gettext ("cannot get section header string table index"));
3141 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3144 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3146 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3148 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3149 int nentries = shdr->sh_size / sh_entsize;
3150 printf (ngettext ("\
3151 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3153 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3156 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3160 Elf_Data *data = elf_getdata (scn, NULL);
3165 Library Time Stamp Checksum Version Flags"));
3167 for (int cnt = 0; cnt < nentries; ++cnt)
3170 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3171 if (unlikely (lib == NULL))
3174 time_t t = (time_t) lib->l_time_stamp;
3175 struct tm *tm = gmtime (&t);
3176 if (unlikely (tm == NULL))
3179 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3180 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3181 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3182 tm->tm_hour, tm->tm_min, tm->tm_sec,
3183 (unsigned int) lib->l_checksum,
3184 (unsigned int) lib->l_version,
3185 (unsigned int) lib->l_flags);
3192 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3194 /* Find the object attributes 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_ATTRIBUTES
3210 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3211 || ehdr->e_machine != EM_ARM)))
3215 \nObject attributes section [%2zu] '%s' of %" PRIu64
3216 " bytes at offset %#0" PRIx64 ":\n"),
3218 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3219 shdr->sh_size, shdr->sh_offset);
3221 Elf_Data *data = elf_rawdata (scn, NULL);
3225 const unsigned char *p = data->d_buf;
3227 if (unlikely (*p++ != 'A'))
3230 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3232 inline size_t left (void)
3234 return (const unsigned char *) data->d_buf + data->d_size - p;
3237 while (left () >= 4)
3240 memcpy (&len, p, sizeof len);
3242 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3245 if (unlikely (len > left ()))
3248 const unsigned char *name = p + sizeof len;
3251 unsigned const char *q = memchr (name, '\0', len);
3252 if (unlikely (q == NULL))
3256 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3258 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3259 || (q - name == sizeof "gnu"
3260 && !memcmp (name, "gnu", sizeof "gnu")))
3263 const unsigned char *const sub = q;
3265 unsigned int subsection_tag;
3266 get_uleb128 (subsection_tag, q);
3267 if (unlikely (q >= p))
3270 uint32_t subsection_len;
3271 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3274 memcpy (&subsection_len, q, sizeof subsection_len);
3276 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3277 CONVERT (subsection_len);
3279 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3282 const unsigned char *r = q + sizeof subsection_len;
3283 q = sub + subsection_len;
3285 switch (subsection_tag)
3288 printf (gettext (" %-4u %12" PRIu32 "\n"),
3289 subsection_tag, subsection_len);
3292 case 1: /* Tag_File */
3293 printf (gettext (" File: %11" PRIu32 "\n"),
3299 get_uleb128 (tag, r);
3300 if (unlikely (r >= q))
3304 const char *string = NULL;
3305 if (tag == 32 || (tag & 1) == 0)
3307 get_uleb128 (value, r);
3311 if (tag == 32 || (tag & 1) != 0)
3313 r = memchr (r, '\0', q - r);
3319 const char *tag_name = NULL;
3320 const char *value_name = NULL;
3321 ebl_check_object_attribute (ebl, (const char *) name,
3323 &tag_name, &value_name);
3325 if (tag_name != NULL)
3328 printf (gettext (" %s: %" PRId64 ", %s\n"),
3329 tag_name, value, string);
3330 else if (string == NULL && value_name == NULL)
3331 printf (gettext (" %s: %" PRId64 "\n"),
3334 printf (gettext (" %s: %s\n"),
3335 tag_name, string ?: value_name);
3341 printf (gettext (" %u: %" PRId64 "\n"),
3344 printf (gettext (" %u: %s\n"),
3356 format_dwarf_addr (Dwfl_Module *dwflmod,
3357 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3359 /* See if there is a name we can give for this address. */
3362 const char *name = (print_address_names && ! print_unresolved_addresses)
3363 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3367 if (print_unresolved_addresses)
3374 /* Relativize the address. */
3375 int n = dwfl_module_relocations (dwflmod);
3376 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3378 /* In an ET_REL file there is a section name to refer to. */
3380 : dwfl_module_relocation_info (dwflmod, i, NULL));
3387 ? (address_size == 0
3388 ? asprintf (&result,
3389 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3390 scn, address, name, off)
3391 : asprintf (&result,
3392 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3393 scn, 2 + address_size * 2, address,
3395 : (address_size == 0
3396 ? asprintf (&result,
3397 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3399 : asprintf (&result,
3400 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3401 2 + address_size * 2, address,
3404 ? (address_size == 0
3405 ? asprintf (&result,
3406 gettext ("%s+%#" PRIx64 " <%s>"),
3408 : asprintf (&result,
3409 gettext ("%s+%#0*" PRIx64 " <%s>"),
3410 scn, 2 + address_size * 2, address, name))
3411 : (address_size == 0
3412 ? asprintf (&result,
3413 gettext ("%#" PRIx64 " <%s>"),
3415 : asprintf (&result,
3416 gettext ("%#0*" PRIx64 " <%s>"),
3417 2 + address_size * 2, address, name))))
3419 ? (address_size == 0
3420 ? asprintf (&result,
3421 gettext ("%s+%#" PRIx64),
3423 : asprintf (&result,
3424 gettext ("%s+%#0*" PRIx64),
3425 scn, 2 + address_size * 2, address))
3426 : (address_size == 0
3427 ? asprintf (&result,
3430 : asprintf (&result,
3432 2 + address_size * 2, address)))) < 0)
3433 error (EXIT_FAILURE, 0, _("memory exhausted"));
3439 dwarf_tag_string (unsigned int tag)
3443 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3445 #undef ONE_KNOWN_DW_TAG
3453 dwarf_attr_string (unsigned int attrnum)
3457 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3459 #undef ONE_KNOWN_DW_AT
3467 dwarf_form_string (unsigned int form)
3471 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3472 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3474 #undef ONE_KNOWN_DW_FORM
3475 #undef ONE_KNOWN_DW_FORM_DESC
3483 dwarf_lang_string (unsigned int lang)
3487 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3489 #undef ONE_KNOWN_DW_LANG_DESC
3497 dwarf_inline_string (unsigned int code)
3499 static const char *const known[] =
3501 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3503 #undef ONE_KNOWN_DW_INL
3506 if (likely (code < sizeof (known) / sizeof (known[0])))
3514 dwarf_encoding_string (unsigned int code)
3516 static const char *const known[] =
3518 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3520 #undef ONE_KNOWN_DW_ATE
3523 if (likely (code < sizeof (known) / sizeof (known[0])))
3531 dwarf_access_string (unsigned int code)
3533 static const char *const known[] =
3535 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3537 #undef ONE_KNOWN_DW_ACCESS
3540 if (likely (code < sizeof (known) / sizeof (known[0])))
3548 dwarf_visibility_string (unsigned int code)
3550 static const char *const known[] =
3552 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3554 #undef ONE_KNOWN_DW_VIS
3557 if (likely (code < sizeof (known) / sizeof (known[0])))
3565 dwarf_virtuality_string (unsigned int code)
3567 static const char *const known[] =
3569 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3570 ALL_KNOWN_DW_VIRTUALITY
3571 #undef ONE_KNOWN_DW_VIRTUALITY
3574 if (likely (code < sizeof (known) / sizeof (known[0])))
3582 dwarf_identifier_case_string (unsigned int code)
3584 static const char *const known[] =
3586 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3588 #undef ONE_KNOWN_DW_ID
3591 if (likely (code < sizeof (known) / sizeof (known[0])))
3599 dwarf_calling_convention_string (unsigned int code)
3601 static const char *const known[] =
3603 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3605 #undef ONE_KNOWN_DW_CC
3608 if (likely (code < sizeof (known) / sizeof (known[0])))
3616 dwarf_ordering_string (unsigned int code)
3618 static const char *const known[] =
3620 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3622 #undef ONE_KNOWN_DW_ORD
3625 if (likely (code < sizeof (known) / sizeof (known[0])))
3633 dwarf_discr_list_string (unsigned int code)
3635 static const char *const known[] =
3637 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3639 #undef ONE_KNOWN_DW_DSC
3642 if (likely (code < sizeof (known) / sizeof (known[0])))
3650 dwarf_locexpr_opcode_string (unsigned int code)
3652 static const char *const known[] =
3654 /* Normally we can't affort building huge table of 64K entries,
3655 most of them zero, just because there are a couple defined
3656 values at the far end. In case of opcodes, it's OK. */
3657 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3658 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3660 #undef ONE_KNOWN_DW_OP
3661 #undef ONE_KNOWN_DW_OP_DESC
3664 if (likely (code < sizeof (known) / sizeof (known[0])))
3671 /* Used by all dwarf_foo_name functions. */
3673 string_or_unknown (const char *known, unsigned int code,
3674 unsigned int lo_user, unsigned int hi_user,
3675 bool print_unknown_num)
3677 static char unknown_buf[20];
3679 if (likely (known != NULL))
3682 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3684 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3689 if (print_unknown_num)
3691 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3700 dwarf_tag_name (unsigned int tag)
3702 const char *ret = dwarf_tag_string (tag);
3703 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3707 dwarf_attr_name (unsigned int attr)
3709 const char *ret = dwarf_attr_string (attr);
3710 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3715 dwarf_form_name (unsigned int form)
3717 const char *ret = dwarf_form_string (form);
3718 return string_or_unknown (ret, form, 0, 0, true);
3723 dwarf_lang_name (unsigned int lang)
3725 const char *ret = dwarf_lang_string (lang);
3726 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3731 dwarf_inline_name (unsigned int code)
3733 const char *ret = dwarf_inline_string (code);
3734 return string_or_unknown (ret, code, 0, 0, false);
3739 dwarf_encoding_name (unsigned int code)
3741 const char *ret = dwarf_encoding_string (code);
3742 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3747 dwarf_access_name (unsigned int code)
3749 const char *ret = dwarf_access_string (code);
3750 return string_or_unknown (ret, code, 0, 0, false);
3755 dwarf_visibility_name (unsigned int code)
3757 const char *ret = dwarf_visibility_string (code);
3758 return string_or_unknown (ret, code, 0, 0, false);
3763 dwarf_virtuality_name (unsigned int code)
3765 const char *ret = dwarf_virtuality_string (code);
3766 return string_or_unknown (ret, code, 0, 0, false);
3771 dwarf_identifier_case_name (unsigned int code)
3773 const char *ret = dwarf_identifier_case_string (code);
3774 return string_or_unknown (ret, code, 0, 0, false);
3779 dwarf_calling_convention_name (unsigned int code)
3781 const char *ret = dwarf_calling_convention_string (code);
3782 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3787 dwarf_ordering_name (unsigned int code)
3789 const char *ret = dwarf_ordering_string (code);
3790 return string_or_unknown (ret, code, 0, 0, false);
3795 dwarf_discr_list_name (unsigned int code)
3797 const char *ret = dwarf_discr_list_string (code);
3798 return string_or_unknown (ret, code, 0, 0, false);
3803 print_block (size_t n, const void *block)
3806 puts (_("empty block"));
3809 printf (_("%zu byte block:"), n);
3810 const unsigned char *data = block;
3812 printf (" %02x", *data++);
3819 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3820 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3821 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3823 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3827 printf ("%*s(empty)\n", indent, "");
3831 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3832 #define CONSUME(n) NEED (n); else len -= (n)
3834 Dwarf_Word offset = 0;
3837 uint_fast8_t op = *data++;
3839 const char *op_name = dwarf_locexpr_opcode_string (op);
3840 if (unlikely (op_name == NULL))
3842 static char buf[20];
3843 if (op >= DW_OP_lo_user)
3844 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3846 snprintf (buf, sizeof buf, "??? (%#x)", op);
3853 /* Address operand. */
3857 addr = read_4ubyte_unaligned (dbg, data);
3860 assert (addrsize == 8);
3861 addr = read_8ubyte_unaligned (dbg, data);
3866 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3867 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3868 indent, "", (uintmax_t) offset, op_name, a);
3871 offset += 1 + addrsize;
3874 case DW_OP_call_ref:
3875 /* Offset operand. */
3878 addr = read_4ubyte_unaligned (dbg, data);
3881 assert (ref_size == 8);
3882 addr = read_8ubyte_unaligned (dbg, data);
3887 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
3888 indent, "", (uintmax_t) offset,
3889 op_name, (uintmax_t) addr);
3890 offset += 1 + ref_size;
3893 case DW_OP_deref_size:
3894 case DW_OP_xderef_size:
3897 // XXX value might be modified by relocation
3899 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
3900 indent, "", (uintmax_t) offset,
3901 op_name, *((uint8_t *) data));
3909 // XXX value might be modified by relocation
3910 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3911 indent, "", (uintmax_t) offset,
3912 op_name, read_2ubyte_unaligned (dbg, data));
3920 // XXX value might be modified by relocation
3921 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3922 indent, "", (uintmax_t) offset,
3923 op_name, read_4ubyte_unaligned (dbg, data));
3931 // XXX value might be modified by relocation
3932 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3933 indent, "", (uintmax_t) offset,
3934 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
3942 // XXX value might be modified by relocation
3943 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
3944 indent, "", (uintmax_t) offset,
3945 op_name, *((int8_t *) data));
3953 // XXX value might be modified by relocation
3954 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
3955 indent, "", (uintmax_t) offset,
3956 op_name, read_2sbyte_unaligned (dbg, data));
3964 // XXX value might be modified by relocation
3965 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
3966 indent, "", (uintmax_t) offset,
3967 op_name, read_4sbyte_unaligned (dbg, data));
3975 // XXX value might be modified by relocation
3976 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3977 indent, "", (uintmax_t) offset,
3978 op_name, read_8sbyte_unaligned (dbg, data));
3986 case DW_OP_plus_uconst:
3988 const unsigned char *start = data;
3991 get_uleb128 (uleb, data); /* XXX check overrun */
3992 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3993 indent, "", (uintmax_t) offset, op_name, uleb);
3994 CONSUME (data - start);
3995 offset += 1 + (data - start);
3998 case DW_OP_bit_piece:
4002 get_uleb128 (uleb, data); /* XXX check overrun */
4003 get_uleb128 (uleb2, data); /* XXX check overrun */
4004 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4005 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4006 CONSUME (data - start);
4007 offset += 1 + (data - start);
4011 case DW_OP_breg0 ... DW_OP_breg31:
4016 get_sleb128 (sleb, data); /* XXX check overrun */
4017 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4018 indent, "", (uintmax_t) offset, op_name, sleb);
4019 CONSUME (data - start);
4020 offset += 1 + (data - start);
4026 get_uleb128 (uleb, data); /* XXX check overrun */
4027 get_sleb128 (sleb, data); /* XXX check overrun */
4028 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4029 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4030 CONSUME (data - start);
4031 offset += 1 + (data - start);
4036 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4037 indent, "", (uintmax_t) offset, op_name,
4038 read_2ubyte_unaligned (dbg, data));
4045 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4046 indent, "", (uintmax_t) offset, op_name,
4047 read_4ubyte_unaligned (dbg, data));
4055 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4056 indent, "", (uintmax_t) offset, op_name,
4057 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4063 case DW_OP_implicit_value:
4066 get_uleb128 (uleb, data); /* XXX check overrun */
4067 printf ("%*s[%4" PRIuMAX "] %s: ",
4068 indent, "", (uintmax_t) offset, op_name);
4070 print_block (uleb, data);
4072 CONSUME (data - start);
4073 offset += 1 + (data - start);
4076 case DW_OP_GNU_implicit_pointer:
4077 /* DIE offset operand. */
4079 NEED (ref_size + 1);
4081 addr = read_4ubyte_unaligned (dbg, data);
4084 assert (ref_size == 8);
4085 addr = read_8ubyte_unaligned (dbg, data);
4088 /* Byte offset operand. */
4089 get_sleb128 (sleb, data); /* XXX check overrun */
4091 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4092 indent, "", (intmax_t) offset,
4093 op_name, (uintmax_t) addr, sleb);
4094 CONSUME (data - start);
4095 offset += 1 + (data - start);
4098 case DW_OP_GNU_entry_value:
4099 /* Size plus expression block. */
4102 get_uleb128 (uleb, data); /* XXX check overrun */
4103 printf ("%*s[%4" PRIuMAX "] %s:\n",
4104 indent, "", (uintmax_t) offset, op_name);
4106 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4107 addrsize, offset_size, cu, uleb, data);
4109 CONSUME (data - start);
4110 offset += 1 + (data - start);
4113 case DW_OP_GNU_const_type:
4114 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4115 unsigned size plus block. */
4118 get_uleb128 (uleb, data); /* XXX check overrun */
4119 if (! print_unresolved_addresses && cu != NULL)
4121 uint8_t usize = *(uint8_t *) data++;
4123 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4124 indent, "", (uintmax_t) offset, op_name, uleb);
4125 print_block (usize, data);
4127 CONSUME (data - start);
4128 offset += 1 + (data - start);
4131 case DW_OP_GNU_regval_type:
4132 /* uleb128 register number, uleb128 CU relative
4133 DW_TAG_base_type DIE offset. */
4136 get_uleb128 (uleb, data); /* XXX check overrun */
4137 get_uleb128 (uleb2, data); /* XXX check overrun */
4138 if (! print_unresolved_addresses && cu != NULL)
4140 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4141 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4142 CONSUME (data - start);
4143 offset += 1 + (data - start);
4146 case DW_OP_GNU_deref_type:
4147 /* 1-byte unsigned size of value, uleb128 CU relative
4148 DW_TAG_base_type DIE offset. */
4151 usize = *(uint8_t *) data++;
4152 get_uleb128 (uleb, data); /* XXX check overrun */
4153 if (! print_unresolved_addresses && cu != NULL)
4155 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4156 indent, "", (uintmax_t) offset,
4157 op_name, usize, uleb);
4158 CONSUME (data - start);
4159 offset += 1 + (data - start);
4162 case DW_OP_GNU_convert:
4163 case DW_OP_GNU_reinterpret:
4164 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4165 for conversion to untyped. */
4168 get_uleb128 (uleb, data); /* XXX check overrun */
4169 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4171 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4172 indent, "", (uintmax_t) offset, op_name, uleb);
4173 CONSUME (data - start);
4174 offset += 1 + (data - start);
4177 case DW_OP_GNU_parameter_ref:
4178 /* 4 byte CU relative reference to the abstract optimized away
4179 DW_TAG_formal_parameter. */
4181 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4182 if (! print_unresolved_addresses && cu != NULL)
4183 param_off += cu->start;
4184 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4185 indent, "", (uintmax_t) offset, op_name, param_off);
4193 printf ("%*s[%4" PRIuMAX "] %s\n",
4194 indent, "", (uintmax_t) offset, op_name);
4199 indent = indentrest;
4203 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4204 indent, "", (uintmax_t) offset, op_name);
4212 Dwarf_Off offset:(64 - 3);
4216 struct Dwarf_CU *cu;
4219 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4220 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4223 listptr_base (struct listptr *p)
4226 Dwarf_Die cu = CUDIE (p->cu);
4227 /* Find the base address of the compilation unit. It will normally
4228 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4229 address could be overridden by DW_AT_entry_pc. It's been
4230 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4231 compilation units with discontinuous ranges. */
4232 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4234 Dwarf_Attribute attr_mem;
4235 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4243 compare_listptr (const void *a, const void *b, void *arg)
4245 const char *name = arg;
4246 struct listptr *p1 = (void *) a;
4247 struct listptr *p2 = (void *) b;
4249 if (p1->offset < p2->offset)
4251 if (p1->offset > p2->offset)
4254 if (!p1->warned && !p2->warned)
4256 if (p1->addr64 != p2->addr64)
4258 p1->warned = p2->warned = true;
4260 gettext ("%s %#" PRIx64 " used with different address sizes"),
4261 name, (uint64_t) p1->offset);
4263 if (p1->dwarf64 != p2->dwarf64)
4265 p1->warned = p2->warned = true;
4267 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4268 name, (uint64_t) p1->offset);
4270 if (listptr_base (p1) != listptr_base (p2))
4272 p1->warned = p2->warned = true;
4274 gettext ("%s %#" PRIx64 " used with different base addresses"),
4275 name, (uint64_t) p1->offset);
4282 struct listptr_table
4286 struct listptr *table;
4289 static struct listptr_table known_loclistptr;
4290 static struct listptr_table known_rangelistptr;
4293 reset_listptr (struct listptr_table *table)
4295 free (table->table);
4296 table->table = NULL;
4297 table->n = table->alloc = 0;
4301 notice_listptr (enum section_e section, struct listptr_table *table,
4302 uint_fast8_t address_size, uint_fast8_t offset_size,
4303 struct Dwarf_CU *cu, Dwarf_Off offset)
4305 if (print_debug_sections & section)
4307 if (table->n == table->alloc)
4309 if (table->alloc == 0)
4313 table->table = xrealloc (table->table,
4314 table->alloc * sizeof table->table[0]);
4317 struct listptr *p = &table->table[table->n++];
4319 *p = (struct listptr)
4321 .addr64 = address_size == 8,
4322 .dwarf64 = offset_size == 8,
4326 assert (p->offset == offset);
4331 sort_listptr (struct listptr_table *table, const char *name)
4334 qsort_r (table->table, table->n, sizeof table->table[0],
4335 &compare_listptr, (void *) name);
4339 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4340 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4341 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4342 unsigned char **readp, unsigned char *endp)
4347 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4350 struct listptr *p = &table->table[*idxp];
4352 if (*idxp == table->n
4353 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4356 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4361 if (p->offset != (Dwarf_Off) offset)
4363 *readp += p->offset - offset;
4364 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4365 offset, (Dwarf_Off) p->offset - offset);
4369 if (address_sizep != NULL)
4370 *address_sizep = listptr_address_size (p);
4371 if (offset_sizep != NULL)
4372 *offset_sizep = listptr_offset_size (p);
4374 *base = listptr_base (p);
4383 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4384 Ebl *ebl, GElf_Ehdr *ehdr,
4385 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4387 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4388 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4390 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4392 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4393 (uint64_t) shdr->sh_offset);
4395 Dwarf_Off offset = 0;
4396 while (offset < sh_size)
4398 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4404 Dwarf_Abbrev abbrev;
4406 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4409 if (unlikely (res < 0))
4412 *** error while reading abbreviation: %s\n"),
4417 /* This is the NUL byte at the end of the section. */
4422 /* We know these calls can never fail. */
4423 unsigned int code = dwarf_getabbrevcode (&abbrev);
4424 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4425 int has_children = dwarf_abbrevhaschildren (&abbrev);
4427 printf (gettext (" [%5u] offset: %" PRId64
4428 ", children: %s, tag: %s\n"),
4429 code, (int64_t) offset,
4430 has_children ? gettext ("yes") : gettext ("no"),
4431 dwarf_tag_name (tag));
4437 while (dwarf_getabbrevattr (&abbrev, cnt,
4438 &name, &form, &enoffset) == 0)
4440 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4441 dwarf_attr_name (name), dwarf_form_name (form),
4442 (uint64_t) enoffset);
4453 /* Print content of DWARF .debug_aranges section. We fortunately do
4454 not have to know a bit about the structure of the section, libdwarf
4455 takes care of it. */
4457 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4458 GElf_Shdr *shdr, Dwarf *dbg)
4460 Dwarf_Aranges *aranges;
4462 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4464 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4469 GElf_Shdr glink_mem;
4471 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4474 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4479 printf (ngettext ("\
4480 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4482 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4484 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4485 (uint64_t) shdr->sh_offset, cnt);
4487 /* Compute floor(log16(cnt)). */
4496 for (size_t n = 0; n < cnt; ++n)
4498 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4499 if (unlikely (runp == NULL))
4501 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4509 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4510 printf (gettext (" [%*zu] ???\n"), digits, n);
4512 printf (gettext (" [%*zu] start: %0#*" PRIx64
4513 ", length: %5" PRIu64 ", CU DIE offset: %6"
4515 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4516 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4521 /* Print content of DWARF .debug_aranges section. */
4523 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4524 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4525 GElf_Shdr *shdr, Dwarf *dbg)
4529 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4533 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4535 if (unlikely (data == NULL))
4537 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4543 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4544 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4545 (uint64_t) shdr->sh_offset);
4547 const unsigned char *readp = data->d_buf;
4548 const unsigned char *readendp = readp + data->d_size;
4550 while (readp < readendp)
4552 const unsigned char *hdrstart = readp;
4553 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4555 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4556 if (readp + 4 > readendp)
4559 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4560 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4564 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4565 unsigned int length_bytes = 4;
4566 if (length == DWARF3_LENGTH_64_BIT)
4568 if (readp + 8 > readendp)
4570 length = read_8ubyte_unaligned_inc (dbg, readp);
4574 const unsigned char *nexthdr = readp + length;
4575 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4578 if (nexthdr > readendp)
4584 if (readp + 2 > readendp)
4586 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4587 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4591 error (0, 0, gettext ("unsupported aranges version"));
4596 if (readp + length_bytes > readendp)
4598 if (length_bytes == 8)
4599 offset = read_8ubyte_unaligned_inc (dbg, readp);
4601 offset = read_4ubyte_unaligned_inc (dbg, readp);
4602 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4605 if (readp + 1 > readendp)
4607 unsigned int address_size = *readp++;
4608 printf (gettext (" Address size: %6" PRIu64 "\n"),
4609 (uint64_t) address_size);
4610 if (address_size != 4 && address_size != 8)
4612 error (0, 0, gettext ("unsupported address size"));
4616 unsigned int segment_size = *readp++;
4617 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4618 (uint64_t) segment_size);
4619 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4621 error (0, 0, gettext ("unsupported segment size"));
4625 /* Round the address to the next multiple of 2*address_size. */
4626 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4627 % (2 * address_size));
4629 while (readp < nexthdr)
4631 Dwarf_Word range_address;
4632 Dwarf_Word range_length;
4633 Dwarf_Word segment = 0;
4634 if (readp + 2 * address_size + segment_size > readendp)
4636 if (address_size == 4)
4638 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4639 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4643 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4644 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4647 if (segment_size == 4)
4648 segment = read_4ubyte_unaligned_inc (dbg, readp);
4649 else if (segment_size == 8)
4650 segment = read_8ubyte_unaligned_inc (dbg, readp);
4652 if (range_address == 0 && range_length == 0 && segment == 0)
4655 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4657 char *e = format_dwarf_addr (dwflmod, address_size,
4658 range_address + range_length - 1,
4660 if (segment_size != 0)
4661 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4662 (uint64_t) segment);
4664 printf (gettext (" %s..%s\n"), b, e);
4670 if (readp != nexthdr)
4672 size_t padding = nexthdr - readp;
4673 printf (gettext (" %Zu padding bytes\n"), padding);
4680 /* Print content of DWARF .debug_ranges section. */
4682 print_debug_ranges_section (Dwfl_Module *dwflmod,
4683 Ebl *ebl, GElf_Ehdr *ehdr,
4684 Elf_Scn *scn, GElf_Shdr *shdr,
4687 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4689 if (unlikely (data == NULL))
4691 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4697 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4698 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4699 (uint64_t) shdr->sh_offset);
4701 sort_listptr (&known_rangelistptr, "rangelistptr");
4702 size_t listptr_idx = 0;
4704 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4707 Dwarf_Addr base = 0;
4708 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4709 unsigned char *readp = data->d_buf;
4710 while (readp < endp)
4712 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4714 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4715 &address_size, NULL, &base, NULL,
4716 offset, &readp, endp))
4719 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4721 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4727 if (address_size == 8)
4729 begin = read_8ubyte_unaligned_inc (dbg, readp);
4730 end = read_8ubyte_unaligned_inc (dbg, readp);
4734 begin = read_4ubyte_unaligned_inc (dbg, readp);
4735 end = read_4ubyte_unaligned_inc (dbg, readp);
4736 if (begin == (Dwarf_Addr) (uint32_t) -1)
4737 begin = (Dwarf_Addr) -1l;
4740 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4742 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4743 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4747 else if (begin == 0 && end == 0) /* End of list entry. */
4750 printf (gettext (" [%6tx] empty list\n"), offset);
4755 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4757 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4759 /* We have an address range entry. */
4760 if (first) /* First address range entry in a list. */
4761 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4763 printf (gettext (" %s..%s\n"), b, e);
4772 #define REGNAMESZ 16
4774 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4775 char name[REGNAMESZ], int *bits, int *type)
4780 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4781 bits ?: &ignore, type ?: &ignore);
4785 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4787 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4789 *bits = loc != NULL ? loc->bits : 0;
4791 *type = DW_ATE_unsigned;
4792 set = "??? unrecognized";
4796 if (bits != NULL && *bits <= 0)
4797 *bits = loc != NULL ? loc->bits : 0;
4798 if (type != NULL && *type == DW_ATE_void)
4799 *type = DW_ATE_unsigned;
4806 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4807 Dwarf_Word vma_base, unsigned int code_align,
4809 unsigned int version, unsigned int ptr_size,
4810 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4812 char regnamebuf[REGNAMESZ];
4813 const char *regname (unsigned int regno)
4815 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4819 puts ("\n Program:");
4820 Dwarf_Word pc = vma_base;
4821 while (readp < endp)
4823 unsigned int opcode = *readp++;
4825 if (opcode < DW_CFA_advance_loc)
4826 /* Extended opcode. */
4837 case DW_CFA_set_loc:
4838 // XXX overflow check
4839 get_uleb128 (op1, readp);
4841 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4843 case DW_CFA_advance_loc1:
4844 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4845 *readp, pc += *readp * code_align);
4848 case DW_CFA_advance_loc2:
4849 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4850 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4851 op1, pc += op1 * code_align);
4853 case DW_CFA_advance_loc4:
4854 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4855 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4856 op1, pc += op1 * code_align);
4858 case DW_CFA_offset_extended:
4859 // XXX overflow check
4860 get_uleb128 (op1, readp);
4861 get_uleb128 (op2, readp);
4862 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4864 op1, regname (op1), op2 * data_align);
4866 case DW_CFA_restore_extended:
4867 // XXX overflow check
4868 get_uleb128 (op1, readp);
4869 printf (" restore_extended r%" PRIu64 " (%s)\n",
4870 op1, regname (op1));
4872 case DW_CFA_undefined:
4873 // XXX overflow check
4874 get_uleb128 (op1, readp);
4875 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4877 case DW_CFA_same_value:
4878 // XXX overflow check
4879 get_uleb128 (op1, readp);
4880 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4882 case DW_CFA_register:
4883 // XXX overflow check
4884 get_uleb128 (op1, readp);
4885 get_uleb128 (op2, readp);
4886 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4887 op1, regname (op1), op2, regname (op2));
4889 case DW_CFA_remember_state:
4890 puts (" remember_state");
4892 case DW_CFA_restore_state:
4893 puts (" restore_state");
4895 case DW_CFA_def_cfa:
4896 // XXX overflow check
4897 get_uleb128 (op1, readp);
4898 get_uleb128 (op2, readp);
4899 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4900 op1, regname (op1), op2);
4902 case DW_CFA_def_cfa_register:
4903 // XXX overflow check
4904 get_uleb128 (op1, readp);
4905 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
4906 op1, regname (op1));
4908 case DW_CFA_def_cfa_offset:
4909 // XXX overflow check
4910 get_uleb128 (op1, readp);
4911 printf (" def_cfa_offset %" PRIu64 "\n", op1);
4913 case DW_CFA_def_cfa_expression:
4914 // XXX overflow check
4915 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
4916 printf (" def_cfa_expression %" PRIu64 "\n", op1);
4917 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4921 case DW_CFA_expression:
4922 // XXX overflow check
4923 get_uleb128 (op1, readp);
4924 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4925 printf (" expression r%" PRIu64 " (%s) \n",
4926 op1, regname (op1));
4927 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4931 case DW_CFA_offset_extended_sf:
4932 // XXX overflow check
4933 get_uleb128 (op1, readp);
4934 get_sleb128 (sop2, readp);
4935 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
4937 op1, regname (op1), sop2 * data_align);
4939 case DW_CFA_def_cfa_sf:
4940 // XXX overflow check
4941 get_uleb128 (op1, readp);
4942 get_sleb128 (sop2, readp);
4943 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
4944 op1, regname (op1), sop2 * data_align);
4946 case DW_CFA_def_cfa_offset_sf:
4947 // XXX overflow check
4948 get_sleb128 (sop1, readp);
4949 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
4951 case DW_CFA_val_offset:
4952 // XXX overflow check
4953 get_uleb128 (op1, readp);
4954 get_uleb128 (op2, readp);
4955 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
4956 op1, op2 * data_align);
4958 case DW_CFA_val_offset_sf:
4959 // XXX overflow check
4960 get_uleb128 (op1, readp);
4961 get_sleb128 (sop2, readp);
4962 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
4963 op1, sop2 * data_align);
4965 case DW_CFA_val_expression:
4966 // XXX overflow check
4967 get_uleb128 (op1, readp);
4968 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4969 printf (" val_expression r%" PRIu64 " (%s)\n",
4970 op1, regname (op1));
4971 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
4975 case DW_CFA_MIPS_advance_loc8:
4976 op1 = read_8ubyte_unaligned_inc (dbg, readp);
4977 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
4978 op1, pc += op1 * code_align);
4980 case DW_CFA_GNU_window_save:
4981 puts (" GNU_window_save");
4983 case DW_CFA_GNU_args_size:
4984 // XXX overflow check
4985 get_uleb128 (op1, readp);
4986 printf (" args_size %" PRIu64 "\n", op1);
4989 printf (" ??? (%u)\n", opcode);
4992 else if (opcode < DW_CFA_offset)
4993 printf (" advance_loc %u to %#" PRIx64 "\n",
4994 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
4995 else if (opcode < DW_CFA_restore)
4998 // XXX overflow check
4999 get_uleb128 (offset, readp);
5000 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5001 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5004 printf (" restore r%u (%s)\n",
5005 opcode & 0x3f, regname (opcode & 0x3f));
5011 encoded_ptr_size (int encoding, unsigned int ptr_size)
5013 switch (encoding & 7)
5028 print_encoding (unsigned int val)
5032 case DW_EH_PE_absptr:
5033 fputs ("absptr", stdout);
5035 case DW_EH_PE_uleb128:
5036 fputs ("uleb128", stdout);
5038 case DW_EH_PE_udata2:
5039 fputs ("udata2", stdout);
5041 case DW_EH_PE_udata4:
5042 fputs ("udata4", stdout);
5044 case DW_EH_PE_udata8:
5045 fputs ("udata8", stdout);
5047 case DW_EH_PE_sleb128:
5048 fputs ("sleb128", stdout);
5050 case DW_EH_PE_sdata2:
5051 fputs ("sdata2", stdout);
5053 case DW_EH_PE_sdata4:
5054 fputs ("sdata4", stdout);
5056 case DW_EH_PE_sdata8:
5057 fputs ("sdata8", stdout);
5060 /* We did not use any of the bits after all. */
5069 print_relinfo (unsigned int val)
5073 case DW_EH_PE_pcrel:
5074 fputs ("pcrel", stdout);
5076 case DW_EH_PE_textrel:
5077 fputs ("textrel", stdout);
5079 case DW_EH_PE_datarel:
5080 fputs ("datarel", stdout);
5082 case DW_EH_PE_funcrel:
5083 fputs ("funcrel", stdout);
5085 case DW_EH_PE_aligned:
5086 fputs ("aligned", stdout);
5097 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5099 printf ("(%s", pfx);
5101 if (fde_encoding == DW_EH_PE_omit)
5105 unsigned int w = fde_encoding;
5107 w = print_encoding (w);
5111 if (w != fde_encoding)
5112 fputc_unlocked (' ', stdout);
5114 w = print_relinfo (w);
5118 printf ("%s%x", w != fde_encoding ? " " : "", w);
5125 static const unsigned char *
5126 read_encoded (unsigned int encoding, const unsigned char *readp,
5127 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5129 if ((encoding & 0xf) == DW_EH_PE_absptr)
5130 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5131 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5133 switch (encoding & 0xf)
5135 case DW_EH_PE_uleb128:
5136 // XXX buffer overrun check
5137 get_uleb128 (*res, readp);
5139 case DW_EH_PE_sleb128:
5140 // XXX buffer overrun check
5141 get_sleb128 (*res, readp);
5143 case DW_EH_PE_udata2:
5144 if (readp + 2 > endp)
5146 *res = read_2ubyte_unaligned_inc (dbg, readp);
5148 case DW_EH_PE_udata4:
5149 if (readp + 4 > endp)
5151 *res = read_4ubyte_unaligned_inc (dbg, readp);
5153 case DW_EH_PE_udata8:
5154 if (readp + 8 > endp)
5156 *res = read_8ubyte_unaligned_inc (dbg, readp);
5158 case DW_EH_PE_sdata2:
5159 if (readp + 2 > endp)
5161 *res = read_2sbyte_unaligned_inc (dbg, readp);
5163 case DW_EH_PE_sdata4:
5164 if (readp + 4 > endp)
5166 *res = read_4sbyte_unaligned_inc (dbg, readp);
5168 case DW_EH_PE_sdata8:
5169 if (readp + 8 > endp)
5171 *res = read_8sbyte_unaligned_inc (dbg, readp);
5176 gettext ("invalid encoding"));
5184 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5185 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5188 /* We know this call will succeed since it did in the caller. */
5189 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5190 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5192 /* Needed if we find PC-relative addresses. */
5194 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5196 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5200 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5201 Elf_Data *data = (is_eh_frame
5202 ? elf_rawdata (scn, NULL)
5203 : dbg->sectiondata[IDX_debug_frame]);
5205 if (unlikely (data == NULL))
5207 error (0, 0, gettext ("cannot get %s content: %s"),
5208 scnname, elf_errmsg (-1));
5214 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5215 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5218 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5219 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5223 ptrdiff_t cie_offset;
5224 const char *augmentation;
5225 unsigned int code_alignment_factor;
5226 unsigned int data_alignment_factor;
5227 uint8_t address_size;
5228 uint8_t fde_encoding;
5229 uint8_t lsda_encoding;
5230 struct cieinfo *next;
5233 const unsigned char *readp = data->d_buf;
5234 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5236 while (readp < dataend)
5238 if (unlikely (readp + 4 > dataend))
5241 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5242 elf_ndxscn (scn), scnname);
5246 /* At the beginning there must be a CIE. There can be multiple,
5247 hence we test tis in a loop. */
5248 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5250 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5251 unsigned int length = 4;
5252 if (unlikely (unit_length == 0xffffffff))
5254 if (unlikely (readp + 8 > dataend))
5257 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5261 if (unlikely (unit_length == 0))
5263 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5267 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5269 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5270 const unsigned char *const cieend = readp + unit_length;
5271 if (unlikely (cieend > dataend || readp + 8 > dataend))
5277 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5278 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5279 cie_id = DW_CIE_ID_64;
5282 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5284 uint_fast8_t version = 2;
5285 unsigned int code_alignment_factor;
5286 int data_alignment_factor;
5287 unsigned int fde_encoding = 0;
5288 unsigned int lsda_encoding = 0;
5289 Dwarf_Word initial_location = 0;
5290 Dwarf_Word vma_base = 0;
5292 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5295 const char *const augmentation = (const char *) readp;
5296 readp = memchr (readp, '\0', cieend - readp);
5297 if (unlikely (readp == NULL))
5301 uint_fast8_t segment_size = 0;
5304 if (cieend - readp < 5)
5306 ptr_size = *readp++;
5307 segment_size = *readp++;
5310 // XXX Check overflow
5311 get_uleb128 (code_alignment_factor, readp);
5312 // XXX Check overflow
5313 get_sleb128 (data_alignment_factor, readp);
5315 /* In some variant for unwind data there is another field. */
5316 if (strcmp (augmentation, "eh") == 0)
5317 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5319 unsigned int return_address_register;
5320 if (unlikely (version == 1))
5321 return_address_register = *readp++;
5323 // XXX Check overflow
5324 get_uleb128 (return_address_register, readp);
5326 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5327 " CIE_id: %" PRIu64 "\n"
5329 " augmentation: \"%s\"\n",
5330 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5331 version, augmentation);
5333 printf (" address_size: %u\n"
5334 " segment_size: %u\n",
5335 ptr_size, segment_size);
5336 printf (" code_alignment_factor: %u\n"
5337 " data_alignment_factor: %d\n"
5338 " return_address_register: %u\n",
5339 code_alignment_factor,
5340 data_alignment_factor, return_address_register);
5342 if (augmentation[0] == 'z')
5344 unsigned int augmentationlen;
5345 get_uleb128 (augmentationlen, readp);
5347 if (augmentationlen > (size_t) (dataend - readp))
5348 error (1, 0, gettext ("invalid augmentation length"));
5350 const char *hdr = "Augmentation data:";
5351 const char *cp = augmentation + 1;
5354 printf (" %-26s%#x ", hdr, *readp);
5359 fde_encoding = *readp++;
5360 print_encoding_base (gettext ("FDE address encoding: "),
5363 else if (*cp == 'L')
5365 lsda_encoding = *readp++;
5366 print_encoding_base (gettext ("LSDA pointer encoding: "),
5369 else if (*cp == 'P')
5371 /* Personality. This field usually has a relocation
5372 attached pointing to __gcc_personality_v0. */
5373 const unsigned char *startp = readp;
5374 unsigned int encoding = *readp++;
5376 readp = read_encoded (encoding, readp,
5377 readp - 1 + augmentationlen,
5380 while (++startp < readp)
5381 printf ("%#x ", *startp);
5384 print_encoding (encoding);
5386 switch (encoding & 0xf)
5388 case DW_EH_PE_sleb128:
5389 case DW_EH_PE_sdata2:
5390 case DW_EH_PE_sdata4:
5391 printf ("%" PRId64 ")\n", val);
5394 printf ("%#" PRIx64 ")\n", val);
5399 printf ("(%x)\n", *readp++);
5405 if (likely (ptr_size == 4 || ptr_size == 8))
5407 struct cieinfo *newp = alloca (sizeof (*newp));
5408 newp->cie_offset = offset;
5409 newp->augmentation = augmentation;
5410 newp->fde_encoding = fde_encoding;
5411 newp->lsda_encoding = lsda_encoding;
5412 newp->address_size = ptr_size;
5413 newp->code_alignment_factor = code_alignment_factor;
5414 newp->data_alignment_factor = data_alignment_factor;
5421 struct cieinfo *cie = cies;
5424 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5425 : (ptrdiff_t) cie_id == cie->cie_offset)
5429 if (unlikely (cie == NULL))
5431 puts ("invalid CIE reference in FDE");
5435 /* Initialize from CIE data. */
5436 fde_encoding = cie->fde_encoding;
5437 lsda_encoding = cie->lsda_encoding;
5438 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5439 code_alignment_factor = cie->code_alignment_factor;
5440 data_alignment_factor = cie->data_alignment_factor;
5442 const unsigned char *base = readp;
5443 // XXX There are sometimes relocations for this value
5444 initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5445 Dwarf_Word address_range
5446 = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5448 /* pcrel for an FDE address is relative to the runtime
5449 address of the start_address field itself. Sign extend
5450 if necessary to make sure the calculation is done on the
5451 full 64 bit address even when initial_location only holds
5452 the lower 32 bits. */
5453 Dwarf_Addr pc_start = initial_location;
5455 pc_start = (uint64_t) (int32_t) pc_start;
5456 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5457 pc_start += ((uint64_t) shdr->sh_addr
5458 + (base - (const unsigned char *) data->d_buf)
5461 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5462 pc_start, initial_location);
5463 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5464 " CIE_pointer: %" PRIu64 "\n"
5465 " initial_location: %s",
5466 offset, (uint64_t) unit_length,
5467 cie->cie_offset, (uint64_t) cie_id, a);
5469 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5471 vma_base = (((uint64_t) shdr->sh_offset
5472 + (base - (const unsigned char *) data->d_buf)
5473 + (uint64_t) initial_location)
5475 ? UINT64_C (0xffffffff)
5476 : UINT64_C (0xffffffffffffffff)));
5477 printf (gettext (" (offset: %#" PRIx64 ")"),
5478 (uint64_t) vma_base);
5481 printf ("\n address_range: %#" PRIx64,
5482 (uint64_t) address_range);
5483 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5484 printf (gettext (" (end offset: %#" PRIx64 ")"),
5485 ((uint64_t) vma_base + (uint64_t) address_range)
5487 ? UINT64_C (0xffffffff)
5488 : UINT64_C (0xffffffffffffffff)));
5491 if (cie->augmentation[0] == 'z')
5493 unsigned int augmentationlen;
5494 get_uleb128 (augmentationlen, readp);
5496 if (augmentationlen > 0)
5498 const char *hdr = "Augmentation data:";
5499 const char *cp = cie->augmentation + 1;
5505 uint64_t lsda_pointer;
5506 const unsigned char *p
5507 = read_encoded (lsda_encoding, &readp[u],
5508 &readp[augmentationlen],
5509 &lsda_pointer, dbg);
5512 %-26sLSDA pointer: %#" PRIx64 "\n"),
5519 while (u < augmentationlen)
5521 printf (" %-26s%#x\n", hdr, readp[u++]);
5526 readp += augmentationlen;
5530 /* Handle the initialization instructions. */
5531 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5532 data_alignment_factor, version, ptr_size,
5541 Dwfl_Module *dwflmod;
5546 unsigned int version;
5547 unsigned int addrsize;
5548 unsigned int offset_size;
5549 struct Dwarf_CU *cu;
5554 attr_callback (Dwarf_Attribute *attrp, void *arg)
5556 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5557 const int level = cbargs->level;
5559 unsigned int attr = dwarf_whatattr (attrp);
5560 if (unlikely (attr == 0))
5562 if (!cbargs->silent)
5563 error (0, 0, gettext ("cannot get attribute code: %s"),
5565 return DWARF_CB_ABORT;
5568 unsigned int form = dwarf_whatform (attrp);
5569 if (unlikely (form == 0))
5571 if (!cbargs->silent)
5572 error (0, 0, gettext ("cannot get attribute form: %s"),
5574 return DWARF_CB_ABORT;
5580 if (!cbargs->silent)
5583 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5586 if (!cbargs->silent)
5587 error (0, 0, gettext ("cannot get attribute value: %s"),
5589 return DWARF_CB_ABORT;
5591 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5593 printf (" %*s%-20s (%s) %s\n",
5594 (int) (level * 2), "", dwarf_attr_name (attr),
5595 dwarf_form_name (form), a);
5600 case DW_FORM_indirect:
5602 case DW_FORM_string:
5603 case DW_FORM_GNU_strp_alt:
5606 const char *str = dwarf_formstring (attrp);
5607 if (unlikely (str == NULL))
5609 printf (" %*s%-20s (%s) \"%s\"\n",
5610 (int) (level * 2), "", dwarf_attr_name (attr),
5611 dwarf_form_name (form), str);
5614 case DW_FORM_ref_addr:
5615 case DW_FORM_ref_udata:
5620 case DW_FORM_GNU_ref_alt:
5624 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5627 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5628 (int) (level * 2), "", dwarf_attr_name (attr),
5629 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5632 case DW_FORM_ref_sig8:
5635 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5636 (int) (level * 2), "", dwarf_attr_name (attr),
5637 dwarf_form_name (form),
5638 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5641 case DW_FORM_sec_offset:
5647 case DW_FORM_data1:;
5649 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5652 const char *valuestr = NULL;
5655 /* This case can take either a constant or a loclistptr. */
5656 case DW_AT_data_member_location:
5657 if (form != DW_FORM_sec_offset
5658 && (cbargs->version >= 4
5659 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5661 if (!cbargs->silent)
5662 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5663 (int) (level * 2), "", dwarf_attr_name (attr),
5664 dwarf_form_name (form), (uintmax_t) num);
5667 /* else fallthrough */
5669 /* These cases always take a loclistptr and no constant. */
5670 case DW_AT_location:
5671 case DW_AT_data_location:
5672 case DW_AT_vtable_elem_location:
5673 case DW_AT_string_length:
5674 case DW_AT_use_location:
5675 case DW_AT_frame_base:
5676 case DW_AT_return_addr:
5677 case DW_AT_static_link:
5678 case DW_AT_GNU_call_site_value:
5679 case DW_AT_GNU_call_site_data_value:
5680 case DW_AT_GNU_call_site_target:
5681 case DW_AT_GNU_call_site_target_clobbered:
5682 notice_listptr (section_loc, &known_loclistptr,
5683 cbargs->addrsize, cbargs->offset_size,
5685 if (!cbargs->silent)
5686 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5687 (int) (level * 2), "", dwarf_attr_name (attr),
5688 dwarf_form_name (form), (uintmax_t) num);
5692 notice_listptr (section_ranges, &known_rangelistptr,
5693 cbargs->addrsize, cbargs->offset_size,
5695 if (!cbargs->silent)
5696 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5697 (int) (level * 2), "", dwarf_attr_name (attr),
5698 dwarf_form_name (form), (uintmax_t) num);
5701 case DW_AT_language:
5702 valuestr = dwarf_lang_name (num);
5704 case DW_AT_encoding:
5705 valuestr = dwarf_encoding_name (num);
5707 case DW_AT_accessibility:
5708 valuestr = dwarf_access_name (num);
5710 case DW_AT_visibility:
5711 valuestr = dwarf_visibility_name (num);
5713 case DW_AT_virtuality:
5714 valuestr = dwarf_virtuality_name (num);
5716 case DW_AT_identifier_case:
5717 valuestr = dwarf_identifier_case_name (num);
5719 case DW_AT_calling_convention:
5720 valuestr = dwarf_calling_convention_name (num);
5723 valuestr = dwarf_inline_name (num);
5725 case DW_AT_ordering:
5726 valuestr = dwarf_ordering_name (num);
5728 case DW_AT_discr_list:
5729 valuestr = dwarf_discr_list_name (num);
5739 /* When highpc is in constant form it is relative to lowpc.
5740 In that case also show the address. */
5742 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5744 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5746 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5747 (int) (level * 2), "", dwarf_attr_name (attr),
5748 dwarf_form_name (form), (uintmax_t) num, a);
5753 Dwarf_Sword snum = 0;
5754 if (form == DW_FORM_sdata)
5755 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5758 if (valuestr == NULL)
5760 printf (" %*s%-20s (%s)",
5761 (int) (level * 2), "", dwarf_attr_name (attr),
5762 dwarf_form_name (form));
5763 if (form == DW_FORM_sdata)
5764 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5766 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5770 printf (" %*s%-20s (%s) %s",
5771 (int) (level * 2), "", dwarf_attr_name (attr),
5772 dwarf_form_name (form), valuestr);
5773 if (form == DW_FORM_sdata)
5774 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5776 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
5785 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5788 printf (" %*s%-20s (%s) %s\n",
5789 (int) (level * 2), "", dwarf_attr_name (attr),
5790 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5793 case DW_FORM_flag_present:
5796 printf (" %*s%-20s (%s) %s\n",
5797 (int) (level * 2), "", dwarf_attr_name (attr),
5798 dwarf_form_name (form), nl_langinfo (YESSTR));
5801 case DW_FORM_exprloc:
5802 case DW_FORM_block4:
5803 case DW_FORM_block2:
5804 case DW_FORM_block1:
5809 if (unlikely (dwarf_formblock (attrp, &block) != 0))
5812 printf (" %*s%-20s (%s) ",
5813 (int) (level * 2), "", dwarf_attr_name (attr),
5814 dwarf_form_name (form));
5819 if (form != DW_FORM_exprloc)
5821 print_block (block.length, block.data);
5826 case DW_AT_location:
5827 case DW_AT_data_location:
5828 case DW_AT_data_member_location:
5829 case DW_AT_vtable_elem_location:
5830 case DW_AT_string_length:
5831 case DW_AT_use_location:
5832 case DW_AT_frame_base:
5833 case DW_AT_return_addr:
5834 case DW_AT_static_link:
5835 case DW_AT_allocated:
5836 case DW_AT_associated:
5837 case DW_AT_bit_size:
5838 case DW_AT_bit_offset:
5839 case DW_AT_bit_stride:
5840 case DW_AT_byte_size:
5841 case DW_AT_byte_stride:
5843 case DW_AT_lower_bound:
5844 case DW_AT_upper_bound:
5845 case DW_AT_GNU_call_site_value:
5846 case DW_AT_GNU_call_site_data_value:
5847 case DW_AT_GNU_call_site_target:
5848 case DW_AT_GNU_call_site_target_clobbered:
5850 print_ops (cbargs->dwflmod, cbargs->dbg,
5851 12 + level * 2, 12 + level * 2,
5852 cbargs->version, cbargs->addrsize, cbargs->offset_size,
5853 attrp->cu, block.length, block.data);
5861 printf (" %*s%-20s (form: %#x) ???\n",
5862 (int) (level * 2), "", dwarf_attr_name (attr),
5871 print_debug_units (Dwfl_Module *dwflmod,
5872 Ebl *ebl, GElf_Ehdr *ehdr,
5873 Elf_Scn *scn, GElf_Shdr *shdr,
5874 Dwarf *dbg, bool debug_types)
5876 const bool silent = !(print_debug_sections & section_info);
5877 const char *secname = section_name (ebl, ehdr, shdr);
5881 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5882 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5884 /* If the section is empty we don't have to do anything. */
5885 if (!silent && shdr->sh_size == 0)
5889 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5891 Dwarf_Off offset = 0;
5893 /* New compilation unit. */
5896 Dwarf_Off abbroffset;
5903 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5904 &abbroffset, &addrsize, &offsize,
5905 debug_types ? &typesig : NULL,
5906 debug_types ? &typeoff : NULL) != 0)
5912 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5913 " Version: %" PRIu16 ", Abbreviation section offset: %"
5914 PRIu64 ", Address size: %" PRIu8
5915 ", Offset size: %" PRIu8
5916 "\n Type signature: %#" PRIx64
5917 ", Type offset: %#" PRIx64 "\n"),
5918 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5919 typesig, (uint64_t) typeoff);
5921 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5922 " Version: %" PRIu16 ", Abbreviation section offset: %"
5923 PRIu64 ", Address size: %" PRIu8
5924 ", Offset size: %" PRIu8 "\n"),
5925 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5928 struct attrcb_args args =
5934 .addrsize = addrsize,
5935 .offset_size = offsize
5942 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
5943 (dbg, offset, &dies[level]) == NULL))
5946 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
5947 " in section '%s': %s"),
5948 (uint64_t) offset, secname, dwarf_errmsg (-1));
5952 args.cu = dies[0].cu;
5956 offset = dwarf_dieoffset (&dies[level]);
5957 if (unlikely (offset == ~0ul))
5960 error (0, 0, gettext ("cannot get DIE offset: %s"),
5965 int tag = dwarf_tag (&dies[level]);
5966 if (unlikely (tag == DW_TAG_invalid))
5969 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
5970 " in section '%s': %s"),
5971 (uint64_t) offset, secname, dwarf_errmsg (-1));
5976 printf (" [%6" PRIx64 "] %*s%s\n",
5977 (uint64_t) offset, (int) (level * 2), "",
5978 dwarf_tag_name (tag));
5980 /* Print the attribute values. */
5982 args.die = &dies[level];
5983 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
5985 /* Make room for the next level's DIE. */
5986 if (level + 1 == maxdies)
5987 dies = (Dwarf_Die *) xrealloc (dies,
5989 * sizeof (Dwarf_Die));
5991 int res = dwarf_child (&dies[level], &dies[level + 1]);
5994 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
5998 if (unlikely (res == -1))
6001 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6006 else if (unlikely (res < 0))
6009 error (0, 0, gettext ("cannot get next DIE: %s"),
6027 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6028 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6030 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6034 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6035 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6037 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6042 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6043 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6046 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6047 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6048 (uint64_t) shdr->sh_offset);
6051 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6054 Dwarf_Off ncuoffset = 0;
6056 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6057 NULL, NULL, NULL) == 0)
6060 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6065 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6068 printf (" CU [%" PRIx64 "] %s\n",
6069 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6070 printf (" line:col SBPE* disc isa op address"
6071 " (Statement Block Prologue Epilogue *End)\n");
6072 const char *last_file = "";
6073 for (size_t n = 0; n < nlines; n++)
6075 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6076 Dwarf_Word mtime, length;
6077 const char *file = dwarf_linesrc (line, &mtime, &length);
6078 if (strcmp (last_file, file) != 0)
6080 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6081 file, mtime, length);
6086 bool statement, endseq, block, prologue_end, epilogue_begin;
6087 unsigned int lineop, isa, disc;
6089 dwarf_lineaddr (line, &address);
6090 dwarf_lineno (line, &lineno);
6091 dwarf_linecol (line, &colno);
6092 dwarf_lineop_index (line, &lineop);
6093 dwarf_linebeginstatement (line, &statement);
6094 dwarf_lineendsequence (line, &endseq);
6095 dwarf_lineblock (line, &block);
6096 dwarf_lineprologueend (line, &prologue_end);
6097 dwarf_lineepiloguebegin (line, &epilogue_begin);
6098 dwarf_lineisa (line, &isa);
6099 dwarf_linediscriminator (line, &disc);
6101 /* End sequence is special, it is one byte past. */
6102 char *a = format_dwarf_addr (dwflmod, address_size,
6103 address - (endseq ? 1 : 0), address);
6104 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6106 (statement ? 'S' : ' '),
6107 (block ? 'B' : ' '),
6108 (prologue_end ? 'P' : ' '),
6109 (epilogue_begin ? 'E' : ' '),
6110 (endseq ? '*' : ' '),
6111 disc, isa, lineop, a);
6122 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6123 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6127 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6132 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6133 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6134 (uint64_t) shdr->sh_offset);
6136 if (shdr->sh_size == 0)
6139 /* There is no functionality in libdw to read the information in the
6140 way it is represented here. Hardcode the decoder. */
6141 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6142 if (unlikely (data == NULL || data->d_buf == NULL))
6144 error (0, 0, gettext ("cannot get line data section data: %s"),
6149 const unsigned char *linep = (const unsigned char *) data->d_buf;
6150 const unsigned char *lineendp;
6153 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6155 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6157 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6159 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6160 unsigned int length = 4;
6161 if (unlikely (unit_length == 0xffffffff))
6163 if (unlikely (linep + 8 > lineendp))
6166 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6167 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6170 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6174 /* Check whether we have enough room in the section. */
6175 if (unit_length < 2 + length + 5 * 1
6176 || unlikely (linep + unit_length > lineendp))
6178 lineendp = linep + unit_length;
6180 /* The next element of the header is the version identifier. */
6181 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6183 /* Next comes the header length. */
6184 Dwarf_Word header_length;
6186 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6188 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6189 //const unsigned char *header_start = linep;
6191 /* Next the minimum instruction length. */
6192 uint_fast8_t minimum_instr_len = *linep++;
6194 /* Next the maximum operations per instruction, in version 4 format. */
6195 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6197 /* Then the flag determining the default value of the is_stmt
6199 uint_fast8_t default_is_stmt = *linep++;
6201 /* Now the line base. */
6202 int_fast8_t line_base = *((const int_fast8_t *) linep);
6205 /* And the line range. */
6206 uint_fast8_t line_range = *linep++;
6208 /* The opcode base. */
6209 uint_fast8_t opcode_base = *linep++;
6211 /* Print what we got so far. */
6212 printf (gettext ("\n"
6213 " Length: %" PRIu64 "\n"
6214 " DWARF version: %" PRIuFAST16 "\n"
6215 " Prologue length: %" PRIu64 "\n"
6216 " Minimum instruction length: %" PRIuFAST8 "\n"
6217 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6218 " Initial value if '%s': %" PRIuFAST8 "\n"
6219 " Line base: %" PRIdFAST8 "\n"
6220 " Line range: %" PRIuFAST8 "\n"
6221 " Opcode base: %" PRIuFAST8 "\n"
6224 (uint64_t) unit_length, version, (uint64_t) header_length,
6225 minimum_instr_len, max_ops_per_instr,
6226 "is_stmt", default_is_stmt, line_base,
6227 line_range, opcode_base);
6229 if (unlikely (linep + opcode_base - 1 >= lineendp))
6233 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6234 linep - (const unsigned char *) data->d_buf,
6235 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6239 int opcode_base_l10 = 1;
6240 unsigned int tmp = opcode_base;
6246 const uint8_t *standard_opcode_lengths = linep - 1;
6247 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6248 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6249 " [%*" PRIuFAST8 "] %hhu arguments\n",
6250 (int) linep[cnt - 1]),
6251 opcode_base_l10, cnt, linep[cnt - 1]);
6252 linep += opcode_base - 1;
6253 if (unlikely (linep >= lineendp))
6256 puts (gettext ("\nDirectory table:"));
6259 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6260 if (unlikely (endp == NULL))
6263 printf (" %s\n", (char *) linep);
6267 /* Skip the final NUL byte. */
6270 if (unlikely (linep >= lineendp))
6272 puts (gettext ("\nFile name table:\n"
6273 " Entry Dir Time Size Name"));
6274 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6276 /* First comes the file name. */
6277 char *fname = (char *) linep;
6278 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6279 if (unlikely (endp == NULL))
6283 /* Then the index. */
6284 unsigned int diridx;
6285 get_uleb128 (diridx, linep);
6287 /* Next comes the modification time. */
6289 get_uleb128 (mtime, linep);
6291 /* Finally the length of the file. */
6293 get_uleb128 (fsize, linep);
6295 printf (" %-5u %-5u %-9u %-9u %s\n",
6296 cnt, diridx, mtime, fsize, fname);
6298 /* Skip the final NUL byte. */
6301 puts (gettext ("\nLine number statements:"));
6302 Dwarf_Word address = 0;
6303 unsigned int op_index = 0;
6305 uint_fast8_t is_stmt = default_is_stmt;
6307 /* Default address value, in case we do not find the CU. */
6309 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6311 /* Determine the CU this block is for. */
6313 Dwarf_Off ncuoffset = 0;
6315 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6316 NULL, NULL, NULL) == 0)
6319 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6321 Dwarf_Attribute stmt_list;
6322 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6325 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6327 if (lineoff == start_offset)
6330 address_size = cudie.cu->address_size;
6335 /* Apply the "operation advance" from a special opcode
6336 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6337 unsigned int op_addr_advance;
6339 inline void advance_pc (unsigned int op_advance)
6341 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6342 / max_ops_per_instr);
6343 address += op_advance;
6344 show_op_index = (op_index > 0 ||
6345 (op_index + op_advance) % max_ops_per_instr > 0);
6346 op_index = (op_index + op_advance) % max_ops_per_instr;
6349 while (linep < lineendp)
6351 size_t offset = linep - (const unsigned char *) data->d_buf;
6355 /* Read the opcode. */
6356 unsigned int opcode = *linep++;
6358 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6359 /* Is this a special opcode? */
6360 if (likely (opcode >= opcode_base))
6362 /* Yes. Handling this is quite easy since the opcode value
6365 opcode = (desired line increment - line_base)
6366 + (line_range * address advance) + opcode_base
6368 int line_increment = (line_base
6369 + (opcode - opcode_base) % line_range);
6371 /* Perform the increments. */
6372 line += line_increment;
6373 advance_pc ((opcode - opcode_base) / line_range);
6375 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6378 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6379 opcode, op_addr_advance, a, op_index,
6380 line_increment, line);
6383 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6384 opcode, op_addr_advance, a, line_increment, line);
6387 else if (opcode == 0)
6389 /* This an extended opcode. */
6390 if (unlikely (linep + 2 > lineendp))
6394 unsigned int len = *linep++;
6396 if (unlikely (linep + len > lineendp))
6399 /* The sub-opcode. */
6402 printf (gettext (" extended opcode %u: "), opcode);
6406 case DW_LNE_end_sequence:
6407 puts (gettext (" end of sequence"));
6409 /* Reset the registers we care about. */
6413 is_stmt = default_is_stmt;
6416 case DW_LNE_set_address:
6418 if (address_size == 4)
6419 address = read_4ubyte_unaligned_inc (dbg, linep);
6421 address = read_8ubyte_unaligned_inc (dbg, linep);
6423 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6424 printf (gettext (" set address to %s\n"), a);
6429 case DW_LNE_define_file:
6431 char *fname = (char *) linep;
6432 unsigned char *endp = memchr (linep, '\0',
6434 if (unlikely (endp == NULL))
6438 unsigned int diridx;
6439 get_uleb128 (diridx, linep);
6441 get_uleb128 (mtime, linep);
6442 Dwarf_Word filelength;
6443 get_uleb128 (filelength, linep);
6446 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6447 diridx, (uint64_t) mtime, (uint64_t) filelength,
6452 case DW_LNE_set_discriminator:
6453 /* Takes one ULEB128 parameter, the discriminator. */
6454 if (unlikely (standard_opcode_lengths[opcode] != 1))
6457 get_uleb128 (u128, linep);
6458 printf (gettext (" set discriminator to %u\n"), u128);
6462 /* Unknown, ignore it. */
6463 puts (gettext (" unknown opcode"));
6468 else if (opcode <= DW_LNS_set_isa)
6470 /* This is a known standard opcode. */
6474 /* Takes no argument. */
6475 puts (gettext (" copy"));
6478 case DW_LNS_advance_pc:
6479 /* Takes one uleb128 parameter which is added to the
6481 get_uleb128 (u128, linep);
6484 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6487 advance address by %u to %s, op_index to %u\n"),
6488 op_addr_advance, a, op_index);
6490 printf (gettext (" advance address by %u to %s\n"),
6491 op_addr_advance, a);
6496 case DW_LNS_advance_line:
6497 /* Takes one sleb128 parameter which is added to the
6499 get_sleb128 (s128, linep);
6502 advance line by constant %d to %" PRId64 "\n"),
6503 s128, (int64_t) line);
6506 case DW_LNS_set_file:
6507 /* Takes one uleb128 parameter which is stored in file. */
6508 get_uleb128 (u128, linep);
6509 printf (gettext (" set file to %" PRIu64 "\n"),
6513 case DW_LNS_set_column:
6514 /* Takes one uleb128 parameter which is stored in column. */
6515 if (unlikely (standard_opcode_lengths[opcode] != 1))
6518 get_uleb128 (u128, linep);
6519 printf (gettext (" set column to %" PRIu64 "\n"),
6523 case DW_LNS_negate_stmt:
6524 /* Takes no argument. */
6525 is_stmt = 1 - is_stmt;
6526 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6527 "is_stmt", is_stmt);
6530 case DW_LNS_set_basic_block:
6531 /* Takes no argument. */
6532 puts (gettext (" set basic block flag"));
6535 case DW_LNS_const_add_pc:
6536 /* Takes no argument. */
6537 advance_pc ((255 - opcode_base) / line_range);
6539 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6542 advance address by constant %u to %s, op_index to %u\n"),
6543 op_addr_advance, a, op_index);
6546 advance address by constant %u to %s\n"),
6547 op_addr_advance, a);
6552 case DW_LNS_fixed_advance_pc:
6553 /* Takes one 16 bit parameter which is added to the
6555 if (unlikely (standard_opcode_lengths[opcode] != 1))
6558 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6562 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6564 advance address by fixed value %u to %s\n"),
6570 case DW_LNS_set_prologue_end:
6571 /* Takes no argument. */
6572 puts (gettext (" set prologue end flag"));
6575 case DW_LNS_set_epilogue_begin:
6576 /* Takes no argument. */
6577 puts (gettext (" set epilogue begin flag"));
6580 case DW_LNS_set_isa:
6581 /* Takes one uleb128 parameter which is stored in isa. */
6582 if (unlikely (standard_opcode_lengths[opcode] != 1))
6585 get_uleb128 (u128, linep);
6586 printf (gettext (" set isa to %u\n"), u128);
6592 /* This is a new opcode the generator but not we know about.
6593 Read the parameters associated with it but then discard
6594 everything. Read all the parameters for this opcode. */
6595 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6596 " unknown opcode with %" PRIu8 " parameters:",
6597 standard_opcode_lengths[opcode]),
6598 standard_opcode_lengths[opcode]);
6599 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6601 get_uleb128 (u128, linep);
6602 if (n != standard_opcode_lengths[opcode])
6603 putc_unlocked (',', stdout);
6604 printf (" %u", u128);
6607 /* Next round, ignore this opcode. */
6613 /* There must only be one data block. */
6614 assert (elf_getdata (scn, data) == NULL);
6619 print_debug_loc_section (Dwfl_Module *dwflmod,
6620 Ebl *ebl, GElf_Ehdr *ehdr,
6621 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6623 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6625 if (unlikely (data == NULL))
6627 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6633 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6634 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6635 (uint64_t) shdr->sh_offset);
6637 sort_listptr (&known_loclistptr, "loclistptr");
6638 size_t listptr_idx = 0;
6640 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6641 uint_fast8_t offset_size = 4;
6644 struct Dwarf_CU *cu = NULL;
6645 Dwarf_Addr base = 0;
6646 unsigned char *readp = data->d_buf;
6647 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6648 while (readp < endp)
6650 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6652 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6653 &address_size, &offset_size, &base,
6654 &cu, offset, &readp, endp))
6657 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6659 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6665 if (address_size == 8)
6667 begin = read_8ubyte_unaligned_inc (dbg, readp);
6668 end = read_8ubyte_unaligned_inc (dbg, readp);
6672 begin = read_4ubyte_unaligned_inc (dbg, readp);
6673 end = read_4ubyte_unaligned_inc (dbg, readp);
6674 if (begin == (Dwarf_Addr) (uint32_t) -1)
6675 begin = (Dwarf_Addr) -1l;
6678 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6680 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6681 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6685 else if (begin == 0 && end == 0) /* End of list entry. */
6688 printf (gettext (" [%6tx] empty list\n"), offset);
6693 /* We have a location expression entry. */
6694 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6696 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6698 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6701 if (first) /* First entry in a list. */
6702 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6704 printf (gettext (" %s..%s"), b, e);
6709 if (endp - readp <= (ptrdiff_t) len)
6711 fputs (gettext (" <INVALID DATA>\n"), stdout);
6715 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6716 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6729 struct mac_culist *next;
6734 mac_compare (const void *p1, const void *p2)
6736 struct mac_culist *m1 = (struct mac_culist *) p1;
6737 struct mac_culist *m2 = (struct mac_culist *) p2;
6739 if (m1->offset < m2->offset)
6741 if (m1->offset > m2->offset)
6748 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6749 Ebl *ebl, GElf_Ehdr *ehdr,
6750 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6753 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6754 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6755 (uint64_t) shdr->sh_offset);
6756 putc_unlocked ('\n', stdout);
6758 /* There is no function in libdw to iterate over the raw content of
6759 the section but it is easy enough to do. */
6760 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
6761 if (unlikely (data == NULL || data->d_buf == NULL))
6763 error (0, 0, gettext ("cannot get macro information section data: %s"),
6768 /* Get the source file information for all CUs. */
6772 struct mac_culist *culist = NULL;
6774 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6777 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6780 Dwarf_Attribute attr;
6781 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6785 if (dwarf_formudata (&attr, &macoff) != 0)
6788 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6790 newp->offset = macoff;
6792 newp->next = culist;
6797 /* Convert the list into an array for easier consumption. */
6798 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6801 cus[nculist].offset = data->d_size;
6804 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6806 assert (cnt < nculist);
6808 culist = culist->next;
6811 /* Sort the array according to the offset in the .debug_macinfo
6812 section. Note we keep the sentinel at the end. */
6813 qsort (cus, nculist, sizeof (*cus), mac_compare);
6816 const unsigned char *readp = (const unsigned char *) data->d_buf;
6817 const unsigned char *readendp = readp + data->d_size;
6820 while (readp < readendp)
6822 unsigned int opcode = *readp++;
6824 unsigned int u128_2;
6825 const unsigned char *endp;
6829 case DW_MACINFO_define:
6830 case DW_MACINFO_undef:
6831 case DW_MACINFO_vendor_ext:
6832 /* For the first two opcodes the parameters are
6836 We can treat these cases together. */
6837 get_uleb128 (u128, readp);
6839 endp = memchr (readp, '\0', readendp - readp);
6840 if (unlikely (endp == NULL))
6843 %*s*** non-terminated string at end of section"),
6848 if (opcode == DW_MACINFO_define)
6849 printf ("%*s#define %s, line %u\n",
6850 level, "", (char *) readp, u128);
6851 else if (opcode == DW_MACINFO_undef)
6852 printf ("%*s#undef %s, line %u\n",
6853 level, "", (char *) readp, u128);
6855 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6860 case DW_MACINFO_start_file:
6861 /* The two parameters are line and file index, in this order. */
6862 get_uleb128 (u128, readp);
6863 get_uleb128 (u128_2, readp);
6865 /* Find the CU DIE for this file. */
6866 size_t macoff = readp - (const unsigned char *) data->d_buf;
6867 const char *fname = "???";
6868 if (macoff >= cus[0].offset)
6870 while (macoff >= cus[1].offset)
6873 if (cus[0].files == NULL
6874 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6875 cus[0].files = (Dwarf_Files *) -1l;
6877 if (cus[0].files != (Dwarf_Files *) -1l)
6878 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6882 printf ("%*sstart_file %u, [%u] %s\n",
6883 level, "", u128, u128_2, fname);
6887 case DW_MACINFO_end_file:
6889 printf ("%*send_file\n", level, "");
6890 /* Nothing more to do. */
6894 // XXX gcc seems to generate files with a trailing zero.
6895 if (unlikely (opcode != 0 || readp != readendp))
6896 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6904 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6905 Ebl *ebl, GElf_Ehdr *ehdr,
6906 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6909 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6910 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6911 (uint64_t) shdr->sh_offset);
6912 putc_unlocked ('\n', stdout);
6914 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
6915 if (unlikely (data == NULL || data->d_buf == NULL))
6917 error (0, 0, gettext ("cannot get macro information section data: %s"),
6922 /* Get the source file information for all CUs. Uses same
6923 datastructure as macinfo. But uses offset field to directly
6924 match .debug_line offset. And just stored in a list. */
6928 struct mac_culist *culist = NULL;
6930 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6933 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6936 Dwarf_Attribute attr;
6937 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
6941 if (dwarf_formudata (&attr, &lineoff) != 0)
6944 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6946 newp->offset = lineoff;
6948 newp->next = culist;
6953 const unsigned char *readp = (const unsigned char *) data->d_buf;
6954 const unsigned char *readendp = readp + data->d_size;
6956 while (readp < readendp)
6958 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
6959 (uint64_t) (readp - (const unsigned char *) data->d_buf));
6961 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
6962 // optional vendor extension macro entry table.
6963 if (readp + 2 > readendp)
6966 error (0, 0, gettext ("invalid data"));
6969 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
6970 printf (gettext (" Version: %" PRIu16 "\n"), vers);
6972 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
6973 // 5 when it gets standardized.
6976 printf (gettext (" unknown version, cannot parse section\n"));
6980 if (readp + 1 > readendp)
6982 const unsigned char flag = *readp++;
6983 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
6985 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
6986 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
6987 Dwarf_Off line_offset = -1;
6990 if (offset_len == 8)
6991 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
6993 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
6994 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
6998 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
6999 memset (vendor, 0, sizeof vendor);
7002 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7003 // of arguments, for each argument 1 byte form code.
7004 if (readp + 1 > readendp)
7006 unsigned int tlen = *readp++;
7007 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7009 for (unsigned int i = 0; i < tlen; i++)
7011 if (readp + 1 > readendp)
7013 unsigned int opcode = *readp++;
7014 printf (gettext (" [%" PRIx8 "]"), opcode);
7015 if (opcode < DW_MACRO_GNU_lo_user
7016 || opcode > DW_MACRO_GNU_hi_user)
7018 // Record the start of description for this vendor opcode.
7019 // uleb128 nr args, 1 byte per arg form.
7020 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7021 if (readp + 1 > readendp)
7023 unsigned int args = *readp++;
7026 printf (gettext (" %" PRIu8 " arguments:"), args);
7029 if (readp + 1 > readendp)
7031 unsigned int form = *readp++;
7032 printf (" %s", dwarf_form_string (form));
7033 if (form != DW_FORM_data1
7034 && form != DW_FORM_data2
7035 && form != DW_FORM_data4
7036 && form != DW_FORM_data8
7037 && form != DW_FORM_sdata
7038 && form != DW_FORM_udata
7039 && form != DW_FORM_block
7040 && form != DW_FORM_block1
7041 && form != DW_FORM_block2
7042 && form != DW_FORM_block4
7043 && form != DW_FORM_flag
7044 && form != DW_FORM_string
7045 && form != DW_FORM_strp
7046 && form != DW_FORM_sec_offset)
7050 putchar_unlocked (',');
7054 printf (gettext (" no arguments."));
7055 putchar_unlocked ('\n');
7058 putchar_unlocked ('\n');
7061 if (readp + 1 > readendp)
7063 unsigned int opcode = *readp++;
7067 unsigned int u128_2;
7068 const unsigned char *endp;
7073 case DW_MACRO_GNU_start_file:
7074 get_uleb128 (u128, readp);
7075 get_uleb128 (u128_2, readp);
7077 /* Find the CU DIE that matches this line offset. */
7078 const char *fname = "???";
7079 if (line_offset != (Dwarf_Off) -1)
7081 struct mac_culist *cu = culist;
7082 while (cu != NULL && line_offset != cu->offset)
7086 if (cu->files == NULL
7087 && dwarf_getsrcfiles (&cu->die, &cu->files,
7089 cu->files = (Dwarf_Files *) -1l;
7091 if (cu->files != (Dwarf_Files *) -1l)
7092 fname = (dwarf_filesrc (cu->files, u128_2,
7093 NULL, NULL) ?: "???");
7096 printf ("%*sstart_file %u, [%u] %s\n",
7097 level, "", u128, u128_2, fname);
7101 case DW_MACRO_GNU_end_file:
7103 printf ("%*send_file\n", level, "");
7106 case DW_MACRO_GNU_define:
7107 get_uleb128 (u128, readp);
7108 endp = memchr (readp, '\0', readendp - readp);
7111 printf ("%*s#define %s, line %u\n",
7112 level, "", readp, u128);
7116 case DW_MACRO_GNU_undef:
7117 get_uleb128 (u128, readp);
7118 endp = memchr (readp, '\0', readendp - readp);
7121 printf ("%*s#undef %s, line %u\n",
7122 level, "", readp, u128);
7126 case DW_MACRO_GNU_define_indirect:
7127 get_uleb128 (u128, readp);
7128 if (readp + offset_len > readendp)
7130 if (offset_len == 8)
7131 off = read_8ubyte_unaligned_inc (dbg, readp);
7133 off = read_4ubyte_unaligned_inc (dbg, readp);
7134 printf ("%*s#define %s, line %u (indirect)\n",
7135 level, "", dwarf_getstring (dbg, off, NULL), u128);
7138 case DW_MACRO_GNU_undef_indirect:
7139 get_uleb128 (u128, readp);
7140 if (readp + offset_len > readendp)
7142 if (offset_len == 8)
7143 off = read_8ubyte_unaligned_inc (dbg, readp);
7145 off = read_4ubyte_unaligned_inc (dbg, readp);
7146 printf ("%*s#undef %s, line %u (indirect)\n",
7147 level, "", dwarf_getstring (dbg, off, NULL), u128);
7150 case DW_MACRO_GNU_transparent_include:
7151 if (readp + offset_len > readendp)
7153 if (offset_len == 8)
7154 off = read_8ubyte_unaligned_inc (dbg, readp);
7156 off = read_4ubyte_unaligned_inc (dbg, readp);
7157 printf ("%*s#include offset 0x%" PRIx64 "\n",
7162 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7163 if (opcode < DW_MACRO_GNU_lo_user
7164 || opcode > DW_MACRO_GNU_lo_user
7165 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7168 const unsigned char *op_desc;
7169 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7171 // Just skip the arguments, we cannot really interpret them,
7172 // but print as much as we can.
7173 unsigned int args = *op_desc++;
7176 unsigned int form = *op_desc++;
7181 if (readp + 1 > readendp)
7184 printf (" %" PRIx8, (unsigned int) val);
7188 if (readp + 2 > readendp)
7190 val = read_2ubyte_unaligned_inc (dbg, readp);
7191 printf(" %" PRIx16, (unsigned int) val);
7195 if (readp + 4 > readendp)
7197 val = read_4ubyte_unaligned_inc (dbg, readp);
7198 printf (" %" PRIx32, (unsigned int) val);
7202 if (readp + 8 > readendp)
7204 val = read_8ubyte_unaligned_inc (dbg, readp);
7205 printf (" %" PRIx64, val);
7209 get_sleb128 (val, readp);
7210 printf (" %" PRIx64, val);
7214 get_uleb128 (val, readp);
7215 printf (" %" PRIx64, val);
7219 get_uleb128 (val, readp);
7220 printf (" block[%" PRIu64 "]", val);
7221 if (readp + val > readendp)
7226 case DW_FORM_block1:
7227 if (readp + 1 > readendp)
7230 printf (" block[%" PRIu64 "]", val);
7231 if (readp + val > readendp)
7235 case DW_FORM_block2:
7236 if (readp + 2 > readendp)
7238 val = read_2ubyte_unaligned_inc (dbg, readp);
7239 printf (" block[%" PRIu64 "]", val);
7240 if (readp + val > readendp)
7244 case DW_FORM_block4:
7245 if (readp + 2 > readendp)
7247 val =read_4ubyte_unaligned_inc (dbg, readp);
7248 printf (" block[%" PRIu64 "]", val);
7249 if (readp + val > readendp)
7254 if (readp + 1 > readendp)
7257 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7260 case DW_FORM_string:
7261 endp = memchr (readp, '\0', readendp - readp);
7264 printf (" %s", readp);
7269 if (readp + offset_len > readendp)
7271 if (offset_len == 8)
7272 val = read_8ubyte_unaligned_inc (dbg, readp);
7274 val = read_4ubyte_unaligned_inc (dbg, readp);
7275 printf (" %s", dwarf_getstring (dbg, val, NULL));
7278 case DW_FORM_sec_offset:
7279 if (readp + offset_len > readendp)
7281 if (offset_len == 8)
7282 val = read_8ubyte_unaligned_inc (dbg, readp);
7284 val = read_4ubyte_unaligned_inc (dbg, readp);
7285 printf (" %" PRIx64, val);
7289 error (0, 0, gettext ("vendor opcode not verified?"));
7295 putchar_unlocked (',');
7297 putchar_unlocked ('\n');
7300 if (readp + 1 > readendp)
7304 putchar_unlocked ('\n');
7310 /* Callback for printing global names. */
7312 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7315 int *np = (int *) arg;
7317 printf (gettext (" [%5d] DIE offset: %6" PRId64
7318 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7319 (*np)++, global->die_offset, global->cu_offset, global->name);
7325 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7327 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7328 Ebl *ebl, GElf_Ehdr *ehdr,
7329 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7331 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7332 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7333 (uint64_t) shdr->sh_offset);
7336 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7339 /* Print the content of the DWARF string section '.debug_str'. */
7341 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7342 Ebl *ebl, GElf_Ehdr *ehdr,
7343 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7345 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7346 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7348 /* Compute floor(log16(shdr->sh_size)). */
7349 GElf_Addr tmp = sh_size;
7356 digits = MAX (4, digits);
7358 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7361 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7362 /* TRANS: the debugstr| prefix makes the string unique. */
7363 digits + 2, sgettext ("debugstr|Offset"));
7365 Dwarf_Off offset = 0;
7366 while (offset < sh_size)
7369 const char *str = dwarf_getstring (dbg, offset, &len);
7370 if (unlikely (str == NULL))
7372 printf (gettext (" *** error while reading strings: %s\n"),
7377 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7384 /* Print the content of the call frame search table section
7387 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7388 Ebl *ebl __attribute__ ((unused)),
7389 GElf_Ehdr *ehdr __attribute__ ((unused)),
7390 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7393 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7396 Elf_Data *data = elf_rawdata (scn, NULL);
7398 if (unlikely (data == NULL))
7400 error (0, 0, gettext ("cannot get %s content: %s"),
7401 ".eh_frame_hdr", elf_errmsg (-1));
7405 const unsigned char *readp = data->d_buf;
7406 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7409 if (unlikely (readp + 4 > dataend))
7412 error (0, 0, gettext ("invalid data"));
7416 unsigned int version = *readp++;
7417 unsigned int eh_frame_ptr_enc = *readp++;
7418 unsigned int fde_count_enc = *readp++;
7419 unsigned int table_enc = *readp++;
7421 printf (" version: %u\n"
7422 " eh_frame_ptr_enc: %#x ",
7423 version, eh_frame_ptr_enc);
7424 print_encoding_base ("", eh_frame_ptr_enc);
7425 printf (" fde_count_enc: %#x ", fde_count_enc);
7426 print_encoding_base ("", fde_count_enc);
7427 printf (" table_enc: %#x ", table_enc);
7428 print_encoding_base ("", table_enc);
7430 uint64_t eh_frame_ptr = 0;
7431 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7433 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7435 if (unlikely (readp == NULL))
7438 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7439 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7440 printf (" (offset: %#" PRIx64 ")",
7441 /* +4 because of the 4 byte header of the section. */
7442 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7444 putchar_unlocked ('\n');
7447 uint64_t fde_count = 0;
7448 if (fde_count_enc != DW_EH_PE_omit)
7450 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7451 if (unlikely (readp == NULL))
7454 printf (" fde_count: %" PRIu64 "\n", fde_count);
7457 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7462 /* Optimize for the most common case. */
7463 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7464 while (fde_count > 0 && readp + 8 <= dataend)
7466 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7467 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7468 + (int64_t) initial_location);
7469 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7470 // XXX Possibly print symbol name or section offset for initial_offset
7471 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7472 " fde=[%6" PRIx64 "]\n",
7473 initial_location, initial_offset,
7474 address, address - (eh_frame_ptr + 4));
7477 while (0 && readp < dataend)
7484 /* Print the content of the exception handling table section
7487 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7488 Ebl *ebl __attribute__ ((unused)),
7489 GElf_Ehdr *ehdr __attribute__ ((unused)),
7491 GElf_Shdr *shdr __attribute__ ((unused)),
7492 Dwarf *dbg __attribute__ ((unused)))
7495 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7498 Elf_Data *data = elf_rawdata (scn, NULL);
7500 if (unlikely (data == NULL))
7502 error (0, 0, gettext ("cannot get %s content: %s"),
7503 ".gcc_except_table", elf_errmsg (-1));
7507 const unsigned char *readp = data->d_buf;
7508 const unsigned char *const dataend = readp + data->d_size;
7510 if (unlikely (readp + 1 > dataend))
7513 error (0, 0, gettext ("invalid data"));
7516 unsigned int lpstart_encoding = *readp++;
7517 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7518 print_encoding_base ("", lpstart_encoding);
7519 if (lpstart_encoding != DW_EH_PE_omit)
7522 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7523 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7526 if (unlikely (readp + 1 > dataend))
7528 unsigned int ttype_encoding = *readp++;
7529 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7530 print_encoding_base ("", ttype_encoding);
7531 const unsigned char *ttype_base = NULL;
7532 if (ttype_encoding != DW_EH_PE_omit)
7534 unsigned int ttype_base_offset;
7535 get_uleb128 (ttype_base_offset, readp);
7536 printf (" TType base offset: %#x\n", ttype_base_offset);
7537 ttype_base = readp + ttype_base_offset;
7540 if (unlikely (readp + 1 > dataend))
7542 unsigned int call_site_encoding = *readp++;
7543 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7544 print_encoding_base ("", call_site_encoding);
7545 unsigned int call_site_table_len;
7546 get_uleb128 (call_site_table_len, readp);
7548 const unsigned char *const action_table = readp + call_site_table_len;
7549 if (unlikely (action_table > dataend))
7552 unsigned int max_action = 0;
7553 while (readp < action_table)
7556 puts (gettext ("\n Call site table:"));
7558 uint64_t call_site_start;
7559 readp = read_encoded (call_site_encoding, readp, dataend,
7560 &call_site_start, dbg);
7561 uint64_t call_site_length;
7562 readp = read_encoded (call_site_encoding, readp, dataend,
7563 &call_site_length, dbg);
7564 uint64_t landing_pad;
7565 readp = read_encoded (call_site_encoding, readp, dataend,
7567 unsigned int action;
7568 get_uleb128 (action, readp);
7569 max_action = MAX (action, max_action);
7570 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7571 " Call site length: %" PRIu64 "\n"
7572 " Landing pad: %#" PRIx64 "\n"
7574 u++, call_site_start, call_site_length, landing_pad, action);
7576 assert (readp == action_table);
7578 unsigned int max_ar_filter = 0;
7581 puts ("\n Action table:");
7583 const unsigned char *const action_table_end
7584 = action_table + max_action + 1;
7590 get_sleb128 (ar_filter, readp);
7591 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7592 max_ar_filter = ar_filter;
7594 get_sleb128 (ar_disp, readp);
7596 printf (" [%4u] ar_filter: % d\n"
7598 u, ar_filter, ar_disp);
7599 if (abs (ar_disp) & 1)
7600 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7601 else if (ar_disp != 0)
7604 putchar_unlocked ('\n');
7607 while (readp < action_table_end);
7610 if (max_ar_filter > 0)
7612 puts ("\n TType table:");
7614 // XXX Not *4, size of encoding;
7615 switch (ttype_encoding & 7)
7617 case DW_EH_PE_udata2:
7618 case DW_EH_PE_sdata2:
7619 readp = ttype_base - max_ar_filter * 2;
7621 case DW_EH_PE_udata4:
7622 case DW_EH_PE_sdata4:
7623 readp = ttype_base - max_ar_filter * 4;
7625 case DW_EH_PE_udata8:
7626 case DW_EH_PE_sdata8:
7627 readp = ttype_base - max_ar_filter * 8;
7630 error (1, 0, gettext ("invalid TType encoding"));
7636 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7638 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7640 while (readp < ttype_base);
7644 /* Print the content of the '.gdb_index' section.
7645 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7648 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7649 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7651 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7652 " contains %" PRId64 " bytes :\n"),
7653 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7654 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7656 Elf_Data *data = elf_rawdata (scn, NULL);
7658 if (unlikely (data == NULL))
7660 error (0, 0, gettext ("cannot get %s content: %s"),
7661 ".gdb_index", elf_errmsg (-1));
7665 // .gdb_index is always in little endian.
7666 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7669 const unsigned char *readp = data->d_buf;
7670 const unsigned char *const dataend = readp + data->d_size;
7672 if (unlikely (readp + 4 > dataend))
7675 error (0, 0, gettext ("invalid data"));
7679 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7680 printf (gettext (" Version: %" PRId32 "\n"), vers);
7682 // The only difference between version 4 and version 5 is the
7683 // hash used for generating the table. Version 6 contains symbols
7684 // for inlined functions, older versions didn't. Version 7 adds
7685 // symbol kinds. Version 8 just indicates that it correctly includes
7687 if (vers < 4 || vers > 8)
7689 printf (gettext (" unknown version, cannot parse section\n"));
7694 if (unlikely (readp + 4 > dataend))
7697 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7698 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7701 if (unlikely (readp + 4 > dataend))
7704 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7705 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7708 if (unlikely (readp + 4 > dataend))
7711 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7712 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
7715 if (unlikely (readp + 4 > dataend))
7718 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7719 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
7722 if (unlikely (readp + 4 > dataend))
7725 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7726 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7728 readp = data->d_buf + cu_off;
7730 const unsigned char *nextp = data->d_buf + tu_off;
7731 size_t cu_nr = (nextp - readp) / 16;
7733 printf (gettext ("\n CU list at offset %#" PRIx32
7734 " contains %zu entries:\n"),
7738 while (readp + 16 <= dataend && n < cu_nr)
7740 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7743 uint64_t len = read_8ubyte_unaligned (dbg, readp);
7746 printf (" [%4zu] start: %0#8" PRIx64
7747 ", length: %5" PRIu64 "\n", n, off, len);
7751 readp = data->d_buf + tu_off;
7752 nextp = data->d_buf + addr_off;
7753 size_t tu_nr = (nextp - readp) / 24;
7755 printf (gettext ("\n TU list at offset %#" PRIx32
7756 " contains %zu entries:\n"),
7760 while (readp + 24 <= dataend && n < tu_nr)
7762 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7765 uint64_t type = read_8ubyte_unaligned (dbg, readp);
7768 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7771 printf (" [%4zu] CU offset: %5" PRId64
7772 ", type offset: %5" PRId64
7773 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7777 readp = data->d_buf + addr_off;
7778 nextp = data->d_buf + sym_off;
7779 size_t addr_nr = (nextp - readp) / 20;
7781 printf (gettext ("\n Address list at offset %#" PRIx32
7782 " contains %zu entries:\n"),
7786 while (readp + 20 <= dataend && n < addr_nr)
7788 uint64_t low = read_8ubyte_unaligned (dbg, readp);
7791 uint64_t high = read_8ubyte_unaligned (dbg, readp);
7794 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7797 char *l = format_dwarf_addr (dwflmod, 8, low, low);
7798 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7799 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7806 readp = data->d_buf + sym_off;
7807 nextp = data->d_buf + const_off;
7808 size_t sym_nr = (nextp - readp) / 8;
7810 printf (gettext ("\n Symbol table at offset %#" PRIx32
7811 " contains %zu slots:\n"),
7815 while (readp + 8 <= dataend && n < sym_nr)
7817 uint32_t name = read_4ubyte_unaligned (dbg, readp);
7820 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7823 if (name != 0 || vector != 0)
7825 const unsigned char *sym = data->d_buf + const_off + name;
7826 if (unlikely (sym > dataend))
7829 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7831 const unsigned char *readcus = data->d_buf + const_off + vector;
7832 if (unlikely (readcus + 8 > dataend))
7835 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7838 uint32_t cu_kind, cu, kind;
7841 cu_kind = read_4ubyte_unaligned (dbg, readcus);
7842 cu = cu_kind & ((1 << 24) - 1);
7843 kind = (cu_kind >> 28) & 7;
7844 is_static = cu_kind & (1U << 31);
7846 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
7848 printf ("%" PRId32, cu);
7867 printf ("unknown-0x%" PRIx32, kind);
7870 printf (":%c)", (is_static ? 'S' : 'G'));
7882 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7884 /* Before we start the real work get a debug context descriptor. */
7886 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7890 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7894 if ((print_debug_sections & ~section_exception) != 0)
7895 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7897 if ((print_debug_sections & section_exception) == 0)
7902 /* Get the section header string table index. */
7904 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7905 error (EXIT_FAILURE, 0,
7906 gettext ("cannot get section header string table index"));
7908 /* Look through all the sections for the debugging sections to print. */
7909 Elf_Scn *scn = NULL;
7910 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7913 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7915 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7920 enum section_e bitmask;
7921 void (*fp) (Dwfl_Module *, Ebl *,
7922 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7923 } debug_sections[] =
7925 #define NEW_SECTION(name) \
7926 { ".debug_" #name, section_##name, print_debug_##name##_section }
7927 NEW_SECTION (abbrev),
7928 NEW_SECTION (aranges),
7929 NEW_SECTION (frame),
7931 NEW_SECTION (types),
7934 NEW_SECTION (pubnames),
7936 NEW_SECTION (macinfo),
7937 NEW_SECTION (macro),
7938 NEW_SECTION (ranges),
7939 { ".eh_frame", section_frame | section_exception,
7940 print_debug_frame_section },
7941 { ".eh_frame_hdr", section_frame | section_exception,
7942 print_debug_frame_hdr_section },
7943 { ".gcc_except_table", section_frame | section_exception,
7944 print_debug_exception_table },
7945 { ".gdb_index", section_gdb_index, print_gdb_index_section }
7947 const int ndebug_sections = (sizeof (debug_sections)
7948 / sizeof (debug_sections[0]));
7949 const char *name = elf_strptr (ebl->elf, shstrndx,
7953 for (n = 0; n < ndebug_sections; ++n)
7954 if (strcmp (name, debug_sections[n].name) == 0
7956 || (name[0] == '.' && name[1] == 'z'
7957 && debug_sections[n].name[1] == 'd'
7958 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
7962 if ((print_debug_sections | implicit_debug_sections)
7963 & debug_sections[n].bitmask)
7964 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
7970 reset_listptr (&known_loclistptr);
7971 reset_listptr (&known_rangelistptr);
7975 #define ITEM_INDENT 4
7976 #define WRAP_COLUMN 75
7978 /* Print "NAME: FORMAT", wrapping when output text would make the line
7979 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
7980 but this function is also used for registers which should be printed
7981 aligned. Fortunately registers output uses fixed fields width (such
7982 as %11d) for the alignment.
7984 Line breaks should not depend on the particular values although that
7985 may happen in some cases of the core items. */
7988 __attribute__ ((format (printf, 6, 7)))
7989 print_core_item (unsigned int colno, char sep, unsigned int wrap,
7990 size_t name_width, const char *name, const char *format, ...)
7992 size_t len = strlen (name);
7993 if (name_width < len)
7998 va_start (ap, format);
7999 int out_len = vasprintf (&out, format, ap);
8002 error (EXIT_FAILURE, 0, _("memory exhausted"));
8004 size_t n = name_width + sizeof ": " - 1 + out_len;
8008 printf ("%*s", ITEM_INDENT, "");
8009 colno = ITEM_INDENT + n;
8011 else if (colno + 2 + n < wrap)
8013 printf ("%c ", sep);
8018 printf ("\n%*s", ITEM_INDENT, "");
8019 colno = ITEM_INDENT + n;
8022 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8030 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8031 void *value, const void *data, size_t size)
8033 Elf_Data valuedata =
8037 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8038 .d_version = EV_CURRENT,
8043 .d_buf = (void *) data,
8044 .d_size = valuedata.d_size,
8045 .d_version = EV_CURRENT,
8048 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8049 ? elf32_xlatetom : elf64_xlatetom)
8050 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8052 error (EXIT_FAILURE, 0,
8053 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8055 return data + indata.d_size;
8058 typedef uint8_t GElf_Byte;
8061 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8062 unsigned int colno, size_t *repeated_size)
8064 uint_fast16_t count = item->count ?: 1;
8067 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8068 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8069 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8070 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8071 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8072 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8074 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8075 union { TYPES; } value;
8078 void *data = &value;
8079 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8080 size_t convsize = size;
8081 if (repeated_size != NULL)
8083 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8085 data = alloca (*repeated_size);
8086 count *= *repeated_size / size;
8087 convsize = count * size;
8088 *repeated_size -= convsize;
8090 else if (item->count != 0 || item->format != '\n')
8091 *repeated_size -= size;
8094 convert (core, item->type, count, data, desc + item->offset, convsize);
8096 Elf_Type type = item->type;
8097 if (type == ELF_T_ADDR)
8098 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8100 switch (item->format)
8103 assert (count == 1);
8106 #define DO_TYPE(NAME, Name, hex, dec) \
8107 case ELF_T_##NAME: \
8108 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8109 0, item->name, dec, value.Name[0]); \
8119 assert (count == 1);
8122 #define DO_TYPE(NAME, Name, hex, dec) \
8123 case ELF_T_##NAME: \
8124 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8125 0, item->name, hex, value.Name[0]); \
8136 assert (size % sizeof (unsigned int) == 0);
8137 unsigned int nbits = count * size * 8;
8138 unsigned int pop = 0;
8139 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8140 pop += __builtin_popcount (*i);
8141 bool negate = pop > nbits / 2;
8142 const unsigned int bias = item->format == 'b';
8145 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8149 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8151 assert (size == sizeof (unsigned int) * 2);
8152 for (unsigned int *i = data;
8153 (void *) i < data + count * size; i += 2)
8155 unsigned int w = i[1];
8161 unsigned int lastbit = 0;
8162 unsigned int run = 0;
8163 for (const unsigned int *i = data;
8164 (void *) i < data + count * size; ++i)
8166 unsigned int bit = ((void *) i - data) * 8;
8167 unsigned int w = negate ? ~*i : *i;
8174 if (lastbit != 0 && lastbit + 1 == bit)
8179 p += sprintf (p, "%u", bit - bias);
8181 p += sprintf (p, ",%u", bit - bias);
8183 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8190 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8191 p += sprintf (p, "-%u", lastbit - bias);
8193 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8194 negate ? "~<%s>" : "<%s>", printed);
8199 case (char) ('T'|0x80):
8200 assert (count == 2);
8205 #define DO_TYPE(NAME, Name, hex, dec) \
8206 case ELF_T_##NAME: \
8207 sec = value.Name[0]; \
8208 usec = value.Name[1]; \
8215 if (unlikely (item->format == (char) ('T'|0x80)))
8217 /* This is a hack for an ill-considered 64-bit ABI where
8218 tv_usec is actually a 32-bit field with 32 bits of padding
8219 rounding out struct timeval. We've already converted it as
8220 a 64-bit field. For little-endian, this just means the
8221 high half is the padding; it's presumably zero, but should
8222 be ignored anyway. For big-endian, it means the 32-bit
8223 field went into the high half of USEC. */
8225 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8226 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8231 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8232 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8236 assert (count == 1);
8237 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8238 "%c", value.Byte[0]);
8242 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8243 "%.*s", (int) count, value.Byte);
8247 /* This is a list of strings separated by '\n'. */
8248 assert (item->count == 0);
8249 assert (repeated_size != NULL);
8250 assert (item->name == NULL);
8251 if (unlikely (item->offset >= *repeated_size))
8254 const char *s = desc + item->offset;
8255 size = *repeated_size - item->offset;
8259 const char *eol = memchr (s, '\n', size);
8263 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8266 size -= eol + 1 - s;
8270 colno = WRAP_COLUMN;
8277 error (0, 0, "XXX not handling format '%c' for %s",
8278 item->format, item->name);
8288 /* Sort items by group, and by layout offset within each group. */
8290 compare_core_items (const void *a, const void *b)
8292 const Ebl_Core_Item *const *p1 = a;
8293 const Ebl_Core_Item *const *p2 = b;
8294 const Ebl_Core_Item *item1 = *p1;
8295 const Ebl_Core_Item *item2 = *p2;
8297 return ((item1->group == item2->group ? 0
8298 : strcmp (item1->group, item2->group))
8299 ?: (int) item1->offset - (int) item2->offset);
8302 /* Sort item groups by layout offset of the first item in the group. */
8304 compare_core_item_groups (const void *a, const void *b)
8306 const Ebl_Core_Item *const *const *p1 = a;
8307 const Ebl_Core_Item *const *const *p2 = b;
8308 const Ebl_Core_Item *const *group1 = *p1;
8309 const Ebl_Core_Item *const *group2 = *p2;
8310 const Ebl_Core_Item *item1 = *group1;
8311 const Ebl_Core_Item *item2 = *group2;
8313 return (int) item1->offset - (int) item2->offset;
8317 handle_core_items (Elf *core, const void *desc, size_t descsz,
8318 const Ebl_Core_Item *items, size_t nitems)
8322 unsigned int colno = 0;
8324 /* FORMAT '\n' makes sense to be present only as a single item as it
8325 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8326 if present as a single item but they can be also processed with other
8328 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8329 || items[0].format == 'B'))
8331 assert (items[0].offset == 0);
8332 size_t size = descsz;
8333 colno = handle_core_item (core, items, desc, colno, &size);
8334 /* If SIZE is not zero here there is some remaining data. But we do not
8335 know how to process it anyway. */
8338 for (size_t i = 0; i < nitems; ++i)
8339 assert (items[i].format != '\n');
8341 /* Sort to collect the groups together. */
8342 const Ebl_Core_Item *sorted_items[nitems];
8343 for (size_t i = 0; i < nitems; ++i)
8344 sorted_items[i] = &items[i];
8345 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8347 /* Collect the unique groups and sort them. */
8348 const Ebl_Core_Item **groups[nitems];
8349 groups[0] = &sorted_items[0];
8351 for (size_t i = 1; i < nitems; ++i)
8352 if (sorted_items[i]->group != sorted_items[i - 1]->group
8353 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8354 groups[ngroups++] = &sorted_items[i];
8355 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8357 /* Write out all the groups. */
8358 const void *last = desc;
8361 for (size_t i = 0; i < ngroups; ++i)
8363 for (const Ebl_Core_Item **item = groups[i];
8364 (item < &sorted_items[nitems]
8365 && ((*item)->group == groups[i][0]->group
8366 || !strcmp ((*item)->group, groups[i][0]->group)));
8368 colno = handle_core_item (core, *item, desc, colno, NULL);
8370 /* Force a line break at the end of the group. */
8371 colno = WRAP_COLUMN;
8377 /* This set of items consumed a certain amount of the note's data.
8378 If there is more data there, we have another unit of the same size.
8379 Loop to print that out too. */
8380 const Ebl_Core_Item *item = &items[nitems - 1];
8381 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8382 item->count ?: 1, EV_CURRENT);
8391 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8395 /* For just one repeat, print it unabridged twice. */
8400 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8401 ITEM_INDENT, "", reps);
8411 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8414 desc += regloc->offset;
8422 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8423 const Ebl_Register_Location *regloc, const void *desc,
8426 if (regloc->bits % 8 != 0)
8427 return handle_bit_registers (regloc, desc, colno);
8429 desc += regloc->offset;
8431 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8433 char name[REGNAMESZ];
8436 register_info (ebl, reg, regloc, name, &bits, &type);
8439 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8440 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8441 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8442 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8444 #define BITS(bits, xtype, sfmt, ufmt) \
8445 uint##bits##_t b##bits; int##bits##_t b##bits##s
8446 union { TYPES; uint64_t b128[2]; } value;
8451 case DW_ATE_unsigned:
8453 case DW_ATE_address:
8456 #define BITS(bits, xtype, sfmt, ufmt) \
8458 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8459 if (type == DW_ATE_signed) \
8460 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8462 sfmt, value.b##bits##s); \
8464 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8466 ufmt, value.b##bits); \
8472 assert (type == DW_ATE_unsigned);
8473 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8474 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8475 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8477 "0x%.16" PRIx64 "%.16" PRIx64,
8478 value.b128[!be], value.b128[be]);
8488 /* Print each byte in hex, the whole thing in native byte order. */
8489 assert (bits % 8 == 0);
8490 const uint8_t *bytes = desc;
8492 char hex[bits / 4 + 1];
8493 hex[bits / 4] = '\0';
8495 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8497 bytes += bits / 8 - 1;
8501 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8503 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8504 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8506 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8507 maxregname, name, "0x%s", hex);
8510 desc += regloc->pad;
8519 struct register_info
8521 const Ebl_Register_Location *regloc;
8523 char name[REGNAMESZ];
8530 register_bitpos (const struct register_info *r)
8532 return (r->regloc->offset * 8
8533 + ((r->regno - r->regloc->regno)
8534 * (r->regloc->bits + r->regloc->pad * 8)));
8538 compare_sets_by_info (const struct register_info *r1,
8539 const struct register_info *r2)
8541 return ((int) r2->bits - (int) r1->bits
8542 ?: register_bitpos (r1) - register_bitpos (r2));
8545 /* Sort registers by set, and by size and layout offset within each set. */
8547 compare_registers (const void *a, const void *b)
8549 const struct register_info *r1 = a;
8550 const struct register_info *r2 = b;
8552 /* Unused elements sort last. */
8553 if (r1->regloc == NULL)
8554 return r2->regloc == NULL ? 0 : 1;
8555 if (r2->regloc == NULL)
8558 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8559 ?: compare_sets_by_info (r1, r2));
8562 /* Sort register sets by layout offset of the first register in the set. */
8564 compare_register_sets (const void *a, const void *b)
8566 const struct register_info *const *p1 = a;
8567 const struct register_info *const *p2 = b;
8568 return compare_sets_by_info (*p1, *p2);
8572 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8573 const Ebl_Register_Location *reglocs, size_t nregloc)
8578 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8581 for (size_t i = 0; i < nregloc; ++i)
8582 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8583 maxnreg = reglocs[i].regno + reglocs[i].count;
8584 assert (maxnreg > 0);
8587 struct register_info regs[maxnreg];
8588 memset (regs, 0, sizeof regs);
8590 /* Sort to collect the sets together. */
8592 for (size_t i = 0; i < nregloc; ++i)
8593 for (int reg = reglocs[i].regno;
8594 reg < reglocs[i].regno + reglocs[i].count;
8597 assert (reg < maxnreg);
8600 struct register_info *info = ®s[reg];
8601 info->regloc = ®locs[i];
8603 info->set = register_info (ebl, reg, ®locs[i],
8604 info->name, &info->bits, &info->type);
8606 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8608 /* Collect the unique sets and sort them. */
8609 inline bool same_set (const struct register_info *a,
8610 const struct register_info *b)
8612 return (a < ®s[maxnreg] && a->regloc != NULL
8613 && b < ®s[maxnreg] && b->regloc != NULL
8614 && a->bits == b->bits
8615 && (a->set == b->set || !strcmp (a->set, b->set)));
8617 struct register_info *sets[maxreg + 1];
8620 for (int i = 1; i <= maxreg; ++i)
8621 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8622 sets[nsets++] = ®s[i];
8623 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8625 /* Write out all the sets. */
8626 unsigned int colno = 0;
8627 for (size_t i = 0; i < nsets; ++i)
8629 /* Find the longest name of a register in this set. */
8631 const struct register_info *end;
8632 for (end = sets[i]; same_set (sets[i], end); ++end)
8634 size_t len = strlen (end->name);
8639 for (const struct register_info *reg = sets[i];
8641 reg += reg->regloc->count ?: 1)
8642 colno = handle_core_register (ebl, core, maxname,
8643 reg->regloc, desc, colno);
8645 /* Force a line break at the end of the group. */
8646 colno = WRAP_COLUMN;
8653 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8655 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8658 error (EXIT_FAILURE, 0,
8659 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8661 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8662 for (size_t i = 0; i < nauxv; ++i)
8665 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8671 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8674 if (av->a_un.a_val == 0)
8675 printf (" %" PRIu64 "\n", av->a_type);
8677 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8678 av->a_type, av->a_un.a_val);
8683 case '\0': /* Normally zero. */
8684 if (av->a_un.a_val == 0)
8686 printf (" %s\n", name);
8691 case 'p': /* address */
8692 case 's': /* address of string */
8693 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8696 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8699 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8703 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8705 const char *pfx = "<";
8706 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8708 if (av->a_un.a_val & bit)
8710 printf ("%s%s", pfx, p);
8725 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8727 return ptr < end && (size_t) (end - ptr) >= sz;
8731 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8734 if (! buf_has_data (*ptrp, end, 4))
8737 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8742 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8745 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8746 if (! buf_has_data (*ptrp, end, sz))
8755 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
8765 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8767 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8769 error (EXIT_FAILURE, 0,
8770 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8772 unsigned char const *ptr = data->d_buf;
8773 unsigned char const *const end = data->d_buf + data->d_size;
8775 /* Siginfo head is three ints: signal number, error number, origin
8777 int si_signo, si_errno, si_code;
8778 if (! buf_read_int (core, &ptr, end, &si_signo)
8779 || ! buf_read_int (core, &ptr, end, &si_errno)
8780 || ! buf_read_int (core, &ptr, end, &si_code))
8783 printf (" Not enough data in NT_SIGINFO note.\n");
8787 /* Next is a pointer-aligned union of structures. On 64-bit
8788 machines, that implies a word of padding. */
8789 if (gelf_getclass (core) == ELFCLASS64)
8792 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
8793 si_signo, si_errno, si_code);
8804 if (! buf_read_ulong (core, &ptr, end, &addr))
8806 printf (" fault address: %#" PRIx64 "\n", addr);
8812 else if (si_code == SI_USER)
8815 if (! buf_read_int (core, &ptr, end, &pid)
8816 || ! buf_read_int (core, &ptr, end, &uid))
8818 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
8823 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8825 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8827 error (EXIT_FAILURE, 0,
8828 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8830 unsigned char const *ptr = data->d_buf;
8831 unsigned char const *const end = data->d_buf + data->d_size;
8833 uint64_t count, page_size;
8834 if (! buf_read_ulong (core, &ptr, end, &count)
8835 || ! buf_read_ulong (core, &ptr, end, &page_size))
8838 printf (" Not enough data in NT_FILE note.\n");
8842 /* Where file names are stored. */
8843 unsigned char const *const fstart
8844 = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8845 char const *fptr = (char *) fstart;
8847 printf (" %" PRId64 " files:\n", count);
8848 for (uint64_t i = 0; i < count; ++i)
8850 uint64_t mstart, mend, moffset;
8851 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
8852 || ! buf_read_ulong (core, &ptr, fstart, &mend)
8853 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
8856 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
8860 int ct = printf (" %08" PRIx64 "-%08" PRIx64
8861 " %08" PRIx64 " %" PRId64,
8862 mstart, mend, moffset * page_size, mend - mstart);
8863 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
8870 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8871 const char *name, const void *desc)
8873 GElf_Word regs_offset;
8875 const Ebl_Register_Location *reglocs;
8877 const Ebl_Core_Item *items;
8879 if (! ebl_core_note (ebl, nhdr, name,
8880 ®s_offset, &nregloc, ®locs, &nitems, &items))
8883 /* Pass 0 for DESCSZ when there are registers in the note,
8884 so that the ITEMS array does not describe the whole thing.
8885 For non-register notes, the actual descsz might be a multiple
8886 of the unit size, not just exactly the unit size. */
8887 unsigned int colno = handle_core_items (ebl->elf, desc,
8888 nregloc == 0 ? nhdr->n_descsz : 0,
8891 putchar_unlocked ('\n');
8893 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8896 putchar_unlocked ('\n');
8900 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8901 GElf_Off start, Elf_Data *data)
8903 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
8912 while (offset < data->d_size
8913 && (offset = gelf_getnote (data, offset,
8914 &nhdr, &name_offset, &desc_offset)) > 0)
8916 const char *name = data->d_buf + name_offset;
8917 const char *desc = data->d_buf + desc_offset;
8921 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
8922 (int) nhdr.n_namesz, name, nhdr.n_descsz,
8923 ehdr->e_type == ET_CORE
8924 ? ebl_core_note_type_name (ebl, nhdr.n_type,
8926 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8927 buf2, sizeof (buf2)));
8929 /* Filter out invalid entries. */
8930 if (memchr (name, '\0', nhdr.n_namesz) != NULL
8931 /* XXX For now help broken Linux kernels. */
8934 if (ehdr->e_type == ET_CORE)
8936 if (nhdr.n_type == NT_AUXV
8937 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
8938 || (nhdr.n_namesz == 5 && name[4] == '\0'))
8939 && !memcmp (name, "CORE", 4))
8940 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
8941 start + desc_offset);
8942 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
8943 switch (nhdr.n_type)
8946 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
8947 start + desc_offset);
8951 handle_file_note (ebl->elf, nhdr.n_descsz,
8952 start + desc_offset);
8956 handle_core_note (ebl, &nhdr, name, desc);
8959 handle_core_note (ebl, &nhdr, name, desc);
8962 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
8966 if (offset == data->d_size)
8970 error (EXIT_FAILURE, 0,
8971 gettext ("cannot get content of note section: %s"),
8976 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
8978 /* If we have section headers, just look for SHT_NOTE sections.
8979 In a debuginfo file, the program headers are not reliable. */
8982 /* Get the section header string table index. */
8984 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
8985 error (EXIT_FAILURE, 0,
8986 gettext ("cannot get section header string table index"));
8988 Elf_Scn *scn = NULL;
8989 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8992 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8994 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
8995 /* Not what we are looking for. */
8999 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9001 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9002 shdr->sh_size, shdr->sh_offset);
9004 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9005 elf_getdata (scn, NULL));
9010 /* We have to look through the program header to find the note
9011 sections. There can be more than one. */
9012 for (size_t cnt = 0; cnt < phnum; ++cnt)
9015 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9017 if (phdr == NULL || phdr->p_type != PT_NOTE)
9018 /* Not what we are looking for. */
9022 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9023 phdr->p_filesz, phdr->p_offset);
9025 handle_notes_data (ebl, ehdr, phdr->p_offset,
9026 elf_getdata_rawchunk (ebl->elf,
9027 phdr->p_offset, phdr->p_filesz,
9034 hex_dump (const uint8_t *data, size_t len)
9039 printf (" 0x%08Zx ", pos);
9041 const size_t chunk = MIN (len - pos, 16);
9043 for (size_t i = 0; i < chunk; ++i)
9045 printf ("%02x ", data[pos + i]);
9047 printf ("%02x", data[pos + i]);
9050 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9052 for (size_t i = 0; i < chunk; ++i)
9054 unsigned char b = data[pos + i];
9055 printf ("%c", isprint (b) ? b : '.');
9064 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9066 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9067 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9068 elf_ndxscn (scn), name);
9071 Elf_Data *data = elf_rawdata (scn, NULL);
9073 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9074 elf_ndxscn (scn), name, elf_errmsg (-1));
9077 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9078 " bytes at offset %#0" PRIx64 ":\n"),
9079 elf_ndxscn (scn), name,
9080 shdr->sh_size, shdr->sh_offset);
9081 hex_dump (data->d_buf, data->d_size);
9087 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9089 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9090 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9091 elf_ndxscn (scn), name);
9094 Elf_Data *data = elf_rawdata (scn, NULL);
9096 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9097 elf_ndxscn (scn), name, elf_errmsg (-1));
9100 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9101 " bytes at offset %#0" PRIx64 ":\n"),
9102 elf_ndxscn (scn), name,
9103 shdr->sh_size, shdr->sh_offset);
9105 const char *start = data->d_buf;
9106 const char *const limit = start + data->d_size;
9109 const char *end = memchr (start, '\0', limit - start);
9110 const size_t pos = start - (const char *) data->d_buf;
9111 if (unlikely (end == NULL))
9113 printf (" [%6Zx]- %.*s\n",
9114 pos, (int) (limit - start), start);
9117 printf (" [%6Zx] %s\n", pos, start);
9119 } while (start < limit);
9125 for_each_section_argument (Elf *elf, const struct section_argument *list,
9126 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9129 /* Get the section header string table index. */
9131 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9132 error (EXIT_FAILURE, 0,
9133 gettext ("cannot get section header string table index"));
9135 for (const struct section_argument *a = list; a != NULL; a = a->next)
9139 const char *name = NULL;
9142 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9143 if (endp != a->arg && *endp == '\0')
9145 scn = elf_getscn (elf, shndx);
9148 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9152 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9153 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9155 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9159 /* Need to look up the section by name. */
9162 while ((scn = elf_nextscn (elf, scn)) != NULL)
9164 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9166 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9169 if (!strcmp (name, a->arg))
9172 (*dump) (scn, &shdr_mem, name);
9176 if (unlikely (!found) && !a->implicit)
9177 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9183 dump_data (Ebl *ebl)
9185 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9189 dump_strings (Ebl *ebl)
9191 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9195 print_strings (Ebl *ebl)
9197 /* Get the section header string table index. */
9199 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9200 error (EXIT_FAILURE, 0,
9201 gettext ("cannot get section header string table index"));
9207 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9209 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9212 if (shdr_mem.sh_type != SHT_PROGBITS
9213 || !(shdr_mem.sh_flags & SHF_STRINGS))
9216 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9220 print_string_section (scn, &shdr_mem, name);
9225 dump_archive_index (Elf *elf, const char *fname)
9228 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9231 int result = elf_errno ();
9232 if (unlikely (result != ELF_E_NO_INDEX))
9233 error (EXIT_FAILURE, 0,
9234 gettext ("cannot get symbol index of archive '%s': %s"),
9235 fname, elf_errmsg (result));
9237 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9241 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9245 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9247 if (s->as_off != as_off)
9252 if (unlikely (elf_rand (elf, as_off) == 0)
9253 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9255 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9258 error (EXIT_FAILURE, 0,
9259 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9260 as_off, fname, elf_errmsg (-1));
9262 const Elf_Arhdr *h = elf_getarhdr (subelf);
9264 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9269 printf ("\t%s\n", s->as_name);
9273 #include "debugpred.h"