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)
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 /* This is a relocation against a STT_SECTION symbol. */
1898 GElf_Shdr secshdr_mem;
1900 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
1901 sym->st_shndx == SHN_XINDEX
1902 ? xndx : sym->st_shndx),
1905 if (unlikely (secshdr == NULL))
1906 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1907 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1908 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1909 /* Avoid the leading R_ which isn't carrying any
1911 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1912 buf, sizeof (buf)) + 2
1913 : gettext ("<INVALID RELOC>"),
1914 gettext ("INVALID SECTION"),
1915 (long int) (sym->st_shndx == SHN_XINDEX
1916 ? xndx : sym->st_shndx));
1918 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1919 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1920 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1921 /* Avoid the leading R_ which isn't carrying any
1923 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1924 buf, sizeof (buf)) + 2
1925 : gettext ("<INVALID RELOC>"),
1926 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1927 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
1934 /* Handle a relocation section. */
1936 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1938 int class = gelf_getclass (ebl->elf);
1939 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1940 int nentries = shdr->sh_size / sh_entsize;
1942 /* Get the data of the section. */
1943 Elf_Data *data = elf_getdata (scn, NULL);
1947 /* Get the symbol table information. */
1948 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1949 GElf_Shdr symshdr_mem;
1950 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1951 Elf_Data *symdata = elf_getdata (symscn, NULL);
1953 /* Get the section header of the section the relocations are for. */
1954 GElf_Shdr destshdr_mem;
1955 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1958 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1960 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1965 /* Search for the optional extended section index table. */
1966 Elf_Data *xndxdata = NULL;
1967 int xndxscnidx = elf_scnshndx (scn);
1968 if (unlikely (xndxscnidx > 0))
1969 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1971 /* Get the section header string table index. */
1973 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1974 error (EXIT_FAILURE, 0,
1975 gettext ("cannot get section header string table index"));
1977 if (shdr->sh_info != 0)
1978 printf (ngettext ("\
1979 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1981 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1984 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1985 (unsigned int) shdr->sh_info,
1986 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1990 /* The .rela.dyn section does not refer to a specific section but
1991 instead of section index zero. Do not try to print a section
1993 printf (ngettext ("\
1994 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1996 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1998 (unsigned int) elf_ndxscn (scn),
1999 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2002 fputs_unlocked (class == ELFCLASS32
2004 Offset Type Value Addend Name\n")
2006 Offset Type Value Addend Name\n"),
2009 int is_statically_linked = 0;
2010 for (int cnt = 0; cnt < nentries; ++cnt)
2013 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2014 if (likely (rel != NULL))
2019 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2020 GELF_R_SYM (rel->r_info),
2023 if (unlikely (sym == NULL))
2025 /* As a special case we have to handle relocations in static
2026 executables. This only happens for IRELATIVE relocations
2027 (so far). There is no symbol table. */
2028 if (is_statically_linked == 0)
2030 /* Find the program header and look for a PT_INTERP entry. */
2031 is_statically_linked = -1;
2032 if (ehdr->e_type == ET_EXEC)
2034 is_statically_linked = 1;
2036 for (size_t inner = 0; inner < phnum; ++inner)
2039 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2041 if (phdr != NULL && phdr->p_type == PT_INTERP)
2043 is_statically_linked = -1;
2050 if (is_statically_linked > 0 && shdr->sh_link == 0)
2052 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2053 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2054 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2055 /* Avoid the leading R_ which isn't carrying any
2057 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2058 buf, sizeof (buf)) + 2
2059 : gettext ("<INVALID RELOC>"),
2060 class == ELFCLASS32 ? 10 : 18, "",
2062 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2064 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2065 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2066 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2067 /* Avoid the leading R_ which isn't carrying any
2069 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2070 buf, sizeof (buf)) + 2
2071 : gettext ("<INVALID RELOC>"),
2072 gettext ("INVALID SYMBOL"),
2073 (long int) GELF_R_SYM (rel->r_info));
2075 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2077 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2078 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2079 likely (ebl_reloc_type_check (ebl,
2080 GELF_R_TYPE (rel->r_info)))
2081 /* Avoid the leading R_ which isn't carrying any
2083 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2084 buf, sizeof (buf)) + 2
2085 : gettext ("<INVALID RELOC>"),
2086 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2088 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2091 /* This is a relocation against a STT_SECTION symbol. */
2092 GElf_Shdr secshdr_mem;
2094 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2095 sym->st_shndx == SHN_XINDEX
2096 ? xndx : sym->st_shndx),
2099 if (unlikely (secshdr == NULL))
2100 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2101 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2102 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2103 /* Avoid the leading R_ which isn't carrying any
2105 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2106 buf, sizeof (buf)) + 2
2107 : gettext ("<INVALID RELOC>"),
2108 gettext ("INVALID SECTION"),
2109 (long int) (sym->st_shndx == SHN_XINDEX
2110 ? xndx : sym->st_shndx));
2113 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2114 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2115 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2116 /* Avoid the leading R_ which isn't carrying any
2118 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2119 buf, sizeof (buf)) + 2
2120 : gettext ("<INVALID RELOC>"),
2121 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2123 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2130 /* Print the program header. */
2132 print_symtab (Ebl *ebl, int type)
2134 /* Find the symbol table(s). For this we have to search through the
2136 Elf_Scn *scn = NULL;
2138 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2140 /* Handle the section if it is a symbol table. */
2142 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2144 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2145 handle_symtab (ebl, scn, shdr);
2151 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2153 Elf_Data *versym_data = NULL;
2154 Elf_Data *verneed_data = NULL;
2155 Elf_Data *verdef_data = NULL;
2156 Elf_Data *xndx_data = NULL;
2157 int class = gelf_getclass (ebl->elf);
2158 Elf32_Word verneed_stridx = 0;
2159 Elf32_Word verdef_stridx = 0;
2161 /* Get the data of the section. */
2162 Elf_Data *data = elf_getdata (scn, NULL);
2166 /* Find out whether we have other sections we might need. */
2167 Elf_Scn *runscn = NULL;
2168 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2170 GElf_Shdr runshdr_mem;
2171 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2173 if (likely (runshdr != NULL))
2175 if (runshdr->sh_type == SHT_GNU_versym
2176 && runshdr->sh_link == elf_ndxscn (scn))
2177 /* Bingo, found the version information. Now get the data. */
2178 versym_data = elf_getdata (runscn, NULL);
2179 else if (runshdr->sh_type == SHT_GNU_verneed)
2181 /* This is the information about the needed versions. */
2182 verneed_data = elf_getdata (runscn, NULL);
2183 verneed_stridx = runshdr->sh_link;
2185 else if (runshdr->sh_type == SHT_GNU_verdef)
2187 /* This is the information about the defined versions. */
2188 verdef_data = elf_getdata (runscn, NULL);
2189 verdef_stridx = runshdr->sh_link;
2191 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2192 && runshdr->sh_link == elf_ndxscn (scn))
2193 /* Extended section index. */
2194 xndx_data = elf_getdata (runscn, NULL);
2198 /* Get the section header string table index. */
2200 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2201 error (EXIT_FAILURE, 0,
2202 gettext ("cannot get section header string table index"));
2204 GElf_Shdr glink_mem;
2205 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2208 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2211 /* Now we can compute the number of entries in the section. */
2212 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2213 ? sizeof (Elf32_Sym)
2214 : sizeof (Elf64_Sym));
2216 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2217 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2219 (unsigned int) elf_ndxscn (scn),
2220 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2221 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2222 " %lu local symbols String table: [%2u] '%s'\n",
2224 (unsigned long int) shdr->sh_info,
2225 (unsigned int) shdr->sh_link,
2226 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2228 fputs_unlocked (class == ELFCLASS32
2230 Num: Value Size Type Bind Vis Ndx Name\n")
2232 Num: Value Size Type Bind Vis Ndx Name\n"),
2235 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2242 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2244 if (unlikely (sym == NULL))
2247 /* Determine the real section index. */
2248 if (likely (sym->st_shndx != SHN_XINDEX))
2249 xndx = sym->st_shndx;
2252 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2254 class == ELFCLASS32 ? 8 : 16,
2257 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2258 typebuf, sizeof (typebuf)),
2259 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2260 bindbuf, sizeof (bindbuf)),
2261 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2262 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2263 sizeof (scnbuf), NULL, shnum),
2264 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2266 if (versym_data != NULL)
2268 /* Get the version information. */
2269 GElf_Versym versym_mem;
2270 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2272 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2274 bool is_nobits = false;
2275 bool check_def = xndx != SHN_UNDEF;
2277 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2279 GElf_Shdr symshdr_mem;
2280 GElf_Shdr *symshdr =
2281 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2283 is_nobits = (symshdr != NULL
2284 && symshdr->sh_type == SHT_NOBITS);
2287 if (is_nobits || ! check_def)
2289 /* We must test both. */
2290 GElf_Vernaux vernaux_mem;
2291 GElf_Vernaux *vernaux = NULL;
2292 size_t vn_offset = 0;
2294 GElf_Verneed verneed_mem;
2295 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2297 while (verneed != NULL)
2299 size_t vna_offset = vn_offset;
2301 vernaux = gelf_getvernaux (verneed_data,
2302 vna_offset += verneed->vn_aux,
2304 while (vernaux != NULL
2305 && vernaux->vna_other != *versym
2306 && vernaux->vna_next != 0)
2308 /* Update the offset. */
2309 vna_offset += vernaux->vna_next;
2311 vernaux = (vernaux->vna_next == 0
2313 : gelf_getvernaux (verneed_data,
2318 /* Check whether we found the version. */
2319 if (vernaux != NULL && vernaux->vna_other == *versym)
2323 vn_offset += verneed->vn_next;
2324 verneed = (verneed->vn_next == 0
2326 : gelf_getverneed (verneed_data, vn_offset,
2330 if (vernaux != NULL && vernaux->vna_other == *versym)
2333 elf_strptr (ebl->elf, verneed_stridx,
2335 (unsigned int) vernaux->vna_other);
2338 else if (unlikely (! is_nobits))
2339 error (0, 0, gettext ("bad dynamic symbol"));
2344 if (check_def && *versym != 0x8001)
2346 /* We must test both. */
2347 size_t vd_offset = 0;
2349 GElf_Verdef verdef_mem;
2350 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2352 while (verdef != NULL)
2354 if (verdef->vd_ndx == (*versym & 0x7fff))
2355 /* Found the definition. */
2358 vd_offset += verdef->vd_next;
2359 verdef = (verdef->vd_next == 0
2361 : gelf_getverdef (verdef_data, vd_offset,
2367 GElf_Verdaux verdaux_mem;
2368 GElf_Verdaux *verdaux
2369 = gelf_getverdaux (verdef_data,
2370 vd_offset + verdef->vd_aux,
2373 if (verdaux != NULL)
2374 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2375 elf_strptr (ebl->elf, verdef_stridx,
2376 verdaux->vda_name));
2382 putchar_unlocked ('\n');
2387 /* Print version information. */
2389 print_verinfo (Ebl *ebl)
2391 /* Find the version information sections. For this we have to
2392 search through the section table. */
2393 Elf_Scn *scn = NULL;
2395 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2397 /* Handle the section if it is part of the versioning handling. */
2399 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2401 if (likely (shdr != NULL))
2403 if (shdr->sh_type == SHT_GNU_verneed)
2404 handle_verneed (ebl, scn, shdr);
2405 else if (shdr->sh_type == SHT_GNU_verdef)
2406 handle_verdef (ebl, scn, shdr);
2407 else if (shdr->sh_type == SHT_GNU_versym)
2408 handle_versym (ebl, scn, shdr);
2415 get_ver_flags (unsigned int flags)
2417 static char buf[32];
2421 return gettext ("none");
2423 if (flags & VER_FLG_BASE)
2424 endp = stpcpy (buf, "BASE ");
2428 if (flags & VER_FLG_WEAK)
2431 endp = stpcpy (endp, "| ");
2433 endp = stpcpy (endp, "WEAK ");
2436 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2438 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2439 buf[sizeof (buf) - 1] = '\0';
2447 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2449 int class = gelf_getclass (ebl->elf);
2451 /* Get the data of the section. */
2452 Elf_Data *data = elf_getdata (scn, NULL);
2456 /* Get the section header string table index. */
2458 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2459 error (EXIT_FAILURE, 0,
2460 gettext ("cannot get section header string table index"));
2462 GElf_Shdr glink_mem;
2463 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2466 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2469 printf (ngettext ("\
2470 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2472 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2474 (unsigned int) elf_ndxscn (scn),
2475 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2476 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2478 (unsigned int) shdr->sh_link,
2479 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2481 unsigned int offset = 0;
2482 for (int cnt = shdr->sh_info; --cnt >= 0; )
2484 /* Get the data at the next offset. */
2485 GElf_Verneed needmem;
2486 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2487 if (unlikely (need == NULL))
2490 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2491 offset, (unsigned short int) need->vn_version,
2492 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2493 (unsigned short int) need->vn_cnt);
2495 unsigned int auxoffset = offset + need->vn_aux;
2496 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2498 GElf_Vernaux auxmem;
2499 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2500 if (unlikely (aux == NULL))
2503 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2505 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2506 get_ver_flags (aux->vna_flags),
2507 (unsigned short int) aux->vna_other);
2509 if (aux->vna_next == 0)
2512 auxoffset += aux->vna_next;
2515 /* Find the next offset. */
2516 if (need->vn_next == 0)
2519 offset += need->vn_next;
2525 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2527 /* Get the data of the section. */
2528 Elf_Data *data = elf_getdata (scn, NULL);
2532 /* Get the section header string table index. */
2534 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2535 error (EXIT_FAILURE, 0,
2536 gettext ("cannot get section header string table index"));
2538 GElf_Shdr glink_mem;
2539 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2542 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2545 int class = gelf_getclass (ebl->elf);
2546 printf (ngettext ("\
2547 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2549 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2551 (unsigned int) elf_ndxscn (scn),
2552 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2554 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2556 (unsigned int) shdr->sh_link,
2557 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2559 unsigned int offset = 0;
2560 for (int cnt = shdr->sh_info; --cnt >= 0; )
2562 /* Get the data at the next offset. */
2564 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2565 if (unlikely (def == NULL))
2568 unsigned int auxoffset = offset + def->vd_aux;
2569 GElf_Verdaux auxmem;
2570 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2571 if (unlikely (aux == NULL))
2575 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2576 offset, def->vd_version,
2577 get_ver_flags (def->vd_flags),
2580 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2582 auxoffset += aux->vda_next;
2583 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2585 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2586 if (unlikely (aux == NULL))
2589 printf (gettext (" %#06x: Parent %d: %s\n"),
2591 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2593 if (aux->vda_next == 0)
2596 auxoffset += aux->vda_next;
2599 /* Find the next offset. */
2600 if (def->vd_next == 0)
2602 offset += def->vd_next;
2608 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2610 int class = gelf_getclass (ebl->elf);
2611 const char **vername;
2612 const char **filename;
2614 /* Get the data of the section. */
2615 Elf_Data *data = elf_getdata (scn, NULL);
2619 /* Get the section header string table index. */
2621 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2622 error (EXIT_FAILURE, 0,
2623 gettext ("cannot get section header string table index"));
2625 /* We have to find the version definition section and extract the
2627 Elf_Scn *defscn = NULL;
2628 Elf_Scn *needscn = NULL;
2630 Elf_Scn *verscn = NULL;
2631 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2633 GElf_Shdr vershdr_mem;
2634 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2636 if (likely (vershdr != NULL))
2638 if (vershdr->sh_type == SHT_GNU_verdef)
2640 else if (vershdr->sh_type == SHT_GNU_verneed)
2646 if (defscn != NULL || needscn != NULL)
2648 /* We have a version information (better should have). Now get
2649 the version names. First find the maximum version number. */
2653 /* Run through the version definitions and find the highest
2655 unsigned int offset = 0;
2657 GElf_Shdr defshdrmem;
2660 defdata = elf_getdata (defscn, NULL);
2661 if (unlikely (defdata == NULL))
2664 defshdr = gelf_getshdr (defscn, &defshdrmem);
2665 if (unlikely (defshdr == NULL))
2668 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2673 /* Get the data at the next offset. */
2674 def = gelf_getverdef (defdata, offset, &defmem);
2675 if (unlikely (def == NULL))
2678 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2680 if (def->vd_next == 0)
2682 offset += def->vd_next;
2685 if (needscn != NULL)
2687 unsigned int offset = 0;
2689 GElf_Shdr needshdrmem;
2690 GElf_Shdr *needshdr;
2692 needdata = elf_getdata (needscn, NULL);
2693 if (unlikely (needdata == NULL))
2696 needshdr = gelf_getshdr (needscn, &needshdrmem);
2697 if (unlikely (needshdr == NULL))
2700 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2702 GElf_Verneed needmem;
2704 unsigned int auxoffset;
2707 /* Get the data at the next offset. */
2708 need = gelf_getverneed (needdata, offset, &needmem);
2709 if (unlikely (need == NULL))
2712 /* Run through the auxiliary entries. */
2713 auxoffset = offset + need->vn_aux;
2714 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2716 GElf_Vernaux auxmem;
2719 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2720 if (unlikely (aux == NULL))
2723 nvername = MAX (nvername,
2724 (size_t) (aux->vna_other & 0x7fff));
2726 if (aux->vna_next == 0)
2728 auxoffset += aux->vna_next;
2731 if (need->vn_next == 0)
2733 offset += need->vn_next;
2737 /* This is the number of versions we know about. */
2740 /* Allocate the array. */
2741 vername = (const char **) alloca (nvername * sizeof (const char *));
2742 memset(vername, 0, nvername * sizeof (const char *));
2743 filename = (const char **) alloca (nvername * sizeof (const char *));
2744 memset(filename, 0, nvername * sizeof (const char *));
2746 /* Run through the data structures again and collect the strings. */
2749 /* Run through the version definitions and find the highest
2751 unsigned int offset = 0;
2753 GElf_Shdr defshdrmem;
2756 defdata = elf_getdata (defscn, NULL);
2757 if (unlikely (defdata == NULL))
2760 defshdr = gelf_getshdr (defscn, &defshdrmem);
2761 if (unlikely (defshdr == NULL))
2764 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2767 /* Get the data at the next offset. */
2769 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2770 if (unlikely (def == NULL))
2773 GElf_Verdaux auxmem;
2774 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2775 offset + def->vd_aux,
2777 if (unlikely (aux == NULL))
2780 vername[def->vd_ndx & 0x7fff]
2781 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2782 filename[def->vd_ndx & 0x7fff] = NULL;
2784 if (def->vd_next == 0)
2786 offset += def->vd_next;
2789 if (needscn != NULL)
2791 unsigned int offset = 0;
2793 Elf_Data *needdata = elf_getdata (needscn, NULL);
2794 GElf_Shdr needshdrmem;
2795 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2796 if (unlikely (needdata == NULL || needshdr == NULL))
2799 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2801 /* Get the data at the next offset. */
2802 GElf_Verneed needmem;
2803 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2805 if (unlikely (need == NULL))
2808 /* Run through the auxiliary entries. */
2809 unsigned int auxoffset = offset + need->vn_aux;
2810 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2812 GElf_Vernaux auxmem;
2813 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2815 if (unlikely (aux == NULL))
2818 vername[aux->vna_other & 0x7fff]
2819 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2820 filename[aux->vna_other & 0x7fff]
2821 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2823 if (aux->vna_next == 0)
2825 auxoffset += aux->vna_next;
2828 if (need->vn_next == 0)
2830 offset += need->vn_next;
2841 GElf_Shdr glink_mem;
2842 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2844 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2846 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2849 /* Print the header. */
2850 printf (ngettext ("\
2851 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2853 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2854 shdr->sh_size / sh_entsize),
2855 (unsigned int) elf_ndxscn (scn),
2856 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2857 (int) (shdr->sh_size / sh_entsize),
2858 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2860 (unsigned int) shdr->sh_link,
2861 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2863 /* Now we can finally look at the actual contents of this section. */
2864 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2867 printf ("\n %4d:", cnt);
2870 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2878 fputs_unlocked (gettext (" 0 *local* "),
2883 fputs_unlocked (gettext (" 1 *global* "),
2888 n = printf ("%4d%c%s",
2889 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2891 && (unsigned int) (*sym & 0x7fff) < nvername)
2892 ? vername[*sym & 0x7fff] : "???");
2893 if ((unsigned int) (*sym & 0x7fff) < nvername
2894 && filename != NULL && filename[*sym & 0x7fff] != NULL)
2895 n += printf ("(%s)", filename[*sym & 0x7fff]);
2896 printf ("%*s", MAX (0, 33 - (int) n), " ");
2900 putchar_unlocked ('\n');
2905 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2906 uint_fast32_t maxlength, Elf32_Word nbucket,
2907 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2909 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2911 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2912 ++counts[lengths[cnt]];
2914 GElf_Shdr glink_mem;
2915 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2920 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2925 printf (ngettext ("\
2926 \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",
2928 \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",
2930 (unsigned int) elf_ndxscn (scn),
2931 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2933 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2936 (unsigned int) shdr->sh_link,
2937 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2939 if (extrastr != NULL)
2940 fputs (extrastr, stdout);
2942 if (likely (nbucket > 0))
2944 uint64_t success = 0;
2946 /* xgettext:no-c-format */
2947 fputs_unlocked (gettext ("\
2948 Length Number % of total Coverage\n"), stdout);
2949 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2950 counts[0], (counts[0] * 100.0) / nbucket);
2952 uint64_t nzero_counts = 0;
2953 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2955 nzero_counts += counts[cnt] * cnt;
2957 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2958 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2959 (nzero_counts * 100.0) / nsyms);
2963 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2966 success += counts[cnt] * acc;
2970 Average number of tests: successful lookup: %f\n\
2971 unsuccessful lookup: %f\n"),
2972 (double) success / (double) nzero_counts,
2973 (double) nzero_counts / (double) nbucket);
2980 /* This function handles the traditional System V-style hash table format. */
2982 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2984 Elf_Data *data = elf_getdata (scn, NULL);
2985 if (unlikely (data == NULL))
2987 error (0, 0, gettext ("cannot get data for section %d: %s"),
2988 (int) elf_ndxscn (scn), elf_errmsg (-1));
2992 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
2995 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
2996 (int) elf_ndxscn (scn));
3000 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3001 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3003 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3004 if (used_buf > data->d_size)
3007 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3008 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3010 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3012 uint_fast32_t maxlength = 0;
3013 uint_fast32_t nsyms = 0;
3014 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3016 Elf32_Word inner = bucket[cnt];
3017 while (inner > 0 && inner < nchain)
3020 if (maxlength < ++lengths[cnt])
3023 inner = chain[inner];
3027 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3034 /* This function handles the incorrect, System V-style hash table
3035 format some 64-bit architectures use. */
3037 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3039 Elf_Data *data = elf_getdata (scn, NULL);
3040 if (unlikely (data == NULL))
3042 error (0, 0, gettext ("cannot get data for section %d: %s"),
3043 (int) elf_ndxscn (scn), elf_errmsg (-1));
3047 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3050 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3051 (int) elf_ndxscn (scn));
3055 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3056 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3058 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3060 || maxwords - 2 < nbucket
3061 || maxwords - 2 - nbucket < nchain)
3064 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3065 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3067 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3069 uint_fast32_t maxlength = 0;
3070 uint_fast32_t nsyms = 0;
3071 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3073 Elf64_Xword inner = bucket[cnt];
3074 while (inner > 0 && inner < nchain)
3077 if (maxlength < ++lengths[cnt])
3080 inner = chain[inner];
3084 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3091 /* This function handles the GNU-style hash table format. */
3093 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3095 Elf_Data *data = elf_getdata (scn, NULL);
3096 if (unlikely (data == NULL))
3098 error (0, 0, gettext ("cannot get data for section %d: %s"),
3099 (int) elf_ndxscn (scn), elf_errmsg (-1));
3103 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3106 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3107 (int) elf_ndxscn (scn));
3111 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3112 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3114 /* Next comes the size of the bitmap. It's measured in words for
3115 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3116 64 bit archs. There is always a bloom filter present, so zero is
3117 an invalid value. */
3118 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3119 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3122 if (bitmask_words == 0)
3125 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3127 /* Is there still room for the sym chain?
3128 Use uint64_t calculation to prevent 32bit overlow. */
3129 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3130 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3131 if (used_buf > data->d_size)
3134 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3136 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3137 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3138 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3141 /* Compute distribution of chain lengths. */
3142 uint_fast32_t maxlength = 0;
3143 uint_fast32_t nsyms = 0;
3144 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3145 if (bucket[cnt] != 0)
3147 Elf32_Word inner = bucket[cnt] - symbias;
3151 if (maxlength < ++lengths[cnt])
3153 if (inner > max_nsyms)
3156 while ((chain[inner++] & 1) == 0);
3159 /* Count bits in bitmask. */
3160 uint_fast32_t nbits = 0;
3161 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3163 uint_fast32_t word = bitmask[cnt];
3165 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3166 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3167 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3168 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3169 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3173 if (unlikely (asprintf (&str, gettext ("\
3175 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3176 (unsigned int) symbias,
3177 bitmask_words * sizeof (Elf32_Word),
3179 / (uint_fast32_t) (bitmask_words
3180 * sizeof (Elf32_Word) * 8)),
3181 (unsigned int) shift) == -1))
3182 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3184 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3192 /* Find the symbol table(s). For this we have to search through the
3195 handle_hash (Ebl *ebl)
3197 /* Get the section header string table index. */
3199 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3200 error (EXIT_FAILURE, 0,
3201 gettext ("cannot get section header string table index"));
3203 Elf_Scn *scn = NULL;
3204 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3206 /* Handle the section if it is a symbol table. */
3208 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3210 if (likely (shdr != NULL))
3212 if (shdr->sh_type == SHT_HASH)
3214 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3215 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3217 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3219 else if (shdr->sh_type == SHT_GNU_HASH)
3220 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3227 print_liblist (Ebl *ebl)
3229 /* Find the library list sections. For this we have to search
3230 through the section table. */
3231 Elf_Scn *scn = NULL;
3233 /* Get the section header string table index. */
3235 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3236 error (EXIT_FAILURE, 0,
3237 gettext ("cannot get section header string table index"));
3239 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3242 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3244 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3246 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3247 int nentries = shdr->sh_size / sh_entsize;
3248 printf (ngettext ("\
3249 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3251 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3254 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3258 Elf_Data *data = elf_getdata (scn, NULL);
3263 Library Time Stamp Checksum Version Flags"));
3265 for (int cnt = 0; cnt < nentries; ++cnt)
3268 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3269 if (unlikely (lib == NULL))
3272 time_t t = (time_t) lib->l_time_stamp;
3273 struct tm *tm = gmtime (&t);
3274 if (unlikely (tm == NULL))
3277 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3278 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3279 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3280 tm->tm_hour, tm->tm_min, tm->tm_sec,
3281 (unsigned int) lib->l_checksum,
3282 (unsigned int) lib->l_version,
3283 (unsigned int) lib->l_flags);
3290 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3292 /* Find the object attributes sections. For this we have to search
3293 through the section table. */
3294 Elf_Scn *scn = NULL;
3296 /* Get the section header string table index. */
3298 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3299 error (EXIT_FAILURE, 0,
3300 gettext ("cannot get section header string table index"));
3302 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3305 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3307 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3308 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3309 || ehdr->e_machine != EM_ARM)))
3313 \nObject attributes section [%2zu] '%s' of %" PRIu64
3314 " bytes at offset %#0" PRIx64 ":\n"),
3316 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3317 shdr->sh_size, shdr->sh_offset);
3319 Elf_Data *data = elf_rawdata (scn, NULL);
3320 if (unlikely (data == NULL || data->d_size == 0))
3323 const unsigned char *p = data->d_buf;
3325 /* There is only one 'version', A. */
3326 if (unlikely (*p++ != 'A'))
3329 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3331 inline size_t left (void)
3333 return (const unsigned char *) data->d_buf + data->d_size - p;
3336 /* Loop over the sections. */
3337 while (left () >= 4)
3339 /* Section length. */
3341 memcpy (&len, p, sizeof len);
3343 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3346 if (unlikely (len > left ()))
3349 /* Section vendor name. */
3350 const unsigned char *name = p + sizeof len;
3353 unsigned const char *q = memchr (name, '\0', len);
3354 if (unlikely (q == NULL))
3358 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3360 bool gnu_vendor = (q - name == sizeof "gnu"
3361 && !memcmp (name, "gnu", sizeof "gnu"));
3363 /* Loop over subsections. */
3364 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3368 const unsigned char *const sub = q;
3370 unsigned int subsection_tag;
3371 get_uleb128 (subsection_tag, q, p);
3372 if (unlikely (q >= p))
3375 uint32_t subsection_len;
3376 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3379 memcpy (&subsection_len, q, sizeof subsection_len);
3381 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3382 CONVERT (subsection_len);
3384 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3385 if (unlikely (subsection_len == 0
3386 || subsection_len >= (uint32_t) PTRDIFF_MAX
3387 || p - sub < (ptrdiff_t) subsection_len))
3390 const unsigned char *r = q + sizeof subsection_len;
3391 q = sub + subsection_len;
3393 switch (subsection_tag)
3396 /* Unknown subsection, print and skip. */
3397 printf (gettext (" %-4u %12" PRIu32 "\n"),
3398 subsection_tag, subsection_len);
3401 case 1: /* Tag_File */
3402 printf (gettext (" File: %11" PRIu32 "\n"),
3408 get_uleb128 (tag, r, q);
3409 if (unlikely (r >= q))
3412 /* GNU style tags have either a uleb128 value,
3413 when lowest bit is not set, or a string
3414 when the lowest bit is set.
3415 "compatibility" (32) is special. It has
3416 both a string and a uleb128 value. For
3417 non-gnu we assume 6 till 31 only take ints.
3418 XXX see arm backend, do we need a separate
3421 const char *string = NULL;
3422 if (tag == 32 || (tag & 1) == 0
3423 || (! gnu_vendor && (tag > 5 && tag < 32)))
3425 get_uleb128 (value, r, q);
3432 || (! gnu_vendor && tag > 32)))
3433 || (! gnu_vendor && tag > 3 && tag < 6))
3435 string = (const char *) r;
3436 r = memchr (r, '\0', q - r);
3442 const char *tag_name = NULL;
3443 const char *value_name = NULL;
3444 ebl_check_object_attribute (ebl, (const char *) name,
3446 &tag_name, &value_name);
3448 if (tag_name != NULL)
3451 printf (gettext (" %s: %" PRId64 ", %s\n"),
3452 tag_name, value, string);
3453 else if (string == NULL && value_name == NULL)
3454 printf (gettext (" %s: %" PRId64 "\n"),
3457 printf (gettext (" %s: %s\n"),
3458 tag_name, string ?: value_name);
3462 /* For "gnu" vendor 32 "compatibility" has
3463 already been handled above. */
3465 || strcmp ((const char *) name, "gnu"));
3467 printf (gettext (" %u: %" PRId64 "\n"),
3470 printf (gettext (" %u: %s\n"),
3482 format_dwarf_addr (Dwfl_Module *dwflmod,
3483 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3485 /* See if there is a name we can give for this address. */
3488 const char *name = (print_address_names && ! print_unresolved_addresses)
3489 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3493 if (print_unresolved_addresses)
3500 /* Relativize the address. */
3501 int n = dwfl_module_relocations (dwflmod);
3502 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3504 /* In an ET_REL file there is a section name to refer to. */
3506 : dwfl_module_relocation_info (dwflmod, i, NULL));
3513 ? (address_size == 0
3514 ? asprintf (&result,
3515 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3516 scn, address, name, off)
3517 : asprintf (&result,
3518 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3519 scn, 2 + address_size * 2, address,
3521 : (address_size == 0
3522 ? asprintf (&result,
3523 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3525 : asprintf (&result,
3526 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3527 2 + address_size * 2, address,
3530 ? (address_size == 0
3531 ? asprintf (&result,
3532 gettext ("%s+%#" PRIx64 " <%s>"),
3534 : asprintf (&result,
3535 gettext ("%s+%#0*" PRIx64 " <%s>"),
3536 scn, 2 + address_size * 2, address, name))
3537 : (address_size == 0
3538 ? asprintf (&result,
3539 gettext ("%#" PRIx64 " <%s>"),
3541 : asprintf (&result,
3542 gettext ("%#0*" PRIx64 " <%s>"),
3543 2 + address_size * 2, address, name))))
3545 ? (address_size == 0
3546 ? asprintf (&result,
3547 gettext ("%s+%#" PRIx64),
3549 : asprintf (&result,
3550 gettext ("%s+%#0*" PRIx64),
3551 scn, 2 + address_size * 2, address))
3552 : (address_size == 0
3553 ? asprintf (&result,
3556 : asprintf (&result,
3558 2 + address_size * 2, address)))) < 0)
3559 error (EXIT_FAILURE, 0, _("memory exhausted"));
3565 dwarf_tag_string (unsigned int tag)
3569 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3571 #undef ONE_KNOWN_DW_TAG
3579 dwarf_attr_string (unsigned int attrnum)
3583 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3585 #undef ONE_KNOWN_DW_AT
3593 dwarf_form_string (unsigned int form)
3597 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3598 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3600 #undef ONE_KNOWN_DW_FORM
3601 #undef ONE_KNOWN_DW_FORM_DESC
3609 dwarf_lang_string (unsigned int lang)
3613 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3615 #undef ONE_KNOWN_DW_LANG_DESC
3623 dwarf_inline_string (unsigned int code)
3625 static const char *const known[] =
3627 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3629 #undef ONE_KNOWN_DW_INL
3632 if (likely (code < sizeof (known) / sizeof (known[0])))
3640 dwarf_encoding_string (unsigned int code)
3642 static const char *const known[] =
3644 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3646 #undef ONE_KNOWN_DW_ATE
3649 if (likely (code < sizeof (known) / sizeof (known[0])))
3657 dwarf_access_string (unsigned int code)
3659 static const char *const known[] =
3661 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3663 #undef ONE_KNOWN_DW_ACCESS
3666 if (likely (code < sizeof (known) / sizeof (known[0])))
3674 dwarf_visibility_string (unsigned int code)
3676 static const char *const known[] =
3678 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3680 #undef ONE_KNOWN_DW_VIS
3683 if (likely (code < sizeof (known) / sizeof (known[0])))
3691 dwarf_virtuality_string (unsigned int code)
3693 static const char *const known[] =
3695 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3696 ALL_KNOWN_DW_VIRTUALITY
3697 #undef ONE_KNOWN_DW_VIRTUALITY
3700 if (likely (code < sizeof (known) / sizeof (known[0])))
3708 dwarf_identifier_case_string (unsigned int code)
3710 static const char *const known[] =
3712 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3714 #undef ONE_KNOWN_DW_ID
3717 if (likely (code < sizeof (known) / sizeof (known[0])))
3725 dwarf_calling_convention_string (unsigned int code)
3727 static const char *const known[] =
3729 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3731 #undef ONE_KNOWN_DW_CC
3734 if (likely (code < sizeof (known) / sizeof (known[0])))
3742 dwarf_ordering_string (unsigned int code)
3744 static const char *const known[] =
3746 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3748 #undef ONE_KNOWN_DW_ORD
3751 if (likely (code < sizeof (known) / sizeof (known[0])))
3759 dwarf_discr_list_string (unsigned int code)
3761 static const char *const known[] =
3763 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3765 #undef ONE_KNOWN_DW_DSC
3768 if (likely (code < sizeof (known) / sizeof (known[0])))
3776 dwarf_locexpr_opcode_string (unsigned int code)
3778 static const char *const known[] =
3780 /* Normally we can't affort building huge table of 64K entries,
3781 most of them zero, just because there are a couple defined
3782 values at the far end. In case of opcodes, it's OK. */
3783 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3784 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3786 #undef ONE_KNOWN_DW_OP
3787 #undef ONE_KNOWN_DW_OP_DESC
3790 if (likely (code < sizeof (known) / sizeof (known[0])))
3797 /* Used by all dwarf_foo_name functions. */
3799 string_or_unknown (const char *known, unsigned int code,
3800 unsigned int lo_user, unsigned int hi_user,
3801 bool print_unknown_num)
3803 static char unknown_buf[20];
3805 if (likely (known != NULL))
3808 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3810 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3815 if (print_unknown_num)
3817 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3826 dwarf_tag_name (unsigned int tag)
3828 const char *ret = dwarf_tag_string (tag);
3829 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3833 dwarf_attr_name (unsigned int attr)
3835 const char *ret = dwarf_attr_string (attr);
3836 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3841 dwarf_form_name (unsigned int form)
3843 const char *ret = dwarf_form_string (form);
3844 return string_or_unknown (ret, form, 0, 0, true);
3849 dwarf_lang_name (unsigned int lang)
3851 const char *ret = dwarf_lang_string (lang);
3852 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3857 dwarf_inline_name (unsigned int code)
3859 const char *ret = dwarf_inline_string (code);
3860 return string_or_unknown (ret, code, 0, 0, false);
3865 dwarf_encoding_name (unsigned int code)
3867 const char *ret = dwarf_encoding_string (code);
3868 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3873 dwarf_access_name (unsigned int code)
3875 const char *ret = dwarf_access_string (code);
3876 return string_or_unknown (ret, code, 0, 0, false);
3881 dwarf_visibility_name (unsigned int code)
3883 const char *ret = dwarf_visibility_string (code);
3884 return string_or_unknown (ret, code, 0, 0, false);
3889 dwarf_virtuality_name (unsigned int code)
3891 const char *ret = dwarf_virtuality_string (code);
3892 return string_or_unknown (ret, code, 0, 0, false);
3897 dwarf_identifier_case_name (unsigned int code)
3899 const char *ret = dwarf_identifier_case_string (code);
3900 return string_or_unknown (ret, code, 0, 0, false);
3905 dwarf_calling_convention_name (unsigned int code)
3907 const char *ret = dwarf_calling_convention_string (code);
3908 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3913 dwarf_ordering_name (unsigned int code)
3915 const char *ret = dwarf_ordering_string (code);
3916 return string_or_unknown (ret, code, 0, 0, false);
3921 dwarf_discr_list_name (unsigned int code)
3923 const char *ret = dwarf_discr_list_string (code);
3924 return string_or_unknown (ret, code, 0, 0, false);
3929 print_block (size_t n, const void *block)
3932 puts (_("empty block"));
3935 printf (_("%zu byte block:"), n);
3936 const unsigned char *data = block;
3938 printf (" %02x", *data++);
3945 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3946 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3947 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3949 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3953 printf ("%*s(empty)\n", indent, "");
3957 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3958 #define CONSUME(n) NEED (n); else len -= (n)
3960 Dwarf_Word offset = 0;
3963 uint_fast8_t op = *data++;
3965 const char *op_name = dwarf_locexpr_opcode_string (op);
3966 if (unlikely (op_name == NULL))
3968 static char buf[20];
3969 if (op >= DW_OP_lo_user)
3970 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3972 snprintf (buf, sizeof buf, "??? (%#x)", op);
3979 /* Address operand. */
3983 addr = read_4ubyte_unaligned (dbg, data);
3984 else if (addrsize == 8)
3985 addr = read_8ubyte_unaligned (dbg, data);
3991 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3992 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3993 indent, "", (uintmax_t) offset, op_name, a);
3996 offset += 1 + addrsize;
3999 case DW_OP_call_ref:
4000 /* Offset operand. */
4001 if (ref_size != 4 && ref_size != 8)
4002 goto invalid; /* Cannot be used in CFA. */
4005 addr = read_4ubyte_unaligned (dbg, data);
4007 addr = read_8ubyte_unaligned (dbg, data);
4011 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4012 indent, "", (uintmax_t) offset,
4013 op_name, (uintmax_t) addr);
4014 offset += 1 + ref_size;
4017 case DW_OP_deref_size:
4018 case DW_OP_xderef_size:
4021 // XXX value might be modified by relocation
4023 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4024 indent, "", (uintmax_t) offset,
4025 op_name, *((uint8_t *) data));
4033 // XXX value might be modified by relocation
4034 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4035 indent, "", (uintmax_t) offset,
4036 op_name, read_2ubyte_unaligned (dbg, data));
4044 // XXX value might be modified by relocation
4045 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4046 indent, "", (uintmax_t) offset,
4047 op_name, read_4ubyte_unaligned (dbg, data));
4055 // XXX value might be modified by relocation
4056 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4057 indent, "", (uintmax_t) offset,
4058 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4066 // XXX value might be modified by relocation
4067 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4068 indent, "", (uintmax_t) offset,
4069 op_name, *((int8_t *) data));
4077 // XXX value might be modified by relocation
4078 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4079 indent, "", (uintmax_t) offset,
4080 op_name, read_2sbyte_unaligned (dbg, data));
4088 // XXX value might be modified by relocation
4089 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4090 indent, "", (uintmax_t) offset,
4091 op_name, read_4sbyte_unaligned (dbg, data));
4099 // XXX value might be modified by relocation
4100 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4101 indent, "", (uintmax_t) offset,
4102 op_name, read_8sbyte_unaligned (dbg, data));
4110 case DW_OP_plus_uconst:
4112 const unsigned char *start = data;
4115 get_uleb128 (uleb, data, data + len);
4116 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4117 indent, "", (uintmax_t) offset, op_name, uleb);
4118 CONSUME (data - start);
4119 offset += 1 + (data - start);
4122 case DW_OP_bit_piece:
4126 get_uleb128 (uleb, data, data + len);
4128 get_uleb128 (uleb2, data, data + len);
4129 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4130 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4131 CONSUME (data - start);
4132 offset += 1 + (data - start);
4136 case DW_OP_breg0 ... DW_OP_breg31:
4141 get_sleb128 (sleb, data, data + len);
4142 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4143 indent, "", (uintmax_t) offset, op_name, sleb);
4144 CONSUME (data - start);
4145 offset += 1 + (data - start);
4151 get_uleb128 (uleb, data, data + len);
4153 get_sleb128 (sleb, data, data + len);
4154 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4155 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4156 CONSUME (data - start);
4157 offset += 1 + (data - start);
4162 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4163 indent, "", (uintmax_t) offset, op_name,
4164 read_2ubyte_unaligned (dbg, data));
4171 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4172 indent, "", (uintmax_t) offset, op_name,
4173 read_4ubyte_unaligned (dbg, data));
4181 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4182 indent, "", (uintmax_t) offset, op_name,
4183 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4189 case DW_OP_implicit_value:
4192 get_uleb128 (uleb, data, data + len);
4193 printf ("%*s[%4" PRIuMAX "] %s: ",
4194 indent, "", (uintmax_t) offset, op_name);
4196 print_block (uleb, data);
4198 CONSUME (data - start);
4199 offset += 1 + (data - start);
4202 case DW_OP_GNU_implicit_pointer:
4203 /* DIE offset operand. */
4206 if (ref_size != 4 && ref_size != 8)
4207 goto invalid; /* Cannot be used in CFA. */
4209 addr = read_4ubyte_unaligned (dbg, data);
4211 addr = read_8ubyte_unaligned (dbg, data);
4213 /* Byte offset operand. */
4215 get_sleb128 (sleb, data, data + len);
4217 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4218 indent, "", (intmax_t) offset,
4219 op_name, (uintmax_t) addr, sleb);
4220 CONSUME (data - start);
4221 offset += 1 + (data - start);
4224 case DW_OP_GNU_entry_value:
4225 /* Size plus expression block. */
4228 get_uleb128 (uleb, data, data + len);
4229 printf ("%*s[%4" PRIuMAX "] %s:\n",
4230 indent, "", (uintmax_t) offset, op_name);
4232 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4233 addrsize, offset_size, cu, uleb, data);
4235 CONSUME (data - start);
4236 offset += 1 + (data - start);
4239 case DW_OP_GNU_const_type:
4240 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4241 unsigned size plus block. */
4244 get_uleb128 (uleb, data, data + len);
4245 if (! print_unresolved_addresses && cu != NULL)
4248 uint8_t usize = *(uint8_t *) data++;
4250 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4251 indent, "", (uintmax_t) offset, op_name, uleb);
4252 print_block (usize, data);
4254 CONSUME (data - start);
4255 offset += 1 + (data - start);
4258 case DW_OP_GNU_regval_type:
4259 /* uleb128 register number, uleb128 CU relative
4260 DW_TAG_base_type DIE offset. */
4263 get_uleb128 (uleb, data, data + len);
4265 get_uleb128 (uleb2, data, data + len);
4266 if (! print_unresolved_addresses && cu != NULL)
4268 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4269 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4270 CONSUME (data - start);
4271 offset += 1 + (data - start);
4274 case DW_OP_GNU_deref_type:
4275 /* 1-byte unsigned size of value, uleb128 CU relative
4276 DW_TAG_base_type DIE offset. */
4279 usize = *(uint8_t *) data++;
4281 get_uleb128 (uleb, data, data + len);
4282 if (! print_unresolved_addresses && cu != NULL)
4284 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4285 indent, "", (uintmax_t) offset,
4286 op_name, usize, uleb);
4287 CONSUME (data - start);
4288 offset += 1 + (data - start);
4291 case DW_OP_GNU_convert:
4292 case DW_OP_GNU_reinterpret:
4293 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4294 for conversion to untyped. */
4297 get_uleb128 (uleb, data, data + len);
4298 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4300 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4301 indent, "", (uintmax_t) offset, op_name, uleb);
4302 CONSUME (data - start);
4303 offset += 1 + (data - start);
4306 case DW_OP_GNU_parameter_ref:
4307 /* 4 byte CU relative reference to the abstract optimized away
4308 DW_TAG_formal_parameter. */
4310 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4311 if (! print_unresolved_addresses && cu != NULL)
4312 param_off += cu->start;
4313 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4314 indent, "", (uintmax_t) offset, op_name, param_off);
4322 printf ("%*s[%4" PRIuMAX "] %s\n",
4323 indent, "", (uintmax_t) offset, op_name);
4328 indent = indentrest;
4332 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4333 indent, "", (uintmax_t) offset, op_name);
4341 Dwarf_Off offset:(64 - 3);
4345 struct Dwarf_CU *cu;
4348 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4349 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4352 listptr_base (struct listptr *p)
4355 Dwarf_Die cu = CUDIE (p->cu);
4356 /* Find the base address of the compilation unit. It will normally
4357 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4358 address could be overridden by DW_AT_entry_pc. It's been
4359 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4360 compilation units with discontinuous ranges. */
4361 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4363 Dwarf_Attribute attr_mem;
4364 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4372 compare_listptr (const void *a, const void *b, void *arg)
4374 const char *name = arg;
4375 struct listptr *p1 = (void *) a;
4376 struct listptr *p2 = (void *) b;
4378 if (p1->offset < p2->offset)
4380 if (p1->offset > p2->offset)
4383 if (!p1->warned && !p2->warned)
4385 if (p1->addr64 != p2->addr64)
4387 p1->warned = p2->warned = true;
4389 gettext ("%s %#" PRIx64 " used with different address sizes"),
4390 name, (uint64_t) p1->offset);
4392 if (p1->dwarf64 != p2->dwarf64)
4394 p1->warned = p2->warned = true;
4396 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4397 name, (uint64_t) p1->offset);
4399 if (listptr_base (p1) != listptr_base (p2))
4401 p1->warned = p2->warned = true;
4403 gettext ("%s %#" PRIx64 " used with different base addresses"),
4404 name, (uint64_t) p1->offset);
4411 struct listptr_table
4415 struct listptr *table;
4418 static struct listptr_table known_loclistptr;
4419 static struct listptr_table known_rangelistptr;
4422 reset_listptr (struct listptr_table *table)
4424 free (table->table);
4425 table->table = NULL;
4426 table->n = table->alloc = 0;
4429 /* Returns false if offset doesn't fit. See struct listptr. */
4431 notice_listptr (enum section_e section, struct listptr_table *table,
4432 uint_fast8_t address_size, uint_fast8_t offset_size,
4433 struct Dwarf_CU *cu, Dwarf_Off offset)
4435 if (print_debug_sections & section)
4437 if (table->n == table->alloc)
4439 if (table->alloc == 0)
4443 table->table = xrealloc (table->table,
4444 table->alloc * sizeof table->table[0]);
4447 struct listptr *p = &table->table[table->n++];
4449 *p = (struct listptr)
4451 .addr64 = address_size == 8,
4452 .dwarf64 = offset_size == 8,
4457 if (p->offset != offset)
4467 sort_listptr (struct listptr_table *table, const char *name)
4470 qsort_r (table->table, table->n, sizeof table->table[0],
4471 &compare_listptr, (void *) name);
4475 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4476 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4477 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4478 unsigned char **readp, unsigned char *endp)
4483 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4486 struct listptr *p = &table->table[*idxp];
4488 if (*idxp == table->n
4489 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4492 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4497 if (p->offset != (Dwarf_Off) offset)
4499 *readp += p->offset - offset;
4500 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4501 offset, (Dwarf_Off) p->offset - offset);
4505 if (address_sizep != NULL)
4506 *address_sizep = listptr_address_size (p);
4507 if (offset_sizep != NULL)
4508 *offset_sizep = listptr_offset_size (p);
4510 *base = listptr_base (p);
4519 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4520 Ebl *ebl, GElf_Ehdr *ehdr,
4521 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4523 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4524 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4526 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4528 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4529 (uint64_t) shdr->sh_offset);
4531 Dwarf_Off offset = 0;
4532 while (offset < sh_size)
4534 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4540 Dwarf_Abbrev abbrev;
4542 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4545 if (unlikely (res < 0))
4548 *** error while reading abbreviation: %s\n"),
4553 /* This is the NUL byte at the end of the section. */
4558 /* We know these calls can never fail. */
4559 unsigned int code = dwarf_getabbrevcode (&abbrev);
4560 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4561 int has_children = dwarf_abbrevhaschildren (&abbrev);
4563 printf (gettext (" [%5u] offset: %" PRId64
4564 ", children: %s, tag: %s\n"),
4565 code, (int64_t) offset,
4566 has_children ? gettext ("yes") : gettext ("no"),
4567 dwarf_tag_name (tag));
4573 while (dwarf_getabbrevattr (&abbrev, cnt,
4574 &name, &form, &enoffset) == 0)
4576 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4577 dwarf_attr_name (name), dwarf_form_name (form),
4578 (uint64_t) enoffset);
4589 /* Print content of DWARF .debug_aranges section. We fortunately do
4590 not have to know a bit about the structure of the section, libdwarf
4591 takes care of it. */
4593 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4594 GElf_Shdr *shdr, Dwarf *dbg)
4596 Dwarf_Aranges *aranges;
4598 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4600 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4605 GElf_Shdr glink_mem;
4607 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4610 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4615 printf (ngettext ("\
4616 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4618 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4620 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4621 (uint64_t) shdr->sh_offset, cnt);
4623 /* Compute floor(log16(cnt)). */
4632 for (size_t n = 0; n < cnt; ++n)
4634 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4635 if (unlikely (runp == NULL))
4637 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4645 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4646 printf (gettext (" [%*zu] ???\n"), digits, n);
4648 printf (gettext (" [%*zu] start: %0#*" PRIx64
4649 ", length: %5" PRIu64 ", CU DIE offset: %6"
4651 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4652 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4657 /* Print content of DWARF .debug_aranges section. */
4659 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4660 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4661 GElf_Shdr *shdr, Dwarf *dbg)
4665 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4669 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4671 if (unlikely (data == NULL))
4673 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4679 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4680 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4681 (uint64_t) shdr->sh_offset);
4683 const unsigned char *readp = data->d_buf;
4684 const unsigned char *readendp = readp + data->d_size;
4686 while (readp < readendp)
4688 const unsigned char *hdrstart = readp;
4689 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4691 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4692 if (readp + 4 > readendp)
4695 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4696 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4700 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4701 unsigned int length_bytes = 4;
4702 if (length == DWARF3_LENGTH_64_BIT)
4704 if (readp + 8 > readendp)
4706 length = read_8ubyte_unaligned_inc (dbg, readp);
4710 const unsigned char *nexthdr = readp + length;
4711 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4714 if (unlikely (length > (size_t) (readendp - readp)))
4720 if (readp + 2 > readendp)
4722 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4723 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4727 error (0, 0, gettext ("unsupported aranges version"));
4732 if (readp + length_bytes > readendp)
4734 if (length_bytes == 8)
4735 offset = read_8ubyte_unaligned_inc (dbg, readp);
4737 offset = read_4ubyte_unaligned_inc (dbg, readp);
4738 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4741 if (readp + 1 > readendp)
4743 unsigned int address_size = *readp++;
4744 printf (gettext (" Address size: %6" PRIu64 "\n"),
4745 (uint64_t) address_size);
4746 if (address_size != 4 && address_size != 8)
4748 error (0, 0, gettext ("unsupported address size"));
4752 unsigned int segment_size = *readp++;
4753 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4754 (uint64_t) segment_size);
4755 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4757 error (0, 0, gettext ("unsupported segment size"));
4761 /* Round the address to the next multiple of 2*address_size. */
4762 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4763 % (2 * address_size));
4765 while (readp < nexthdr)
4767 Dwarf_Word range_address;
4768 Dwarf_Word range_length;
4769 Dwarf_Word segment = 0;
4770 if (readp + 2 * address_size + segment_size > readendp)
4772 if (address_size == 4)
4774 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4775 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4779 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4780 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4783 if (segment_size == 4)
4784 segment = read_4ubyte_unaligned_inc (dbg, readp);
4785 else if (segment_size == 8)
4786 segment = read_8ubyte_unaligned_inc (dbg, readp);
4788 if (range_address == 0 && range_length == 0 && segment == 0)
4791 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4793 char *e = format_dwarf_addr (dwflmod, address_size,
4794 range_address + range_length - 1,
4796 if (segment_size != 0)
4797 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4798 (uint64_t) segment);
4800 printf (gettext (" %s..%s\n"), b, e);
4806 if (readp != nexthdr)
4808 size_t padding = nexthdr - readp;
4809 printf (gettext (" %Zu padding bytes\n"), padding);
4816 /* Print content of DWARF .debug_ranges section. */
4818 print_debug_ranges_section (Dwfl_Module *dwflmod,
4819 Ebl *ebl, GElf_Ehdr *ehdr,
4820 Elf_Scn *scn, GElf_Shdr *shdr,
4823 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4825 if (unlikely (data == NULL))
4827 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4833 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4834 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4835 (uint64_t) shdr->sh_offset);
4837 sort_listptr (&known_rangelistptr, "rangelistptr");
4838 size_t listptr_idx = 0;
4840 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4843 Dwarf_Addr base = 0;
4844 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4845 unsigned char *readp = data->d_buf;
4846 while (readp < endp)
4848 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4850 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4851 &address_size, NULL, &base, NULL,
4852 offset, &readp, endp))
4855 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4857 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4863 if (address_size == 8)
4865 begin = read_8ubyte_unaligned_inc (dbg, readp);
4866 end = read_8ubyte_unaligned_inc (dbg, readp);
4870 begin = read_4ubyte_unaligned_inc (dbg, readp);
4871 end = read_4ubyte_unaligned_inc (dbg, readp);
4872 if (begin == (Dwarf_Addr) (uint32_t) -1)
4873 begin = (Dwarf_Addr) -1l;
4876 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4878 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4879 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4883 else if (begin == 0 && end == 0) /* End of list entry. */
4886 printf (gettext (" [%6tx] empty list\n"), offset);
4891 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4893 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4895 /* We have an address range entry. */
4896 if (first) /* First address range entry in a list. */
4897 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4899 printf (gettext (" %s..%s\n"), b, e);
4908 #define REGNAMESZ 16
4910 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4911 char name[REGNAMESZ], int *bits, int *type)
4916 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4917 bits ?: &ignore, type ?: &ignore);
4921 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4923 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4925 *bits = loc != NULL ? loc->bits : 0;
4927 *type = DW_ATE_unsigned;
4928 set = "??? unrecognized";
4932 if (bits != NULL && *bits <= 0)
4933 *bits = loc != NULL ? loc->bits : 0;
4934 if (type != NULL && *type == DW_ATE_void)
4935 *type = DW_ATE_unsigned;
4942 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4943 Dwarf_Word vma_base, unsigned int code_align,
4945 unsigned int version, unsigned int ptr_size,
4946 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4948 char regnamebuf[REGNAMESZ];
4949 const char *regname (unsigned int regno)
4951 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4955 puts ("\n Program:");
4956 Dwarf_Word pc = vma_base;
4957 while (readp < endp)
4959 unsigned int opcode = *readp++;
4961 if (opcode < DW_CFA_advance_loc)
4962 /* Extended opcode. */
4973 case DW_CFA_set_loc:
4974 if ((uint64_t) (endp - readp) < 1)
4976 get_uleb128 (op1, readp, endp);
4978 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4980 case DW_CFA_advance_loc1:
4981 if ((uint64_t) (endp - readp) < 1)
4983 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4984 *readp, pc += *readp * code_align);
4987 case DW_CFA_advance_loc2:
4988 if ((uint64_t) (endp - readp) < 2)
4990 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4991 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4992 op1, pc += op1 * code_align);
4994 case DW_CFA_advance_loc4:
4995 if ((uint64_t) (endp - readp) < 4)
4997 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4998 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4999 op1, pc += op1 * code_align);
5001 case DW_CFA_offset_extended:
5002 if ((uint64_t) (endp - readp) < 1)
5004 get_uleb128 (op1, readp, endp);
5005 if ((uint64_t) (endp - readp) < 1)
5007 get_uleb128 (op2, readp, endp);
5008 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5010 op1, regname (op1), op2 * data_align);
5012 case DW_CFA_restore_extended:
5013 if ((uint64_t) (endp - readp) < 1)
5015 get_uleb128 (op1, readp, endp);
5016 printf (" restore_extended r%" PRIu64 " (%s)\n",
5017 op1, regname (op1));
5019 case DW_CFA_undefined:
5020 if ((uint64_t) (endp - readp) < 1)
5022 get_uleb128 (op1, readp, endp);
5023 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5025 case DW_CFA_same_value:
5026 if ((uint64_t) (endp - readp) < 1)
5028 get_uleb128 (op1, readp, endp);
5029 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5031 case DW_CFA_register:
5032 if ((uint64_t) (endp - readp) < 1)
5034 get_uleb128 (op1, readp, endp);
5035 if ((uint64_t) (endp - readp) < 1)
5037 get_uleb128 (op2, readp, endp);
5038 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5039 op1, regname (op1), op2, regname (op2));
5041 case DW_CFA_remember_state:
5042 puts (" remember_state");
5044 case DW_CFA_restore_state:
5045 puts (" restore_state");
5047 case DW_CFA_def_cfa:
5048 if ((uint64_t) (endp - readp) < 1)
5050 get_uleb128 (op1, readp, endp);
5051 if ((uint64_t) (endp - readp) < 1)
5053 get_uleb128 (op2, readp, endp);
5054 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5055 op1, regname (op1), op2);
5057 case DW_CFA_def_cfa_register:
5058 if ((uint64_t) (endp - readp) < 1)
5060 get_uleb128 (op1, readp, endp);
5061 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
5062 op1, regname (op1));
5064 case DW_CFA_def_cfa_offset:
5065 if ((uint64_t) (endp - readp) < 1)
5067 get_uleb128 (op1, readp, endp);
5068 printf (" def_cfa_offset %" PRIu64 "\n", op1);
5070 case DW_CFA_def_cfa_expression:
5071 if ((uint64_t) (endp - readp) < 1)
5073 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
5074 printf (" def_cfa_expression %" PRIu64 "\n", op1);
5075 if ((uint64_t) (endp - readp) < op1)
5078 fputs (gettext (" <INVALID DATA>\n"), stdout);
5081 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5085 case DW_CFA_expression:
5086 if ((uint64_t) (endp - readp) < 1)
5088 get_uleb128 (op1, readp, endp);
5089 if ((uint64_t) (endp - readp) < 1)
5091 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5092 printf (" expression r%" PRIu64 " (%s) \n",
5093 op1, regname (op1));
5094 if ((uint64_t) (endp - readp) < op2)
5096 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5100 case DW_CFA_offset_extended_sf:
5101 if ((uint64_t) (endp - readp) < 1)
5103 get_uleb128 (op1, readp, endp);
5104 if ((uint64_t) (endp - readp) < 1)
5106 get_sleb128 (sop2, readp, endp);
5107 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5109 op1, regname (op1), sop2 * data_align);
5111 case DW_CFA_def_cfa_sf:
5112 if ((uint64_t) (endp - readp) < 1)
5114 get_uleb128 (op1, readp, endp);
5115 if ((uint64_t) (endp - readp) < 1)
5117 get_sleb128 (sop2, readp, endp);
5118 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5119 op1, regname (op1), sop2 * data_align);
5121 case DW_CFA_def_cfa_offset_sf:
5122 if ((uint64_t) (endp - readp) < 1)
5124 get_sleb128 (sop1, readp, endp);
5125 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5127 case DW_CFA_val_offset:
5128 if ((uint64_t) (endp - readp) < 1)
5130 get_uleb128 (op1, readp, endp);
5131 if ((uint64_t) (endp - readp) < 1)
5133 get_uleb128 (op2, readp, endp);
5134 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5135 op1, op2 * data_align);
5137 case DW_CFA_val_offset_sf:
5138 if ((uint64_t) (endp - readp) < 1)
5140 get_uleb128 (op1, readp, endp);
5141 if ((uint64_t) (endp - readp) < 1)
5143 get_sleb128 (sop2, readp, endp);
5144 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5145 op1, sop2 * data_align);
5147 case DW_CFA_val_expression:
5148 if ((uint64_t) (endp - readp) < 1)
5150 get_uleb128 (op1, readp, endp);
5151 if ((uint64_t) (endp - readp) < 1)
5153 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5154 printf (" val_expression r%" PRIu64 " (%s)\n",
5155 op1, regname (op1));
5156 if ((uint64_t) (endp - readp) < op2)
5158 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5162 case DW_CFA_MIPS_advance_loc8:
5163 if ((uint64_t) (endp - readp) < 8)
5165 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5166 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5167 op1, pc += op1 * code_align);
5169 case DW_CFA_GNU_window_save:
5170 puts (" GNU_window_save");
5172 case DW_CFA_GNU_args_size:
5173 if ((uint64_t) (endp - readp) < 1)
5175 get_uleb128 (op1, readp, endp);
5176 printf (" args_size %" PRIu64 "\n", op1);
5179 printf (" ??? (%u)\n", opcode);
5182 else if (opcode < DW_CFA_offset)
5183 printf (" advance_loc %u to %#" PRIx64 "\n",
5184 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5185 else if (opcode < DW_CFA_restore)
5188 if ((uint64_t) (endp - readp) < 1)
5190 get_uleb128 (offset, readp, endp);
5191 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5192 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5195 printf (" restore r%u (%s)\n",
5196 opcode & 0x3f, regname (opcode & 0x3f));
5202 encoded_ptr_size (int encoding, unsigned int ptr_size)
5204 switch (encoding & 7)
5206 case DW_EH_PE_udata4:
5208 case DW_EH_PE_udata8:
5214 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5215 "assuming pointer size of %d.\n", encoding, ptr_size);
5221 print_encoding (unsigned int val)
5225 case DW_EH_PE_absptr:
5226 fputs ("absptr", stdout);
5228 case DW_EH_PE_uleb128:
5229 fputs ("uleb128", stdout);
5231 case DW_EH_PE_udata2:
5232 fputs ("udata2", stdout);
5234 case DW_EH_PE_udata4:
5235 fputs ("udata4", stdout);
5237 case DW_EH_PE_udata8:
5238 fputs ("udata8", stdout);
5240 case DW_EH_PE_sleb128:
5241 fputs ("sleb128", stdout);
5243 case DW_EH_PE_sdata2:
5244 fputs ("sdata2", stdout);
5246 case DW_EH_PE_sdata4:
5247 fputs ("sdata4", stdout);
5249 case DW_EH_PE_sdata8:
5250 fputs ("sdata8", stdout);
5253 /* We did not use any of the bits after all. */
5262 print_relinfo (unsigned int val)
5266 case DW_EH_PE_pcrel:
5267 fputs ("pcrel", stdout);
5269 case DW_EH_PE_textrel:
5270 fputs ("textrel", stdout);
5272 case DW_EH_PE_datarel:
5273 fputs ("datarel", stdout);
5275 case DW_EH_PE_funcrel:
5276 fputs ("funcrel", stdout);
5278 case DW_EH_PE_aligned:
5279 fputs ("aligned", stdout);
5290 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5292 printf ("(%s", pfx);
5294 if (fde_encoding == DW_EH_PE_omit)
5298 unsigned int w = fde_encoding;
5300 w = print_encoding (w);
5304 if (w != fde_encoding)
5305 fputc_unlocked (' ', stdout);
5307 w = print_relinfo (w);
5311 printf ("%s%x", w != fde_encoding ? " " : "", w);
5318 static const unsigned char *
5319 read_encoded (unsigned int encoding, const unsigned char *readp,
5320 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5322 if ((encoding & 0xf) == DW_EH_PE_absptr)
5323 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5324 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5326 switch (encoding & 0xf)
5328 case DW_EH_PE_uleb128:
5329 get_uleb128 (*res, readp, endp);
5331 case DW_EH_PE_sleb128:
5332 get_sleb128 (*res, readp, endp);
5334 case DW_EH_PE_udata2:
5335 if (readp + 2 > endp)
5337 *res = read_2ubyte_unaligned_inc (dbg, readp);
5339 case DW_EH_PE_udata4:
5340 if (readp + 4 > endp)
5342 *res = read_4ubyte_unaligned_inc (dbg, readp);
5344 case DW_EH_PE_udata8:
5345 if (readp + 8 > endp)
5347 *res = read_8ubyte_unaligned_inc (dbg, readp);
5349 case DW_EH_PE_sdata2:
5350 if (readp + 2 > endp)
5352 *res = read_2sbyte_unaligned_inc (dbg, readp);
5354 case DW_EH_PE_sdata4:
5355 if (readp + 4 > endp)
5357 *res = read_4sbyte_unaligned_inc (dbg, readp);
5359 case DW_EH_PE_sdata8:
5360 if (readp + 8 > endp)
5362 *res = read_8sbyte_unaligned_inc (dbg, readp);
5367 gettext ("invalid encoding"));
5375 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5376 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5379 /* We know this call will succeed since it did in the caller. */
5380 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5381 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5383 /* Needed if we find PC-relative addresses. */
5385 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5387 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5391 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5392 Elf_Data *data = (is_eh_frame
5393 ? elf_rawdata (scn, NULL)
5394 : dbg->sectiondata[IDX_debug_frame]);
5396 if (unlikely (data == NULL))
5398 error (0, 0, gettext ("cannot get %s content: %s"),
5399 scnname, elf_errmsg (-1));
5405 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5406 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5409 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5410 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5414 ptrdiff_t cie_offset;
5415 const char *augmentation;
5416 unsigned int code_alignment_factor;
5417 unsigned int data_alignment_factor;
5418 uint8_t address_size;
5419 uint8_t fde_encoding;
5420 uint8_t lsda_encoding;
5421 struct cieinfo *next;
5424 const unsigned char *readp = data->d_buf;
5425 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5427 while (readp < dataend)
5429 if (unlikely (readp + 4 > dataend))
5432 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5433 elf_ndxscn (scn), scnname);
5437 /* At the beginning there must be a CIE. There can be multiple,
5438 hence we test tis in a loop. */
5439 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5441 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5442 unsigned int length = 4;
5443 if (unlikely (unit_length == 0xffffffff))
5445 if (unlikely (readp + 8 > dataend))
5448 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5452 if (unlikely (unit_length == 0))
5454 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5458 Dwarf_Word maxsize = dataend - readp;
5459 if (unlikely (unit_length > maxsize))
5462 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5464 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5465 const unsigned char *const cieend = readp + unit_length;
5466 if (unlikely (cieend > dataend || readp + 8 > dataend))
5472 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5473 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5474 cie_id = DW_CIE_ID_64;
5477 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5479 uint_fast8_t version = 2;
5480 unsigned int code_alignment_factor;
5481 int data_alignment_factor;
5482 unsigned int fde_encoding = 0;
5483 unsigned int lsda_encoding = 0;
5484 Dwarf_Word initial_location = 0;
5485 Dwarf_Word vma_base = 0;
5487 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5490 const char *const augmentation = (const char *) readp;
5491 readp = memchr (readp, '\0', cieend - readp);
5492 if (unlikely (readp == NULL))
5496 uint_fast8_t segment_size = 0;
5499 if (cieend - readp < 5)
5501 ptr_size = *readp++;
5502 segment_size = *readp++;
5505 if (cieend - readp < 1)
5507 get_uleb128 (code_alignment_factor, readp, cieend);
5508 if (cieend - readp < 1)
5510 get_sleb128 (data_alignment_factor, readp, cieend);
5512 /* In some variant for unwind data there is another field. */
5513 if (strcmp (augmentation, "eh") == 0)
5514 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5516 unsigned int return_address_register;
5517 if (cieend - readp < 1)
5519 if (unlikely (version == 1))
5520 return_address_register = *readp++;
5522 get_uleb128 (return_address_register, readp, cieend);
5524 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5525 " CIE_id: %" PRIu64 "\n"
5527 " augmentation: \"%s\"\n",
5528 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5529 version, augmentation);
5531 printf (" address_size: %u\n"
5532 " segment_size: %u\n",
5533 ptr_size, segment_size);
5534 printf (" code_alignment_factor: %u\n"
5535 " data_alignment_factor: %d\n"
5536 " return_address_register: %u\n",
5537 code_alignment_factor,
5538 data_alignment_factor, return_address_register);
5540 if (augmentation[0] == 'z')
5542 unsigned int augmentationlen;
5543 get_uleb128 (augmentationlen, readp, cieend);
5545 if (augmentationlen > (size_t) (cieend - readp))
5547 error (0, 0, gettext ("invalid augmentation length"));
5552 const char *hdr = "Augmentation data:";
5553 const char *cp = augmentation + 1;
5554 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5556 printf (" %-26s%#x ", hdr, *readp);
5561 fde_encoding = *readp++;
5562 print_encoding_base (gettext ("FDE address encoding: "),
5565 else if (*cp == 'L')
5567 lsda_encoding = *readp++;
5568 print_encoding_base (gettext ("LSDA pointer encoding: "),
5571 else if (*cp == 'P')
5573 /* Personality. This field usually has a relocation
5574 attached pointing to __gcc_personality_v0. */
5575 const unsigned char *startp = readp;
5576 unsigned int encoding = *readp++;
5578 readp = read_encoded (encoding, readp,
5579 readp - 1 + augmentationlen,
5582 while (++startp < readp)
5583 printf ("%#x ", *startp);
5586 print_encoding (encoding);
5588 switch (encoding & 0xf)
5590 case DW_EH_PE_sleb128:
5591 case DW_EH_PE_sdata2:
5592 case DW_EH_PE_sdata4:
5593 printf ("%" PRId64 ")\n", val);
5596 printf ("%#" PRIx64 ")\n", val);
5601 printf ("(%x)\n", *readp++);
5607 if (likely (ptr_size == 4 || ptr_size == 8))
5609 struct cieinfo *newp = alloca (sizeof (*newp));
5610 newp->cie_offset = offset;
5611 newp->augmentation = augmentation;
5612 newp->fde_encoding = fde_encoding;
5613 newp->lsda_encoding = lsda_encoding;
5614 newp->address_size = ptr_size;
5615 newp->code_alignment_factor = code_alignment_factor;
5616 newp->data_alignment_factor = data_alignment_factor;
5623 struct cieinfo *cie = cies;
5626 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5627 : (ptrdiff_t) cie_id == cie->cie_offset)
5631 if (unlikely (cie == NULL))
5633 puts ("invalid CIE reference in FDE");
5637 /* Initialize from CIE data. */
5638 fde_encoding = cie->fde_encoding;
5639 lsda_encoding = cie->lsda_encoding;
5640 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5641 code_alignment_factor = cie->code_alignment_factor;
5642 data_alignment_factor = cie->data_alignment_factor;
5644 const unsigned char *base = readp;
5645 // XXX There are sometimes relocations for this value
5646 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5647 Dwarf_Word address_range
5648 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5650 /* pcrel for an FDE address is relative to the runtime
5651 address of the start_address field itself. Sign extend
5652 if necessary to make sure the calculation is done on the
5653 full 64 bit address even when initial_location only holds
5654 the lower 32 bits. */
5655 Dwarf_Addr pc_start = initial_location;
5657 pc_start = (uint64_t) (int32_t) pc_start;
5658 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5659 pc_start += ((uint64_t) shdr->sh_addr
5660 + (base - (const unsigned char *) data->d_buf)
5663 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5664 pc_start, initial_location);
5665 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5666 " CIE_pointer: %" PRIu64 "\n"
5667 " initial_location: %s",
5668 offset, (uint64_t) unit_length,
5669 cie->cie_offset, (uint64_t) cie_id, a);
5671 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5673 vma_base = (((uint64_t) shdr->sh_offset
5674 + (base - (const unsigned char *) data->d_buf)
5675 + (uint64_t) initial_location)
5677 ? UINT64_C (0xffffffff)
5678 : UINT64_C (0xffffffffffffffff)));
5679 printf (gettext (" (offset: %#" PRIx64 ")"),
5680 (uint64_t) vma_base);
5683 printf ("\n address_range: %#" PRIx64,
5684 (uint64_t) address_range);
5685 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5686 printf (gettext (" (end offset: %#" PRIx64 ")"),
5687 ((uint64_t) vma_base + (uint64_t) address_range)
5689 ? UINT64_C (0xffffffff)
5690 : UINT64_C (0xffffffffffffffff)));
5693 if (cie->augmentation[0] == 'z')
5695 unsigned int augmentationlen;
5696 if (cieend - readp < 1)
5698 get_uleb128 (augmentationlen, readp, cieend);
5700 if (augmentationlen > (size_t) (cieend - readp))
5702 error (0, 0, gettext ("invalid augmentation length"));
5707 if (augmentationlen > 0)
5709 const char *hdr = "Augmentation data:";
5710 const char *cp = cie->augmentation + 1;
5713 && cp < cie->augmentation + augmentationlen + 1)
5717 uint64_t lsda_pointer;
5718 const unsigned char *p
5719 = read_encoded (lsda_encoding, &readp[u],
5720 &readp[augmentationlen],
5721 &lsda_pointer, dbg);
5724 %-26sLSDA pointer: %#" PRIx64 "\n"),
5731 while (u < augmentationlen)
5733 printf (" %-26s%#x\n", hdr, readp[u++]);
5738 readp += augmentationlen;
5742 /* Handle the initialization instructions. */
5743 if (ptr_size != 4 && ptr_size !=8)
5744 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5746 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5747 data_alignment_factor, version, ptr_size,
5756 Dwfl_Module *dwflmod;
5761 unsigned int version;
5762 unsigned int addrsize;
5763 unsigned int offset_size;
5764 struct Dwarf_CU *cu;
5769 attr_callback (Dwarf_Attribute *attrp, void *arg)
5771 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5772 const int level = cbargs->level;
5774 unsigned int attr = dwarf_whatattr (attrp);
5775 if (unlikely (attr == 0))
5777 if (!cbargs->silent)
5778 error (0, 0, gettext ("cannot get attribute code: %s"),
5780 return DWARF_CB_ABORT;
5783 unsigned int form = dwarf_whatform (attrp);
5784 if (unlikely (form == 0))
5786 if (!cbargs->silent)
5787 error (0, 0, gettext ("cannot get attribute form: %s"),
5789 return DWARF_CB_ABORT;
5795 if (!cbargs->silent)
5798 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5801 if (!cbargs->silent)
5802 error (0, 0, gettext ("cannot get attribute value: %s"),
5804 return DWARF_CB_ABORT;
5806 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5808 printf (" %*s%-20s (%s) %s\n",
5809 (int) (level * 2), "", dwarf_attr_name (attr),
5810 dwarf_form_name (form), a);
5815 case DW_FORM_indirect:
5817 case DW_FORM_string:
5818 case DW_FORM_GNU_strp_alt:
5821 const char *str = dwarf_formstring (attrp);
5822 if (unlikely (str == NULL))
5824 printf (" %*s%-20s (%s) \"%s\"\n",
5825 (int) (level * 2), "", dwarf_attr_name (attr),
5826 dwarf_form_name (form), str);
5829 case DW_FORM_ref_addr:
5830 case DW_FORM_ref_udata:
5835 case DW_FORM_GNU_ref_alt:
5839 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5842 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5843 (int) (level * 2), "", dwarf_attr_name (attr),
5844 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5847 case DW_FORM_ref_sig8:
5850 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5851 (int) (level * 2), "", dwarf_attr_name (attr),
5852 dwarf_form_name (form),
5853 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5856 case DW_FORM_sec_offset:
5862 case DW_FORM_data1:;
5864 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5867 const char *valuestr = NULL;
5870 /* This case can take either a constant or a loclistptr. */
5871 case DW_AT_data_member_location:
5872 if (form != DW_FORM_sec_offset
5873 && (cbargs->version >= 4
5874 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5876 if (!cbargs->silent)
5877 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5878 (int) (level * 2), "", dwarf_attr_name (attr),
5879 dwarf_form_name (form), (uintmax_t) num);
5882 /* else fallthrough */
5884 /* These cases always take a loclistptr and no constant. */
5885 case DW_AT_location:
5886 case DW_AT_data_location:
5887 case DW_AT_vtable_elem_location:
5888 case DW_AT_string_length:
5889 case DW_AT_use_location:
5890 case DW_AT_frame_base:
5891 case DW_AT_return_addr:
5892 case DW_AT_static_link:
5893 case DW_AT_GNU_call_site_value:
5894 case DW_AT_GNU_call_site_data_value:
5895 case DW_AT_GNU_call_site_target:
5896 case DW_AT_GNU_call_site_target_clobbered:
5898 bool nlpt = notice_listptr (section_loc, &known_loclistptr,
5899 cbargs->addrsize, cbargs->offset_size,
5901 if (!cbargs->silent)
5902 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
5903 (int) (level * 2), "", dwarf_attr_name (attr),
5904 dwarf_form_name (form), (uintmax_t) num,
5905 nlpt ? "" : " <WARNING offset too big>");
5911 bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
5912 cbargs->addrsize, cbargs->offset_size,
5914 if (!cbargs->silent)
5915 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
5916 (int) (level * 2), "", dwarf_attr_name (attr),
5917 dwarf_form_name (form), (uintmax_t) num,
5918 nlpt ? "" : " <WARNING offset too big>");
5922 case DW_AT_language:
5923 valuestr = dwarf_lang_name (num);
5925 case DW_AT_encoding:
5926 valuestr = dwarf_encoding_name (num);
5928 case DW_AT_accessibility:
5929 valuestr = dwarf_access_name (num);
5931 case DW_AT_visibility:
5932 valuestr = dwarf_visibility_name (num);
5934 case DW_AT_virtuality:
5935 valuestr = dwarf_virtuality_name (num);
5937 case DW_AT_identifier_case:
5938 valuestr = dwarf_identifier_case_name (num);
5940 case DW_AT_calling_convention:
5941 valuestr = dwarf_calling_convention_name (num);
5944 valuestr = dwarf_inline_name (num);
5946 case DW_AT_ordering:
5947 valuestr = dwarf_ordering_name (num);
5949 case DW_AT_discr_list:
5950 valuestr = dwarf_discr_list_name (num);
5960 /* When highpc is in constant form it is relative to lowpc.
5961 In that case also show the address. */
5963 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5965 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5967 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5968 (int) (level * 2), "", dwarf_attr_name (attr),
5969 dwarf_form_name (form), (uintmax_t) num, a);
5974 Dwarf_Sword snum = 0;
5975 if (form == DW_FORM_sdata)
5976 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5979 if (valuestr == NULL)
5981 printf (" %*s%-20s (%s)",
5982 (int) (level * 2), "", dwarf_attr_name (attr),
5983 dwarf_form_name (form));
5984 if (form == DW_FORM_sdata)
5985 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5987 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5991 printf (" %*s%-20s (%s) %s",
5992 (int) (level * 2), "", dwarf_attr_name (attr),
5993 dwarf_form_name (form), valuestr);
5994 if (form == DW_FORM_sdata)
5995 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5997 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6006 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6009 printf (" %*s%-20s (%s) %s\n",
6010 (int) (level * 2), "", dwarf_attr_name (attr),
6011 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
6014 case DW_FORM_flag_present:
6017 printf (" %*s%-20s (%s) %s\n",
6018 (int) (level * 2), "", dwarf_attr_name (attr),
6019 dwarf_form_name (form), nl_langinfo (YESSTR));
6022 case DW_FORM_exprloc:
6023 case DW_FORM_block4:
6024 case DW_FORM_block2:
6025 case DW_FORM_block1:
6030 if (unlikely (dwarf_formblock (attrp, &block) != 0))
6033 printf (" %*s%-20s (%s) ",
6034 (int) (level * 2), "", dwarf_attr_name (attr),
6035 dwarf_form_name (form));
6040 if (form != DW_FORM_exprloc)
6042 print_block (block.length, block.data);
6047 case DW_AT_location:
6048 case DW_AT_data_location:
6049 case DW_AT_data_member_location:
6050 case DW_AT_vtable_elem_location:
6051 case DW_AT_string_length:
6052 case DW_AT_use_location:
6053 case DW_AT_frame_base:
6054 case DW_AT_return_addr:
6055 case DW_AT_static_link:
6056 case DW_AT_allocated:
6057 case DW_AT_associated:
6058 case DW_AT_bit_size:
6059 case DW_AT_bit_offset:
6060 case DW_AT_bit_stride:
6061 case DW_AT_byte_size:
6062 case DW_AT_byte_stride:
6064 case DW_AT_lower_bound:
6065 case DW_AT_upper_bound:
6066 case DW_AT_GNU_call_site_value:
6067 case DW_AT_GNU_call_site_data_value:
6068 case DW_AT_GNU_call_site_target:
6069 case DW_AT_GNU_call_site_target_clobbered:
6071 print_ops (cbargs->dwflmod, cbargs->dbg,
6072 12 + level * 2, 12 + level * 2,
6073 cbargs->version, cbargs->addrsize, cbargs->offset_size,
6074 attrp->cu, block.length, block.data);
6082 printf (" %*s%-20s (form: %#x) ???\n",
6083 (int) (level * 2), "", dwarf_attr_name (attr),
6092 print_debug_units (Dwfl_Module *dwflmod,
6093 Ebl *ebl, GElf_Ehdr *ehdr,
6094 Elf_Scn *scn, GElf_Shdr *shdr,
6095 Dwarf *dbg, bool debug_types)
6097 const bool silent = !(print_debug_sections & section_info);
6098 const char *secname = section_name (ebl, ehdr, shdr);
6102 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6103 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6105 /* If the section is empty we don't have to do anything. */
6106 if (!silent && shdr->sh_size == 0)
6110 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6112 Dwarf_Off offset = 0;
6114 /* New compilation unit. */
6117 Dwarf_Off abbroffset;
6124 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6125 &abbroffset, &addrsize, &offsize,
6126 debug_types ? &typesig : NULL,
6127 debug_types ? &typeoff : NULL) != 0)
6133 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6134 " Version: %" PRIu16 ", Abbreviation section offset: %"
6135 PRIu64 ", Address size: %" PRIu8
6136 ", Offset size: %" PRIu8
6137 "\n Type signature: %#" PRIx64
6138 ", Type offset: %#" PRIx64 "\n"),
6139 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6140 typesig, (uint64_t) typeoff);
6142 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6143 " Version: %" PRIu16 ", Abbreviation section offset: %"
6144 PRIu64 ", Address size: %" PRIu8
6145 ", Offset size: %" PRIu8 "\n"),
6146 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6149 struct attrcb_args args =
6155 .addrsize = addrsize,
6156 .offset_size = offsize
6163 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6164 (dbg, offset, &dies[level]) == NULL))
6167 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6168 " in section '%s': %s"),
6169 (uint64_t) offset, secname, dwarf_errmsg (-1));
6173 args.cu = dies[0].cu;
6177 offset = dwarf_dieoffset (&dies[level]);
6178 if (unlikely (offset == ~0ul))
6181 error (0, 0, gettext ("cannot get DIE offset: %s"),
6186 int tag = dwarf_tag (&dies[level]);
6187 if (unlikely (tag == DW_TAG_invalid))
6190 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6191 " in section '%s': %s"),
6192 (uint64_t) offset, secname, dwarf_errmsg (-1));
6197 printf (" [%6" PRIx64 "] %*s%s\n",
6198 (uint64_t) offset, (int) (level * 2), "",
6199 dwarf_tag_name (tag));
6201 /* Print the attribute values. */
6203 args.die = &dies[level];
6204 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6206 /* Make room for the next level's DIE. */
6207 if (level + 1 == maxdies)
6208 dies = (Dwarf_Die *) xrealloc (dies,
6210 * sizeof (Dwarf_Die));
6212 int res = dwarf_child (&dies[level], &dies[level + 1]);
6215 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6219 if (unlikely (res == -1))
6222 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6227 else if (unlikely (res < 0))
6230 error (0, 0, gettext ("cannot get next DIE: %s"),
6248 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6249 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6251 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6255 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6256 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6258 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6263 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6264 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6267 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6268 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6269 (uint64_t) shdr->sh_offset);
6272 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6275 Dwarf_Off ncuoffset = 0;
6277 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6278 NULL, NULL, NULL) == 0)
6281 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6286 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6289 printf (" CU [%" PRIx64 "] %s\n",
6290 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6291 printf (" line:col SBPE* disc isa op address"
6292 " (Statement Block Prologue Epilogue *End)\n");
6293 const char *last_file = "";
6294 for (size_t n = 0; n < nlines; n++)
6296 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6299 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6302 Dwarf_Word mtime, length;
6303 const char *file = dwarf_linesrc (line, &mtime, &length);
6306 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6309 else if (strcmp (last_file, file) != 0)
6311 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6312 file, mtime, length);
6317 bool statement, endseq, block, prologue_end, epilogue_begin;
6318 unsigned int lineop, isa, disc;
6320 dwarf_lineaddr (line, &address);
6321 dwarf_lineno (line, &lineno);
6322 dwarf_linecol (line, &colno);
6323 dwarf_lineop_index (line, &lineop);
6324 dwarf_linebeginstatement (line, &statement);
6325 dwarf_lineendsequence (line, &endseq);
6326 dwarf_lineblock (line, &block);
6327 dwarf_lineprologueend (line, &prologue_end);
6328 dwarf_lineepiloguebegin (line, &epilogue_begin);
6329 dwarf_lineisa (line, &isa);
6330 dwarf_linediscriminator (line, &disc);
6332 /* End sequence is special, it is one byte past. */
6333 char *a = format_dwarf_addr (dwflmod, address_size,
6334 address - (endseq ? 1 : 0), address);
6335 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6337 (statement ? 'S' : ' '),
6338 (block ? 'B' : ' '),
6339 (prologue_end ? 'P' : ' '),
6340 (epilogue_begin ? 'E' : ' '),
6341 (endseq ? '*' : ' '),
6342 disc, isa, lineop, a);
6353 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6354 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6358 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6363 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6364 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6365 (uint64_t) shdr->sh_offset);
6367 if (shdr->sh_size == 0)
6370 /* There is no functionality in libdw to read the information in the
6371 way it is represented here. Hardcode the decoder. */
6372 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6373 if (unlikely (data == NULL || data->d_buf == NULL))
6375 error (0, 0, gettext ("cannot get line data section data: %s"),
6380 const unsigned char *linep = (const unsigned char *) data->d_buf;
6381 const unsigned char *lineendp;
6384 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6386 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6388 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6390 if (unlikely (linep + 4 > lineendp))
6392 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6393 unsigned int length = 4;
6394 if (unlikely (unit_length == 0xffffffff))
6396 if (unlikely (linep + 8 > lineendp))
6399 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6400 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6403 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6407 /* Check whether we have enough room in the section. */
6408 if (unlikely (unit_length > (size_t) (lineendp - linep)
6409 || unit_length < 2 + length + 5 * 1))
6411 lineendp = linep + unit_length;
6413 /* The next element of the header is the version identifier. */
6414 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6416 /* Next comes the header length. */
6417 Dwarf_Word header_length;
6419 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6421 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6422 //const unsigned char *header_start = linep;
6424 /* Next the minimum instruction length. */
6425 uint_fast8_t minimum_instr_len = *linep++;
6427 /* Next the maximum operations per instruction, in version 4 format. */
6428 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6430 /* Then the flag determining the default value of the is_stmt
6432 uint_fast8_t default_is_stmt = *linep++;
6434 /* Now the line base. */
6435 int_fast8_t line_base = *((const int_fast8_t *) linep);
6438 /* And the line range. */
6439 uint_fast8_t line_range = *linep++;
6441 /* The opcode base. */
6442 uint_fast8_t opcode_base = *linep++;
6444 /* Print what we got so far. */
6445 printf (gettext ("\n"
6446 " Length: %" PRIu64 "\n"
6447 " DWARF version: %" PRIuFAST16 "\n"
6448 " Prologue length: %" PRIu64 "\n"
6449 " Minimum instruction length: %" PRIuFAST8 "\n"
6450 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6451 " Initial value if '%s': %" PRIuFAST8 "\n"
6452 " Line base: %" PRIdFAST8 "\n"
6453 " Line range: %" PRIuFAST8 "\n"
6454 " Opcode base: %" PRIuFAST8 "\n"
6457 (uint64_t) unit_length, version, (uint64_t) header_length,
6458 minimum_instr_len, max_ops_per_instr,
6459 "is_stmt", default_is_stmt, line_base,
6460 line_range, opcode_base);
6462 if (unlikely (linep + opcode_base - 1 >= lineendp))
6466 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6467 linep - (const unsigned char *) data->d_buf,
6468 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6472 int opcode_base_l10 = 1;
6473 unsigned int tmp = opcode_base;
6479 const uint8_t *standard_opcode_lengths = linep - 1;
6480 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6481 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6482 " [%*" PRIuFAST8 "] %hhu arguments\n",
6483 (int) linep[cnt - 1]),
6484 opcode_base_l10, cnt, linep[cnt - 1]);
6485 linep += opcode_base - 1;
6486 if (unlikely (linep >= lineendp))
6489 puts (gettext ("\nDirectory table:"));
6492 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6493 if (unlikely (endp == NULL))
6496 printf (" %s\n", (char *) linep);
6500 /* Skip the final NUL byte. */
6503 if (unlikely (linep >= lineendp))
6505 puts (gettext ("\nFile name table:\n"
6506 " Entry Dir Time Size Name"));
6507 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6509 /* First comes the file name. */
6510 char *fname = (char *) linep;
6511 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6512 if (unlikely (endp == NULL))
6516 /* Then the index. */
6517 unsigned int diridx;
6518 if (lineendp - linep < 1)
6520 get_uleb128 (diridx, linep, lineendp);
6522 /* Next comes the modification time. */
6524 if (lineendp - linep < 1)
6526 get_uleb128 (mtime, linep, lineendp);
6528 /* Finally the length of the file. */
6530 if (lineendp - linep < 1)
6532 get_uleb128 (fsize, linep, lineendp);
6534 printf (" %-5u %-5u %-9u %-9u %s\n",
6535 cnt, diridx, mtime, fsize, fname);
6537 /* Skip the final NUL byte. */
6540 puts (gettext ("\nLine number statements:"));
6541 Dwarf_Word address = 0;
6542 unsigned int op_index = 0;
6544 uint_fast8_t is_stmt = default_is_stmt;
6546 /* Default address value, in case we do not find the CU. */
6548 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6550 /* Determine the CU this block is for. */
6552 Dwarf_Off ncuoffset = 0;
6554 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6555 NULL, NULL, NULL) == 0)
6558 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6560 Dwarf_Attribute stmt_list;
6561 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6564 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6566 if (lineoff == start_offset)
6569 address_size = cudie.cu->address_size;
6574 /* Apply the "operation advance" from a special opcode
6575 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6576 unsigned int op_addr_advance;
6578 inline void advance_pc (unsigned int op_advance)
6580 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6581 / max_ops_per_instr);
6582 address += op_advance;
6583 show_op_index = (op_index > 0 ||
6584 (op_index + op_advance) % max_ops_per_instr > 0);
6585 op_index = (op_index + op_advance) % max_ops_per_instr;
6588 if (max_ops_per_instr == 0)
6591 gettext ("invalid maximum operations per instruction is zero"));
6596 while (linep < lineendp)
6598 size_t offset = linep - (const unsigned char *) data->d_buf;
6602 /* Read the opcode. */
6603 unsigned int opcode = *linep++;
6605 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6606 /* Is this a special opcode? */
6607 if (likely (opcode >= opcode_base))
6609 if (unlikely (line_range == 0))
6612 /* Yes. Handling this is quite easy since the opcode value
6615 opcode = (desired line increment - line_base)
6616 + (line_range * address advance) + opcode_base
6618 int line_increment = (line_base
6619 + (opcode - opcode_base) % line_range);
6621 /* Perform the increments. */
6622 line += line_increment;
6623 advance_pc ((opcode - opcode_base) / line_range);
6625 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6628 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6629 opcode, op_addr_advance, a, op_index,
6630 line_increment, line);
6633 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6634 opcode, op_addr_advance, a, line_increment, line);
6637 else if (opcode == 0)
6639 /* This an extended opcode. */
6640 if (unlikely (linep + 2 > lineendp))
6644 unsigned int len = *linep++;
6646 if (unlikely (linep + len > lineendp))
6649 /* The sub-opcode. */
6652 printf (gettext (" extended opcode %u: "), opcode);
6656 case DW_LNE_end_sequence:
6657 puts (gettext (" end of sequence"));
6659 /* Reset the registers we care about. */
6663 is_stmt = default_is_stmt;
6666 case DW_LNE_set_address:
6668 if (unlikely ((size_t) (lineendp - linep) < address_size))
6670 if (address_size == 4)
6671 address = read_4ubyte_unaligned_inc (dbg, linep);
6673 address = read_8ubyte_unaligned_inc (dbg, linep);
6675 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6676 printf (gettext (" set address to %s\n"), a);
6681 case DW_LNE_define_file:
6683 char *fname = (char *) linep;
6684 unsigned char *endp = memchr (linep, '\0',
6686 if (unlikely (endp == NULL))
6690 unsigned int diridx;
6691 if (lineendp - linep < 1)
6693 get_uleb128 (diridx, linep, lineendp);
6695 if (lineendp - linep < 1)
6697 get_uleb128 (mtime, linep, lineendp);
6698 Dwarf_Word filelength;
6699 if (lineendp - linep < 1)
6701 get_uleb128 (filelength, linep, lineendp);
6704 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6705 diridx, (uint64_t) mtime, (uint64_t) filelength,
6710 case DW_LNE_set_discriminator:
6711 /* Takes one ULEB128 parameter, the discriminator. */
6712 if (unlikely (standard_opcode_lengths[opcode] != 1))
6715 get_uleb128 (u128, linep, lineendp);
6716 printf (gettext (" set discriminator to %u\n"), u128);
6720 /* Unknown, ignore it. */
6721 puts (gettext (" unknown opcode"));
6726 else if (opcode <= DW_LNS_set_isa)
6728 /* This is a known standard opcode. */
6732 /* Takes no argument. */
6733 puts (gettext (" copy"));
6736 case DW_LNS_advance_pc:
6737 /* Takes one uleb128 parameter which is added to the
6739 get_uleb128 (u128, linep, lineendp);
6742 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6745 advance address by %u to %s, op_index to %u\n"),
6746 op_addr_advance, a, op_index);
6748 printf (gettext (" advance address by %u to %s\n"),
6749 op_addr_advance, a);
6754 case DW_LNS_advance_line:
6755 /* Takes one sleb128 parameter which is added to the
6757 get_sleb128 (s128, linep, lineendp);
6760 advance line by constant %d to %" PRId64 "\n"),
6761 s128, (int64_t) line);
6764 case DW_LNS_set_file:
6765 /* Takes one uleb128 parameter which is stored in file. */
6766 get_uleb128 (u128, linep, lineendp);
6767 printf (gettext (" set file to %" PRIu64 "\n"),
6771 case DW_LNS_set_column:
6772 /* Takes one uleb128 parameter which is stored in column. */
6773 if (unlikely (standard_opcode_lengths[opcode] != 1))
6776 get_uleb128 (u128, linep, lineendp);
6777 printf (gettext (" set column to %" PRIu64 "\n"),
6781 case DW_LNS_negate_stmt:
6782 /* Takes no argument. */
6783 is_stmt = 1 - is_stmt;
6784 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6785 "is_stmt", is_stmt);
6788 case DW_LNS_set_basic_block:
6789 /* Takes no argument. */
6790 puts (gettext (" set basic block flag"));
6793 case DW_LNS_const_add_pc:
6794 /* Takes no argument. */
6796 if (unlikely (line_range == 0))
6799 advance_pc ((255 - opcode_base) / line_range);
6801 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6804 advance address by constant %u to %s, op_index to %u\n"),
6805 op_addr_advance, a, op_index);
6808 advance address by constant %u to %s\n"),
6809 op_addr_advance, a);
6814 case DW_LNS_fixed_advance_pc:
6815 /* Takes one 16 bit parameter which is added to the
6817 if (unlikely (standard_opcode_lengths[opcode] != 1))
6820 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6824 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6826 advance address by fixed value %u to %s\n"),
6832 case DW_LNS_set_prologue_end:
6833 /* Takes no argument. */
6834 puts (gettext (" set prologue end flag"));
6837 case DW_LNS_set_epilogue_begin:
6838 /* Takes no argument. */
6839 puts (gettext (" set epilogue begin flag"));
6842 case DW_LNS_set_isa:
6843 /* Takes one uleb128 parameter which is stored in isa. */
6844 if (unlikely (standard_opcode_lengths[opcode] != 1))
6847 get_uleb128 (u128, linep, lineendp);
6848 printf (gettext (" set isa to %u\n"), u128);
6854 /* This is a new opcode the generator but not we know about.
6855 Read the parameters associated with it but then discard
6856 everything. Read all the parameters for this opcode. */
6857 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6858 " unknown opcode with %" PRIu8 " parameters:",
6859 standard_opcode_lengths[opcode]),
6860 standard_opcode_lengths[opcode]);
6861 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6863 get_uleb128 (u128, linep, lineendp);
6864 if (n != standard_opcode_lengths[opcode])
6865 putc_unlocked (',', stdout);
6866 printf (" %u", u128);
6869 /* Next round, ignore this opcode. */
6875 /* There must only be one data block. */
6876 assert (elf_getdata (scn, data) == NULL);
6881 print_debug_loc_section (Dwfl_Module *dwflmod,
6882 Ebl *ebl, GElf_Ehdr *ehdr,
6883 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6885 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6887 if (unlikely (data == NULL))
6889 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6895 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6896 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6897 (uint64_t) shdr->sh_offset);
6899 sort_listptr (&known_loclistptr, "loclistptr");
6900 size_t listptr_idx = 0;
6902 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6903 uint_fast8_t offset_size = 4;
6906 struct Dwarf_CU *cu = NULL;
6907 Dwarf_Addr base = 0;
6908 unsigned char *readp = data->d_buf;
6909 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6910 while (readp < endp)
6912 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6914 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6915 &address_size, &offset_size, &base,
6916 &cu, offset, &readp, endp))
6919 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6921 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6927 if (address_size == 8)
6929 begin = read_8ubyte_unaligned_inc (dbg, readp);
6930 end = read_8ubyte_unaligned_inc (dbg, readp);
6934 begin = read_4ubyte_unaligned_inc (dbg, readp);
6935 end = read_4ubyte_unaligned_inc (dbg, readp);
6936 if (begin == (Dwarf_Addr) (uint32_t) -1)
6937 begin = (Dwarf_Addr) -1l;
6940 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6942 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6943 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6947 else if (begin == 0 && end == 0) /* End of list entry. */
6950 printf (gettext (" [%6tx] empty list\n"), offset);
6955 /* We have a location expression entry. */
6956 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6958 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6960 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6963 if (first) /* First entry in a list. */
6964 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6966 printf (gettext (" %s..%s"), b, e);
6971 if (endp - readp <= (ptrdiff_t) len)
6973 fputs (gettext (" <INVALID DATA>\n"), stdout);
6977 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6978 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6991 struct mac_culist *next;
6996 mac_compare (const void *p1, const void *p2)
6998 struct mac_culist *m1 = (struct mac_culist *) p1;
6999 struct mac_culist *m2 = (struct mac_culist *) p2;
7001 if (m1->offset < m2->offset)
7003 if (m1->offset > m2->offset)
7010 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7011 Ebl *ebl, GElf_Ehdr *ehdr,
7012 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7015 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7016 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7017 (uint64_t) shdr->sh_offset);
7018 putc_unlocked ('\n', stdout);
7020 /* There is no function in libdw to iterate over the raw content of
7021 the section but it is easy enough to do. */
7022 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7023 if (unlikely (data == NULL || data->d_buf == NULL))
7025 error (0, 0, gettext ("cannot get macro information section data: %s"),
7030 /* Get the source file information for all CUs. */
7034 struct mac_culist *culist = NULL;
7036 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7039 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7042 Dwarf_Attribute attr;
7043 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7047 if (dwarf_formudata (&attr, &macoff) != 0)
7050 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7052 newp->offset = macoff;
7054 newp->next = culist;
7059 /* Convert the list into an array for easier consumption. */
7060 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7063 cus[nculist].offset = data->d_size;
7066 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7068 assert (cnt < nculist);
7070 culist = culist->next;
7073 /* Sort the array according to the offset in the .debug_macinfo
7074 section. Note we keep the sentinel at the end. */
7075 qsort (cus, nculist, sizeof (*cus), mac_compare);
7078 const unsigned char *readp = (const unsigned char *) data->d_buf;
7079 const unsigned char *readendp = readp + data->d_size;
7082 while (readp < readendp)
7084 unsigned int opcode = *readp++;
7086 unsigned int u128_2;
7087 const unsigned char *endp;
7091 case DW_MACINFO_define:
7092 case DW_MACINFO_undef:
7093 case DW_MACINFO_vendor_ext:
7094 /* For the first two opcodes the parameters are
7098 We can treat these cases together. */
7099 get_uleb128 (u128, readp, readendp);
7101 endp = memchr (readp, '\0', readendp - readp);
7102 if (unlikely (endp == NULL))
7105 %*s*** non-terminated string at end of section"),
7110 if (opcode == DW_MACINFO_define)
7111 printf ("%*s#define %s, line %u\n",
7112 level, "", (char *) readp, u128);
7113 else if (opcode == DW_MACINFO_undef)
7114 printf ("%*s#undef %s, line %u\n",
7115 level, "", (char *) readp, u128);
7117 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7122 case DW_MACINFO_start_file:
7123 /* The two parameters are line and file index, in this order. */
7124 get_uleb128 (u128, readp, readendp);
7125 if (readendp - readp < 1)
7128 %*s*** missing DW_MACINFO_start_file argument at end of section"),
7132 get_uleb128 (u128_2, readp, readendp);
7134 /* Find the CU DIE for this file. */
7135 size_t macoff = readp - (const unsigned char *) data->d_buf;
7136 const char *fname = "???";
7137 if (macoff >= cus[0].offset)
7139 while (macoff >= cus[1].offset)
7142 if (cus[0].files == NULL
7143 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7144 cus[0].files = (Dwarf_Files *) -1l;
7146 if (cus[0].files != (Dwarf_Files *) -1l)
7147 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7151 printf ("%*sstart_file %u, [%u] %s\n",
7152 level, "", u128, u128_2, fname);
7156 case DW_MACINFO_end_file:
7158 printf ("%*send_file\n", level, "");
7159 /* Nothing more to do. */
7163 // XXX gcc seems to generate files with a trailing zero.
7164 if (unlikely (opcode != 0 || readp != readendp))
7165 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7173 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7174 Ebl *ebl, GElf_Ehdr *ehdr,
7175 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7178 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7179 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7180 (uint64_t) shdr->sh_offset);
7181 putc_unlocked ('\n', stdout);
7183 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7184 if (unlikely (data == NULL || data->d_buf == NULL))
7186 error (0, 0, gettext ("cannot get macro information section data: %s"),
7191 /* Get the source file information for all CUs. Uses same
7192 datastructure as macinfo. But uses offset field to directly
7193 match .debug_line offset. And just stored in a list. */
7197 struct mac_culist *culist = NULL;
7199 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7202 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7205 Dwarf_Attribute attr;
7206 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7210 if (dwarf_formudata (&attr, &lineoff) != 0)
7213 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7215 newp->offset = lineoff;
7217 newp->next = culist;
7222 const unsigned char *readp = (const unsigned char *) data->d_buf;
7223 const unsigned char *readendp = readp + data->d_size;
7225 while (readp < readendp)
7227 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7228 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7230 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7231 // optional vendor extension macro entry table.
7232 if (readp + 2 > readendp)
7235 error (0, 0, gettext ("invalid data"));
7238 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7239 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7241 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7242 // 5 when it gets standardized.
7245 printf (gettext (" unknown version, cannot parse section\n"));
7249 if (readp + 1 > readendp)
7251 const unsigned char flag = *readp++;
7252 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7254 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7255 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7256 Dwarf_Off line_offset = -1;
7259 if (offset_len == 8)
7260 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7262 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7263 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7267 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7268 memset (vendor, 0, sizeof vendor);
7271 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7272 // of arguments, for each argument 1 byte form code.
7273 if (readp + 1 > readendp)
7275 unsigned int tlen = *readp++;
7276 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7278 for (unsigned int i = 0; i < tlen; i++)
7280 if (readp + 1 > readendp)
7282 unsigned int opcode = *readp++;
7283 printf (gettext (" [%" PRIx8 "]"), opcode);
7284 if (opcode < DW_MACRO_GNU_lo_user
7285 || opcode > DW_MACRO_GNU_hi_user)
7287 // Record the start of description for this vendor opcode.
7288 // uleb128 nr args, 1 byte per arg form.
7289 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7290 if (readp + 1 > readendp)
7292 unsigned int args = *readp++;
7295 printf (gettext (" %" PRIu8 " arguments:"), args);
7298 if (readp + 1 > readendp)
7300 unsigned int form = *readp++;
7301 printf (" %s", dwarf_form_string (form));
7302 if (form != DW_FORM_data1
7303 && form != DW_FORM_data2
7304 && form != DW_FORM_data4
7305 && form != DW_FORM_data8
7306 && form != DW_FORM_sdata
7307 && form != DW_FORM_udata
7308 && form != DW_FORM_block
7309 && form != DW_FORM_block1
7310 && form != DW_FORM_block2
7311 && form != DW_FORM_block4
7312 && form != DW_FORM_flag
7313 && form != DW_FORM_string
7314 && form != DW_FORM_strp
7315 && form != DW_FORM_sec_offset)
7319 putchar_unlocked (',');
7323 printf (gettext (" no arguments."));
7324 putchar_unlocked ('\n');
7327 putchar_unlocked ('\n');
7330 if (readp + 1 > readendp)
7332 unsigned int opcode = *readp++;
7336 unsigned int u128_2;
7337 const unsigned char *endp;
7342 case DW_MACRO_GNU_start_file:
7343 get_uleb128 (u128, readp, readendp);
7344 if (readp >= readendp)
7346 get_uleb128 (u128_2, readp, readendp);
7348 /* Find the CU DIE that matches this line offset. */
7349 const char *fname = "???";
7350 if (line_offset != (Dwarf_Off) -1)
7352 struct mac_culist *cu = culist;
7353 while (cu != NULL && line_offset != cu->offset)
7357 if (cu->files == NULL
7358 && dwarf_getsrcfiles (&cu->die, &cu->files,
7360 cu->files = (Dwarf_Files *) -1l;
7362 if (cu->files != (Dwarf_Files *) -1l)
7363 fname = (dwarf_filesrc (cu->files, u128_2,
7364 NULL, NULL) ?: "???");
7367 printf ("%*sstart_file %u, [%u] %s\n",
7368 level, "", u128, u128_2, fname);
7372 case DW_MACRO_GNU_end_file:
7374 printf ("%*send_file\n", level, "");
7377 case DW_MACRO_GNU_define:
7378 get_uleb128 (u128, readp, readendp);
7379 endp = memchr (readp, '\0', readendp - readp);
7382 printf ("%*s#define %s, line %u\n",
7383 level, "", readp, u128);
7387 case DW_MACRO_GNU_undef:
7388 get_uleb128 (u128, readp, readendp);
7389 endp = memchr (readp, '\0', readendp - readp);
7392 printf ("%*s#undef %s, line %u\n",
7393 level, "", readp, u128);
7397 case DW_MACRO_GNU_define_indirect:
7398 get_uleb128 (u128, readp, readendp);
7399 if (readp + offset_len > readendp)
7401 if (offset_len == 8)
7402 off = read_8ubyte_unaligned_inc (dbg, readp);
7404 off = read_4ubyte_unaligned_inc (dbg, readp);
7405 printf ("%*s#define %s, line %u (indirect)\n",
7406 level, "", dwarf_getstring (dbg, off, NULL), u128);
7409 case DW_MACRO_GNU_undef_indirect:
7410 get_uleb128 (u128, readp, readendp);
7411 if (readp + offset_len > readendp)
7413 if (offset_len == 8)
7414 off = read_8ubyte_unaligned_inc (dbg, readp);
7416 off = read_4ubyte_unaligned_inc (dbg, readp);
7417 printf ("%*s#undef %s, line %u (indirect)\n",
7418 level, "", dwarf_getstring (dbg, off, NULL), u128);
7421 case DW_MACRO_GNU_transparent_include:
7422 if (readp + offset_len > readendp)
7424 if (offset_len == 8)
7425 off = read_8ubyte_unaligned_inc (dbg, readp);
7427 off = read_4ubyte_unaligned_inc (dbg, readp);
7428 printf ("%*s#include offset 0x%" PRIx64 "\n",
7433 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7434 if (opcode < DW_MACRO_GNU_lo_user
7435 || opcode > DW_MACRO_GNU_lo_user
7436 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7439 const unsigned char *op_desc;
7440 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7442 // Just skip the arguments, we cannot really interpret them,
7443 // but print as much as we can.
7444 unsigned int args = *op_desc++;
7447 unsigned int form = *op_desc++;
7452 if (readp + 1 > readendp)
7455 printf (" %" PRIx8, (unsigned int) val);
7459 if (readp + 2 > readendp)
7461 val = read_2ubyte_unaligned_inc (dbg, readp);
7462 printf(" %" PRIx16, (unsigned int) val);
7466 if (readp + 4 > readendp)
7468 val = read_4ubyte_unaligned_inc (dbg, readp);
7469 printf (" %" PRIx32, (unsigned int) val);
7473 if (readp + 8 > readendp)
7475 val = read_8ubyte_unaligned_inc (dbg, readp);
7476 printf (" %" PRIx64, val);
7480 get_sleb128 (val, readp, readendp);
7481 printf (" %" PRIx64, val);
7485 get_uleb128 (val, readp, readendp);
7486 printf (" %" PRIx64, val);
7490 get_uleb128 (val, readp, readendp);
7491 printf (" block[%" PRIu64 "]", val);
7492 if (readp + val > readendp)
7497 case DW_FORM_block1:
7498 if (readp + 1 > readendp)
7501 printf (" block[%" PRIu64 "]", val);
7502 if (readp + val > readendp)
7506 case DW_FORM_block2:
7507 if (readp + 2 > readendp)
7509 val = read_2ubyte_unaligned_inc (dbg, readp);
7510 printf (" block[%" PRIu64 "]", val);
7511 if (readp + val > readendp)
7515 case DW_FORM_block4:
7516 if (readp + 2 > readendp)
7518 val =read_4ubyte_unaligned_inc (dbg, readp);
7519 printf (" block[%" PRIu64 "]", val);
7520 if (readp + val > readendp)
7525 if (readp + 1 > readendp)
7528 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7531 case DW_FORM_string:
7532 endp = memchr (readp, '\0', readendp - readp);
7535 printf (" %s", readp);
7540 if (readp + offset_len > readendp)
7542 if (offset_len == 8)
7543 val = read_8ubyte_unaligned_inc (dbg, readp);
7545 val = read_4ubyte_unaligned_inc (dbg, readp);
7546 printf (" %s", dwarf_getstring (dbg, val, NULL));
7549 case DW_FORM_sec_offset:
7550 if (readp + offset_len > readendp)
7552 if (offset_len == 8)
7553 val = read_8ubyte_unaligned_inc (dbg, readp);
7555 val = read_4ubyte_unaligned_inc (dbg, readp);
7556 printf (" %" PRIx64, val);
7560 error (0, 0, gettext ("vendor opcode not verified?"));
7566 putchar_unlocked (',');
7568 putchar_unlocked ('\n');
7571 if (readp + 1 > readendp)
7575 putchar_unlocked ('\n');
7581 /* Callback for printing global names. */
7583 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7586 int *np = (int *) arg;
7588 printf (gettext (" [%5d] DIE offset: %6" PRId64
7589 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7590 (*np)++, global->die_offset, global->cu_offset, global->name);
7596 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7598 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7599 Ebl *ebl, GElf_Ehdr *ehdr,
7600 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7602 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7603 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7604 (uint64_t) shdr->sh_offset);
7607 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7610 /* Print the content of the DWARF string section '.debug_str'. */
7612 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7613 Ebl *ebl, GElf_Ehdr *ehdr,
7614 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7616 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7617 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7619 /* Compute floor(log16(shdr->sh_size)). */
7620 GElf_Addr tmp = sh_size;
7627 digits = MAX (4, digits);
7629 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7632 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7633 /* TRANS: the debugstr| prefix makes the string unique. */
7634 digits + 2, sgettext ("debugstr|Offset"));
7636 Dwarf_Off offset = 0;
7637 while (offset < sh_size)
7640 const char *str = dwarf_getstring (dbg, offset, &len);
7641 if (unlikely (str == NULL))
7643 printf (gettext (" *** error while reading strings: %s\n"),
7648 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7655 /* Print the content of the call frame search table section
7658 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7659 Ebl *ebl __attribute__ ((unused)),
7660 GElf_Ehdr *ehdr __attribute__ ((unused)),
7661 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7664 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7667 Elf_Data *data = elf_rawdata (scn, NULL);
7669 if (unlikely (data == NULL))
7671 error (0, 0, gettext ("cannot get %s content: %s"),
7672 ".eh_frame_hdr", elf_errmsg (-1));
7676 const unsigned char *readp = data->d_buf;
7677 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7680 if (unlikely (readp + 4 > dataend))
7683 error (0, 0, gettext ("invalid data"));
7687 unsigned int version = *readp++;
7688 unsigned int eh_frame_ptr_enc = *readp++;
7689 unsigned int fde_count_enc = *readp++;
7690 unsigned int table_enc = *readp++;
7692 printf (" version: %u\n"
7693 " eh_frame_ptr_enc: %#x ",
7694 version, eh_frame_ptr_enc);
7695 print_encoding_base ("", eh_frame_ptr_enc);
7696 printf (" fde_count_enc: %#x ", fde_count_enc);
7697 print_encoding_base ("", fde_count_enc);
7698 printf (" table_enc: %#x ", table_enc);
7699 print_encoding_base ("", table_enc);
7701 uint64_t eh_frame_ptr = 0;
7702 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7704 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7706 if (unlikely (readp == NULL))
7709 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7710 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7711 printf (" (offset: %#" PRIx64 ")",
7712 /* +4 because of the 4 byte header of the section. */
7713 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7715 putchar_unlocked ('\n');
7718 uint64_t fde_count = 0;
7719 if (fde_count_enc != DW_EH_PE_omit)
7721 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7722 if (unlikely (readp == NULL))
7725 printf (" fde_count: %" PRIu64 "\n", fde_count);
7728 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7733 /* Optimize for the most common case. */
7734 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7735 while (fde_count > 0 && readp + 8 <= dataend)
7737 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7738 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7739 + (int64_t) initial_location);
7740 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7741 // XXX Possibly print symbol name or section offset for initial_offset
7742 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7743 " fde=[%6" PRIx64 "]\n",
7744 initial_location, initial_offset,
7745 address, address - (eh_frame_ptr + 4));
7748 while (0 && readp < dataend)
7755 /* Print the content of the exception handling table section
7758 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7759 Ebl *ebl __attribute__ ((unused)),
7760 GElf_Ehdr *ehdr __attribute__ ((unused)),
7762 GElf_Shdr *shdr __attribute__ ((unused)),
7763 Dwarf *dbg __attribute__ ((unused)))
7766 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7769 Elf_Data *data = elf_rawdata (scn, NULL);
7771 if (unlikely (data == NULL))
7773 error (0, 0, gettext ("cannot get %s content: %s"),
7774 ".gcc_except_table", elf_errmsg (-1));
7778 const unsigned char *readp = data->d_buf;
7779 const unsigned char *const dataend = readp + data->d_size;
7781 if (unlikely (readp + 1 > dataend))
7784 error (0, 0, gettext ("invalid data"));
7787 unsigned int lpstart_encoding = *readp++;
7788 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7789 print_encoding_base ("", lpstart_encoding);
7790 if (lpstart_encoding != DW_EH_PE_omit)
7793 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7794 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7797 if (unlikely (readp + 1 > dataend))
7799 unsigned int ttype_encoding = *readp++;
7800 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7801 print_encoding_base ("", ttype_encoding);
7802 const unsigned char *ttype_base = NULL;
7803 if (ttype_encoding != DW_EH_PE_omit)
7805 unsigned int ttype_base_offset;
7806 get_uleb128 (ttype_base_offset, readp, dataend);
7807 printf (" TType base offset: %#x\n", ttype_base_offset);
7808 if ((size_t) (dataend - readp) > ttype_base_offset)
7809 ttype_base = readp + ttype_base_offset;
7812 if (unlikely (readp + 1 > dataend))
7814 unsigned int call_site_encoding = *readp++;
7815 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7816 print_encoding_base ("", call_site_encoding);
7817 unsigned int call_site_table_len;
7818 get_uleb128 (call_site_table_len, readp, dataend);
7820 const unsigned char *const action_table = readp + call_site_table_len;
7821 if (unlikely (action_table > dataend))
7824 unsigned int max_action = 0;
7825 while (readp < action_table)
7828 puts (gettext ("\n Call site table:"));
7830 uint64_t call_site_start;
7831 readp = read_encoded (call_site_encoding, readp, dataend,
7832 &call_site_start, dbg);
7833 uint64_t call_site_length;
7834 readp = read_encoded (call_site_encoding, readp, dataend,
7835 &call_site_length, dbg);
7836 uint64_t landing_pad;
7837 readp = read_encoded (call_site_encoding, readp, dataend,
7839 unsigned int action;
7840 get_uleb128 (action, readp, dataend);
7841 max_action = MAX (action, max_action);
7842 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7843 " Call site length: %" PRIu64 "\n"
7844 " Landing pad: %#" PRIx64 "\n"
7846 u++, call_site_start, call_site_length, landing_pad, action);
7848 if (readp != action_table)
7851 unsigned int max_ar_filter = 0;
7854 puts ("\n Action table:");
7856 size_t maxdata = (size_t) (dataend - action_table);
7857 if (max_action > maxdata || maxdata - max_action < 1)
7859 invalid_action_table:
7860 fputs (gettext (" <INVALID DATA>\n"), stdout);
7864 const unsigned char *const action_table_end
7865 = action_table + max_action + 1;
7871 get_sleb128 (ar_filter, readp, action_table_end);
7872 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7873 max_ar_filter = ar_filter;
7875 if (readp >= action_table_end)
7876 goto invalid_action_table;
7877 get_sleb128 (ar_disp, readp, action_table_end);
7879 printf (" [%4u] ar_filter: % d\n"
7881 u, ar_filter, ar_disp);
7882 if (abs (ar_disp) & 1)
7883 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7884 else if (ar_disp != 0)
7887 putchar_unlocked ('\n');
7890 while (readp < action_table_end);
7893 if (max_ar_filter > 0 && ttype_base != NULL)
7895 unsigned char dsize;
7896 puts ("\n TType table:");
7898 // XXX Not *4, size of encoding;
7899 switch (ttype_encoding & 7)
7901 case DW_EH_PE_udata2:
7902 case DW_EH_PE_sdata2:
7905 case DW_EH_PE_udata4:
7906 case DW_EH_PE_sdata4:
7909 case DW_EH_PE_udata8:
7910 case DW_EH_PE_sdata8:
7914 error (1, 0, gettext ("invalid TType encoding"));
7918 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
7921 readp = ttype_base - max_ar_filter * dsize;
7925 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7927 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7929 while (readp < ttype_base);
7933 /* Print the content of the '.gdb_index' section.
7934 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7937 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7938 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7940 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7941 " contains %" PRId64 " bytes :\n"),
7942 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7943 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7945 Elf_Data *data = elf_rawdata (scn, NULL);
7947 if (unlikely (data == NULL))
7949 error (0, 0, gettext ("cannot get %s content: %s"),
7950 ".gdb_index", elf_errmsg (-1));
7954 // .gdb_index is always in little endian.
7955 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7958 const unsigned char *readp = data->d_buf;
7959 const unsigned char *const dataend = readp + data->d_size;
7961 if (unlikely (readp + 4 > dataend))
7964 error (0, 0, gettext ("invalid data"));
7968 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7969 printf (gettext (" Version: %" PRId32 "\n"), vers);
7971 // The only difference between version 4 and version 5 is the
7972 // hash used for generating the table. Version 6 contains symbols
7973 // for inlined functions, older versions didn't. Version 7 adds
7974 // symbol kinds. Version 8 just indicates that it correctly includes
7976 if (vers < 4 || vers > 8)
7978 printf (gettext (" unknown version, cannot parse section\n"));
7983 if (unlikely (readp + 4 > dataend))
7986 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7987 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7990 if (unlikely (readp + 4 > dataend))
7993 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7994 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7997 if (unlikely (readp + 4 > dataend))
8000 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
8001 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
8004 if (unlikely (readp + 4 > dataend))
8007 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8008 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
8011 if (unlikely (readp + 4 > dataend))
8014 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8015 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8017 readp = data->d_buf + cu_off;
8019 const unsigned char *nextp = data->d_buf + tu_off;
8020 size_t cu_nr = (nextp - readp) / 16;
8022 printf (gettext ("\n CU list at offset %#" PRIx32
8023 " contains %zu entries:\n"),
8027 while (readp + 16 <= dataend && n < cu_nr)
8029 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8032 uint64_t len = read_8ubyte_unaligned (dbg, readp);
8035 printf (" [%4zu] start: %0#8" PRIx64
8036 ", length: %5" PRIu64 "\n", n, off, len);
8040 readp = data->d_buf + tu_off;
8041 nextp = data->d_buf + addr_off;
8042 size_t tu_nr = (nextp - readp) / 24;
8044 printf (gettext ("\n TU list at offset %#" PRIx32
8045 " contains %zu entries:\n"),
8049 while (readp + 24 <= dataend && n < tu_nr)
8051 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8054 uint64_t type = read_8ubyte_unaligned (dbg, readp);
8057 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8060 printf (" [%4zu] CU offset: %5" PRId64
8061 ", type offset: %5" PRId64
8062 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8066 readp = data->d_buf + addr_off;
8067 nextp = data->d_buf + sym_off;
8068 size_t addr_nr = (nextp - readp) / 20;
8070 printf (gettext ("\n Address list at offset %#" PRIx32
8071 " contains %zu entries:\n"),
8075 while (readp + 20 <= dataend && n < addr_nr)
8077 uint64_t low = read_8ubyte_unaligned (dbg, readp);
8080 uint64_t high = read_8ubyte_unaligned (dbg, readp);
8083 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8086 char *l = format_dwarf_addr (dwflmod, 8, low, low);
8087 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8088 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8095 readp = data->d_buf + sym_off;
8096 nextp = data->d_buf + const_off;
8097 size_t sym_nr = (nextp - readp) / 8;
8099 printf (gettext ("\n Symbol table at offset %#" PRIx32
8100 " contains %zu slots:\n"),
8104 while (readp + 8 <= dataend && n < sym_nr)
8106 uint32_t name = read_4ubyte_unaligned (dbg, readp);
8109 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8112 if (name != 0 || vector != 0)
8114 const unsigned char *sym = data->d_buf + const_off + name;
8115 if (unlikely (sym > dataend
8116 || memchr (sym, '\0', dataend - sym) == NULL))
8119 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8121 const unsigned char *readcus = data->d_buf + const_off + vector;
8122 if (unlikely (readcus + 4 > dataend))
8124 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8127 uint32_t cu_kind, cu, kind;
8130 if (unlikely (readcus + 4 > dataend))
8132 cu_kind = read_4ubyte_unaligned (dbg, readcus);
8133 cu = cu_kind & ((1 << 24) - 1);
8134 kind = (cu_kind >> 28) & 7;
8135 is_static = cu_kind & (1U << 31);
8137 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8139 printf ("%" PRId32, cu);
8158 printf ("unknown-0x%" PRIx32, kind);
8161 printf (":%c)", (is_static ? 'S' : 'G'));
8173 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8175 /* Before we start the real work get a debug context descriptor. */
8177 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8181 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8185 if ((print_debug_sections & ~section_exception) != 0)
8186 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8188 if ((print_debug_sections & section_exception) == 0)
8193 /* Get the section header string table index. */
8195 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8196 error (EXIT_FAILURE, 0,
8197 gettext ("cannot get section header string table index"));
8199 /* Look through all the sections for the debugging sections to print. */
8200 Elf_Scn *scn = NULL;
8201 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8204 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8206 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8211 enum section_e bitmask;
8212 void (*fp) (Dwfl_Module *, Ebl *,
8213 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8214 } debug_sections[] =
8216 #define NEW_SECTION(name) \
8217 { ".debug_" #name, section_##name, print_debug_##name##_section }
8218 NEW_SECTION (abbrev),
8219 NEW_SECTION (aranges),
8220 NEW_SECTION (frame),
8222 NEW_SECTION (types),
8225 NEW_SECTION (pubnames),
8227 NEW_SECTION (macinfo),
8228 NEW_SECTION (macro),
8229 NEW_SECTION (ranges),
8230 { ".eh_frame", section_frame | section_exception,
8231 print_debug_frame_section },
8232 { ".eh_frame_hdr", section_frame | section_exception,
8233 print_debug_frame_hdr_section },
8234 { ".gcc_except_table", section_frame | section_exception,
8235 print_debug_exception_table },
8236 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8238 const int ndebug_sections = (sizeof (debug_sections)
8239 / sizeof (debug_sections[0]));
8240 const char *name = elf_strptr (ebl->elf, shstrndx,
8246 for (n = 0; n < ndebug_sections; ++n)
8247 if (strcmp (name, debug_sections[n].name) == 0
8249 || (name[0] == '.' && name[1] == 'z'
8250 && debug_sections[n].name[1] == 'd'
8251 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8255 if ((print_debug_sections | implicit_debug_sections)
8256 & debug_sections[n].bitmask)
8257 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8263 reset_listptr (&known_loclistptr);
8264 reset_listptr (&known_rangelistptr);
8268 #define ITEM_INDENT 4
8269 #define WRAP_COLUMN 75
8271 /* Print "NAME: FORMAT", wrapping when output text would make the line
8272 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8273 but this function is also used for registers which should be printed
8274 aligned. Fortunately registers output uses fixed fields width (such
8275 as %11d) for the alignment.
8277 Line breaks should not depend on the particular values although that
8278 may happen in some cases of the core items. */
8281 __attribute__ ((format (printf, 6, 7)))
8282 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8283 size_t name_width, const char *name, const char *format, ...)
8285 size_t len = strlen (name);
8286 if (name_width < len)
8291 va_start (ap, format);
8292 int out_len = vasprintf (&out, format, ap);
8295 error (EXIT_FAILURE, 0, _("memory exhausted"));
8297 size_t n = name_width + sizeof ": " - 1 + out_len;
8301 printf ("%*s", ITEM_INDENT, "");
8302 colno = ITEM_INDENT + n;
8304 else if (colno + 2 + n < wrap)
8306 printf ("%c ", sep);
8311 printf ("\n%*s", ITEM_INDENT, "");
8312 colno = ITEM_INDENT + n;
8315 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8323 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8324 void *value, const void *data, size_t size)
8326 Elf_Data valuedata =
8330 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8331 .d_version = EV_CURRENT,
8336 .d_buf = (void *) data,
8337 .d_size = valuedata.d_size,
8338 .d_version = EV_CURRENT,
8341 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8342 ? elf32_xlatetom : elf64_xlatetom)
8343 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8345 error (EXIT_FAILURE, 0,
8346 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8348 return data + indata.d_size;
8351 typedef uint8_t GElf_Byte;
8354 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8355 unsigned int colno, size_t *repeated_size)
8357 uint_fast16_t count = item->count ?: 1;
8360 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8361 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8362 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8363 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8364 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8365 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8367 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8368 union { TYPES; } value;
8371 void *data = &value;
8372 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8373 size_t convsize = size;
8374 if (repeated_size != NULL)
8376 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8378 data = alloca (*repeated_size);
8379 count *= *repeated_size / size;
8380 convsize = count * size;
8381 *repeated_size -= convsize;
8383 else if (item->count != 0 || item->format != '\n')
8384 *repeated_size -= size;
8387 convert (core, item->type, count, data, desc + item->offset, convsize);
8389 Elf_Type type = item->type;
8390 if (type == ELF_T_ADDR)
8391 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8393 switch (item->format)
8396 assert (count == 1);
8399 #define DO_TYPE(NAME, Name, hex, dec) \
8400 case ELF_T_##NAME: \
8401 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8402 0, item->name, dec, value.Name[0]); \
8412 assert (count == 1);
8415 #define DO_TYPE(NAME, Name, hex, dec) \
8416 case ELF_T_##NAME: \
8417 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8418 0, item->name, hex, value.Name[0]); \
8429 assert (size % sizeof (unsigned int) == 0);
8430 unsigned int nbits = count * size * 8;
8431 unsigned int pop = 0;
8432 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8433 pop += __builtin_popcount (*i);
8434 bool negate = pop > nbits / 2;
8435 const unsigned int bias = item->format == 'b';
8438 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8442 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8444 assert (size == sizeof (unsigned int) * 2);
8445 for (unsigned int *i = data;
8446 (void *) i < data + count * size; i += 2)
8448 unsigned int w = i[1];
8454 unsigned int lastbit = 0;
8455 unsigned int run = 0;
8456 for (const unsigned int *i = data;
8457 (void *) i < data + count * size; ++i)
8459 unsigned int bit = ((void *) i - data) * 8;
8460 unsigned int w = negate ? ~*i : *i;
8467 if (lastbit != 0 && lastbit + 1 == bit)
8472 p += sprintf (p, "%u", bit - bias);
8474 p += sprintf (p, ",%u", bit - bias);
8476 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8483 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8484 p += sprintf (p, "-%u", lastbit - bias);
8486 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8487 negate ? "~<%s>" : "<%s>", printed);
8492 case (char) ('T'|0x80):
8493 assert (count == 2);
8498 #define DO_TYPE(NAME, Name, hex, dec) \
8499 case ELF_T_##NAME: \
8500 sec = value.Name[0]; \
8501 usec = value.Name[1]; \
8508 if (unlikely (item->format == (char) ('T'|0x80)))
8510 /* This is a hack for an ill-considered 64-bit ABI where
8511 tv_usec is actually a 32-bit field with 32 bits of padding
8512 rounding out struct timeval. We've already converted it as
8513 a 64-bit field. For little-endian, this just means the
8514 high half is the padding; it's presumably zero, but should
8515 be ignored anyway. For big-endian, it means the 32-bit
8516 field went into the high half of USEC. */
8518 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8519 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8524 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8525 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8529 assert (count == 1);
8530 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8531 "%c", value.Byte[0]);
8535 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8536 "%.*s", (int) count, value.Byte);
8540 /* This is a list of strings separated by '\n'. */
8541 assert (item->count == 0);
8542 assert (repeated_size != NULL);
8543 assert (item->name == NULL);
8544 if (unlikely (item->offset >= *repeated_size))
8547 const char *s = desc + item->offset;
8548 size = *repeated_size - item->offset;
8552 const char *eol = memchr (s, '\n', size);
8556 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8559 size -= eol + 1 - s;
8563 colno = WRAP_COLUMN;
8570 error (0, 0, "XXX not handling format '%c' for %s",
8571 item->format, item->name);
8581 /* Sort items by group, and by layout offset within each group. */
8583 compare_core_items (const void *a, const void *b)
8585 const Ebl_Core_Item *const *p1 = a;
8586 const Ebl_Core_Item *const *p2 = b;
8587 const Ebl_Core_Item *item1 = *p1;
8588 const Ebl_Core_Item *item2 = *p2;
8590 return ((item1->group == item2->group ? 0
8591 : strcmp (item1->group, item2->group))
8592 ?: (int) item1->offset - (int) item2->offset);
8595 /* Sort item groups by layout offset of the first item in the group. */
8597 compare_core_item_groups (const void *a, const void *b)
8599 const Ebl_Core_Item *const *const *p1 = a;
8600 const Ebl_Core_Item *const *const *p2 = b;
8601 const Ebl_Core_Item *const *group1 = *p1;
8602 const Ebl_Core_Item *const *group2 = *p2;
8603 const Ebl_Core_Item *item1 = *group1;
8604 const Ebl_Core_Item *item2 = *group2;
8606 return (int) item1->offset - (int) item2->offset;
8610 handle_core_items (Elf *core, const void *desc, size_t descsz,
8611 const Ebl_Core_Item *items, size_t nitems)
8615 unsigned int colno = 0;
8617 /* FORMAT '\n' makes sense to be present only as a single item as it
8618 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8619 if present as a single item but they can be also processed with other
8621 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8622 || items[0].format == 'B'))
8624 assert (items[0].offset == 0);
8625 size_t size = descsz;
8626 colno = handle_core_item (core, items, desc, colno, &size);
8627 /* If SIZE is not zero here there is some remaining data. But we do not
8628 know how to process it anyway. */
8631 for (size_t i = 0; i < nitems; ++i)
8632 assert (items[i].format != '\n');
8634 /* Sort to collect the groups together. */
8635 const Ebl_Core_Item *sorted_items[nitems];
8636 for (size_t i = 0; i < nitems; ++i)
8637 sorted_items[i] = &items[i];
8638 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8640 /* Collect the unique groups and sort them. */
8641 const Ebl_Core_Item **groups[nitems];
8642 groups[0] = &sorted_items[0];
8644 for (size_t i = 1; i < nitems; ++i)
8645 if (sorted_items[i]->group != sorted_items[i - 1]->group
8646 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8647 groups[ngroups++] = &sorted_items[i];
8648 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8650 /* Write out all the groups. */
8651 const void *last = desc;
8654 for (size_t i = 0; i < ngroups; ++i)
8656 for (const Ebl_Core_Item **item = groups[i];
8657 (item < &sorted_items[nitems]
8658 && ((*item)->group == groups[i][0]->group
8659 || !strcmp ((*item)->group, groups[i][0]->group)));
8661 colno = handle_core_item (core, *item, desc, colno, NULL);
8663 /* Force a line break at the end of the group. */
8664 colno = WRAP_COLUMN;
8670 /* This set of items consumed a certain amount of the note's data.
8671 If there is more data there, we have another unit of the same size.
8672 Loop to print that out too. */
8673 const Ebl_Core_Item *item = &items[nitems - 1];
8674 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8675 item->count ?: 1, EV_CURRENT);
8684 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8688 /* For just one repeat, print it unabridged twice. */
8693 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8694 ITEM_INDENT, "", reps);
8704 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8707 desc += regloc->offset;
8715 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8716 const Ebl_Register_Location *regloc, const void *desc,
8719 if (regloc->bits % 8 != 0)
8720 return handle_bit_registers (regloc, desc, colno);
8722 desc += regloc->offset;
8724 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8726 char name[REGNAMESZ];
8729 register_info (ebl, reg, regloc, name, &bits, &type);
8732 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8733 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8734 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8735 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8737 #define BITS(bits, xtype, sfmt, ufmt) \
8738 uint##bits##_t b##bits; int##bits##_t b##bits##s
8739 union { TYPES; uint64_t b128[2]; } value;
8744 case DW_ATE_unsigned:
8746 case DW_ATE_address:
8749 #define BITS(bits, xtype, sfmt, ufmt) \
8751 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8752 if (type == DW_ATE_signed) \
8753 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8755 sfmt, value.b##bits##s); \
8757 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8759 ufmt, value.b##bits); \
8765 assert (type == DW_ATE_unsigned);
8766 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8767 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8768 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8770 "0x%.16" PRIx64 "%.16" PRIx64,
8771 value.b128[!be], value.b128[be]);
8781 /* Print each byte in hex, the whole thing in native byte order. */
8782 assert (bits % 8 == 0);
8783 const uint8_t *bytes = desc;
8785 char hex[bits / 4 + 1];
8786 hex[bits / 4] = '\0';
8788 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8790 bytes += bits / 8 - 1;
8794 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8796 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8797 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8799 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8800 maxregname, name, "0x%s", hex);
8803 desc += regloc->pad;
8812 struct register_info
8814 const Ebl_Register_Location *regloc;
8816 char name[REGNAMESZ];
8823 register_bitpos (const struct register_info *r)
8825 return (r->regloc->offset * 8
8826 + ((r->regno - r->regloc->regno)
8827 * (r->regloc->bits + r->regloc->pad * 8)));
8831 compare_sets_by_info (const struct register_info *r1,
8832 const struct register_info *r2)
8834 return ((int) r2->bits - (int) r1->bits
8835 ?: register_bitpos (r1) - register_bitpos (r2));
8838 /* Sort registers by set, and by size and layout offset within each set. */
8840 compare_registers (const void *a, const void *b)
8842 const struct register_info *r1 = a;
8843 const struct register_info *r2 = b;
8845 /* Unused elements sort last. */
8846 if (r1->regloc == NULL)
8847 return r2->regloc == NULL ? 0 : 1;
8848 if (r2->regloc == NULL)
8851 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8852 ?: compare_sets_by_info (r1, r2));
8855 /* Sort register sets by layout offset of the first register in the set. */
8857 compare_register_sets (const void *a, const void *b)
8859 const struct register_info *const *p1 = a;
8860 const struct register_info *const *p2 = b;
8861 return compare_sets_by_info (*p1, *p2);
8865 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8866 const Ebl_Register_Location *reglocs, size_t nregloc)
8871 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8874 for (size_t i = 0; i < nregloc; ++i)
8875 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8876 maxnreg = reglocs[i].regno + reglocs[i].count;
8877 assert (maxnreg > 0);
8880 struct register_info regs[maxnreg];
8881 memset (regs, 0, sizeof regs);
8883 /* Sort to collect the sets together. */
8885 for (size_t i = 0; i < nregloc; ++i)
8886 for (int reg = reglocs[i].regno;
8887 reg < reglocs[i].regno + reglocs[i].count;
8890 assert (reg < maxnreg);
8893 struct register_info *info = ®s[reg];
8894 info->regloc = ®locs[i];
8896 info->set = register_info (ebl, reg, ®locs[i],
8897 info->name, &info->bits, &info->type);
8899 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8901 /* Collect the unique sets and sort them. */
8902 inline bool same_set (const struct register_info *a,
8903 const struct register_info *b)
8905 return (a < ®s[maxnreg] && a->regloc != NULL
8906 && b < ®s[maxnreg] && b->regloc != NULL
8907 && a->bits == b->bits
8908 && (a->set == b->set || !strcmp (a->set, b->set)));
8910 struct register_info *sets[maxreg + 1];
8913 for (int i = 1; i <= maxreg; ++i)
8914 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8915 sets[nsets++] = ®s[i];
8916 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8918 /* Write out all the sets. */
8919 unsigned int colno = 0;
8920 for (size_t i = 0; i < nsets; ++i)
8922 /* Find the longest name of a register in this set. */
8924 const struct register_info *end;
8925 for (end = sets[i]; same_set (sets[i], end); ++end)
8927 size_t len = strlen (end->name);
8932 for (const struct register_info *reg = sets[i];
8934 reg += reg->regloc->count ?: 1)
8935 colno = handle_core_register (ebl, core, maxname,
8936 reg->regloc, desc, colno);
8938 /* Force a line break at the end of the group. */
8939 colno = WRAP_COLUMN;
8946 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8948 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8951 error (EXIT_FAILURE, 0,
8952 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8954 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8955 for (size_t i = 0; i < nauxv; ++i)
8958 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8964 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8967 if (av->a_un.a_val == 0)
8968 printf (" %" PRIu64 "\n", av->a_type);
8970 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8971 av->a_type, av->a_un.a_val);
8976 case '\0': /* Normally zero. */
8977 if (av->a_un.a_val == 0)
8979 printf (" %s\n", name);
8984 case 'p': /* address */
8985 case 's': /* address of string */
8986 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8989 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8992 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8996 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8998 const char *pfx = "<";
8999 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9001 if (av->a_un.a_val & bit)
9003 printf ("%s%s", pfx, p);
9018 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9020 return ptr < end && (size_t) (end - ptr) >= sz;
9024 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9027 if (! buf_has_data (*ptrp, end, 4))
9030 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9035 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9038 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9039 if (! buf_has_data (*ptrp, end, sz))
9048 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9058 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9060 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9062 error (EXIT_FAILURE, 0,
9063 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9065 unsigned char const *ptr = data->d_buf;
9066 unsigned char const *const end = data->d_buf + data->d_size;
9068 /* Siginfo head is three ints: signal number, error number, origin
9070 int si_signo, si_errno, si_code;
9071 if (! buf_read_int (core, &ptr, end, &si_signo)
9072 || ! buf_read_int (core, &ptr, end, &si_errno)
9073 || ! buf_read_int (core, &ptr, end, &si_code))
9076 printf (" Not enough data in NT_SIGINFO note.\n");
9080 /* Next is a pointer-aligned union of structures. On 64-bit
9081 machines, that implies a word of padding. */
9082 if (gelf_getclass (core) == ELFCLASS64)
9085 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
9086 si_signo, si_errno, si_code);
9097 if (! buf_read_ulong (core, &ptr, end, &addr))
9099 printf (" fault address: %#" PRIx64 "\n", addr);
9105 else if (si_code == SI_USER)
9108 if (! buf_read_int (core, &ptr, end, &pid)
9109 || ! buf_read_int (core, &ptr, end, &uid))
9111 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
9116 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9118 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9120 error (EXIT_FAILURE, 0,
9121 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9123 unsigned char const *ptr = data->d_buf;
9124 unsigned char const *const end = data->d_buf + data->d_size;
9126 uint64_t count, page_size;
9127 if (! buf_read_ulong (core, &ptr, end, &count)
9128 || ! buf_read_ulong (core, &ptr, end, &page_size))
9131 printf (" Not enough data in NT_FILE note.\n");
9135 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9136 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9137 if (count > maxcount)
9140 /* Where file names are stored. */
9141 unsigned char const *const fstart = ptr + 3 * count * addrsize;
9142 char const *fptr = (char *) fstart;
9144 printf (" %" PRId64 " files:\n", count);
9145 for (uint64_t i = 0; i < count; ++i)
9147 uint64_t mstart, mend, moffset;
9148 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9149 || ! buf_read_ulong (core, &ptr, fstart, &mend)
9150 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9153 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9157 int ct = printf (" %08" PRIx64 "-%08" PRIx64
9158 " %08" PRIx64 " %" PRId64,
9159 mstart, mend, moffset * page_size, mend - mstart);
9160 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9167 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9168 const char *name, const void *desc)
9170 GElf_Word regs_offset;
9172 const Ebl_Register_Location *reglocs;
9174 const Ebl_Core_Item *items;
9176 if (! ebl_core_note (ebl, nhdr, name,
9177 ®s_offset, &nregloc, ®locs, &nitems, &items))
9180 /* Pass 0 for DESCSZ when there are registers in the note,
9181 so that the ITEMS array does not describe the whole thing.
9182 For non-register notes, the actual descsz might be a multiple
9183 of the unit size, not just exactly the unit size. */
9184 unsigned int colno = handle_core_items (ebl->elf, desc,
9185 nregloc == 0 ? nhdr->n_descsz : 0,
9188 putchar_unlocked ('\n');
9190 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9193 putchar_unlocked ('\n');
9197 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9198 GElf_Off start, Elf_Data *data)
9200 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
9209 while (offset < data->d_size
9210 && (offset = gelf_getnote (data, offset,
9211 &nhdr, &name_offset, &desc_offset)) > 0)
9213 const char *name = data->d_buf + name_offset;
9214 const char *desc = data->d_buf + desc_offset;
9218 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
9219 (int) nhdr.n_namesz, name, nhdr.n_descsz,
9220 ehdr->e_type == ET_CORE
9221 ? ebl_core_note_type_name (ebl, nhdr.n_type,
9223 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9224 buf2, sizeof (buf2)));
9226 /* Filter out invalid entries. */
9227 if (memchr (name, '\0', nhdr.n_namesz) != NULL
9228 /* XXX For now help broken Linux kernels. */
9231 if (ehdr->e_type == ET_CORE)
9233 if (nhdr.n_type == NT_AUXV
9234 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9235 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9236 && !memcmp (name, "CORE", 4))
9237 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9238 start + desc_offset);
9239 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9240 switch (nhdr.n_type)
9243 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9244 start + desc_offset);
9248 handle_file_note (ebl->elf, nhdr.n_descsz,
9249 start + desc_offset);
9253 handle_core_note (ebl, &nhdr, name, desc);
9256 handle_core_note (ebl, &nhdr, name, desc);
9259 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9263 if (offset == data->d_size)
9267 error (EXIT_FAILURE, 0,
9268 gettext ("cannot get content of note section: %s"),
9273 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9275 /* If we have section headers, just look for SHT_NOTE sections.
9276 In a debuginfo file, the program headers are not reliable. */
9279 /* Get the section header string table index. */
9281 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9282 error (EXIT_FAILURE, 0,
9283 gettext ("cannot get section header string table index"));
9285 Elf_Scn *scn = NULL;
9286 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9289 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9291 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9292 /* Not what we are looking for. */
9296 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9298 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9299 shdr->sh_size, shdr->sh_offset);
9301 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9302 elf_getdata (scn, NULL));
9307 /* We have to look through the program header to find the note
9308 sections. There can be more than one. */
9309 for (size_t cnt = 0; cnt < phnum; ++cnt)
9312 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9314 if (phdr == NULL || phdr->p_type != PT_NOTE)
9315 /* Not what we are looking for. */
9319 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9320 phdr->p_filesz, phdr->p_offset);
9322 handle_notes_data (ebl, ehdr, phdr->p_offset,
9323 elf_getdata_rawchunk (ebl->elf,
9324 phdr->p_offset, phdr->p_filesz,
9331 hex_dump (const uint8_t *data, size_t len)
9336 printf (" 0x%08Zx ", pos);
9338 const size_t chunk = MIN (len - pos, 16);
9340 for (size_t i = 0; i < chunk; ++i)
9342 printf ("%02x ", data[pos + i]);
9344 printf ("%02x", data[pos + i]);
9347 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9349 for (size_t i = 0; i < chunk; ++i)
9351 unsigned char b = data[pos + i];
9352 printf ("%c", isprint (b) ? b : '.');
9361 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9363 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9364 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9365 elf_ndxscn (scn), name);
9368 Elf_Data *data = elf_rawdata (scn, NULL);
9370 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9371 elf_ndxscn (scn), name, elf_errmsg (-1));
9374 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9375 " bytes at offset %#0" PRIx64 ":\n"),
9376 elf_ndxscn (scn), name,
9377 shdr->sh_size, shdr->sh_offset);
9378 hex_dump (data->d_buf, data->d_size);
9384 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9386 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9387 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9388 elf_ndxscn (scn), name);
9391 Elf_Data *data = elf_rawdata (scn, NULL);
9393 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9394 elf_ndxscn (scn), name, elf_errmsg (-1));
9397 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9398 " bytes at offset %#0" PRIx64 ":\n"),
9399 elf_ndxscn (scn), name,
9400 shdr->sh_size, shdr->sh_offset);
9402 const char *start = data->d_buf;
9403 const char *const limit = start + data->d_size;
9406 const char *end = memchr (start, '\0', limit - start);
9407 const size_t pos = start - (const char *) data->d_buf;
9408 if (unlikely (end == NULL))
9410 printf (" [%6Zx]- %.*s\n",
9411 pos, (int) (limit - start), start);
9414 printf (" [%6Zx] %s\n", pos, start);
9416 } while (start < limit);
9422 for_each_section_argument (Elf *elf, const struct section_argument *list,
9423 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9426 /* Get the section header string table index. */
9428 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9429 error (EXIT_FAILURE, 0,
9430 gettext ("cannot get section header string table index"));
9432 for (const struct section_argument *a = list; a != NULL; a = a->next)
9436 const char *name = NULL;
9439 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9440 if (endp != a->arg && *endp == '\0')
9442 scn = elf_getscn (elf, shndx);
9445 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9449 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9450 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9452 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9456 /* Need to look up the section by name. */
9459 while ((scn = elf_nextscn (elf, scn)) != NULL)
9461 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9463 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9466 if (!strcmp (name, a->arg))
9469 (*dump) (scn, &shdr_mem, name);
9473 if (unlikely (!found) && !a->implicit)
9474 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9480 dump_data (Ebl *ebl)
9482 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9486 dump_strings (Ebl *ebl)
9488 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9492 print_strings (Ebl *ebl)
9494 /* Get the section header string table index. */
9496 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9497 error (EXIT_FAILURE, 0,
9498 gettext ("cannot get section header string table index"));
9504 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9506 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9509 if (shdr_mem.sh_type != SHT_PROGBITS
9510 || !(shdr_mem.sh_flags & SHF_STRINGS))
9513 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9517 print_string_section (scn, &shdr_mem, name);
9522 dump_archive_index (Elf *elf, const char *fname)
9525 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9528 int result = elf_errno ();
9529 if (unlikely (result != ELF_E_NO_INDEX))
9530 error (EXIT_FAILURE, 0,
9531 gettext ("cannot get symbol index of archive '%s': %s"),
9532 fname, elf_errmsg (result));
9534 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9538 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9542 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9544 if (s->as_off != as_off)
9549 if (unlikely (elf_rand (elf, as_off) == 0)
9550 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9552 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9555 error (EXIT_FAILURE, 0,
9556 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9557 as_off, fname, elf_errmsg (-1));
9559 const Elf_Arhdr *h = elf_getarhdr (subelf);
9561 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9566 printf ("\t%s\n", s->as_name);
9570 #include "debugpred.h"