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. */
698 find_no_debuginfo (Dwfl_Module *mod __attribute__ ((unused)),
699 void **userdata __attribute__ ((unused)),
700 const char *modname __attribute__ ((unused)),
701 Dwarf_Addr base __attribute__ ((unused)),
702 const char *file_name __attribute__ ((unused)),
703 const char *debuglink_file __attribute__ ((unused)),
704 GElf_Word debuglink_crc __attribute__ ((unused)),
705 char **debuginfo_file_name __attribute__ ((unused)))
710 /* Process one input file. */
712 process_file (int fd, const char *fname, bool only_one)
714 if (print_archive_index)
715 check_archive_index (fd, fname, only_one);
717 if (!any_control_option)
720 if (elf_input_section != NULL)
722 /* Replace fname and fd with section content. */
723 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
724 sprintf (fnname, "%s:%s", fname, elf_input_section);
725 fd = open_input_section (fd);
728 error (0, 0, gettext ("No such section '%s' in '%s'"),
729 elf_input_section, fname);
735 /* Duplicate an fd for dwfl_report_offline to swallow. */
736 int dwfl_fd = dup (fd);
737 if (unlikely (dwfl_fd < 0))
738 error (EXIT_FAILURE, errno, "dup");
740 /* Use libdwfl in a trivial way to open the libdw handle for us.
741 This takes care of applying relocations to DWARF data in ET_REL files. */
742 static const Dwfl_Callbacks callbacks =
744 .section_address = dwfl_offline_section_address,
745 .find_debuginfo = find_no_debuginfo
747 Dwfl *dwfl = dwfl_begin (&callbacks);
748 if (likely (dwfl != NULL))
749 /* Let 0 be the logical address of the file (or first in archive). */
750 dwfl->offline_next_address = 0;
751 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
754 if (fstat64 (dwfl_fd, &st) != 0)
755 error (0, errno, gettext ("cannot stat input file"));
756 else if (unlikely (st.st_size == 0))
757 error (0, 0, gettext ("input file is empty"));
759 error (0, 0, gettext ("failed reading '%s': %s"),
760 fname, dwfl_errmsg (-1));
761 close (dwfl_fd); /* Consumed on success, not on failure. */
765 dwfl_report_end (dwfl, NULL, NULL);
769 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
771 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
774 /* Process the one or more modules gleaned from this file. */
775 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
776 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
780 /* Need to close the replaced fd if we created it. Caller takes
782 if (elf_input_section != NULL)
787 /* Process one ELF file. */
789 process_elf_file (Dwfl_Module *dwflmod, int fd)
792 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
795 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
800 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
804 Ebl *ebl = ebl_openbackend (elf);
805 if (unlikely (ebl == NULL))
808 error (0, errno, gettext ("cannot create EBL handle"));
812 /* Determine the number of sections. */
813 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
814 error (EXIT_FAILURE, 0,
815 gettext ("cannot determine number of sections: %s"),
818 /* Determine the number of phdrs. */
819 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
820 error (EXIT_FAILURE, 0,
821 gettext ("cannot determine number of program headers: %s"),
824 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs
825 and may have applied relocation to some sections.
826 So we need to get a fresh Elf handle on the file to display those. */
827 bool print_unrelocated = (print_section_header
829 || dump_data_sections != NULL
832 Elf *pure_elf = NULL;
834 if (ehdr->e_type == ET_REL && print_unrelocated)
836 /* Read the file afresh. */
837 off64_t aroff = elf_getaroff (elf);
838 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
841 /* Archive member. */
842 (void) elf_rand (pure_elf, aroff);
843 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
847 if (pure_elf == NULL)
849 pure_ebl = ebl_openbackend (pure_elf);
850 if (pure_ebl == NULL)
854 if (print_file_header)
855 print_ehdr (ebl, ehdr);
856 if (print_section_header)
857 print_shdr (pure_ebl, ehdr);
858 if (print_program_header)
859 print_phdr (ebl, ehdr);
860 if (print_section_groups)
862 if (print_dynamic_table)
864 if (print_relocations)
865 print_relocs (pure_ebl, ehdr);
868 if (print_symbol_table)
869 print_symtab (ebl, SHT_DYNSYM);
870 if (print_version_info)
872 if (print_symbol_table)
873 print_symtab (ebl, SHT_SYMTAB);
877 print_attributes (ebl, ehdr);
878 if (dump_data_sections != NULL)
879 dump_data (pure_ebl);
880 if (string_sections != NULL)
882 if ((print_debug_sections | implicit_debug_sections) != 0)
883 print_debug (dwflmod, ebl, ehdr);
885 handle_notes (pure_ebl, ehdr);
886 if (print_string_sections)
889 ebl_closebackend (ebl);
893 ebl_closebackend (pure_ebl);
899 /* Print file type. */
901 print_file_type (unsigned short int e_type)
903 if (likely (e_type <= ET_CORE))
905 static const char *const knowntypes[] =
908 N_("REL (Relocatable file)"),
909 N_("EXEC (Executable file)"),
910 N_("DYN (Shared object file)"),
911 N_("CORE (Core file)")
913 puts (gettext (knowntypes[e_type]));
915 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
916 printf (gettext ("OS Specific: (%x)\n"), e_type);
917 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
918 printf (gettext ("Processor Specific: (%x)\n"), e_type);
924 /* Print ELF header. */
926 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
928 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
929 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
930 printf (" %02hhx", ehdr->e_ident[cnt]);
932 printf (gettext ("\n Class: %s\n"),
933 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
934 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
937 printf (gettext (" Data: %s\n"),
938 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
939 ? "2's complement, little endian"
940 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
941 ? "2's complement, big endian" : "\?\?\?");
943 printf (gettext (" Ident Version: %hhd %s\n"),
944 ehdr->e_ident[EI_VERSION],
945 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
949 printf (gettext (" OS/ABI: %s\n"),
950 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
952 printf (gettext (" ABI Version: %hhd\n"),
953 ehdr->e_ident[EI_ABIVERSION]);
955 fputs_unlocked (gettext (" Type: "), stdout);
956 print_file_type (ehdr->e_type);
958 printf (gettext (" Machine: %s\n"), ebl->name);
960 printf (gettext (" Version: %d %s\n"),
962 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
964 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
967 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
968 ehdr->e_phoff, gettext ("(bytes into file)"));
970 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
971 ehdr->e_shoff, gettext ("(bytes into file)"));
973 printf (gettext (" Flags: %s\n"),
974 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
976 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
977 ehdr->e_ehsize, gettext ("(bytes)"));
979 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
980 ehdr->e_phentsize, gettext ("(bytes)"));
982 printf (gettext (" Number of program headers entries: %" PRId16),
984 if (ehdr->e_phnum == PN_XNUM)
987 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
989 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
990 (uint32_t) shdr->sh_info);
992 fputs_unlocked (gettext (" ([0] not available)"), stdout);
994 fputc_unlocked ('\n', stdout);
996 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
997 ehdr->e_shentsize, gettext ("(bytes)"));
999 printf (gettext (" Number of section headers entries: %" PRId16),
1001 if (ehdr->e_shnum == 0)
1004 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1006 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1007 (uint32_t) shdr->sh_size);
1009 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1011 fputc_unlocked ('\n', stdout);
1013 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1016 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1018 /* We managed to get the zeroth section. */
1019 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1020 (uint32_t) shdr->sh_link);
1023 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1024 buf[sizeof (buf) - 1] = '\0';
1027 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1031 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1037 get_visibility_type (int value)
1055 /* Print the section headers. */
1057 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1062 if (! print_file_header)
1064 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1066 ehdr->e_shnum, ehdr->e_shoff);
1068 /* Get the section header string table index. */
1069 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1070 error (EXIT_FAILURE, 0,
1071 gettext ("cannot get section header string table index"));
1073 puts (gettext ("Section Headers:"));
1075 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1076 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1078 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1080 for (cnt = 0; cnt < shnum; ++cnt)
1082 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1084 if (unlikely (scn == NULL))
1085 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1088 /* Get the section header. */
1090 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1091 if (unlikely (shdr == NULL))
1092 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1097 if (shdr->sh_flags & SHF_WRITE)
1099 if (shdr->sh_flags & SHF_ALLOC)
1101 if (shdr->sh_flags & SHF_EXECINSTR)
1103 if (shdr->sh_flags & SHF_MERGE)
1105 if (shdr->sh_flags & SHF_STRINGS)
1107 if (shdr->sh_flags & SHF_INFO_LINK)
1109 if (shdr->sh_flags & SHF_LINK_ORDER)
1111 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1113 if (shdr->sh_flags & SHF_GROUP)
1115 if (shdr->sh_flags & SHF_TLS)
1117 if (shdr->sh_flags & SHF_ORDERED)
1119 if (shdr->sh_flags & SHF_EXCLUDE)
1124 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1125 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1128 elf_strptr (ebl->elf, shstrndx, shdr->sh_name)
1130 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1131 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1132 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1133 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1134 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1135 shdr->sh_addralign);
1138 fputc_unlocked ('\n', stdout);
1142 /* Print the program header. */
1144 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1146 if (ehdr->e_phnum == 0)
1147 /* No program header, this is OK in relocatable objects. */
1150 puts (gettext ("Program Headers:"));
1151 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1153 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1156 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1158 /* Process all program headers. */
1159 bool has_relro = false;
1160 GElf_Addr relro_from = 0;
1161 GElf_Addr relro_to = 0;
1162 for (size_t cnt = 0; cnt < phnum; ++cnt)
1166 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1168 /* If for some reason the header cannot be returned show this. */
1169 if (unlikely (phdr == NULL))
1175 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1176 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1177 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1179 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1180 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1183 phdr->p_flags & PF_R ? 'R' : ' ',
1184 phdr->p_flags & PF_W ? 'W' : ' ',
1185 phdr->p_flags & PF_X ? 'E' : ' ',
1188 if (phdr->p_type == PT_INTERP)
1190 /* We can show the user the name of the interpreter. */
1192 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1194 if (filedata != NULL && phdr->p_offset < maxsize
1195 && phdr->p_filesz <= maxsize - phdr->p_offset
1196 && memchr (filedata + phdr->p_offset, '\0',
1197 phdr->p_filesz) != NULL)
1198 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1199 filedata + phdr->p_offset);
1201 else if (phdr->p_type == PT_GNU_RELRO)
1204 relro_from = phdr->p_vaddr;
1205 relro_to = relro_from + phdr->p_memsz;
1209 if (ehdr->e_shnum == 0)
1210 /* No sections in the file. Punt. */
1213 /* Get the section header string table index. */
1215 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1216 error (EXIT_FAILURE, 0,
1217 gettext ("cannot get section header string table index"));
1219 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1221 for (size_t cnt = 0; cnt < phnum; ++cnt)
1223 /* Print the segment number. */
1224 printf (" %2.2zu ", cnt);
1227 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1228 /* This must not happen. */
1229 if (unlikely (phdr == NULL))
1230 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1233 /* Iterate over the sections. */
1234 bool in_relro = false;
1236 for (size_t inner = 1; inner < shnum; ++inner)
1238 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1239 /* This should not happen. */
1240 if (unlikely (scn == NULL))
1241 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1244 /* Get the section header. */
1246 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1247 if (unlikely (shdr == NULL))
1248 error (EXIT_FAILURE, 0,
1249 gettext ("cannot get section header: %s"),
1252 if (shdr->sh_size > 0
1253 /* Compare allocated sections by VMA, unallocated
1254 sections by file offset. */
1255 && (shdr->sh_flags & SHF_ALLOC
1256 ? (shdr->sh_addr >= phdr->p_vaddr
1257 && (shdr->sh_addr + shdr->sh_size
1258 <= phdr->p_vaddr + phdr->p_memsz))
1259 : (shdr->sh_offset >= phdr->p_offset
1260 && (shdr->sh_offset + shdr->sh_size
1261 <= phdr->p_offset + phdr->p_filesz))))
1263 if (has_relro && !in_relro
1264 && shdr->sh_addr >= relro_from
1265 && shdr->sh_addr + shdr->sh_size <= relro_to)
1267 fputs_unlocked (" [RELRO:", stdout);
1270 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1272 fputs_unlocked ("]", stdout);
1275 else if (has_relro && in_relro
1276 && shdr->sh_addr + shdr->sh_size > relro_to)
1277 fputs_unlocked ("] <RELRO:", stdout);
1278 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1282 fputs_unlocked (" [RO:", stdout);
1288 /* Determine the segment this section is part of. */
1290 GElf_Phdr *phdr2 = NULL;
1291 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1293 GElf_Phdr phdr2_mem;
1294 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1296 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1297 && shdr->sh_addr >= phdr2->p_vaddr
1298 && (shdr->sh_addr + shdr->sh_size
1299 <= phdr2->p_vaddr + phdr2->p_memsz))
1305 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1307 fputs_unlocked (" [RO:", stdout);
1310 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1312 fputs_unlocked ("]", stdout);
1319 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1321 /* Signal that this sectin is only partially covered. */
1322 if (has_relro && in_relro
1323 && shdr->sh_addr + shdr->sh_size > relro_to)
1325 fputs_unlocked (">", stdout);
1330 if (in_relro || in_ro)
1331 fputs_unlocked ("]", stdout);
1333 /* Finish the line. */
1334 fputc_unlocked ('\n', stdout);
1340 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1342 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1347 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1349 /* Get the data of the section. */
1350 Elf_Data *data = elf_getdata (scn, NULL);
1352 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1353 GElf_Shdr symshdr_mem;
1354 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1355 Elf_Data *symdata = elf_getdata (symscn, NULL);
1357 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1361 /* Get the section header string table index. */
1363 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1364 error (EXIT_FAILURE, 0,
1365 gettext ("cannot get section header string table index"));
1367 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1370 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1372 printf ((grpref[0] & GRP_COMDAT)
1374 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1376 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1377 data->d_size / sizeof (Elf32_Word) - 1)
1379 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1380 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1381 data->d_size / sizeof (Elf32_Word) - 1),
1383 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1385 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1386 ?: gettext ("<INVALID SYMBOL>"),
1387 data->d_size / sizeof (Elf32_Word) - 1);
1389 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1391 GElf_Shdr grpshdr_mem;
1392 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1396 printf (" [%2u] %s\n",
1399 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1400 ? str : gettext ("<INVALID SECTION>"));
1406 print_scngrp (Ebl *ebl)
1408 /* Find all relocation sections and handle them. */
1409 Elf_Scn *scn = NULL;
1411 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1413 /* Handle the section if it is a symbol table. */
1415 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1417 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1418 handle_scngrp (ebl, scn, shdr);
1423 static const struct flags
1429 { DF_ORIGIN, "ORIGIN" },
1430 { DF_SYMBOLIC, "SYMBOLIC" },
1431 { DF_TEXTREL, "TEXTREL" },
1432 { DF_BIND_NOW, "BIND_NOW" },
1433 { DF_STATIC_TLS, "STATIC_TLS" }
1435 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1437 static const struct flags dt_flags_1[] =
1439 { DF_1_NOW, "NOW" },
1440 { DF_1_GLOBAL, "GLOBAL" },
1441 { DF_1_GROUP, "GROUP" },
1442 { DF_1_NODELETE, "NODELETE" },
1443 { DF_1_LOADFLTR, "LOADFLTR" },
1444 { DF_1_INITFIRST, "INITFIRST" },
1445 { DF_1_NOOPEN, "NOOPEN" },
1446 { DF_1_ORIGIN, "ORIGIN" },
1447 { DF_1_DIRECT, "DIRECT" },
1448 { DF_1_TRANS, "TRANS" },
1449 { DF_1_INTERPOSE, "INTERPOSE" },
1450 { DF_1_NODEFLIB, "NODEFLIB" },
1451 { DF_1_NODUMP, "NODUMP" },
1452 { DF_1_CONFALT, "CONFALT" },
1453 { DF_1_ENDFILTEE, "ENDFILTEE" },
1454 { DF_1_DISPRELDNE, "DISPRELDNE" },
1455 { DF_1_DISPRELPND, "DISPRELPND" },
1457 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1459 static const struct flags dt_feature_1[] =
1461 { DTF_1_PARINIT, "PARINIT" },
1462 { DTF_1_CONFEXP, "CONFEXP" }
1464 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1465 / sizeof (dt_feature_1[0]));
1467 static const struct flags dt_posflag_1[] =
1469 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1470 { DF_P1_GROUPPERM, "GROUPPERM" }
1472 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1473 / sizeof (dt_posflag_1[0]));
1477 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1483 for (cnt = 0; cnt < nflags; ++cnt)
1484 if (d_val & flags[cnt].mask)
1487 putchar_unlocked (' ');
1488 fputs_unlocked (flags[cnt].str, stdout);
1489 d_val &= ~flags[cnt].mask;
1496 putchar_unlocked (' ');
1497 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1500 putchar_unlocked ('\n');
1505 print_dt_flags (int class, GElf_Xword d_val)
1507 print_flags (class, d_val, dt_flags, ndt_flags);
1512 print_dt_flags_1 (int class, GElf_Xword d_val)
1514 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1519 print_dt_feature_1 (int class, GElf_Xword d_val)
1521 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1526 print_dt_posflag_1 (int class, GElf_Xword d_val)
1528 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1533 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1535 int class = gelf_getclass (ebl->elf);
1536 GElf_Shdr glink_mem;
1543 /* Get the data of the section. */
1544 data = elf_getdata (scn, NULL);
1548 /* Get the section header string table index. */
1549 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1550 error (EXIT_FAILURE, 0,
1551 gettext ("cannot get section header string table index"));
1553 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1555 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1557 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1560 printf (ngettext ("\
1561 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1563 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1564 shdr->sh_size / sh_entsize),
1565 (unsigned long int) (shdr->sh_size / sh_entsize),
1566 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1568 (int) shdr->sh_link,
1569 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1570 fputs_unlocked (gettext (" Type Value\n"), stdout);
1572 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1575 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1581 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1589 /* No further output. */
1590 fputc_unlocked ('\n', stdout);
1594 printf (gettext ("Shared library: [%s]\n"),
1595 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1599 printf (gettext ("Library soname: [%s]\n"),
1600 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1604 printf (gettext ("Library rpath: [%s]\n"),
1605 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1609 printf (gettext ("Library runpath: [%s]\n"),
1610 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1623 case DT_INIT_ARRAYSZ:
1624 case DT_FINI_ARRAYSZ:
1627 case DT_GNU_CONFLICTSZ:
1628 case DT_GNU_LIBLISTSZ:
1629 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1636 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1640 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1642 puts (tagname ?: "???");
1646 print_dt_flags (class, dyn->d_un.d_val);
1650 print_dt_flags_1 (class, dyn->d_un.d_val);
1654 print_dt_feature_1 (class, dyn->d_un.d_val);
1658 print_dt_posflag_1 (class, dyn->d_un.d_val);
1662 printf ("%#0*" PRIx64 "\n",
1663 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1670 /* Print the dynamic segment. */
1672 print_dynamic (Ebl *ebl)
1674 for (size_t i = 0; i < phnum; ++i)
1677 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1679 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1681 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1683 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1684 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1685 handle_dynamic (ebl, scn, shdr);
1692 /* Print relocations. */
1694 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1696 /* Find all relocation sections and handle them. */
1697 Elf_Scn *scn = NULL;
1699 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1701 /* Handle the section if it is a symbol table. */
1703 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1705 if (likely (shdr != NULL))
1707 if (shdr->sh_type == SHT_REL)
1708 handle_relocs_rel (ebl, ehdr, scn, shdr);
1709 else if (shdr->sh_type == SHT_RELA)
1710 handle_relocs_rela (ebl, ehdr, scn, shdr);
1716 /* Handle a relocation section. */
1718 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1720 int class = gelf_getclass (ebl->elf);
1721 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1722 int nentries = shdr->sh_size / sh_entsize;
1724 /* Get the data of the section. */
1725 Elf_Data *data = elf_getdata (scn, NULL);
1729 /* Get the symbol table information. */
1730 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1731 GElf_Shdr symshdr_mem;
1732 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1733 Elf_Data *symdata = elf_getdata (symscn, NULL);
1735 /* Get the section header of the section the relocations are for. */
1736 GElf_Shdr destshdr_mem;
1737 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1740 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1742 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1747 /* Search for the optional extended section index table. */
1748 Elf_Data *xndxdata = NULL;
1749 int xndxscnidx = elf_scnshndx (scn);
1750 if (unlikely (xndxscnidx > 0))
1751 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1753 /* Get the section header string table index. */
1755 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1756 error (EXIT_FAILURE, 0,
1757 gettext ("cannot get section header string table index"));
1759 if (shdr->sh_info != 0)
1760 printf (ngettext ("\
1761 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1763 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1766 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1767 (unsigned int) shdr->sh_info,
1768 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1772 /* The .rel.dyn section does not refer to a specific section but
1773 instead of section index zero. Do not try to print a section
1775 printf (ngettext ("\
1776 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1778 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1780 (unsigned int) elf_ndxscn (scn),
1781 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1784 fputs_unlocked (class == ELFCLASS32
1786 Offset Type Value Name\n")
1788 Offset Type Value Name\n"),
1791 int is_statically_linked = 0;
1792 for (int cnt = 0; cnt < nentries; ++cnt)
1795 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1796 if (likely (rel != NULL))
1801 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1802 GELF_R_SYM (rel->r_info),
1804 if (unlikely (sym == NULL))
1806 /* As a special case we have to handle relocations in static
1807 executables. This only happens for IRELATIVE relocations
1808 (so far). There is no symbol table. */
1809 if (is_statically_linked == 0)
1811 /* Find the program header and look for a PT_INTERP entry. */
1812 is_statically_linked = -1;
1813 if (ehdr->e_type == ET_EXEC)
1815 is_statically_linked = 1;
1817 for (size_t inner = 0; inner < phnum; ++inner)
1820 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1822 if (phdr != NULL && phdr->p_type == PT_INTERP)
1824 is_statically_linked = -1;
1831 if (is_statically_linked > 0 && shdr->sh_link == 0)
1833 %#0*" PRIx64 " %-20s %*s %s\n",
1834 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1835 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1836 /* Avoid the leading R_ which isn't carrying any
1838 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1839 buf, sizeof (buf)) + 2
1840 : gettext ("<INVALID RELOC>"),
1841 class == ELFCLASS32 ? 10 : 18, "",
1842 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1844 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1845 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1846 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1847 /* Avoid the leading R_ which isn't carrying any
1849 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1850 buf, sizeof (buf)) + 2
1851 : gettext ("<INVALID RELOC>"),
1852 gettext ("INVALID SYMBOL"),
1853 (long int) GELF_R_SYM (rel->r_info));
1855 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1856 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1857 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1858 likely (ebl_reloc_type_check (ebl,
1859 GELF_R_TYPE (rel->r_info)))
1860 /* Avoid the leading R_ which isn't carrying any
1862 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1863 buf, sizeof (buf)) + 2
1864 : gettext ("<INVALID RELOC>"),
1865 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1866 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1869 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
1870 sym->st_shndx == SHN_XINDEX
1871 ? xndx : sym->st_shndx),
1874 if (unlikely (destshdr == NULL))
1875 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1876 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1877 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1878 /* Avoid the leading R_ which isn't carrying any
1880 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1881 buf, sizeof (buf)) + 2
1882 : gettext ("<INVALID RELOC>"),
1883 gettext ("INVALID SECTION"),
1884 (long int) (sym->st_shndx == SHN_XINDEX
1885 ? xndx : sym->st_shndx));
1887 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1888 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1889 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1890 /* Avoid the leading R_ which isn't carrying any
1892 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1893 buf, sizeof (buf)) + 2
1894 : gettext ("<INVALID RELOC>"),
1895 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1896 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1903 /* Handle a relocation section. */
1905 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1907 int class = gelf_getclass (ebl->elf);
1908 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1909 int nentries = shdr->sh_size / sh_entsize;
1911 /* Get the data of the section. */
1912 Elf_Data *data = elf_getdata (scn, NULL);
1916 /* Get the symbol table information. */
1917 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1918 GElf_Shdr symshdr_mem;
1919 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1920 Elf_Data *symdata = elf_getdata (symscn, NULL);
1922 /* Get the section header of the section the relocations are for. */
1923 GElf_Shdr destshdr_mem;
1924 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1927 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1929 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1934 /* Search for the optional extended section index table. */
1935 Elf_Data *xndxdata = NULL;
1936 int xndxscnidx = elf_scnshndx (scn);
1937 if (unlikely (xndxscnidx > 0))
1938 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1940 /* Get the section header string table index. */
1942 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1943 error (EXIT_FAILURE, 0,
1944 gettext ("cannot get section header string table index"));
1946 printf (ngettext ("\
1947 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1949 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1952 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1953 (unsigned int) shdr->sh_info,
1954 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1957 fputs_unlocked (class == ELFCLASS32
1959 Offset Type Value Addend Name\n")
1961 Offset Type Value Addend Name\n"),
1964 int is_statically_linked = 0;
1965 for (int cnt = 0; cnt < nentries; ++cnt)
1968 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
1969 if (likely (rel != NULL))
1974 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1975 GELF_R_SYM (rel->r_info),
1978 if (unlikely (sym == NULL))
1980 /* As a special case we have to handle relocations in static
1981 executables. This only happens for IRELATIVE relocations
1982 (so far). There is no symbol table. */
1983 if (is_statically_linked == 0)
1985 /* Find the program header and look for a PT_INTERP entry. */
1986 is_statically_linked = -1;
1987 if (ehdr->e_type == ET_EXEC)
1989 is_statically_linked = 1;
1991 for (size_t inner = 0; inner < phnum; ++inner)
1994 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1996 if (phdr != NULL && phdr->p_type == PT_INTERP)
1998 is_statically_linked = -1;
2005 if (is_statically_linked > 0 && shdr->sh_link == 0)
2007 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2008 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2009 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2010 /* Avoid the leading R_ which isn't carrying any
2012 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2013 buf, sizeof (buf)) + 2
2014 : gettext ("<INVALID RELOC>"),
2015 class == ELFCLASS32 ? 10 : 18, "",
2017 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2019 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2020 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2021 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2022 /* Avoid the leading R_ which isn't carrying any
2024 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2025 buf, sizeof (buf)) + 2
2026 : gettext ("<INVALID RELOC>"),
2027 gettext ("INVALID SYMBOL"),
2028 (long int) GELF_R_SYM (rel->r_info));
2030 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2032 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2033 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2034 likely (ebl_reloc_type_check (ebl,
2035 GELF_R_TYPE (rel->r_info)))
2036 /* Avoid the leading R_ which isn't carrying any
2038 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2039 buf, sizeof (buf)) + 2
2040 : gettext ("<INVALID RELOC>"),
2041 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2043 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2046 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
2047 sym->st_shndx == SHN_XINDEX
2048 ? xndx : sym->st_shndx),
2051 if (unlikely (shdr == NULL))
2052 printf (" %#0*" PRIx64 " %-15s <%s %ld>\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 gettext ("INVALID SECTION"),
2061 (long int) (sym->st_shndx == SHN_XINDEX
2062 ? xndx : sym->st_shndx));
2065 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2066 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2067 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2068 /* Avoid the leading R_ which isn't carrying any
2070 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2071 buf, sizeof (buf)) + 2
2072 : gettext ("<INVALID RELOC>"),
2073 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2075 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2082 /* Print the program header. */
2084 print_symtab (Ebl *ebl, int type)
2086 /* Find the symbol table(s). For this we have to search through the
2088 Elf_Scn *scn = NULL;
2090 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2092 /* Handle the section if it is a symbol table. */
2094 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2096 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2097 handle_symtab (ebl, scn, shdr);
2103 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2105 Elf_Data *versym_data = NULL;
2106 Elf_Data *verneed_data = NULL;
2107 Elf_Data *verdef_data = NULL;
2108 Elf_Data *xndx_data = NULL;
2109 int class = gelf_getclass (ebl->elf);
2110 Elf32_Word verneed_stridx = 0;
2111 Elf32_Word verdef_stridx = 0;
2113 /* Get the data of the section. */
2114 Elf_Data *data = elf_getdata (scn, NULL);
2118 /* Find out whether we have other sections we might need. */
2119 Elf_Scn *runscn = NULL;
2120 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2122 GElf_Shdr runshdr_mem;
2123 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2125 if (likely (runshdr != NULL))
2127 if (runshdr->sh_type == SHT_GNU_versym
2128 && runshdr->sh_link == elf_ndxscn (scn))
2129 /* Bingo, found the version information. Now get the data. */
2130 versym_data = elf_getdata (runscn, NULL);
2131 else if (runshdr->sh_type == SHT_GNU_verneed)
2133 /* This is the information about the needed versions. */
2134 verneed_data = elf_getdata (runscn, NULL);
2135 verneed_stridx = runshdr->sh_link;
2137 else if (runshdr->sh_type == SHT_GNU_verdef)
2139 /* This is the information about the defined versions. */
2140 verdef_data = elf_getdata (runscn, NULL);
2141 verdef_stridx = runshdr->sh_link;
2143 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2144 && runshdr->sh_link == elf_ndxscn (scn))
2145 /* Extended section index. */
2146 xndx_data = elf_getdata (runscn, NULL);
2150 /* Get the section header string table index. */
2152 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2153 error (EXIT_FAILURE, 0,
2154 gettext ("cannot get section header string table index"));
2156 GElf_Shdr glink_mem;
2157 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2160 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2163 /* Now we can compute the number of entries in the section. */
2164 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2165 ? sizeof (Elf32_Sym)
2166 : sizeof (Elf64_Sym));
2168 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2169 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2171 (unsigned int) elf_ndxscn (scn),
2172 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2173 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2174 " %lu local symbols String table: [%2u] '%s'\n",
2176 (unsigned long int) shdr->sh_info,
2177 (unsigned int) shdr->sh_link,
2178 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2180 fputs_unlocked (class == ELFCLASS32
2182 Num: Value Size Type Bind Vis Ndx Name\n")
2184 Num: Value Size Type Bind Vis Ndx Name\n"),
2187 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2194 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2196 if (unlikely (sym == NULL))
2199 /* Determine the real section index. */
2200 if (likely (sym->st_shndx != SHN_XINDEX))
2201 xndx = sym->st_shndx;
2204 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2206 class == ELFCLASS32 ? 8 : 16,
2209 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2210 typebuf, sizeof (typebuf)),
2211 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2212 bindbuf, sizeof (bindbuf)),
2213 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2214 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2215 sizeof (scnbuf), NULL, shnum),
2216 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2218 if (versym_data != NULL)
2220 /* Get the version information. */
2221 GElf_Versym versym_mem;
2222 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2224 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2226 bool is_nobits = false;
2227 bool check_def = xndx != SHN_UNDEF;
2229 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2231 GElf_Shdr symshdr_mem;
2232 GElf_Shdr *symshdr =
2233 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2235 is_nobits = (symshdr != NULL
2236 && symshdr->sh_type == SHT_NOBITS);
2239 if (is_nobits || ! check_def)
2241 /* We must test both. */
2242 GElf_Vernaux vernaux_mem;
2243 GElf_Vernaux *vernaux = NULL;
2244 size_t vn_offset = 0;
2246 GElf_Verneed verneed_mem;
2247 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2249 while (verneed != NULL)
2251 size_t vna_offset = vn_offset;
2253 vernaux = gelf_getvernaux (verneed_data,
2254 vna_offset += verneed->vn_aux,
2256 while (vernaux != NULL
2257 && vernaux->vna_other != *versym
2258 && vernaux->vna_next != 0)
2260 /* Update the offset. */
2261 vna_offset += vernaux->vna_next;
2263 vernaux = (vernaux->vna_next == 0
2265 : gelf_getvernaux (verneed_data,
2270 /* Check whether we found the version. */
2271 if (vernaux != NULL && vernaux->vna_other == *versym)
2275 vn_offset += verneed->vn_next;
2276 verneed = (verneed->vn_next == 0
2278 : gelf_getverneed (verneed_data, vn_offset,
2282 if (vernaux != NULL && vernaux->vna_other == *versym)
2285 elf_strptr (ebl->elf, verneed_stridx,
2287 (unsigned int) vernaux->vna_other);
2290 else if (unlikely (! is_nobits))
2291 error (0, 0, gettext ("bad dynamic symbol"));
2296 if (check_def && *versym != 0x8001)
2298 /* We must test both. */
2299 size_t vd_offset = 0;
2301 GElf_Verdef verdef_mem;
2302 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2304 while (verdef != NULL)
2306 if (verdef->vd_ndx == (*versym & 0x7fff))
2307 /* Found the definition. */
2310 vd_offset += verdef->vd_next;
2311 verdef = (verdef->vd_next == 0
2313 : gelf_getverdef (verdef_data, vd_offset,
2319 GElf_Verdaux verdaux_mem;
2320 GElf_Verdaux *verdaux
2321 = gelf_getverdaux (verdef_data,
2322 vd_offset + verdef->vd_aux,
2325 if (verdaux != NULL)
2326 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2327 elf_strptr (ebl->elf, verdef_stridx,
2328 verdaux->vda_name));
2334 putchar_unlocked ('\n');
2339 /* Print version information. */
2341 print_verinfo (Ebl *ebl)
2343 /* Find the version information sections. For this we have to
2344 search through the section table. */
2345 Elf_Scn *scn = NULL;
2347 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2349 /* Handle the section if it is part of the versioning handling. */
2351 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2353 if (likely (shdr != NULL))
2355 if (shdr->sh_type == SHT_GNU_verneed)
2356 handle_verneed (ebl, scn, shdr);
2357 else if (shdr->sh_type == SHT_GNU_verdef)
2358 handle_verdef (ebl, scn, shdr);
2359 else if (shdr->sh_type == SHT_GNU_versym)
2360 handle_versym (ebl, scn, shdr);
2367 get_ver_flags (unsigned int flags)
2369 static char buf[32];
2373 return gettext ("none");
2375 if (flags & VER_FLG_BASE)
2376 endp = stpcpy (buf, "BASE ");
2380 if (flags & VER_FLG_WEAK)
2383 endp = stpcpy (endp, "| ");
2385 endp = stpcpy (endp, "WEAK ");
2388 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2390 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2391 buf[sizeof (buf) - 1] = '\0';
2399 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2401 int class = gelf_getclass (ebl->elf);
2403 /* Get the data of the section. */
2404 Elf_Data *data = elf_getdata (scn, NULL);
2408 /* Get the section header string table index. */
2410 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2411 error (EXIT_FAILURE, 0,
2412 gettext ("cannot get section header string table index"));
2414 GElf_Shdr glink_mem;
2415 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2418 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2421 printf (ngettext ("\
2422 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2424 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2426 (unsigned int) elf_ndxscn (scn),
2427 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2428 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2430 (unsigned int) shdr->sh_link,
2431 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2433 unsigned int offset = 0;
2434 for (int cnt = shdr->sh_info; --cnt >= 0; )
2436 /* Get the data at the next offset. */
2437 GElf_Verneed needmem;
2438 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2439 if (unlikely (need == NULL))
2442 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2443 offset, (unsigned short int) need->vn_version,
2444 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2445 (unsigned short int) need->vn_cnt);
2447 unsigned int auxoffset = offset + need->vn_aux;
2448 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2450 GElf_Vernaux auxmem;
2451 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2452 if (unlikely (aux == NULL))
2455 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2457 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2458 get_ver_flags (aux->vna_flags),
2459 (unsigned short int) aux->vna_other);
2461 auxoffset += aux->vna_next;
2464 /* Find the next offset. */
2465 offset += need->vn_next;
2471 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2473 /* Get the data of the section. */
2474 Elf_Data *data = elf_getdata (scn, NULL);
2478 /* Get the section header string table index. */
2480 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2481 error (EXIT_FAILURE, 0,
2482 gettext ("cannot get section header string table index"));
2484 GElf_Shdr glink_mem;
2485 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2488 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2491 int class = gelf_getclass (ebl->elf);
2492 printf (ngettext ("\
2493 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2495 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2497 (unsigned int) elf_ndxscn (scn),
2498 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2500 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2502 (unsigned int) shdr->sh_link,
2503 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2505 unsigned int offset = 0;
2506 for (int cnt = shdr->sh_info; --cnt >= 0; )
2508 /* Get the data at the next offset. */
2510 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2511 if (unlikely (def == NULL))
2514 unsigned int auxoffset = offset + def->vd_aux;
2515 GElf_Verdaux auxmem;
2516 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2517 if (unlikely (aux == NULL))
2521 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2522 offset, def->vd_version,
2523 get_ver_flags (def->vd_flags),
2526 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2528 auxoffset += aux->vda_next;
2529 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2531 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2532 if (unlikely (aux == NULL))
2535 printf (gettext (" %#06x: Parent %d: %s\n"),
2537 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2539 auxoffset += aux->vda_next;
2542 /* Find the next offset. */
2543 offset += def->vd_next;
2549 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2551 int class = gelf_getclass (ebl->elf);
2552 const char **vername;
2553 const char **filename;
2555 /* Get the data of the section. */
2556 Elf_Data *data = elf_getdata (scn, NULL);
2560 /* Get the section header string table index. */
2562 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2563 error (EXIT_FAILURE, 0,
2564 gettext ("cannot get section header string table index"));
2566 /* We have to find the version definition section and extract the
2568 Elf_Scn *defscn = NULL;
2569 Elf_Scn *needscn = NULL;
2571 Elf_Scn *verscn = NULL;
2572 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2574 GElf_Shdr vershdr_mem;
2575 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2577 if (likely (vershdr != NULL))
2579 if (vershdr->sh_type == SHT_GNU_verdef)
2581 else if (vershdr->sh_type == SHT_GNU_verneed)
2587 if (defscn != NULL || needscn != NULL)
2589 /* We have a version information (better should have). Now get
2590 the version names. First find the maximum version number. */
2594 /* Run through the version definitions and find the highest
2596 unsigned int offset = 0;
2598 GElf_Shdr defshdrmem;
2601 defdata = elf_getdata (defscn, NULL);
2602 if (unlikely (defdata == NULL))
2605 defshdr = gelf_getshdr (defscn, &defshdrmem);
2606 if (unlikely (defshdr == NULL))
2609 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2614 /* Get the data at the next offset. */
2615 def = gelf_getverdef (defdata, offset, &defmem);
2616 if (unlikely (def == NULL))
2619 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2621 offset += def->vd_next;
2624 if (needscn != NULL)
2626 unsigned int offset = 0;
2628 GElf_Shdr needshdrmem;
2629 GElf_Shdr *needshdr;
2631 needdata = elf_getdata (needscn, NULL);
2632 if (unlikely (needdata == NULL))
2635 needshdr = gelf_getshdr (needscn, &needshdrmem);
2636 if (unlikely (needshdr == NULL))
2639 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2641 GElf_Verneed needmem;
2643 unsigned int auxoffset;
2646 /* Get the data at the next offset. */
2647 need = gelf_getverneed (needdata, offset, &needmem);
2648 if (unlikely (need == NULL))
2651 /* Run through the auxiliary entries. */
2652 auxoffset = offset + need->vn_aux;
2653 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2655 GElf_Vernaux auxmem;
2658 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2659 if (unlikely (aux == NULL))
2662 nvername = MAX (nvername,
2663 (size_t) (aux->vna_other & 0x7fff));
2665 auxoffset += aux->vna_next;
2668 offset += need->vn_next;
2672 /* This is the number of versions we know about. */
2675 /* Allocate the array. */
2676 vername = (const char **) alloca (nvername * sizeof (const char *));
2677 filename = (const char **) alloca (nvername * sizeof (const char *));
2679 /* Run through the data structures again and collect the strings. */
2682 /* Run through the version definitions and find the highest
2684 unsigned int offset = 0;
2686 GElf_Shdr defshdrmem;
2689 defdata = elf_getdata (defscn, NULL);
2690 if (unlikely (defdata == NULL))
2693 defshdr = gelf_getshdr (defscn, &defshdrmem);
2694 if (unlikely (defshdr == NULL))
2697 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2700 /* Get the data at the next offset. */
2702 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2703 GElf_Verdaux auxmem;
2704 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2705 offset + def->vd_aux,
2707 if (unlikely (def == NULL || aux == NULL))
2710 vername[def->vd_ndx & 0x7fff]
2711 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2712 filename[def->vd_ndx & 0x7fff] = NULL;
2714 offset += def->vd_next;
2717 if (needscn != NULL)
2719 unsigned int offset = 0;
2721 Elf_Data *needdata = elf_getdata (needscn, NULL);
2722 GElf_Shdr needshdrmem;
2723 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2724 if (unlikely (needdata == NULL || needshdr == NULL))
2727 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2729 /* Get the data at the next offset. */
2730 GElf_Verneed needmem;
2731 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2733 if (unlikely (need == NULL))
2736 /* Run through the auxiliary entries. */
2737 unsigned int auxoffset = offset + need->vn_aux;
2738 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2740 GElf_Vernaux auxmem;
2741 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2743 if (unlikely (aux == NULL))
2746 vername[aux->vna_other & 0x7fff]
2747 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2748 filename[aux->vna_other & 0x7fff]
2749 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2751 auxoffset += aux->vna_next;
2754 offset += need->vn_next;
2765 GElf_Shdr glink_mem;
2766 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2768 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2770 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2773 /* Print the header. */
2774 printf (ngettext ("\
2775 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2777 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2778 shdr->sh_size / sh_entsize),
2779 (unsigned int) elf_ndxscn (scn),
2780 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2781 (int) (shdr->sh_size / sh_entsize),
2782 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2784 (unsigned int) shdr->sh_link,
2785 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2787 /* Now we can finally look at the actual contents of this section. */
2788 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2791 printf ("\n %4d:", cnt);
2794 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2802 fputs_unlocked (gettext (" 0 *local* "),
2807 fputs_unlocked (gettext (" 1 *global* "),
2812 n = printf ("%4d%c%s",
2813 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2814 (unsigned int) (*sym & 0x7fff) < nvername
2815 ? vername[*sym & 0x7fff] : "???");
2816 if ((unsigned int) (*sym & 0x7fff) < nvername
2817 && filename[*sym & 0x7fff] != NULL)
2818 n += printf ("(%s)", filename[*sym & 0x7fff]);
2819 printf ("%*s", MAX (0, 33 - (int) n), " ");
2823 putchar_unlocked ('\n');
2828 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2829 uint_fast32_t maxlength, Elf32_Word nbucket,
2830 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2832 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2834 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2835 ++counts[lengths[cnt]];
2837 GElf_Shdr glink_mem;
2838 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2843 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2848 printf (ngettext ("\
2849 \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",
2851 \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",
2853 (unsigned int) elf_ndxscn (scn),
2854 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2856 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2859 (unsigned int) shdr->sh_link,
2860 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2862 if (extrastr != NULL)
2863 fputs (extrastr, stdout);
2865 if (likely (nbucket > 0))
2867 uint64_t success = 0;
2869 /* xgettext:no-c-format */
2870 fputs_unlocked (gettext ("\
2871 Length Number % of total Coverage\n"), stdout);
2872 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2873 counts[0], (counts[0] * 100.0) / nbucket);
2875 uint64_t nzero_counts = 0;
2876 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2878 nzero_counts += counts[cnt] * cnt;
2880 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2881 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2882 (nzero_counts * 100.0) / nsyms);
2886 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2889 success += counts[cnt] * acc;
2893 Average number of tests: successful lookup: %f\n\
2894 unsuccessful lookup: %f\n"),
2895 (double) success / (double) nzero_counts,
2896 (double) nzero_counts / (double) nbucket);
2903 /* This function handles the traditional System V-style hash table format. */
2905 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2907 Elf_Data *data = elf_getdata (scn, NULL);
2908 if (unlikely (data == NULL))
2910 error (0, 0, gettext ("cannot get data for section %d: %s"),
2911 (int) elf_ndxscn (scn), elf_errmsg (-1));
2915 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2916 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2917 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2918 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2920 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2922 uint_fast32_t maxlength = 0;
2923 uint_fast32_t nsyms = 0;
2924 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2926 Elf32_Word inner = bucket[cnt];
2927 while (inner > 0 && inner < nchain)
2930 if (maxlength < ++lengths[cnt])
2933 inner = chain[inner];
2937 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2944 /* This function handles the incorrect, System V-style hash table
2945 format some 64-bit architectures use. */
2947 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2949 Elf_Data *data = elf_getdata (scn, NULL);
2950 if (unlikely (data == NULL))
2952 error (0, 0, gettext ("cannot get data for section %d: %s"),
2953 (int) elf_ndxscn (scn), elf_errmsg (-1));
2957 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
2958 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
2959 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
2960 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
2962 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2964 uint_fast32_t maxlength = 0;
2965 uint_fast32_t nsyms = 0;
2966 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
2968 Elf64_Xword inner = bucket[cnt];
2969 while (inner > 0 && inner < nchain)
2972 if (maxlength < ++lengths[cnt])
2975 inner = chain[inner];
2979 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2986 /* This function handles the GNU-style hash table format. */
2988 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2990 Elf_Data *data = elf_getdata (scn, NULL);
2991 if (unlikely (data == NULL))
2993 error (0, 0, gettext ("cannot get data for section %d: %s"),
2994 (int) elf_ndxscn (scn), elf_errmsg (-1));
2998 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2999 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3001 /* Next comes the size of the bitmap. It's measured in words for
3002 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3004 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3005 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3008 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3010 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3012 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3013 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3014 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3017 /* Compute distribution of chain lengths. */
3018 uint_fast32_t maxlength = 0;
3019 uint_fast32_t nsyms = 0;
3020 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3021 if (bucket[cnt] != 0)
3023 Elf32_Word inner = bucket[cnt] - symbias;
3027 if (maxlength < ++lengths[cnt])
3030 while ((chain[inner++] & 1) == 0);
3033 /* Count bits in bitmask. */
3034 uint_fast32_t nbits = 0;
3035 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3037 uint_fast32_t word = bitmask[cnt];
3039 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3040 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3041 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3042 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3043 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3047 if (unlikely (asprintf (&str, gettext ("\
3049 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3050 (unsigned int) symbias,
3051 bitmask_words * sizeof (Elf32_Word),
3053 / (uint_fast32_t) (bitmask_words
3054 * sizeof (Elf32_Word) * 8)),
3055 (unsigned int) shift) == -1))
3056 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3058 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3066 /* Find the symbol table(s). For this we have to search through the
3069 handle_hash (Ebl *ebl)
3071 /* Get the section header string table index. */
3073 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3074 error (EXIT_FAILURE, 0,
3075 gettext ("cannot get section header string table index"));
3077 Elf_Scn *scn = NULL;
3078 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3080 /* Handle the section if it is a symbol table. */
3082 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3084 if (likely (shdr != NULL))
3086 if (shdr->sh_type == SHT_HASH)
3088 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3089 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3091 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3093 else if (shdr->sh_type == SHT_GNU_HASH)
3094 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3101 print_liblist (Ebl *ebl)
3103 /* Find the library list sections. For this we have to search
3104 through the section table. */
3105 Elf_Scn *scn = NULL;
3107 /* Get the section header string table index. */
3109 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3110 error (EXIT_FAILURE, 0,
3111 gettext ("cannot get section header string table index"));
3113 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3116 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3118 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3120 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3121 int nentries = shdr->sh_size / sh_entsize;
3122 printf (ngettext ("\
3123 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3125 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3128 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3132 Elf_Data *data = elf_getdata (scn, NULL);
3137 Library Time Stamp Checksum Version Flags"));
3139 for (int cnt = 0; cnt < nentries; ++cnt)
3142 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3143 if (unlikely (lib == NULL))
3146 time_t t = (time_t) lib->l_time_stamp;
3147 struct tm *tm = gmtime (&t);
3148 if (unlikely (tm == NULL))
3151 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3152 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3153 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3154 tm->tm_hour, tm->tm_min, tm->tm_sec,
3155 (unsigned int) lib->l_checksum,
3156 (unsigned int) lib->l_version,
3157 (unsigned int) lib->l_flags);
3164 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3166 /* Find the object attributes sections. For this we have to search
3167 through the section table. */
3168 Elf_Scn *scn = NULL;
3170 /* Get the section header string table index. */
3172 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3173 error (EXIT_FAILURE, 0,
3174 gettext ("cannot get section header string table index"));
3176 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3179 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3181 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3182 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3183 || ehdr->e_machine != EM_ARM)))
3187 \nObject attributes section [%2zu] '%s' of %" PRIu64
3188 " bytes at offset %#0" PRIx64 ":\n"),
3190 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3191 shdr->sh_size, shdr->sh_offset);
3193 Elf_Data *data = elf_rawdata (scn, NULL);
3197 const unsigned char *p = data->d_buf;
3199 if (unlikely (*p++ != 'A'))
3202 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3204 inline size_t left (void)
3206 return (const unsigned char *) data->d_buf + data->d_size - p;
3209 while (left () >= 4)
3212 memcpy (&len, p, sizeof len);
3214 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3217 if (unlikely (len > left ()))
3220 const unsigned char *name = p + sizeof len;
3223 unsigned const char *q = memchr (name, '\0', len);
3224 if (unlikely (q == NULL))
3228 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3230 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3231 || (q - name == sizeof "gnu"
3232 && !memcmp (name, "gnu", sizeof "gnu")))
3235 const unsigned char *const sub = q;
3237 unsigned int subsection_tag;
3238 get_uleb128 (subsection_tag, q);
3239 if (unlikely (q >= p))
3242 uint32_t subsection_len;
3243 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3246 memcpy (&subsection_len, q, sizeof subsection_len);
3248 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3249 CONVERT (subsection_len);
3251 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3254 const unsigned char *r = q + sizeof subsection_len;
3255 q = sub + subsection_len;
3257 switch (subsection_tag)
3260 printf (gettext (" %-4u %12" PRIu32 "\n"),
3261 subsection_tag, subsection_len);
3264 case 1: /* Tag_File */
3265 printf (gettext (" File: %11" PRIu32 "\n"),
3271 get_uleb128 (tag, r);
3272 if (unlikely (r >= q))
3276 const char *string = NULL;
3277 if (tag == 32 || (tag & 1) == 0)
3279 get_uleb128 (value, r);
3283 if (tag == 32 || (tag & 1) != 0)
3285 r = memchr (r, '\0', q - r);
3291 const char *tag_name = NULL;
3292 const char *value_name = NULL;
3293 ebl_check_object_attribute (ebl, (const char *) name,
3295 &tag_name, &value_name);
3297 if (tag_name != NULL)
3300 printf (gettext (" %s: %" PRId64 ", %s\n"),
3301 tag_name, value, string);
3302 else if (string == NULL && value_name == NULL)
3303 printf (gettext (" %s: %" PRId64 "\n"),
3306 printf (gettext (" %s: %s\n"),
3307 tag_name, string ?: value_name);
3313 printf (gettext (" %u: %" PRId64 "\n"),
3316 printf (gettext (" %u: %s\n"),
3328 format_dwarf_addr (Dwfl_Module *dwflmod,
3329 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3331 /* See if there is a name we can give for this address. */
3334 const char *name = (print_address_names && ! print_unresolved_addresses)
3335 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3339 if (print_unresolved_addresses)
3346 /* Relativize the address. */
3347 int n = dwfl_module_relocations (dwflmod);
3348 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3350 /* In an ET_REL file there is a section name to refer to. */
3352 : dwfl_module_relocation_info (dwflmod, i, NULL));
3359 ? (address_size == 0
3360 ? asprintf (&result,
3361 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3362 scn, address, name, off)
3363 : asprintf (&result,
3364 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3365 scn, 2 + address_size * 2, address,
3367 : (address_size == 0
3368 ? asprintf (&result,
3369 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3371 : asprintf (&result,
3372 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3373 2 + address_size * 2, address,
3376 ? (address_size == 0
3377 ? asprintf (&result,
3378 gettext ("%s+%#" PRIx64 " <%s>"),
3380 : asprintf (&result,
3381 gettext ("%s+%#0*" PRIx64 " <%s>"),
3382 scn, 2 + address_size * 2, address, name))
3383 : (address_size == 0
3384 ? asprintf (&result,
3385 gettext ("%#" PRIx64 " <%s>"),
3387 : asprintf (&result,
3388 gettext ("%#0*" PRIx64 " <%s>"),
3389 2 + address_size * 2, address, name))))
3391 ? (address_size == 0
3392 ? asprintf (&result,
3393 gettext ("%s+%#" PRIx64),
3395 : asprintf (&result,
3396 gettext ("%s+%#0*" PRIx64),
3397 scn, 2 + address_size * 2, address))
3398 : (address_size == 0
3399 ? asprintf (&result,
3402 : asprintf (&result,
3404 2 + address_size * 2, address)))) < 0)
3405 error (EXIT_FAILURE, 0, _("memory exhausted"));
3411 dwarf_tag_string (unsigned int tag)
3415 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3417 #undef ONE_KNOWN_DW_TAG
3425 dwarf_attr_string (unsigned int attrnum)
3429 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3431 #undef ONE_KNOWN_DW_AT
3439 dwarf_form_string (unsigned int form)
3443 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3444 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3446 #undef ONE_KNOWN_DW_FORM
3447 #undef ONE_KNOWN_DW_FORM_DESC
3455 dwarf_lang_string (unsigned int lang)
3459 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3461 #undef ONE_KNOWN_DW_LANG_DESC
3469 dwarf_inline_string (unsigned int code)
3471 static const char *const known[] =
3473 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3475 #undef ONE_KNOWN_DW_INL
3478 if (likely (code < sizeof (known) / sizeof (known[0])))
3486 dwarf_encoding_string (unsigned int code)
3488 static const char *const known[] =
3490 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3492 #undef ONE_KNOWN_DW_ATE
3495 if (likely (code < sizeof (known) / sizeof (known[0])))
3503 dwarf_access_string (unsigned int code)
3505 static const char *const known[] =
3507 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3509 #undef ONE_KNOWN_DW_ACCESS
3512 if (likely (code < sizeof (known) / sizeof (known[0])))
3520 dwarf_visibility_string (unsigned int code)
3522 static const char *const known[] =
3524 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3526 #undef ONE_KNOWN_DW_VIS
3529 if (likely (code < sizeof (known) / sizeof (known[0])))
3537 dwarf_virtuality_string (unsigned int code)
3539 static const char *const known[] =
3541 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3542 ALL_KNOWN_DW_VIRTUALITY
3543 #undef ONE_KNOWN_DW_VIRTUALITY
3546 if (likely (code < sizeof (known) / sizeof (known[0])))
3554 dwarf_identifier_case_string (unsigned int code)
3556 static const char *const known[] =
3558 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3560 #undef ONE_KNOWN_DW_ID
3563 if (likely (code < sizeof (known) / sizeof (known[0])))
3571 dwarf_calling_convention_string (unsigned int code)
3573 static const char *const known[] =
3575 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3577 #undef ONE_KNOWN_DW_CC
3580 if (likely (code < sizeof (known) / sizeof (known[0])))
3588 dwarf_ordering_string (unsigned int code)
3590 static const char *const known[] =
3592 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3594 #undef ONE_KNOWN_DW_ORD
3597 if (likely (code < sizeof (known) / sizeof (known[0])))
3605 dwarf_discr_list_string (unsigned int code)
3607 static const char *const known[] =
3609 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3611 #undef ONE_KNOWN_DW_DSC
3614 if (likely (code < sizeof (known) / sizeof (known[0])))
3622 dwarf_locexpr_opcode_string (unsigned int code)
3624 static const char *const known[] =
3626 /* Normally we can't affort building huge table of 64K entries,
3627 most of them zero, just because there are a couple defined
3628 values at the far end. In case of opcodes, it's OK. */
3629 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3630 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3632 #undef ONE_KNOWN_DW_OP
3633 #undef ONE_KNOWN_DW_OP_DESC
3636 if (likely (code < sizeof (known) / sizeof (known[0])))
3643 /* Used by all dwarf_foo_name functions. */
3645 string_or_unknown (const char *known, unsigned int code,
3646 unsigned int lo_user, unsigned int hi_user,
3647 bool print_unknown_num)
3649 static char unknown_buf[20];
3651 if (likely (known != NULL))
3654 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3656 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3661 if (print_unknown_num)
3663 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3672 dwarf_tag_name (unsigned int tag)
3674 const char *ret = dwarf_tag_string (tag);
3675 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3679 dwarf_attr_name (unsigned int attr)
3681 const char *ret = dwarf_attr_string (attr);
3682 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3687 dwarf_form_name (unsigned int form)
3689 const char *ret = dwarf_form_string (form);
3690 return string_or_unknown (ret, form, 0, 0, true);
3695 dwarf_lang_name (unsigned int lang)
3697 const char *ret = dwarf_lang_string (lang);
3698 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3703 dwarf_inline_name (unsigned int code)
3705 const char *ret = dwarf_inline_string (code);
3706 return string_or_unknown (ret, code, 0, 0, false);
3711 dwarf_encoding_name (unsigned int code)
3713 const char *ret = dwarf_encoding_string (code);
3714 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3719 dwarf_access_name (unsigned int code)
3721 const char *ret = dwarf_access_string (code);
3722 return string_or_unknown (ret, code, 0, 0, false);
3727 dwarf_visibility_name (unsigned int code)
3729 const char *ret = dwarf_visibility_string (code);
3730 return string_or_unknown (ret, code, 0, 0, false);
3735 dwarf_virtuality_name (unsigned int code)
3737 const char *ret = dwarf_virtuality_string (code);
3738 return string_or_unknown (ret, code, 0, 0, false);
3743 dwarf_identifier_case_name (unsigned int code)
3745 const char *ret = dwarf_identifier_case_string (code);
3746 return string_or_unknown (ret, code, 0, 0, false);
3751 dwarf_calling_convention_name (unsigned int code)
3753 const char *ret = dwarf_calling_convention_string (code);
3754 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3759 dwarf_ordering_name (unsigned int code)
3761 const char *ret = dwarf_ordering_string (code);
3762 return string_or_unknown (ret, code, 0, 0, false);
3767 dwarf_discr_list_name (unsigned int code)
3769 const char *ret = dwarf_discr_list_string (code);
3770 return string_or_unknown (ret, code, 0, 0, false);
3775 print_block (size_t n, const void *block)
3778 puts (_("empty block"));
3781 printf (_("%zu byte block:"), n);
3782 const unsigned char *data = block;
3784 printf (" %02x", *data++);
3791 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3792 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3793 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3795 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3799 printf ("%*s(empty)\n", indent, "");
3803 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3804 #define CONSUME(n) NEED (n); else len -= (n)
3806 Dwarf_Word offset = 0;
3809 uint_fast8_t op = *data++;
3811 const char *op_name = dwarf_locexpr_opcode_string (op);
3812 if (unlikely (op_name == NULL))
3814 static char buf[20];
3815 if (op >= DW_OP_lo_user)
3816 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3818 snprintf (buf, sizeof buf, "??? (%#x)", op);
3825 /* Address operand. */
3829 addr = read_4ubyte_unaligned (dbg, data);
3832 assert (addrsize == 8);
3833 addr = read_8ubyte_unaligned (dbg, data);
3838 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3839 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3840 indent, "", (uintmax_t) offset, op_name, a);
3843 offset += 1 + addrsize;
3846 case DW_OP_call_ref:
3847 /* Offset operand. */
3850 addr = read_4ubyte_unaligned (dbg, data);
3853 assert (ref_size == 8);
3854 addr = read_8ubyte_unaligned (dbg, data);
3859 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
3860 indent, "", (uintmax_t) offset,
3861 op_name, (uintmax_t) addr);
3862 offset += 1 + ref_size;
3865 case DW_OP_deref_size:
3866 case DW_OP_xderef_size:
3869 // XXX value might be modified by relocation
3871 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
3872 indent, "", (uintmax_t) offset,
3873 op_name, *((uint8_t *) data));
3881 // XXX value might be modified by relocation
3882 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3883 indent, "", (uintmax_t) offset,
3884 op_name, read_2ubyte_unaligned (dbg, data));
3892 // XXX value might be modified by relocation
3893 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3894 indent, "", (uintmax_t) offset,
3895 op_name, read_4ubyte_unaligned (dbg, data));
3903 // XXX value might be modified by relocation
3904 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3905 indent, "", (uintmax_t) offset,
3906 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
3914 // XXX value might be modified by relocation
3915 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
3916 indent, "", (uintmax_t) offset,
3917 op_name, *((int8_t *) data));
3925 // XXX value might be modified by relocation
3926 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
3927 indent, "", (uintmax_t) offset,
3928 op_name, read_2sbyte_unaligned (dbg, data));
3936 // XXX value might be modified by relocation
3937 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
3938 indent, "", (uintmax_t) offset,
3939 op_name, read_4sbyte_unaligned (dbg, data));
3947 // XXX value might be modified by relocation
3948 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3949 indent, "", (uintmax_t) offset,
3950 op_name, read_8sbyte_unaligned (dbg, data));
3958 case DW_OP_plus_uconst:
3960 const unsigned char *start = data;
3963 get_uleb128 (uleb, data); /* XXX check overrun */
3964 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3965 indent, "", (uintmax_t) offset, op_name, uleb);
3966 CONSUME (data - start);
3967 offset += 1 + (data - start);
3970 case DW_OP_bit_piece:
3974 get_uleb128 (uleb, data); /* XXX check overrun */
3975 get_uleb128 (uleb2, data); /* XXX check overrun */
3976 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
3977 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
3978 CONSUME (data - start);
3979 offset += 1 + (data - start);
3983 case DW_OP_breg0 ... DW_OP_breg31:
3988 get_sleb128 (sleb, data); /* XXX check overrun */
3989 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3990 indent, "", (uintmax_t) offset, op_name, sleb);
3991 CONSUME (data - start);
3992 offset += 1 + (data - start);
3998 get_uleb128 (uleb, data); /* XXX check overrun */
3999 get_sleb128 (sleb, data); /* XXX check overrun */
4000 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4001 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4002 CONSUME (data - start);
4003 offset += 1 + (data - start);
4008 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4009 indent, "", (uintmax_t) offset, op_name,
4010 read_2ubyte_unaligned (dbg, data));
4017 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4018 indent, "", (uintmax_t) offset, op_name,
4019 read_4ubyte_unaligned (dbg, data));
4027 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4028 indent, "", (uintmax_t) offset, op_name,
4029 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4035 case DW_OP_implicit_value:
4038 get_uleb128 (uleb, data); /* XXX check overrun */
4039 printf ("%*s[%4" PRIuMAX "] %s: ",
4040 indent, "", (uintmax_t) offset, op_name);
4042 print_block (uleb, data);
4044 CONSUME (data - start);
4045 offset += 1 + (data - start);
4048 case DW_OP_GNU_implicit_pointer:
4049 /* DIE offset operand. */
4051 NEED (ref_size + 1);
4053 addr = read_4ubyte_unaligned (dbg, data);
4056 assert (ref_size == 8);
4057 addr = read_8ubyte_unaligned (dbg, data);
4060 /* Byte offset operand. */
4061 get_sleb128 (sleb, data); /* XXX check overrun */
4063 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4064 indent, "", (intmax_t) offset,
4065 op_name, (uintmax_t) addr, sleb);
4066 CONSUME (data - start);
4067 offset += 1 + (data - start);
4070 case DW_OP_GNU_entry_value:
4071 /* Size plus expression block. */
4074 get_uleb128 (uleb, data); /* XXX check overrun */
4075 printf ("%*s[%4" PRIuMAX "] %s:\n",
4076 indent, "", (uintmax_t) offset, op_name);
4078 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4079 addrsize, offset_size, cu, uleb, data);
4081 CONSUME (data - start);
4082 offset += 1 + (data - start);
4085 case DW_OP_GNU_const_type:
4086 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4087 unsigned size plus block. */
4090 get_uleb128 (uleb, data); /* XXX check overrun */
4091 if (! print_unresolved_addresses && cu != NULL)
4093 uint8_t usize = *(uint8_t *) data++;
4095 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4096 indent, "", (uintmax_t) offset, op_name, uleb);
4097 print_block (usize, data);
4099 CONSUME (data - start);
4100 offset += 1 + (data - start);
4103 case DW_OP_GNU_regval_type:
4104 /* uleb128 register number, uleb128 CU relative
4105 DW_TAG_base_type DIE offset. */
4108 get_uleb128 (uleb, data); /* XXX check overrun */
4109 get_uleb128 (uleb2, data); /* XXX check overrun */
4110 if (! print_unresolved_addresses && cu != NULL)
4112 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4113 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4114 CONSUME (data - start);
4115 offset += 1 + (data - start);
4118 case DW_OP_GNU_deref_type:
4119 /* 1-byte unsigned size of value, uleb128 CU relative
4120 DW_TAG_base_type DIE offset. */
4123 usize = *(uint8_t *) data++;
4124 get_uleb128 (uleb, data); /* XXX check overrun */
4125 if (! print_unresolved_addresses && cu != NULL)
4127 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4128 indent, "", (uintmax_t) offset,
4129 op_name, usize, uleb);
4130 CONSUME (data - start);
4131 offset += 1 + (data - start);
4134 case DW_OP_GNU_convert:
4135 case DW_OP_GNU_reinterpret:
4136 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4137 for conversion to untyped. */
4140 get_uleb128 (uleb, data); /* XXX check overrun */
4141 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4143 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4144 indent, "", (uintmax_t) offset, op_name, uleb);
4145 CONSUME (data - start);
4146 offset += 1 + (data - start);
4149 case DW_OP_GNU_parameter_ref:
4150 /* 4 byte CU relative reference to the abstract optimized away
4151 DW_TAG_formal_parameter. */
4153 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4154 if (! print_unresolved_addresses && cu != NULL)
4155 param_off += cu->start;
4156 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4157 indent, "", (uintmax_t) offset, op_name, param_off);
4165 printf ("%*s[%4" PRIuMAX "] %s\n",
4166 indent, "", (uintmax_t) offset, op_name);
4171 indent = indentrest;
4175 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4176 indent, "", (uintmax_t) offset, op_name);
4184 Dwarf_Off offset:(64 - 3);
4188 struct Dwarf_CU *cu;
4191 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4192 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4195 listptr_base (struct listptr *p)
4198 Dwarf_Die cu = CUDIE (p->cu);
4199 /* Find the base address of the compilation unit. It will normally
4200 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4201 address could be overridden by DW_AT_entry_pc. It's been
4202 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4203 compilation units with discontinuous ranges. */
4204 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4206 Dwarf_Attribute attr_mem;
4207 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4215 compare_listptr (const void *a, const void *b, void *arg)
4217 const char *name = arg;
4218 struct listptr *p1 = (void *) a;
4219 struct listptr *p2 = (void *) b;
4221 if (p1->offset < p2->offset)
4223 if (p1->offset > p2->offset)
4226 if (!p1->warned && !p2->warned)
4228 if (p1->addr64 != p2->addr64)
4230 p1->warned = p2->warned = true;
4232 gettext ("%s %#" PRIx64 " used with different address sizes"),
4233 name, (uint64_t) p1->offset);
4235 if (p1->dwarf64 != p2->dwarf64)
4237 p1->warned = p2->warned = true;
4239 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4240 name, (uint64_t) p1->offset);
4242 if (listptr_base (p1) != listptr_base (p2))
4244 p1->warned = p2->warned = true;
4246 gettext ("%s %#" PRIx64 " used with different base addresses"),
4247 name, (uint64_t) p1->offset);
4254 struct listptr_table
4258 struct listptr *table;
4261 static struct listptr_table known_loclistptr;
4262 static struct listptr_table known_rangelistptr;
4265 reset_listptr (struct listptr_table *table)
4267 free (table->table);
4268 table->table = NULL;
4269 table->n = table->alloc = 0;
4273 notice_listptr (enum section_e section, struct listptr_table *table,
4274 uint_fast8_t address_size, uint_fast8_t offset_size,
4275 struct Dwarf_CU *cu, Dwarf_Off offset)
4277 if (print_debug_sections & section)
4279 if (table->n == table->alloc)
4281 if (table->alloc == 0)
4285 table->table = xrealloc (table->table,
4286 table->alloc * sizeof table->table[0]);
4289 struct listptr *p = &table->table[table->n++];
4291 *p = (struct listptr)
4293 .addr64 = address_size == 8,
4294 .dwarf64 = offset_size == 8,
4298 assert (p->offset == offset);
4303 sort_listptr (struct listptr_table *table, const char *name)
4306 qsort_r (table->table, table->n, sizeof table->table[0],
4307 &compare_listptr, (void *) name);
4311 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4312 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4313 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4314 unsigned char **readp, unsigned char *endp)
4319 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4322 struct listptr *p = &table->table[*idxp];
4324 if (*idxp == table->n
4325 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4328 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4333 if (p->offset != (Dwarf_Off) offset)
4335 *readp += p->offset - offset;
4336 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4337 offset, (Dwarf_Off) p->offset - offset);
4341 if (address_sizep != NULL)
4342 *address_sizep = listptr_address_size (p);
4343 if (offset_sizep != NULL)
4344 *offset_sizep = listptr_offset_size (p);
4346 *base = listptr_base (p);
4355 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4356 Ebl *ebl, GElf_Ehdr *ehdr,
4357 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4359 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4360 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4362 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4364 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4365 (uint64_t) shdr->sh_offset);
4367 Dwarf_Off offset = 0;
4368 while (offset < sh_size)
4370 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4376 Dwarf_Abbrev abbrev;
4378 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4381 if (unlikely (res < 0))
4384 *** error while reading abbreviation: %s\n"),
4389 /* This is the NUL byte at the end of the section. */
4394 /* We know these calls can never fail. */
4395 unsigned int code = dwarf_getabbrevcode (&abbrev);
4396 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4397 int has_children = dwarf_abbrevhaschildren (&abbrev);
4399 printf (gettext (" [%5u] offset: %" PRId64
4400 ", children: %s, tag: %s\n"),
4401 code, (int64_t) offset,
4402 has_children ? gettext ("yes") : gettext ("no"),
4403 dwarf_tag_name (tag));
4409 while (dwarf_getabbrevattr (&abbrev, cnt,
4410 &name, &form, &enoffset) == 0)
4412 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4413 dwarf_attr_name (name), dwarf_form_name (form),
4414 (uint64_t) enoffset);
4425 /* Print content of DWARF .debug_aranges section. We fortunately do
4426 not have to know a bit about the structure of the section, libdwarf
4427 takes care of it. */
4429 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4430 GElf_Shdr *shdr, Dwarf *dbg)
4432 Dwarf_Aranges *aranges;
4434 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4436 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4441 GElf_Shdr glink_mem;
4443 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4446 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4451 printf (ngettext ("\
4452 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4454 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4456 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4457 (uint64_t) shdr->sh_offset, cnt);
4459 /* Compute floor(log16(cnt)). */
4468 for (size_t n = 0; n < cnt; ++n)
4470 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4471 if (unlikely (runp == NULL))
4473 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4481 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4482 printf (gettext (" [%*zu] ???\n"), digits, n);
4484 printf (gettext (" [%*zu] start: %0#*" PRIx64
4485 ", length: %5" PRIu64 ", CU DIE offset: %6"
4487 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4488 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4493 /* Print content of DWARF .debug_aranges section. */
4495 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4496 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4497 GElf_Shdr *shdr, Dwarf *dbg)
4501 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4505 Elf_Data *data = elf_rawdata (scn, NULL);
4507 if (unlikely (data == NULL))
4509 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4515 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4516 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4517 (uint64_t) shdr->sh_offset);
4519 const unsigned char *readp = data->d_buf;
4520 const unsigned char *readendp = readp + data->d_size;
4522 while (readp < readendp)
4524 const unsigned char *hdrstart = readp;
4525 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4527 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4528 if (readp + 4 > readendp)
4531 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4532 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4536 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4537 unsigned int length_bytes = 4;
4538 if (length == DWARF3_LENGTH_64_BIT)
4540 if (readp + 8 > readendp)
4542 length = read_8ubyte_unaligned_inc (dbg, readp);
4546 const unsigned char *nexthdr = readp + length;
4547 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4550 if (nexthdr > readendp)
4556 if (readp + 2 > readendp)
4558 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4559 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4563 error (0, 0, gettext ("unsupported aranges version"));
4568 if (readp + length_bytes > readendp)
4570 if (length_bytes == 8)
4571 offset = read_8ubyte_unaligned_inc (dbg, readp);
4573 offset = read_4ubyte_unaligned_inc (dbg, readp);
4574 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4577 if (readp + 1 > readendp)
4579 unsigned int address_size = *readp++;
4580 printf (gettext (" Address size: %6" PRIu64 "\n"),
4581 (uint64_t) address_size);
4582 if (address_size != 4 && address_size != 8)
4584 error (0, 0, gettext ("unsupported address size"));
4588 unsigned int segment_size = *readp++;
4589 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4590 (uint64_t) segment_size);
4591 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4593 error (0, 0, gettext ("unsupported segment size"));
4597 /* Round the address to the next multiple of 2*address_size. */
4598 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4599 % (2 * address_size));
4601 while (readp < nexthdr)
4603 Dwarf_Word range_address;
4604 Dwarf_Word range_length;
4605 Dwarf_Word segment = 0;
4606 if (readp + 2 * address_size + segment_size > readendp)
4608 if (address_size == 4)
4610 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4611 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4615 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4616 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4619 if (segment_size == 4)
4620 segment = read_4ubyte_unaligned_inc (dbg, readp);
4621 else if (segment_size == 8)
4622 segment = read_8ubyte_unaligned_inc (dbg, readp);
4624 if (range_address == 0 && range_length == 0 && segment == 0)
4627 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4629 char *e = format_dwarf_addr (dwflmod, address_size,
4630 range_address + range_length - 1,
4632 if (segment_size != 0)
4633 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4634 (uint64_t) segment);
4636 printf (gettext (" %s..%s\n"), b, e);
4642 if (readp != nexthdr)
4644 size_t padding = nexthdr - readp;
4645 printf (gettext (" %Zu padding bytes\n"), padding);
4652 /* Print content of DWARF .debug_ranges section. */
4654 print_debug_ranges_section (Dwfl_Module *dwflmod,
4655 Ebl *ebl, GElf_Ehdr *ehdr,
4656 Elf_Scn *scn, GElf_Shdr *shdr,
4659 Elf_Data *data = elf_rawdata (scn, NULL);
4661 if (unlikely (data == NULL))
4663 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4669 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4670 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4671 (uint64_t) shdr->sh_offset);
4673 sort_listptr (&known_rangelistptr, "rangelistptr");
4674 size_t listptr_idx = 0;
4676 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4679 Dwarf_Addr base = 0;
4680 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4681 unsigned char *readp = data->d_buf;
4682 while (readp < endp)
4684 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4686 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4687 &address_size, NULL, &base, NULL,
4688 offset, &readp, endp))
4691 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4693 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4699 if (address_size == 8)
4701 begin = read_8ubyte_unaligned_inc (dbg, readp);
4702 end = read_8ubyte_unaligned_inc (dbg, readp);
4706 begin = read_4ubyte_unaligned_inc (dbg, readp);
4707 end = read_4ubyte_unaligned_inc (dbg, readp);
4708 if (begin == (Dwarf_Addr) (uint32_t) -1)
4709 begin = (Dwarf_Addr) -1l;
4712 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4714 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4715 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4719 else if (begin == 0 && end == 0) /* End of list entry. */
4722 printf (gettext (" [%6tx] empty list\n"), offset);
4727 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4729 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4731 /* We have an address range entry. */
4732 if (first) /* First address range entry in a list. */
4733 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4735 printf (gettext (" %s..%s\n"), b, e);
4744 #define REGNAMESZ 16
4746 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4747 char name[REGNAMESZ], int *bits, int *type)
4752 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4753 bits ?: &ignore, type ?: &ignore);
4757 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4759 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4761 *bits = loc != NULL ? loc->bits : 0;
4763 *type = DW_ATE_unsigned;
4764 set = "??? unrecognized";
4768 if (bits != NULL && *bits <= 0)
4769 *bits = loc != NULL ? loc->bits : 0;
4770 if (type != NULL && *type == DW_ATE_void)
4771 *type = DW_ATE_unsigned;
4778 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4779 Dwarf_Word vma_base, unsigned int code_align,
4781 unsigned int version, unsigned int ptr_size,
4782 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4784 char regnamebuf[REGNAMESZ];
4785 const char *regname (unsigned int regno)
4787 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4791 puts ("\n Program:");
4792 Dwarf_Word pc = vma_base;
4793 while (readp < endp)
4795 unsigned int opcode = *readp++;
4797 if (opcode < DW_CFA_advance_loc)
4798 /* Extended opcode. */
4809 case DW_CFA_set_loc:
4810 // XXX overflow check
4811 get_uleb128 (op1, readp);
4813 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4815 case DW_CFA_advance_loc1:
4816 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4817 *readp, pc += *readp * code_align);
4820 case DW_CFA_advance_loc2:
4821 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4822 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4823 op1, pc += op1 * code_align);
4825 case DW_CFA_advance_loc4:
4826 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4827 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4828 op1, pc += op1 * code_align);
4830 case DW_CFA_offset_extended:
4831 // XXX overflow check
4832 get_uleb128 (op1, readp);
4833 get_uleb128 (op2, readp);
4834 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4836 op1, regname (op1), op2 * data_align);
4838 case DW_CFA_restore_extended:
4839 // XXX overflow check
4840 get_uleb128 (op1, readp);
4841 printf (" restore_extended r%" PRIu64 " (%s)\n",
4842 op1, regname (op1));
4844 case DW_CFA_undefined:
4845 // XXX overflow check
4846 get_uleb128 (op1, readp);
4847 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4849 case DW_CFA_same_value:
4850 // XXX overflow check
4851 get_uleb128 (op1, readp);
4852 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4854 case DW_CFA_register:
4855 // XXX overflow check
4856 get_uleb128 (op1, readp);
4857 get_uleb128 (op2, readp);
4858 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4859 op1, regname (op1), op2, regname (op2));
4861 case DW_CFA_remember_state:
4862 puts (" remember_state");
4864 case DW_CFA_restore_state:
4865 puts (" restore_state");
4867 case DW_CFA_def_cfa:
4868 // XXX overflow check
4869 get_uleb128 (op1, readp);
4870 get_uleb128 (op2, readp);
4871 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4872 op1, regname (op1), op2);
4874 case DW_CFA_def_cfa_register:
4875 // XXX overflow check
4876 get_uleb128 (op1, readp);
4877 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
4878 op1, regname (op1));
4880 case DW_CFA_def_cfa_offset:
4881 // XXX overflow check
4882 get_uleb128 (op1, readp);
4883 printf (" def_cfa_offset %" PRIu64 "\n", op1);
4885 case DW_CFA_def_cfa_expression:
4886 // XXX overflow check
4887 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
4888 printf (" def_cfa_expression %" PRIu64 "\n", op1);
4889 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4893 case DW_CFA_expression:
4894 // XXX overflow check
4895 get_uleb128 (op1, readp);
4896 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4897 printf (" expression r%" PRIu64 " (%s) \n",
4898 op1, regname (op1));
4899 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4903 case DW_CFA_offset_extended_sf:
4904 // XXX overflow check
4905 get_uleb128 (op1, readp);
4906 get_sleb128 (sop2, readp);
4907 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
4909 op1, regname (op1), sop2 * data_align);
4911 case DW_CFA_def_cfa_sf:
4912 // XXX overflow check
4913 get_uleb128 (op1, readp);
4914 get_sleb128 (sop2, readp);
4915 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
4916 op1, regname (op1), sop2 * data_align);
4918 case DW_CFA_def_cfa_offset_sf:
4919 // XXX overflow check
4920 get_sleb128 (sop1, readp);
4921 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
4923 case DW_CFA_val_offset:
4924 // XXX overflow check
4925 get_uleb128 (op1, readp);
4926 get_uleb128 (op2, readp);
4927 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
4928 op1, op2 * data_align);
4930 case DW_CFA_val_offset_sf:
4931 // XXX overflow check
4932 get_uleb128 (op1, readp);
4933 get_sleb128 (sop2, readp);
4934 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
4935 op1, sop2 * data_align);
4937 case DW_CFA_val_expression:
4938 // XXX overflow check
4939 get_uleb128 (op1, readp);
4940 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4941 printf (" val_expression r%" PRIu64 " (%s)\n",
4942 op1, regname (op1));
4943 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
4947 case DW_CFA_MIPS_advance_loc8:
4948 op1 = read_8ubyte_unaligned_inc (dbg, readp);
4949 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
4950 op1, pc += op1 * code_align);
4952 case DW_CFA_GNU_window_save:
4953 puts (" GNU_window_save");
4955 case DW_CFA_GNU_args_size:
4956 // XXX overflow check
4957 get_uleb128 (op1, readp);
4958 printf (" args_size %" PRIu64 "\n", op1);
4961 printf (" ??? (%u)\n", opcode);
4964 else if (opcode < DW_CFA_offset)
4965 printf (" advance_loc %u to %#" PRIx64 "\n",
4966 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
4967 else if (opcode < DW_CFA_restore)
4970 // XXX overflow check
4971 get_uleb128 (offset, readp);
4972 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
4973 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
4976 printf (" restore r%u (%s)\n",
4977 opcode & 0x3f, regname (opcode & 0x3f));
4983 encoded_ptr_size (int encoding, unsigned int ptr_size)
4985 switch (encoding & 7)
5000 print_encoding (unsigned int val)
5004 case DW_EH_PE_absptr:
5005 fputs ("absptr", stdout);
5007 case DW_EH_PE_uleb128:
5008 fputs ("uleb128", stdout);
5010 case DW_EH_PE_udata2:
5011 fputs ("udata2", stdout);
5013 case DW_EH_PE_udata4:
5014 fputs ("udata4", stdout);
5016 case DW_EH_PE_udata8:
5017 fputs ("udata8", stdout);
5019 case DW_EH_PE_sleb128:
5020 fputs ("sleb128", stdout);
5022 case DW_EH_PE_sdata2:
5023 fputs ("sdata2", stdout);
5025 case DW_EH_PE_sdata4:
5026 fputs ("sdata4", stdout);
5028 case DW_EH_PE_sdata8:
5029 fputs ("sdata8", stdout);
5032 /* We did not use any of the bits after all. */
5041 print_relinfo (unsigned int val)
5045 case DW_EH_PE_pcrel:
5046 fputs ("pcrel", stdout);
5048 case DW_EH_PE_textrel:
5049 fputs ("textrel", stdout);
5051 case DW_EH_PE_datarel:
5052 fputs ("datarel", stdout);
5054 case DW_EH_PE_funcrel:
5055 fputs ("funcrel", stdout);
5057 case DW_EH_PE_aligned:
5058 fputs ("aligned", stdout);
5069 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5071 printf ("(%s", pfx);
5073 if (fde_encoding == DW_EH_PE_omit)
5077 unsigned int w = fde_encoding;
5079 w = print_encoding (w);
5083 if (w != fde_encoding)
5084 fputc_unlocked (' ', stdout);
5086 w = print_relinfo (w);
5090 printf ("%s%x", w != fde_encoding ? " " : "", w);
5097 static const unsigned char *
5098 read_encoded (unsigned int encoding, const unsigned char *readp,
5099 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5101 if ((encoding & 0xf) == DW_EH_PE_absptr)
5102 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5103 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5105 switch (encoding & 0xf)
5107 case DW_EH_PE_uleb128:
5108 // XXX buffer overrun check
5109 get_uleb128 (*res, readp);
5111 case DW_EH_PE_sleb128:
5112 // XXX buffer overrun check
5113 get_sleb128 (*res, readp);
5115 case DW_EH_PE_udata2:
5116 if (readp + 2 > endp)
5118 *res = read_2ubyte_unaligned_inc (dbg, readp);
5120 case DW_EH_PE_udata4:
5121 if (readp + 4 > endp)
5123 *res = read_4ubyte_unaligned_inc (dbg, readp);
5125 case DW_EH_PE_udata8:
5126 if (readp + 8 > endp)
5128 *res = read_8ubyte_unaligned_inc (dbg, readp);
5130 case DW_EH_PE_sdata2:
5131 if (readp + 2 > endp)
5133 *res = read_2sbyte_unaligned_inc (dbg, readp);
5135 case DW_EH_PE_sdata4:
5136 if (readp + 4 > endp)
5138 *res = read_4sbyte_unaligned_inc (dbg, readp);
5140 case DW_EH_PE_sdata8:
5141 if (readp + 8 > endp)
5143 *res = read_8sbyte_unaligned_inc (dbg, readp);
5148 gettext ("invalid encoding"));
5156 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5157 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5160 /* We know this call will succeed since it did in the caller. */
5161 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5162 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5164 /* Needed if we find PC-relative addresses. */
5166 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5168 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5172 Elf_Data *data = elf_rawdata (scn, NULL);
5174 if (unlikely (data == NULL))
5176 error (0, 0, gettext ("cannot get %s content: %s"),
5177 scnname, elf_errmsg (-1));
5180 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5184 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5185 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5188 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5189 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5193 ptrdiff_t cie_offset;
5194 const char *augmentation;
5195 unsigned int code_alignment_factor;
5196 unsigned int data_alignment_factor;
5197 uint8_t address_size;
5198 uint8_t fde_encoding;
5199 uint8_t lsda_encoding;
5200 struct cieinfo *next;
5203 const unsigned char *readp = data->d_buf;
5204 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5206 while (readp < dataend)
5208 if (unlikely (readp + 4 > dataend))
5211 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5212 elf_ndxscn (scn), scnname);
5216 /* At the beginning there must be a CIE. There can be multiple,
5217 hence we test tis in a loop. */
5218 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5220 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5221 unsigned int length = 4;
5222 if (unlikely (unit_length == 0xffffffff))
5224 if (unlikely (readp + 8 > dataend))
5227 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5231 if (unlikely (unit_length == 0))
5233 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5237 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5239 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5240 const unsigned char *const cieend = readp + unit_length;
5241 if (unlikely (cieend > dataend || readp + 8 > dataend))
5247 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5248 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5249 cie_id = DW_CIE_ID_64;
5252 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5254 uint_fast8_t version = 2;
5255 unsigned int code_alignment_factor;
5256 int data_alignment_factor;
5257 unsigned int fde_encoding = 0;
5258 unsigned int lsda_encoding = 0;
5259 Dwarf_Word initial_location = 0;
5260 Dwarf_Word vma_base = 0;
5262 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5265 const char *const augmentation = (const char *) readp;
5266 readp = memchr (readp, '\0', cieend - readp);
5267 if (unlikely (readp == NULL))
5271 uint_fast8_t segment_size = 0;
5274 if (cieend - readp < 5)
5276 ptr_size = *readp++;
5277 segment_size = *readp++;
5280 // XXX Check overflow
5281 get_uleb128 (code_alignment_factor, readp);
5282 // XXX Check overflow
5283 get_sleb128 (data_alignment_factor, readp);
5285 /* In some variant for unwind data there is another field. */
5286 if (strcmp (augmentation, "eh") == 0)
5287 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5289 unsigned int return_address_register;
5290 if (unlikely (version == 1))
5291 return_address_register = *readp++;
5293 // XXX Check overflow
5294 get_uleb128 (return_address_register, readp);
5296 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5297 " CIE_id: %" PRIu64 "\n"
5299 " augmentation: \"%s\"\n",
5300 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5301 version, augmentation);
5303 printf (" address_size: %u\n"
5304 " segment_size: %u\n",
5305 ptr_size, segment_size);
5306 printf (" code_alignment_factor: %u\n"
5307 " data_alignment_factor: %d\n"
5308 " return_address_register: %u\n",
5309 code_alignment_factor,
5310 data_alignment_factor, return_address_register);
5312 if (augmentation[0] == 'z')
5314 unsigned int augmentationlen;
5315 get_uleb128 (augmentationlen, readp);
5317 if (augmentationlen > (size_t) (dataend - readp))
5318 error (1, 0, gettext ("invalid augmentation length"));
5320 const char *hdr = "Augmentation data:";
5321 const char *cp = augmentation + 1;
5324 printf (" %-26s%#x ", hdr, *readp);
5329 fde_encoding = *readp++;
5330 print_encoding_base (gettext ("FDE address encoding: "),
5333 else if (*cp == 'L')
5335 lsda_encoding = *readp++;
5336 print_encoding_base (gettext ("LSDA pointer encoding: "),
5339 else if (*cp == 'P')
5341 /* Personality. This field usually has a relocation
5342 attached pointing to __gcc_personality_v0. */
5343 const unsigned char *startp = readp;
5344 unsigned int encoding = *readp++;
5346 readp = read_encoded (encoding, readp,
5347 readp - 1 + augmentationlen,
5350 while (++startp < readp)
5351 printf ("%#x ", *startp);
5354 print_encoding (encoding);
5356 switch (encoding & 0xf)
5358 case DW_EH_PE_sleb128:
5359 case DW_EH_PE_sdata2:
5360 case DW_EH_PE_sdata4:
5361 printf ("%" PRId64 ")\n", val);
5364 printf ("%#" PRIx64 ")\n", val);
5369 printf ("(%x)\n", *readp++);
5375 if (likely (ptr_size == 4 || ptr_size == 8))
5377 struct cieinfo *newp = alloca (sizeof (*newp));
5378 newp->cie_offset = offset;
5379 newp->augmentation = augmentation;
5380 newp->fde_encoding = fde_encoding;
5381 newp->lsda_encoding = lsda_encoding;
5382 newp->address_size = ptr_size;
5383 newp->code_alignment_factor = code_alignment_factor;
5384 newp->data_alignment_factor = data_alignment_factor;
5391 struct cieinfo *cie = cies;
5394 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5395 : (ptrdiff_t) cie_id == cie->cie_offset)
5399 if (unlikely (cie == NULL))
5401 puts ("invalid CIE reference in FDE");
5405 /* Initialize from CIE data. */
5406 fde_encoding = cie->fde_encoding;
5407 lsda_encoding = cie->lsda_encoding;
5408 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5409 code_alignment_factor = cie->code_alignment_factor;
5410 data_alignment_factor = cie->data_alignment_factor;
5412 const unsigned char *base = readp;
5413 // XXX There are sometimes relocations for this value
5414 initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5415 Dwarf_Word address_range
5416 = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5418 /* pcrel for an FDE address is relative to the runtime
5419 address of the start_address field itself. Sign extend
5420 if necessary to make sure the calculation is done on the
5421 full 64 bit address even when initial_location only holds
5422 the lower 32 bits. */
5423 Dwarf_Addr pc_start = initial_location;
5425 pc_start = (uint64_t) (int32_t) pc_start;
5426 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5427 pc_start += ((uint64_t) shdr->sh_addr
5428 + (base - (const unsigned char *) data->d_buf)
5431 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5432 pc_start, initial_location);
5433 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5434 " CIE_pointer: %" PRIu64 "\n"
5435 " initial_location: %s",
5436 offset, (uint64_t) unit_length,
5437 cie->cie_offset, (uint64_t) cie_id, a);
5439 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5441 vma_base = (((uint64_t) shdr->sh_offset
5442 + (base - (const unsigned char *) data->d_buf)
5443 + (uint64_t) initial_location)
5445 ? UINT64_C (0xffffffff)
5446 : UINT64_C (0xffffffffffffffff)));
5447 printf (gettext (" (offset: %#" PRIx64 ")"),
5448 (uint64_t) vma_base);
5451 printf ("\n address_range: %#" PRIx64,
5452 (uint64_t) address_range);
5453 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5454 printf (gettext (" (end offset: %#" PRIx64 ")"),
5455 ((uint64_t) vma_base + (uint64_t) address_range)
5457 ? UINT64_C (0xffffffff)
5458 : UINT64_C (0xffffffffffffffff)));
5461 if (cie->augmentation[0] == 'z')
5463 unsigned int augmentationlen;
5464 get_uleb128 (augmentationlen, readp);
5466 if (augmentationlen > 0)
5468 const char *hdr = "Augmentation data:";
5469 const char *cp = cie->augmentation + 1;
5475 uint64_t lsda_pointer;
5476 const unsigned char *p
5477 = read_encoded (lsda_encoding, &readp[u],
5478 &readp[augmentationlen],
5479 &lsda_pointer, dbg);
5482 %-26sLSDA pointer: %#" PRIx64 "\n"),
5489 while (u < augmentationlen)
5491 printf (" %-26s%#x\n", hdr, readp[u++]);
5496 readp += augmentationlen;
5500 /* Handle the initialization instructions. */
5501 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5502 data_alignment_factor, version, ptr_size,
5511 Dwfl_Module *dwflmod;
5516 unsigned int version;
5517 unsigned int addrsize;
5518 unsigned int offset_size;
5519 struct Dwarf_CU *cu;
5524 attr_callback (Dwarf_Attribute *attrp, void *arg)
5526 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5527 const int level = cbargs->level;
5529 unsigned int attr = dwarf_whatattr (attrp);
5530 if (unlikely (attr == 0))
5532 if (!cbargs->silent)
5533 error (0, 0, gettext ("cannot get attribute code: %s"),
5535 return DWARF_CB_ABORT;
5538 unsigned int form = dwarf_whatform (attrp);
5539 if (unlikely (form == 0))
5541 if (!cbargs->silent)
5542 error (0, 0, gettext ("cannot get attribute form: %s"),
5544 return DWARF_CB_ABORT;
5550 if (!cbargs->silent)
5553 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5556 if (!cbargs->silent)
5557 error (0, 0, gettext ("cannot get attribute value: %s"),
5559 return DWARF_CB_ABORT;
5561 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5563 printf (" %*s%-20s (%s) %s\n",
5564 (int) (level * 2), "", dwarf_attr_name (attr),
5565 dwarf_form_name (form), a);
5570 case DW_FORM_indirect:
5572 case DW_FORM_string:
5573 case DW_FORM_GNU_strp_alt:
5576 const char *str = dwarf_formstring (attrp);
5577 if (unlikely (str == NULL))
5579 printf (" %*s%-20s (%s) \"%s\"\n",
5580 (int) (level * 2), "", dwarf_attr_name (attr),
5581 dwarf_form_name (form), str);
5584 case DW_FORM_ref_addr:
5585 case DW_FORM_ref_udata:
5590 case DW_FORM_GNU_ref_alt:
5594 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5597 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5598 (int) (level * 2), "", dwarf_attr_name (attr),
5599 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5602 case DW_FORM_ref_sig8:
5605 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5606 (int) (level * 2), "", dwarf_attr_name (attr),
5607 dwarf_form_name (form),
5608 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5611 case DW_FORM_sec_offset:
5617 case DW_FORM_data1:;
5619 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5622 const char *valuestr = NULL;
5625 /* This case can take either a constant or a loclistptr. */
5626 case DW_AT_data_member_location:
5627 if (form != DW_FORM_sec_offset
5628 && (cbargs->version >= 4
5629 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5631 if (!cbargs->silent)
5632 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5633 (int) (level * 2), "", dwarf_attr_name (attr),
5634 dwarf_form_name (form), (uintmax_t) num);
5637 /* else fallthrough */
5639 /* These cases always take a loclistptr and no constant. */
5640 case DW_AT_location:
5641 case DW_AT_data_location:
5642 case DW_AT_vtable_elem_location:
5643 case DW_AT_string_length:
5644 case DW_AT_use_location:
5645 case DW_AT_frame_base:
5646 case DW_AT_return_addr:
5647 case DW_AT_static_link:
5648 case DW_AT_GNU_call_site_value:
5649 case DW_AT_GNU_call_site_data_value:
5650 case DW_AT_GNU_call_site_target:
5651 case DW_AT_GNU_call_site_target_clobbered:
5652 notice_listptr (section_loc, &known_loclistptr,
5653 cbargs->addrsize, cbargs->offset_size,
5655 if (!cbargs->silent)
5656 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5657 (int) (level * 2), "", dwarf_attr_name (attr),
5658 dwarf_form_name (form), (uintmax_t) num);
5662 notice_listptr (section_ranges, &known_rangelistptr,
5663 cbargs->addrsize, cbargs->offset_size,
5665 if (!cbargs->silent)
5666 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5667 (int) (level * 2), "", dwarf_attr_name (attr),
5668 dwarf_form_name (form), (uintmax_t) num);
5671 case DW_AT_language:
5672 valuestr = dwarf_lang_name (num);
5674 case DW_AT_encoding:
5675 valuestr = dwarf_encoding_name (num);
5677 case DW_AT_accessibility:
5678 valuestr = dwarf_access_name (num);
5680 case DW_AT_visibility:
5681 valuestr = dwarf_visibility_name (num);
5683 case DW_AT_virtuality:
5684 valuestr = dwarf_virtuality_name (num);
5686 case DW_AT_identifier_case:
5687 valuestr = dwarf_identifier_case_name (num);
5689 case DW_AT_calling_convention:
5690 valuestr = dwarf_calling_convention_name (num);
5693 valuestr = dwarf_inline_name (num);
5695 case DW_AT_ordering:
5696 valuestr = dwarf_ordering_name (num);
5698 case DW_AT_discr_list:
5699 valuestr = dwarf_discr_list_name (num);
5709 /* When highpc is in constant form it is relative to lowpc.
5710 In that case also show the address. */
5712 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5714 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5716 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5717 (int) (level * 2), "", dwarf_attr_name (attr),
5718 dwarf_form_name (form), (uintmax_t) num, a);
5721 else if (valuestr == NULL)
5722 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
5723 (int) (level * 2), "", dwarf_attr_name (attr),
5724 dwarf_form_name (form), (uintmax_t) num);
5726 printf (" %*s%-20s (%s) %s (%" PRIuMAX ")\n",
5727 (int) (level * 2), "", dwarf_attr_name (attr),
5728 dwarf_form_name (form), valuestr, (uintmax_t) num);
5735 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5738 printf (" %*s%-20s (%s) %s\n",
5739 (int) (level * 2), "", dwarf_attr_name (attr),
5740 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5743 case DW_FORM_flag_present:
5746 printf (" %*s%-20s (%s) %s\n",
5747 (int) (level * 2), "", dwarf_attr_name (attr),
5748 dwarf_form_name (form), nl_langinfo (YESSTR));
5751 case DW_FORM_exprloc:
5752 case DW_FORM_block4:
5753 case DW_FORM_block2:
5754 case DW_FORM_block1:
5759 if (unlikely (dwarf_formblock (attrp, &block) != 0))
5762 printf (" %*s%-20s (%s) ",
5763 (int) (level * 2), "", dwarf_attr_name (attr),
5764 dwarf_form_name (form));
5769 if (form != DW_FORM_exprloc)
5771 print_block (block.length, block.data);
5776 case DW_AT_location:
5777 case DW_AT_data_location:
5778 case DW_AT_data_member_location:
5779 case DW_AT_vtable_elem_location:
5780 case DW_AT_string_length:
5781 case DW_AT_use_location:
5782 case DW_AT_frame_base:
5783 case DW_AT_return_addr:
5784 case DW_AT_static_link:
5785 case DW_AT_allocated:
5786 case DW_AT_associated:
5787 case DW_AT_bit_size:
5788 case DW_AT_bit_offset:
5789 case DW_AT_bit_stride:
5790 case DW_AT_byte_size:
5791 case DW_AT_byte_stride:
5793 case DW_AT_lower_bound:
5794 case DW_AT_upper_bound:
5795 case DW_AT_GNU_call_site_value:
5796 case DW_AT_GNU_call_site_data_value:
5797 case DW_AT_GNU_call_site_target:
5798 case DW_AT_GNU_call_site_target_clobbered:
5800 print_ops (cbargs->dwflmod, cbargs->dbg,
5801 12 + level * 2, 12 + level * 2,
5802 cbargs->version, cbargs->addrsize, cbargs->offset_size,
5803 attrp->cu, block.length, block.data);
5811 printf (" %*s%-20s (form: %#x) ???\n",
5812 (int) (level * 2), "", dwarf_attr_name (attr),
5821 print_debug_units (Dwfl_Module *dwflmod,
5822 Ebl *ebl, GElf_Ehdr *ehdr,
5823 Elf_Scn *scn, GElf_Shdr *shdr,
5824 Dwarf *dbg, bool debug_types)
5826 const bool silent = !(print_debug_sections & section_info);
5827 const char *secname = section_name (ebl, ehdr, shdr);
5831 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5832 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5834 /* If the section is empty we don't have to do anything. */
5835 if (!silent && shdr->sh_size == 0)
5839 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5841 Dwarf_Off offset = 0;
5843 /* New compilation unit. */
5846 Dwarf_Off abbroffset;
5853 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5854 &abbroffset, &addrsize, &offsize,
5855 debug_types ? &typesig : NULL,
5856 debug_types ? &typeoff : NULL) != 0)
5862 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5863 " Version: %" PRIu16 ", Abbreviation section offset: %"
5864 PRIu64 ", Address size: %" PRIu8
5865 ", Offset size: %" PRIu8
5866 "\n Type signature: %#" PRIx64
5867 ", Type offset: %#" PRIx64 "\n"),
5868 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5869 typesig, (uint64_t) typeoff);
5871 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5872 " Version: %" PRIu16 ", Abbreviation section offset: %"
5873 PRIu64 ", Address size: %" PRIu8
5874 ", Offset size: %" PRIu8 "\n"),
5875 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5878 struct attrcb_args args =
5884 .addrsize = addrsize,
5885 .offset_size = offsize
5892 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
5893 (dbg, offset, &dies[level]) == NULL))
5896 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
5897 " in section '%s': %s"),
5898 (uint64_t) offset, secname, dwarf_errmsg (-1));
5902 args.cu = dies[0].cu;
5906 offset = dwarf_dieoffset (&dies[level]);
5907 if (unlikely (offset == ~0ul))
5910 error (0, 0, gettext ("cannot get DIE offset: %s"),
5915 int tag = dwarf_tag (&dies[level]);
5916 if (unlikely (tag == DW_TAG_invalid))
5919 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
5920 " in section '%s': %s"),
5921 (uint64_t) offset, secname, dwarf_errmsg (-1));
5926 printf (" [%6" PRIx64 "] %*s%s\n",
5927 (uint64_t) offset, (int) (level * 2), "",
5928 dwarf_tag_name (tag));
5930 /* Print the attribute values. */
5932 args.die = &dies[level];
5933 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
5935 /* Make room for the next level's DIE. */
5936 if (level + 1 == maxdies)
5937 dies = (Dwarf_Die *) xrealloc (dies,
5939 * sizeof (Dwarf_Die));
5941 int res = dwarf_child (&dies[level], &dies[level + 1]);
5944 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
5948 if (unlikely (res == -1))
5951 error (0, 0, gettext ("cannot get next DIE: %s\n"),
5956 else if (unlikely (res < 0))
5959 error (0, 0, gettext ("cannot get next DIE: %s"),
5977 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5978 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5980 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
5984 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5985 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5987 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
5992 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5993 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5996 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
5997 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
5998 (uint64_t) shdr->sh_offset);
6001 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6004 Dwarf_Off ncuoffset = 0;
6006 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6007 NULL, NULL, NULL) == 0)
6010 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6015 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6018 printf (" CU [%" PRIx64 "] %s\n",
6019 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6020 printf (" line:col SBPE* disc isa op address"
6021 " (Statement Block Prologue Epilogue *End)\n");
6022 const char *last_file = "";
6023 for (size_t n = 0; n < nlines; n++)
6025 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6026 Dwarf_Word mtime, length;
6027 const char *file = dwarf_linesrc (line, &mtime, &length);
6028 if (strcmp (last_file, file) != 0)
6030 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6031 file, mtime, length);
6036 bool statement, endseq, block, prologue_end, epilogue_begin;
6037 unsigned int lineop, isa, disc;
6039 dwarf_lineaddr (line, &address);
6040 dwarf_lineno (line, &lineno);
6041 dwarf_linecol (line, &colno);
6042 dwarf_lineop_index (line, &lineop);
6043 dwarf_linebeginstatement (line, &statement);
6044 dwarf_lineendsequence (line, &endseq);
6045 dwarf_lineblock (line, &block);
6046 dwarf_lineprologueend (line, &prologue_end);
6047 dwarf_lineepiloguebegin (line, &epilogue_begin);
6048 dwarf_lineisa (line, &isa);
6049 dwarf_linediscriminator (line, &disc);
6051 /* End sequence is special, it is one byte past. */
6052 char *a = format_dwarf_addr (dwflmod, address_size,
6053 address - (endseq ? 1 : 0), address);
6054 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6056 (statement ? 'S' : ' '),
6057 (block ? 'B' : ' '),
6058 (prologue_end ? 'P' : ' '),
6059 (epilogue_begin ? 'E' : ' '),
6060 (endseq ? '*' : ' '),
6061 disc, isa, lineop, a);
6072 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6073 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6077 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6082 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6083 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6084 (uint64_t) shdr->sh_offset);
6086 if (shdr->sh_size == 0)
6089 /* There is no functionality in libdw to read the information in the
6090 way it is represented here. Hardcode the decoder. */
6091 Elf_Data *data = elf_getdata (scn, NULL);
6092 if (unlikely (data == NULL || data->d_buf == NULL))
6094 error (0, 0, gettext ("cannot get line data section data: %s"),
6099 const unsigned char *linep = (const unsigned char *) data->d_buf;
6100 const unsigned char *lineendp;
6103 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6105 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6107 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6109 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6110 unsigned int length = 4;
6111 if (unlikely (unit_length == 0xffffffff))
6113 if (unlikely (linep + 8 > lineendp))
6116 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6117 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6120 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6124 /* Check whether we have enough room in the section. */
6125 if (unit_length < 2 + length + 5 * 1
6126 || unlikely (linep + unit_length > lineendp))
6128 lineendp = linep + unit_length;
6130 /* The next element of the header is the version identifier. */
6131 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6133 /* Next comes the header length. */
6134 Dwarf_Word header_length;
6136 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6138 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6139 //const unsigned char *header_start = linep;
6141 /* Next the minimum instruction length. */
6142 uint_fast8_t minimum_instr_len = *linep++;
6144 /* Next the maximum operations per instruction, in version 4 format. */
6145 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6147 /* Then the flag determining the default value of the is_stmt
6149 uint_fast8_t default_is_stmt = *linep++;
6151 /* Now the line base. */
6152 int_fast8_t line_base = *((const int_fast8_t *) linep);
6155 /* And the line range. */
6156 uint_fast8_t line_range = *linep++;
6158 /* The opcode base. */
6159 uint_fast8_t opcode_base = *linep++;
6161 /* Print what we got so far. */
6162 printf (gettext ("\n"
6163 " Length: %" PRIu64 "\n"
6164 " DWARF version: %" PRIuFAST16 "\n"
6165 " Prologue length: %" PRIu64 "\n"
6166 " Minimum instruction length: %" PRIuFAST8 "\n"
6167 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6168 " Initial value if '%s': %" PRIuFAST8 "\n"
6169 " Line base: %" PRIdFAST8 "\n"
6170 " Line range: %" PRIuFAST8 "\n"
6171 " Opcode base: %" PRIuFAST8 "\n"
6174 (uint64_t) unit_length, version, (uint64_t) header_length,
6175 minimum_instr_len, max_ops_per_instr,
6176 "is_stmt", default_is_stmt, line_base,
6177 line_range, opcode_base);
6179 if (unlikely (linep + opcode_base - 1 >= lineendp))
6183 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6184 linep - (const unsigned char *) data->d_buf,
6185 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6189 int opcode_base_l10 = 1;
6190 unsigned int tmp = opcode_base;
6196 const uint8_t *standard_opcode_lengths = linep - 1;
6197 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6198 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6199 " [%*" PRIuFAST8 "] %hhu arguments\n",
6200 (int) linep[cnt - 1]),
6201 opcode_base_l10, cnt, linep[cnt - 1]);
6202 linep += opcode_base - 1;
6203 if (unlikely (linep >= lineendp))
6206 puts (gettext ("\nDirectory table:"));
6209 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6210 if (unlikely (endp == NULL))
6213 printf (" %s\n", (char *) linep);
6217 /* Skip the final NUL byte. */
6220 if (unlikely (linep >= lineendp))
6222 puts (gettext ("\nFile name table:\n"
6223 " Entry Dir Time Size Name"));
6224 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6226 /* First comes the file name. */
6227 char *fname = (char *) linep;
6228 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6229 if (unlikely (endp == NULL))
6233 /* Then the index. */
6234 unsigned int diridx;
6235 get_uleb128 (diridx, linep);
6237 /* Next comes the modification time. */
6239 get_uleb128 (mtime, linep);
6241 /* Finally the length of the file. */
6243 get_uleb128 (fsize, linep);
6245 printf (" %-5u %-5u %-9u %-9u %s\n",
6246 cnt, diridx, mtime, fsize, fname);
6248 /* Skip the final NUL byte. */
6251 puts (gettext ("\nLine number statements:"));
6252 Dwarf_Word address = 0;
6253 unsigned int op_index = 0;
6255 uint_fast8_t is_stmt = default_is_stmt;
6257 /* Default address value, in case we do not find the CU. */
6259 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6261 /* Determine the CU this block is for. */
6263 Dwarf_Off ncuoffset = 0;
6265 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6266 NULL, NULL, NULL) == 0)
6269 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6271 Dwarf_Attribute stmt_list;
6272 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6275 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6277 if (lineoff == start_offset)
6280 address_size = cudie.cu->address_size;
6285 /* Apply the "operation advance" from a special opcode
6286 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6287 unsigned int op_addr_advance;
6289 inline void advance_pc (unsigned int op_advance)
6291 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6292 / max_ops_per_instr);
6293 address += op_advance;
6294 show_op_index = (op_index > 0 ||
6295 (op_index + op_advance) % max_ops_per_instr > 0);
6296 op_index = (op_index + op_advance) % max_ops_per_instr;
6299 while (linep < lineendp)
6301 size_t offset = linep - (const unsigned char *) data->d_buf;
6305 /* Read the opcode. */
6306 unsigned int opcode = *linep++;
6308 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6309 /* Is this a special opcode? */
6310 if (likely (opcode >= opcode_base))
6312 /* Yes. Handling this is quite easy since the opcode value
6315 opcode = (desired line increment - line_base)
6316 + (line_range * address advance) + opcode_base
6318 int line_increment = (line_base
6319 + (opcode - opcode_base) % line_range);
6321 /* Perform the increments. */
6322 line += line_increment;
6323 advance_pc ((opcode - opcode_base) / line_range);
6325 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6328 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6329 opcode, op_addr_advance, a, op_index,
6330 line_increment, line);
6333 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6334 opcode, op_addr_advance, a, line_increment, line);
6337 else if (opcode == 0)
6339 /* This an extended opcode. */
6340 if (unlikely (linep + 2 > lineendp))
6344 unsigned int len = *linep++;
6346 if (unlikely (linep + len > lineendp))
6349 /* The sub-opcode. */
6352 printf (gettext (" extended opcode %u: "), opcode);
6356 case DW_LNE_end_sequence:
6357 puts (gettext (" end of sequence"));
6359 /* Reset the registers we care about. */
6363 is_stmt = default_is_stmt;
6366 case DW_LNE_set_address:
6368 if (address_size == 4)
6369 address = read_4ubyte_unaligned_inc (dbg, linep);
6371 address = read_8ubyte_unaligned_inc (dbg, linep);
6373 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6374 printf (gettext (" set address to %s\n"), a);
6379 case DW_LNE_define_file:
6381 char *fname = (char *) linep;
6382 unsigned char *endp = memchr (linep, '\0',
6384 if (unlikely (endp == NULL))
6388 unsigned int diridx;
6389 get_uleb128 (diridx, linep);
6391 get_uleb128 (mtime, linep);
6392 Dwarf_Word filelength;
6393 get_uleb128 (filelength, linep);
6396 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6397 diridx, (uint64_t) mtime, (uint64_t) filelength,
6402 case DW_LNE_set_discriminator:
6403 /* Takes one ULEB128 parameter, the discriminator. */
6404 if (unlikely (standard_opcode_lengths[opcode] != 1))
6407 get_uleb128 (u128, linep);
6408 printf (gettext (" set discriminator to %u\n"), u128);
6412 /* Unknown, ignore it. */
6413 puts (gettext (" unknown opcode"));
6418 else if (opcode <= DW_LNS_set_isa)
6420 /* This is a known standard opcode. */
6424 /* Takes no argument. */
6425 puts (gettext (" copy"));
6428 case DW_LNS_advance_pc:
6429 /* Takes one uleb128 parameter which is added to the
6431 get_uleb128 (u128, linep);
6434 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6437 advance address by %u to %s, op_index to %u\n"),
6438 op_addr_advance, a, op_index);
6440 printf (gettext (" advance address by %u to %s\n"),
6441 op_addr_advance, a);
6446 case DW_LNS_advance_line:
6447 /* Takes one sleb128 parameter which is added to the
6449 get_sleb128 (s128, linep);
6452 advance line by constant %d to %" PRId64 "\n"),
6453 s128, (int64_t) line);
6456 case DW_LNS_set_file:
6457 /* Takes one uleb128 parameter which is stored in file. */
6458 get_uleb128 (u128, linep);
6459 printf (gettext (" set file to %" PRIu64 "\n"),
6463 case DW_LNS_set_column:
6464 /* Takes one uleb128 parameter which is stored in column. */
6465 if (unlikely (standard_opcode_lengths[opcode] != 1))
6468 get_uleb128 (u128, linep);
6469 printf (gettext (" set column to %" PRIu64 "\n"),
6473 case DW_LNS_negate_stmt:
6474 /* Takes no argument. */
6475 is_stmt = 1 - is_stmt;
6476 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6477 "is_stmt", is_stmt);
6480 case DW_LNS_set_basic_block:
6481 /* Takes no argument. */
6482 puts (gettext (" set basic block flag"));
6485 case DW_LNS_const_add_pc:
6486 /* Takes no argument. */
6487 advance_pc ((255 - opcode_base) / line_range);
6489 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6492 advance address by constant %u to %s, op_index to %u\n"),
6493 op_addr_advance, a, op_index);
6496 advance address by constant %u to %s\n"),
6497 op_addr_advance, a);
6502 case DW_LNS_fixed_advance_pc:
6503 /* Takes one 16 bit parameter which is added to the
6505 if (unlikely (standard_opcode_lengths[opcode] != 1))
6508 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6512 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6514 advance address by fixed value %u to %s\n"),
6520 case DW_LNS_set_prologue_end:
6521 /* Takes no argument. */
6522 puts (gettext (" set prologue end flag"));
6525 case DW_LNS_set_epilogue_begin:
6526 /* Takes no argument. */
6527 puts (gettext (" set epilogue begin flag"));
6530 case DW_LNS_set_isa:
6531 /* Takes one uleb128 parameter which is stored in isa. */
6532 if (unlikely (standard_opcode_lengths[opcode] != 1))
6535 get_uleb128 (u128, linep);
6536 printf (gettext (" set isa to %u\n"), u128);
6542 /* This is a new opcode the generator but not we know about.
6543 Read the parameters associated with it but then discard
6544 everything. Read all the parameters for this opcode. */
6545 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6546 " unknown opcode with %" PRIu8 " parameters:",
6547 standard_opcode_lengths[opcode]),
6548 standard_opcode_lengths[opcode]);
6549 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6551 get_uleb128 (u128, linep);
6552 if (n != standard_opcode_lengths[opcode])
6553 putc_unlocked (',', stdout);
6554 printf (" %u", u128);
6557 /* Next round, ignore this opcode. */
6563 /* There must only be one data block. */
6564 assert (elf_getdata (scn, data) == NULL);
6569 print_debug_loc_section (Dwfl_Module *dwflmod,
6570 Ebl *ebl, GElf_Ehdr *ehdr,
6571 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6573 Elf_Data *data = elf_rawdata (scn, NULL);
6575 if (unlikely (data == NULL))
6577 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6583 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6584 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6585 (uint64_t) shdr->sh_offset);
6587 sort_listptr (&known_loclistptr, "loclistptr");
6588 size_t listptr_idx = 0;
6590 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6591 uint_fast8_t offset_size = 4;
6594 struct Dwarf_CU *cu = NULL;
6595 Dwarf_Addr base = 0;
6596 unsigned char *readp = data->d_buf;
6597 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6598 while (readp < endp)
6600 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6602 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6603 &address_size, &offset_size, &base,
6604 &cu, offset, &readp, endp))
6607 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6609 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6615 if (address_size == 8)
6617 begin = read_8ubyte_unaligned_inc (dbg, readp);
6618 end = read_8ubyte_unaligned_inc (dbg, readp);
6622 begin = read_4ubyte_unaligned_inc (dbg, readp);
6623 end = read_4ubyte_unaligned_inc (dbg, readp);
6624 if (begin == (Dwarf_Addr) (uint32_t) -1)
6625 begin = (Dwarf_Addr) -1l;
6628 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6630 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6631 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6635 else if (begin == 0 && end == 0) /* End of list entry. */
6638 printf (gettext (" [%6tx] empty list\n"), offset);
6643 /* We have a location expression entry. */
6644 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6646 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6648 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6651 if (first) /* First entry in a list. */
6652 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6654 printf (gettext (" %s..%s"), b, e);
6659 if (endp - readp <= (ptrdiff_t) len)
6661 fputs (gettext (" <INVALID DATA>\n"), stdout);
6665 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6666 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6679 struct mac_culist *next;
6684 mac_compare (const void *p1, const void *p2)
6686 struct mac_culist *m1 = (struct mac_culist *) p1;
6687 struct mac_culist *m2 = (struct mac_culist *) p2;
6689 if (m1->offset < m2->offset)
6691 if (m1->offset > m2->offset)
6698 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6699 Ebl *ebl, GElf_Ehdr *ehdr,
6700 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6703 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6704 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6705 (uint64_t) shdr->sh_offset);
6706 putc_unlocked ('\n', stdout);
6708 /* There is no function in libdw to iterate over the raw content of
6709 the section but it is easy enough to do. */
6710 Elf_Data *data = elf_getdata (scn, NULL);
6711 if (unlikely (data == NULL || data->d_buf == NULL))
6713 error (0, 0, gettext ("cannot get macro information section data: %s"),
6718 /* Get the source file information for all CUs. */
6722 struct mac_culist *culist = NULL;
6724 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6727 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6730 Dwarf_Attribute attr;
6731 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6735 if (dwarf_formudata (&attr, &macoff) != 0)
6738 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6740 newp->offset = macoff;
6742 newp->next = culist;
6747 /* Convert the list into an array for easier consumption. */
6748 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6751 cus[nculist].offset = data->d_size;
6754 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6756 assert (cnt < nculist);
6758 culist = culist->next;
6761 /* Sort the array according to the offset in the .debug_macinfo
6762 section. Note we keep the sentinel at the end. */
6763 qsort (cus, nculist, sizeof (*cus), mac_compare);
6766 const unsigned char *readp = (const unsigned char *) data->d_buf;
6767 const unsigned char *readendp = readp + data->d_size;
6770 while (readp < readendp)
6772 unsigned int opcode = *readp++;
6774 unsigned int u128_2;
6775 const unsigned char *endp;
6779 case DW_MACINFO_define:
6780 case DW_MACINFO_undef:
6781 case DW_MACINFO_vendor_ext:
6782 /* For the first two opcodes the parameters are
6786 We can treat these cases together. */
6787 get_uleb128 (u128, readp);
6789 endp = memchr (readp, '\0', readendp - readp);
6790 if (unlikely (endp == NULL))
6793 %*s*** non-terminated string at end of section"),
6798 if (opcode == DW_MACINFO_define)
6799 printf ("%*s#define %s, line %u\n",
6800 level, "", (char *) readp, u128);
6801 else if (opcode == DW_MACINFO_undef)
6802 printf ("%*s#undef %s, line %u\n",
6803 level, "", (char *) readp, u128);
6805 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6810 case DW_MACINFO_start_file:
6811 /* The two parameters are line and file index, in this order. */
6812 get_uleb128 (u128, readp);
6813 get_uleb128 (u128_2, readp);
6815 /* Find the CU DIE for this file. */
6816 size_t macoff = readp - (const unsigned char *) data->d_buf;
6817 const char *fname = "???";
6818 if (macoff >= cus[0].offset)
6820 while (macoff >= cus[1].offset)
6823 if (cus[0].files == NULL
6824 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6825 cus[0].files = (Dwarf_Files *) -1l;
6827 if (cus[0].files != (Dwarf_Files *) -1l)
6828 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6832 printf ("%*sstart_file %u, [%u] %s\n",
6833 level, "", u128, u128_2, fname);
6837 case DW_MACINFO_end_file:
6839 printf ("%*send_file\n", level, "");
6840 /* Nothing more to do. */
6844 // XXX gcc seems to generate files with a trailing zero.
6845 if (unlikely (opcode != 0 || readp != readendp))
6846 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6854 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6855 Ebl *ebl, GElf_Ehdr *ehdr,
6856 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6859 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6860 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6861 (uint64_t) shdr->sh_offset);
6862 putc_unlocked ('\n', stdout);
6864 Elf_Data *data = elf_getdata (scn, NULL);
6865 if (unlikely (data == NULL || data->d_buf == NULL))
6867 error (0, 0, gettext ("cannot get macro information section data: %s"),
6872 /* Get the source file information for all CUs. Uses same
6873 datastructure as macinfo. But uses offset field to directly
6874 match .debug_line offset. And just stored in a list. */
6878 struct mac_culist *culist = NULL;
6880 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6883 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6886 Dwarf_Attribute attr;
6887 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
6891 if (dwarf_formudata (&attr, &lineoff) != 0)
6894 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6896 newp->offset = lineoff;
6898 newp->next = culist;
6903 const unsigned char *readp = (const unsigned char *) data->d_buf;
6904 const unsigned char *readendp = readp + data->d_size;
6906 while (readp < readendp)
6908 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
6909 (uint64_t) (readp - (const unsigned char *) data->d_buf));
6911 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
6912 // optional vendor extension macro entry table.
6913 if (readp + 2 > readendp)
6916 error (0, 0, gettext ("invalid data"));
6919 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
6920 printf (gettext (" Version: %" PRIu16 "\n"), vers);
6922 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
6923 // 5 when it gets standardized.
6926 printf (gettext (" unknown version, cannot parse section\n"));
6930 if (readp + 1 > readendp)
6932 const unsigned char flag = *readp++;
6933 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
6935 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
6936 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
6937 Dwarf_Off line_offset = -1;
6940 if (offset_len == 8)
6941 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
6943 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
6944 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
6948 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
6949 memset (vendor, 0, sizeof vendor);
6952 // 1 byte length, for each item, 1 byte opcode, uleb128 number
6953 // of arguments, for each argument 1 byte form code.
6954 if (readp + 1 > readendp)
6956 unsigned int tlen = *readp++;
6957 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
6959 for (unsigned int i = 0; i < tlen; i++)
6961 if (readp + 1 > readendp)
6963 unsigned int opcode = *readp++;
6964 printf (gettext (" [%" PRIx8 "]"), opcode);
6965 if (opcode < DW_MACRO_GNU_lo_user
6966 || opcode > DW_MACRO_GNU_hi_user)
6968 // Record the start of description for this vendor opcode.
6969 // uleb128 nr args, 1 byte per arg form.
6970 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
6971 if (readp + 1 > readendp)
6973 unsigned int args = *readp++;
6976 printf (gettext (" %" PRIu8 " arguments:"), args);
6979 if (readp + 1 > readendp)
6981 unsigned int form = *readp++;
6982 printf (" %s", dwarf_form_string (form));
6983 if (form != DW_FORM_data1
6984 && form != DW_FORM_data2
6985 && form != DW_FORM_data4
6986 && form != DW_FORM_data8
6987 && form != DW_FORM_sdata
6988 && form != DW_FORM_udata
6989 && form != DW_FORM_block
6990 && form != DW_FORM_block1
6991 && form != DW_FORM_block2
6992 && form != DW_FORM_block4
6993 && form != DW_FORM_flag
6994 && form != DW_FORM_string
6995 && form != DW_FORM_strp
6996 && form != DW_FORM_sec_offset)
7000 putchar_unlocked (',');
7004 printf (gettext (" no arguments."));
7005 putchar_unlocked ('\n');
7008 putchar_unlocked ('\n');
7011 if (readp + 1 > readendp)
7013 unsigned int opcode = *readp++;
7017 unsigned int u128_2;
7018 const unsigned char *endp;
7023 case DW_MACRO_GNU_start_file:
7024 get_uleb128 (u128, readp);
7025 get_uleb128 (u128_2, readp);
7027 /* Find the CU DIE that matches this line offset. */
7028 const char *fname = "???";
7029 if (line_offset != (Dwarf_Off) -1)
7031 struct mac_culist *cu = culist;
7032 while (cu != NULL && line_offset != cu->offset)
7036 if (cu->files == NULL
7037 && dwarf_getsrcfiles (&cu->die, &cu->files,
7039 cu->files = (Dwarf_Files *) -1l;
7041 if (cu->files != (Dwarf_Files *) -1l)
7042 fname = (dwarf_filesrc (cu->files, u128_2,
7043 NULL, NULL) ?: "???");
7046 printf ("%*sstart_file %u, [%u] %s\n",
7047 level, "", u128, u128_2, fname);
7051 case DW_MACRO_GNU_end_file:
7053 printf ("%*send_file\n", level, "");
7056 case DW_MACRO_GNU_define:
7057 get_uleb128 (u128, readp);
7058 endp = memchr (readp, '\0', readendp - readp);
7061 printf ("%*s#define %s, line %u\n",
7062 level, "", readp, u128);
7066 case DW_MACRO_GNU_undef:
7067 get_uleb128 (u128, readp);
7068 endp = memchr (readp, '\0', readendp - readp);
7071 printf ("%*s#undef %s, line %u\n",
7072 level, "", readp, u128);
7076 case DW_MACRO_GNU_define_indirect:
7077 get_uleb128 (u128, readp);
7078 if (readp + offset_len > readendp)
7080 if (offset_len == 8)
7081 off = read_8ubyte_unaligned_inc (dbg, readp);
7083 off = read_4ubyte_unaligned_inc (dbg, readp);
7084 printf ("%*s#define %s, line %u (indirect)\n",
7085 level, "", dwarf_getstring (dbg, off, NULL), u128);
7088 case DW_MACRO_GNU_undef_indirect:
7089 get_uleb128 (u128, readp);
7090 if (readp + offset_len > readendp)
7092 if (offset_len == 8)
7093 off = read_8ubyte_unaligned_inc (dbg, readp);
7095 off = read_4ubyte_unaligned_inc (dbg, readp);
7096 printf ("%*s#undef %s, line %u (indirect)\n",
7097 level, "", dwarf_getstring (dbg, off, NULL), u128);
7100 case DW_MACRO_GNU_transparent_include:
7101 if (readp + offset_len > readendp)
7103 if (offset_len == 8)
7104 off = read_8ubyte_unaligned_inc (dbg, readp);
7106 off = read_4ubyte_unaligned_inc (dbg, readp);
7107 printf ("%*s#include offset 0x%" PRIx64 "\n",
7112 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7113 if (opcode < DW_MACRO_GNU_lo_user
7114 || opcode > DW_MACRO_GNU_lo_user
7115 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7118 const unsigned char *op_desc;
7119 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7121 // Just skip the arguments, we cannot really interpret them,
7122 // but print as much as we can.
7123 unsigned int args = *op_desc++;
7126 unsigned int form = *op_desc++;
7131 if (readp + 1 > readendp)
7134 printf (" %" PRIx8, (unsigned int) val);
7138 if (readp + 2 > readendp)
7140 val = read_2ubyte_unaligned_inc (dbg, readp);
7141 printf(" %" PRIx16, (unsigned int) val);
7145 if (readp + 4 > readendp)
7147 val = read_4ubyte_unaligned_inc (dbg, readp);
7148 printf (" %" PRIx32, (unsigned int) val);
7152 if (readp + 8 > readendp)
7154 val = read_8ubyte_unaligned_inc (dbg, readp);
7155 printf (" %" PRIx64, val);
7159 get_sleb128 (val, readp);
7160 printf (" %" PRIx64, val);
7164 get_uleb128 (val, readp);
7165 printf (" %" PRIx64, val);
7169 get_uleb128 (val, readp);
7170 printf (" block[%" PRIu64 "]", val);
7171 if (readp + val > readendp)
7176 case DW_FORM_block1:
7177 if (readp + 1 > readendp)
7180 printf (" block[%" PRIu64 "]", val);
7181 if (readp + val > readendp)
7185 case DW_FORM_block2:
7186 if (readp + 2 > readendp)
7188 val = read_2ubyte_unaligned_inc (dbg, readp);
7189 printf (" block[%" PRIu64 "]", val);
7190 if (readp + val > readendp)
7194 case DW_FORM_block4:
7195 if (readp + 2 > readendp)
7197 val =read_4ubyte_unaligned_inc (dbg, readp);
7198 printf (" block[%" PRIu64 "]", val);
7199 if (readp + val > readendp)
7204 if (readp + 1 > readendp)
7207 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7210 case DW_FORM_string:
7211 endp = memchr (readp, '\0', readendp - readp);
7214 printf (" %s", readp);
7219 if (readp + offset_len > readendp)
7221 if (offset_len == 8)
7222 val = read_8ubyte_unaligned_inc (dbg, readp);
7224 val = read_4ubyte_unaligned_inc (dbg, readp);
7225 printf (" %s", dwarf_getstring (dbg, val, NULL));
7228 case DW_FORM_sec_offset:
7229 if (readp + offset_len > readendp)
7231 if (offset_len == 8)
7232 val = read_8ubyte_unaligned_inc (dbg, readp);
7234 val = read_4ubyte_unaligned_inc (dbg, readp);
7235 printf (" %" PRIx64, val);
7239 error (0, 0, gettext ("vendor opcode not verified?"));
7245 putchar_unlocked (',');
7247 putchar_unlocked ('\n');
7250 if (readp + 1 > readendp)
7254 putchar_unlocked ('\n');
7260 /* Callback for printing global names. */
7262 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7265 int *np = (int *) arg;
7267 printf (gettext (" [%5d] DIE offset: %6" PRId64
7268 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7269 (*np)++, global->die_offset, global->cu_offset, global->name);
7275 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7277 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7278 Ebl *ebl, GElf_Ehdr *ehdr,
7279 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7281 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7282 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7283 (uint64_t) shdr->sh_offset);
7286 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7289 /* Print the content of the DWARF string section '.debug_str'. */
7291 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7292 Ebl *ebl, GElf_Ehdr *ehdr,
7293 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7295 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7296 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7298 /* Compute floor(log16(shdr->sh_size)). */
7299 GElf_Addr tmp = sh_size;
7306 digits = MAX (4, digits);
7308 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7311 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7312 /* TRANS: the debugstr| prefix makes the string unique. */
7313 digits + 2, sgettext ("debugstr|Offset"));
7315 Dwarf_Off offset = 0;
7316 while (offset < sh_size)
7319 const char *str = dwarf_getstring (dbg, offset, &len);
7320 if (unlikely (str == NULL))
7322 printf (gettext (" *** error while reading strings: %s\n"),
7327 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7334 /* Print the content of the call frame search table section
7337 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7338 Ebl *ebl __attribute__ ((unused)),
7339 GElf_Ehdr *ehdr __attribute__ ((unused)),
7340 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7343 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7346 Elf_Data *data = elf_rawdata (scn, NULL);
7348 if (unlikely (data == NULL))
7350 error (0, 0, gettext ("cannot get %s content: %s"),
7351 ".eh_frame_hdr", elf_errmsg (-1));
7355 const unsigned char *readp = data->d_buf;
7356 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7359 if (unlikely (readp + 4 > dataend))
7362 error (0, 0, gettext ("invalid data"));
7366 unsigned int version = *readp++;
7367 unsigned int eh_frame_ptr_enc = *readp++;
7368 unsigned int fde_count_enc = *readp++;
7369 unsigned int table_enc = *readp++;
7371 printf (" version: %u\n"
7372 " eh_frame_ptr_enc: %#x ",
7373 version, eh_frame_ptr_enc);
7374 print_encoding_base ("", eh_frame_ptr_enc);
7375 printf (" fde_count_enc: %#x ", fde_count_enc);
7376 print_encoding_base ("", fde_count_enc);
7377 printf (" table_enc: %#x ", table_enc);
7378 print_encoding_base ("", table_enc);
7380 uint64_t eh_frame_ptr = 0;
7381 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7383 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7385 if (unlikely (readp == NULL))
7388 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7389 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7390 printf (" (offset: %#" PRIx64 ")",
7391 /* +4 because of the 4 byte header of the section. */
7392 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7394 putchar_unlocked ('\n');
7397 uint64_t fde_count = 0;
7398 if (fde_count_enc != DW_EH_PE_omit)
7400 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7401 if (unlikely (readp == NULL))
7404 printf (" fde_count: %" PRIu64 "\n", fde_count);
7407 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7412 /* Optimize for the most common case. */
7413 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7414 while (fde_count > 0 && readp + 8 <= dataend)
7416 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7417 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7418 + (int64_t) initial_location);
7419 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7420 // XXX Possibly print symbol name or section offset for initial_offset
7421 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7422 " fde=[%6" PRIx64 "]\n",
7423 initial_location, initial_offset,
7424 address, address - (eh_frame_ptr + 4));
7427 while (0 && readp < dataend)
7434 /* Print the content of the exception handling table section
7437 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7438 Ebl *ebl __attribute__ ((unused)),
7439 GElf_Ehdr *ehdr __attribute__ ((unused)),
7441 GElf_Shdr *shdr __attribute__ ((unused)),
7442 Dwarf *dbg __attribute__ ((unused)))
7445 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7448 Elf_Data *data = elf_rawdata (scn, NULL);
7450 if (unlikely (data == NULL))
7452 error (0, 0, gettext ("cannot get %s content: %s"),
7453 ".gcc_except_table", elf_errmsg (-1));
7457 const unsigned char *readp = data->d_buf;
7458 const unsigned char *const dataend = readp + data->d_size;
7460 if (unlikely (readp + 1 > dataend))
7463 error (0, 0, gettext ("invalid data"));
7466 unsigned int lpstart_encoding = *readp++;
7467 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7468 print_encoding_base ("", lpstart_encoding);
7469 if (lpstart_encoding != DW_EH_PE_omit)
7472 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7473 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7476 if (unlikely (readp + 1 > dataend))
7478 unsigned int ttype_encoding = *readp++;
7479 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7480 print_encoding_base ("", ttype_encoding);
7481 const unsigned char *ttype_base = NULL;
7482 if (ttype_encoding != DW_EH_PE_omit)
7484 unsigned int ttype_base_offset;
7485 get_uleb128 (ttype_base_offset, readp);
7486 printf (" TType base offset: %#x\n", ttype_base_offset);
7487 ttype_base = readp + ttype_base_offset;
7490 if (unlikely (readp + 1 > dataend))
7492 unsigned int call_site_encoding = *readp++;
7493 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7494 print_encoding_base ("", call_site_encoding);
7495 unsigned int call_site_table_len;
7496 get_uleb128 (call_site_table_len, readp);
7498 const unsigned char *const action_table = readp + call_site_table_len;
7499 if (unlikely (action_table > dataend))
7502 unsigned int max_action = 0;
7503 while (readp < action_table)
7506 puts (gettext ("\n Call site table:"));
7508 uint64_t call_site_start;
7509 readp = read_encoded (call_site_encoding, readp, dataend,
7510 &call_site_start, dbg);
7511 uint64_t call_site_length;
7512 readp = read_encoded (call_site_encoding, readp, dataend,
7513 &call_site_length, dbg);
7514 uint64_t landing_pad;
7515 readp = read_encoded (call_site_encoding, readp, dataend,
7517 unsigned int action;
7518 get_uleb128 (action, readp);
7519 max_action = MAX (action, max_action);
7520 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7521 " Call site length: %" PRIu64 "\n"
7522 " Landing pad: %#" PRIx64 "\n"
7524 u++, call_site_start, call_site_length, landing_pad, action);
7526 assert (readp == action_table);
7528 unsigned int max_ar_filter = 0;
7531 puts ("\n Action table:");
7533 const unsigned char *const action_table_end
7534 = action_table + max_action + 1;
7540 get_sleb128 (ar_filter, readp);
7541 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7542 max_ar_filter = ar_filter;
7544 get_sleb128 (ar_disp, readp);
7546 printf (" [%4u] ar_filter: % d\n"
7548 u, ar_filter, ar_disp);
7549 if (abs (ar_disp) & 1)
7550 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7551 else if (ar_disp != 0)
7554 putchar_unlocked ('\n');
7557 while (readp < action_table_end);
7560 if (max_ar_filter > 0)
7562 puts ("\n TType table:");
7564 // XXX Not *4, size of encoding;
7565 switch (ttype_encoding & 7)
7567 case DW_EH_PE_udata2:
7568 case DW_EH_PE_sdata2:
7569 readp = ttype_base - max_ar_filter * 2;
7571 case DW_EH_PE_udata4:
7572 case DW_EH_PE_sdata4:
7573 readp = ttype_base - max_ar_filter * 4;
7575 case DW_EH_PE_udata8:
7576 case DW_EH_PE_sdata8:
7577 readp = ttype_base - max_ar_filter * 8;
7580 error (1, 0, gettext ("invalid TType encoding"));
7586 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7588 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7590 while (readp < ttype_base);
7594 /* Print the content of the '.gdb_index' section.
7595 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7598 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7599 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7601 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7602 " contains %" PRId64 " bytes :\n"),
7603 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7604 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7606 Elf_Data *data = elf_rawdata (scn, NULL);
7608 if (unlikely (data == NULL))
7610 error (0, 0, gettext ("cannot get %s content: %s"),
7611 ".gdb_index", elf_errmsg (-1));
7615 // .gdb_index is always in little endian.
7616 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7619 const unsigned char *readp = data->d_buf;
7620 const unsigned char *const dataend = readp + data->d_size;
7622 if (unlikely (readp + 4 > dataend))
7625 error (0, 0, gettext ("invalid data"));
7629 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7630 printf (gettext (" Version: %" PRId32 "\n"), vers);
7632 // The only difference between version 4 and version 5 is the
7633 // hash used for generating the table. Version 6 contains symbols
7634 // for inlined functions, older versions didn't. Version 7 adds
7635 // symbol kinds. Version 8 just indicates that it correctly includes
7637 if (vers < 4 || vers > 8)
7639 printf (gettext (" unknown version, cannot parse section\n"));
7644 if (unlikely (readp + 4 > dataend))
7647 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7648 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7651 if (unlikely (readp + 4 > dataend))
7654 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7655 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7658 if (unlikely (readp + 4 > dataend))
7661 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7662 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
7665 if (unlikely (readp + 4 > dataend))
7668 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7669 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
7672 if (unlikely (readp + 4 > dataend))
7675 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7676 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7678 readp = data->d_buf + cu_off;
7680 const unsigned char *nextp = data->d_buf + tu_off;
7681 size_t cu_nr = (nextp - readp) / 16;
7683 printf (gettext ("\n CU list at offset %#" PRIx32
7684 " contains %zu entries:\n"),
7688 while (readp + 16 <= dataend && n < cu_nr)
7690 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7693 uint64_t len = read_8ubyte_unaligned (dbg, readp);
7696 printf (" [%4zu] start: %0#8" PRIx64
7697 ", length: %5" PRIu64 "\n", n, off, len);
7701 readp = data->d_buf + tu_off;
7702 nextp = data->d_buf + addr_off;
7703 size_t tu_nr = (nextp - readp) / 24;
7705 printf (gettext ("\n TU list at offset %#" PRIx32
7706 " contains %zu entries:\n"),
7710 while (readp + 24 <= dataend && n < tu_nr)
7712 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7715 uint64_t type = read_8ubyte_unaligned (dbg, readp);
7718 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7721 printf (" [%4zu] CU offset: %5" PRId64
7722 ", type offset: %5" PRId64
7723 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7727 readp = data->d_buf + addr_off;
7728 nextp = data->d_buf + sym_off;
7729 size_t addr_nr = (nextp - readp) / 20;
7731 printf (gettext ("\n Address list at offset %#" PRIx32
7732 " contains %zu entries:\n"),
7736 while (readp + 20 <= dataend && n < addr_nr)
7738 uint64_t low = read_8ubyte_unaligned (dbg, readp);
7741 uint64_t high = read_8ubyte_unaligned (dbg, readp);
7744 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7747 char *l = format_dwarf_addr (dwflmod, 8, low, low);
7748 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7749 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7756 readp = data->d_buf + sym_off;
7757 nextp = data->d_buf + const_off;
7758 size_t sym_nr = (nextp - readp) / 8;
7760 printf (gettext ("\n Symbol table at offset %#" PRIx32
7761 " contains %zu slots:\n"),
7765 while (readp + 8 <= dataend && n < sym_nr)
7767 uint32_t name = read_4ubyte_unaligned (dbg, readp);
7770 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7773 if (name != 0 || vector != 0)
7775 const unsigned char *sym = data->d_buf + const_off + name;
7776 if (unlikely (sym > dataend))
7779 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7781 const unsigned char *readcus = data->d_buf + const_off + vector;
7782 if (unlikely (readcus + 8 > dataend))
7785 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7788 uint32_t cu_kind, cu, kind;
7791 cu_kind = read_4ubyte_unaligned (dbg, readcus);
7792 cu = cu_kind & ((1 << 24) - 1);
7793 kind = (cu_kind >> 28) & 7;
7794 is_static = cu_kind & (1 << 31);
7796 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
7798 printf ("%" PRId32, cu);
7817 printf ("unknown-0x%" PRIx32, kind);
7820 printf (":%c)", (is_static ? 'S' : 'G'));
7832 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7834 /* Before we start the real work get a debug context descriptor. */
7836 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7840 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7844 if ((print_debug_sections & ~section_exception) != 0)
7845 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7847 if ((print_debug_sections & section_exception) == 0)
7852 /* Get the section header string table index. */
7854 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7855 error (EXIT_FAILURE, 0,
7856 gettext ("cannot get section header string table index"));
7858 /* Look through all the sections for the debugging sections to print. */
7859 Elf_Scn *scn = NULL;
7860 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7863 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7865 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7870 enum section_e bitmask;
7871 void (*fp) (Dwfl_Module *, Ebl *,
7872 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7873 } debug_sections[] =
7875 #define NEW_SECTION(name) \
7876 { ".debug_" #name, section_##name, print_debug_##name##_section }
7877 NEW_SECTION (abbrev),
7878 NEW_SECTION (aranges),
7879 NEW_SECTION (frame),
7881 NEW_SECTION (types),
7884 NEW_SECTION (pubnames),
7886 NEW_SECTION (macinfo),
7887 NEW_SECTION (macro),
7888 NEW_SECTION (ranges),
7889 { ".eh_frame", section_frame | section_exception,
7890 print_debug_frame_section },
7891 { ".eh_frame_hdr", section_frame | section_exception,
7892 print_debug_frame_hdr_section },
7893 { ".gcc_except_table", section_frame | section_exception,
7894 print_debug_exception_table },
7895 { ".gdb_index", section_gdb_index, print_gdb_index_section }
7897 const int ndebug_sections = (sizeof (debug_sections)
7898 / sizeof (debug_sections[0]));
7899 const char *name = elf_strptr (ebl->elf, shstrndx,
7903 for (n = 0; n < ndebug_sections; ++n)
7904 if (strcmp (name, debug_sections[n].name) == 0
7906 || (name[0] == '.' && name[1] == 'z'
7907 && debug_sections[n].name[1] == 'd'
7908 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
7912 if ((print_debug_sections | implicit_debug_sections)
7913 & debug_sections[n].bitmask)
7914 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
7920 reset_listptr (&known_loclistptr);
7921 reset_listptr (&known_rangelistptr);
7925 #define ITEM_INDENT 4
7926 #define WRAP_COLUMN 75
7928 /* Print "NAME: FORMAT", wrapping when output text would make the line
7929 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
7930 but this function is also used for registers which should be printed
7931 aligned. Fortunately registers output uses fixed fields width (such
7932 as %11d) for the alignment.
7934 Line breaks should not depend on the particular values although that
7935 may happen in some cases of the core items. */
7938 __attribute__ ((format (printf, 6, 7)))
7939 print_core_item (unsigned int colno, char sep, unsigned int wrap,
7940 size_t name_width, const char *name, const char *format, ...)
7942 size_t len = strlen (name);
7943 if (name_width < len)
7948 va_start (ap, format);
7949 int out_len = vasprintf (&out, format, ap);
7952 error (EXIT_FAILURE, 0, _("memory exhausted"));
7954 size_t n = name_width + sizeof ": " - 1 + out_len;
7958 printf ("%*s", ITEM_INDENT, "");
7959 colno = ITEM_INDENT + n;
7961 else if (colno + 2 + n < wrap)
7963 printf ("%c ", sep);
7968 printf ("\n%*s", ITEM_INDENT, "");
7969 colno = ITEM_INDENT + n;
7972 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
7980 convert (Elf *core, Elf_Type type, uint_fast16_t count,
7981 void *value, const void *data, size_t size)
7983 Elf_Data valuedata =
7987 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
7988 .d_version = EV_CURRENT,
7993 .d_buf = (void *) data,
7994 .d_size = valuedata.d_size,
7995 .d_version = EV_CURRENT,
7998 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
7999 ? elf32_xlatetom : elf64_xlatetom)
8000 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8002 error (EXIT_FAILURE, 0,
8003 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8005 return data + indata.d_size;
8008 typedef uint8_t GElf_Byte;
8011 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8012 unsigned int colno, size_t *repeated_size)
8014 uint_fast16_t count = item->count ?: 1;
8017 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8018 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8019 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8020 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8021 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8022 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8024 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8025 union { TYPES; } value;
8028 void *data = &value;
8029 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8030 size_t convsize = size;
8031 if (repeated_size != NULL)
8033 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8035 data = alloca (*repeated_size);
8036 count *= *repeated_size / size;
8037 convsize = count * size;
8038 *repeated_size -= convsize;
8040 else if (item->count != 0 || item->format != '\n')
8041 *repeated_size -= size;
8044 convert (core, item->type, count, data, desc + item->offset, convsize);
8046 Elf_Type type = item->type;
8047 if (type == ELF_T_ADDR)
8048 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8050 switch (item->format)
8053 assert (count == 1);
8056 #define DO_TYPE(NAME, Name, hex, dec) \
8057 case ELF_T_##NAME: \
8058 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8059 0, item->name, dec, value.Name[0]); \
8069 assert (count == 1);
8072 #define DO_TYPE(NAME, Name, hex, dec) \
8073 case ELF_T_##NAME: \
8074 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8075 0, item->name, hex, value.Name[0]); \
8086 assert (size % sizeof (unsigned int) == 0);
8087 unsigned int nbits = count * size * 8;
8088 unsigned int pop = 0;
8089 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8090 pop += __builtin_popcount (*i);
8091 bool negate = pop > nbits / 2;
8092 const unsigned int bias = item->format == 'b';
8095 char printed[(negate ? nbits - pop : pop) * 16];
8099 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8101 assert (size == sizeof (unsigned int) * 2);
8102 for (unsigned int *i = data;
8103 (void *) i < data + count * size; i += 2)
8105 unsigned int w = i[1];
8111 unsigned int lastbit = 0;
8112 unsigned int run = 0;
8113 for (const unsigned int *i = data;
8114 (void *) i < data + count * size; ++i)
8116 unsigned int bit = ((void *) i - data) * 8;
8117 unsigned int w = negate ? ~*i : *i;
8124 if (lastbit != 0 && lastbit + 1 == bit)
8129 p += sprintf (p, "%u", bit - bias);
8131 p += sprintf (p, ",%u", bit - bias);
8133 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8140 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8141 p += sprintf (p, "-%u", lastbit - bias);
8143 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8144 negate ? "~<%s>" : "<%s>", printed);
8149 case (char) ('T'|0x80):
8150 assert (count == 2);
8155 #define DO_TYPE(NAME, Name, hex, dec) \
8156 case ELF_T_##NAME: \
8157 sec = value.Name[0]; \
8158 usec = value.Name[1]; \
8165 if (unlikely (item->format == (char) ('T'|0x80)))
8167 /* This is a hack for an ill-considered 64-bit ABI where
8168 tv_usec is actually a 32-bit field with 32 bits of padding
8169 rounding out struct timeval. We've already converted it as
8170 a 64-bit field. For little-endian, this just means the
8171 high half is the padding; it's presumably zero, but should
8172 be ignored anyway. For big-endian, it means the 32-bit
8173 field went into the high half of USEC. */
8175 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8176 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8181 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8182 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8186 assert (count == 1);
8187 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8188 "%c", value.Byte[0]);
8192 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8193 "%.*s", (int) count, value.Byte);
8197 /* This is a list of strings separated by '\n'. */
8198 assert (item->count == 0);
8199 assert (repeated_size != NULL);
8200 assert (item->name == NULL);
8201 if (unlikely (item->offset >= *repeated_size))
8204 const char *s = desc + item->offset;
8205 size = *repeated_size - item->offset;
8209 const char *eol = memchr (s, '\n', size);
8213 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8216 size -= eol + 1 - s;
8220 colno = WRAP_COLUMN;
8227 error (0, 0, "XXX not handling format '%c' for %s",
8228 item->format, item->name);
8238 /* Sort items by group, and by layout offset within each group. */
8240 compare_core_items (const void *a, const void *b)
8242 const Ebl_Core_Item *const *p1 = a;
8243 const Ebl_Core_Item *const *p2 = b;
8244 const Ebl_Core_Item *item1 = *p1;
8245 const Ebl_Core_Item *item2 = *p2;
8247 return ((item1->group == item2->group ? 0
8248 : strcmp (item1->group, item2->group))
8249 ?: (int) item1->offset - (int) item2->offset);
8252 /* Sort item groups by layout offset of the first item in the group. */
8254 compare_core_item_groups (const void *a, const void *b)
8256 const Ebl_Core_Item *const *const *p1 = a;
8257 const Ebl_Core_Item *const *const *p2 = b;
8258 const Ebl_Core_Item *const *group1 = *p1;
8259 const Ebl_Core_Item *const *group2 = *p2;
8260 const Ebl_Core_Item *item1 = *group1;
8261 const Ebl_Core_Item *item2 = *group2;
8263 return (int) item1->offset - (int) item2->offset;
8267 handle_core_items (Elf *core, const void *desc, size_t descsz,
8268 const Ebl_Core_Item *items, size_t nitems)
8272 unsigned int colno = 0;
8274 /* FORMAT '\n' makes sense to be present only as a single item as it
8275 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8276 if present as a single item but they can be also processed with other
8278 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8279 || items[0].format == 'B'))
8281 assert (items[0].offset == 0);
8282 size_t size = descsz;
8283 colno = handle_core_item (core, items, desc, colno, &size);
8284 /* If SIZE is not zero here there is some remaining data. But we do not
8285 know how to process it anyway. */
8288 for (size_t i = 0; i < nitems; ++i)
8289 assert (items[i].format != '\n');
8291 /* Sort to collect the groups together. */
8292 const Ebl_Core_Item *sorted_items[nitems];
8293 for (size_t i = 0; i < nitems; ++i)
8294 sorted_items[i] = &items[i];
8295 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8297 /* Collect the unique groups and sort them. */
8298 const Ebl_Core_Item **groups[nitems];
8299 groups[0] = &sorted_items[0];
8301 for (size_t i = 1; i < nitems; ++i)
8302 if (sorted_items[i]->group != sorted_items[i - 1]->group
8303 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8304 groups[ngroups++] = &sorted_items[i];
8305 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8307 /* Write out all the groups. */
8308 const void *last = desc;
8311 for (size_t i = 0; i < ngroups; ++i)
8313 for (const Ebl_Core_Item **item = groups[i];
8314 (item < &sorted_items[nitems]
8315 && ((*item)->group == groups[i][0]->group
8316 || !strcmp ((*item)->group, groups[i][0]->group)));
8318 colno = handle_core_item (core, *item, desc, colno, NULL);
8320 /* Force a line break at the end of the group. */
8321 colno = WRAP_COLUMN;
8327 /* This set of items consumed a certain amount of the note's data.
8328 If there is more data there, we have another unit of the same size.
8329 Loop to print that out too. */
8330 const Ebl_Core_Item *item = &items[nitems - 1];
8331 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8332 item->count ?: 1, EV_CURRENT);
8341 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8345 /* For just one repeat, print it unabridged twice. */
8350 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8351 ITEM_INDENT, "", reps);
8361 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8364 desc += regloc->offset;
8372 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8373 const Ebl_Register_Location *regloc, const void *desc,
8376 if (regloc->bits % 8 != 0)
8377 return handle_bit_registers (regloc, desc, colno);
8379 desc += regloc->offset;
8381 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8383 char name[REGNAMESZ];
8386 register_info (ebl, reg, regloc, name, &bits, &type);
8389 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8390 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8391 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8392 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8394 #define BITS(bits, xtype, sfmt, ufmt) \
8395 uint##bits##_t b##bits; int##bits##_t b##bits##s
8396 union { TYPES; uint64_t b128[2]; } value;
8401 case DW_ATE_unsigned:
8403 case DW_ATE_address:
8406 #define BITS(bits, xtype, sfmt, ufmt) \
8408 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8409 if (type == DW_ATE_signed) \
8410 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8412 sfmt, value.b##bits##s); \
8414 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8416 ufmt, value.b##bits); \
8422 assert (type == DW_ATE_unsigned);
8423 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8424 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8425 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8427 "0x%.16" PRIx64 "%.16" PRIx64,
8428 value.b128[!be], value.b128[be]);
8438 /* Print each byte in hex, the whole thing in native byte order. */
8439 assert (bits % 8 == 0);
8440 const uint8_t *bytes = desc;
8442 char hex[bits / 4 + 1];
8443 hex[bits / 4] = '\0';
8445 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8447 bytes += bits / 8 - 1;
8451 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8453 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8454 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8456 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8457 maxregname, name, "0x%s", hex);
8460 desc += regloc->pad;
8469 struct register_info
8471 const Ebl_Register_Location *regloc;
8473 char name[REGNAMESZ];
8480 register_bitpos (const struct register_info *r)
8482 return (r->regloc->offset * 8
8483 + ((r->regno - r->regloc->regno)
8484 * (r->regloc->bits + r->regloc->pad * 8)));
8488 compare_sets_by_info (const struct register_info *r1,
8489 const struct register_info *r2)
8491 return ((int) r2->bits - (int) r1->bits
8492 ?: register_bitpos (r1) - register_bitpos (r2));
8495 /* Sort registers by set, and by size and layout offset within each set. */
8497 compare_registers (const void *a, const void *b)
8499 const struct register_info *r1 = a;
8500 const struct register_info *r2 = b;
8502 /* Unused elements sort last. */
8503 if (r1->regloc == NULL)
8504 return r2->regloc == NULL ? 0 : 1;
8505 if (r2->regloc == NULL)
8508 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8509 ?: compare_sets_by_info (r1, r2));
8512 /* Sort register sets by layout offset of the first register in the set. */
8514 compare_register_sets (const void *a, const void *b)
8516 const struct register_info *const *p1 = a;
8517 const struct register_info *const *p2 = b;
8518 return compare_sets_by_info (*p1, *p2);
8522 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8523 const Ebl_Register_Location *reglocs, size_t nregloc)
8528 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8531 for (size_t i = 0; i < nregloc; ++i)
8532 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8533 maxnreg = reglocs[i].regno + reglocs[i].count;
8534 assert (maxnreg > 0);
8537 struct register_info regs[maxnreg];
8538 memset (regs, 0, sizeof regs);
8540 /* Sort to collect the sets together. */
8542 for (size_t i = 0; i < nregloc; ++i)
8543 for (int reg = reglocs[i].regno;
8544 reg < reglocs[i].regno + reglocs[i].count;
8547 assert (reg < maxnreg);
8550 struct register_info *info = ®s[reg];
8551 info->regloc = ®locs[i];
8553 info->set = register_info (ebl, reg, ®locs[i],
8554 info->name, &info->bits, &info->type);
8556 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8558 /* Collect the unique sets and sort them. */
8559 inline bool same_set (const struct register_info *a,
8560 const struct register_info *b)
8562 return (a < ®s[maxnreg] && a->regloc != NULL
8563 && b < ®s[maxnreg] && b->regloc != NULL
8564 && a->bits == b->bits
8565 && (a->set == b->set || !strcmp (a->set, b->set)));
8567 struct register_info *sets[maxreg + 1];
8570 for (int i = 1; i <= maxreg; ++i)
8571 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8572 sets[nsets++] = ®s[i];
8573 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8575 /* Write out all the sets. */
8576 unsigned int colno = 0;
8577 for (size_t i = 0; i < nsets; ++i)
8579 /* Find the longest name of a register in this set. */
8581 const struct register_info *end;
8582 for (end = sets[i]; same_set (sets[i], end); ++end)
8584 size_t len = strlen (end->name);
8589 for (const struct register_info *reg = sets[i];
8591 reg += reg->regloc->count ?: 1)
8592 colno = handle_core_register (ebl, core, maxname,
8593 reg->regloc, desc, colno);
8595 /* Force a line break at the end of the group. */
8596 colno = WRAP_COLUMN;
8603 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8605 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8608 error (EXIT_FAILURE, 0,
8609 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8611 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8612 for (size_t i = 0; i < nauxv; ++i)
8615 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8621 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8624 if (av->a_un.a_val == 0)
8625 printf (" %" PRIu64 "\n", av->a_type);
8627 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8628 av->a_type, av->a_un.a_val);
8633 case '\0': /* Normally zero. */
8634 if (av->a_un.a_val == 0)
8636 printf (" %s\n", name);
8641 case 'p': /* address */
8642 case 's': /* address of string */
8643 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8646 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8649 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8653 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8655 const char *pfx = "<";
8656 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8658 if (av->a_un.a_val & bit)
8660 printf ("%s%s", pfx, p);
8675 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8677 return ptr < end && (size_t) (end - ptr) >= sz;
8681 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8684 if (! buf_has_data (*ptrp, end, 4))
8687 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8692 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8695 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8696 if (! buf_has_data (*ptrp, end, sz))
8705 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sizeof u);
8715 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8717 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8719 error (EXIT_FAILURE, 0,
8720 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8722 unsigned char const *ptr = data->d_buf;
8723 unsigned char const *const end = data->d_buf + data->d_size;
8725 /* Siginfo head is three ints: signal number, error number, origin
8727 int si_signo, si_errno, si_code;
8728 if (! buf_read_int (core, &ptr, end, &si_signo)
8729 || ! buf_read_int (core, &ptr, end, &si_errno)
8730 || ! buf_read_int (core, &ptr, end, &si_code))
8733 printf (" Not enough data in NT_SIGINFO note.\n");
8737 /* Next is a pointer-aligned union of structures. On 64-bit
8738 machines, that implies a word of padding. */
8739 if (gelf_getclass (core) == ELFCLASS64)
8742 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
8743 si_signo, si_errno, si_code);
8754 if (! buf_read_ulong (core, &ptr, end, &addr))
8756 printf (" fault address: %#" PRIx64 "\n", addr);
8762 else if (si_code == SI_USER)
8765 if (! buf_read_int (core, &ptr, end, &pid)
8766 || ! buf_read_int (core, &ptr, end, &uid))
8768 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
8773 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8775 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8777 error (EXIT_FAILURE, 0,
8778 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8780 unsigned char const *ptr = data->d_buf;
8781 unsigned char const *const end = data->d_buf + data->d_size;
8783 uint64_t count, page_size;
8784 if (! buf_read_ulong (core, &ptr, end, &count)
8785 || ! buf_read_ulong (core, &ptr, end, &page_size))
8788 printf (" Not enough data in NT_FILE note.\n");
8792 /* Where file names are stored. */
8793 unsigned char const *const fstart
8794 = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8795 char const *fptr = (char *) fstart;
8797 printf (" %" PRId64 " files:\n", count);
8798 for (uint64_t i = 0; i < count; ++i)
8800 uint64_t mstart, mend, moffset;
8801 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
8802 || ! buf_read_ulong (core, &ptr, fstart, &mend)
8803 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
8806 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
8810 int ct = printf (" %08" PRIx64 "-%08" PRIx64
8811 " %08" PRIx64 " %" PRId64,
8812 mstart, mend, moffset * page_size, mend - mstart);
8813 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
8820 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8821 const char *name, const void *desc)
8823 GElf_Word regs_offset;
8825 const Ebl_Register_Location *reglocs;
8827 const Ebl_Core_Item *items;
8829 if (! ebl_core_note (ebl, nhdr, name,
8830 ®s_offset, &nregloc, ®locs, &nitems, &items))
8833 /* Pass 0 for DESCSZ when there are registers in the note,
8834 so that the ITEMS array does not describe the whole thing.
8835 For non-register notes, the actual descsz might be a multiple
8836 of the unit size, not just exactly the unit size. */
8837 unsigned int colno = handle_core_items (ebl->elf, desc,
8838 nregloc == 0 ? nhdr->n_descsz : 0,
8841 putchar_unlocked ('\n');
8843 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8846 putchar_unlocked ('\n');
8850 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8851 GElf_Off start, Elf_Data *data)
8853 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
8862 while (offset < data->d_size
8863 && (offset = gelf_getnote (data, offset,
8864 &nhdr, &name_offset, &desc_offset)) > 0)
8866 const char *name = data->d_buf + name_offset;
8867 const char *desc = data->d_buf + desc_offset;
8871 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
8872 (int) nhdr.n_namesz, name, nhdr.n_descsz,
8873 ehdr->e_type == ET_CORE
8874 ? ebl_core_note_type_name (ebl, nhdr.n_type,
8876 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8877 buf2, sizeof (buf2)));
8879 /* Filter out invalid entries. */
8880 if (memchr (name, '\0', nhdr.n_namesz) != NULL
8881 /* XXX For now help broken Linux kernels. */
8884 if (ehdr->e_type == ET_CORE)
8886 if (nhdr.n_type == NT_AUXV
8887 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
8888 || (nhdr.n_namesz == 5 && name[4] == '\0'))
8889 && !memcmp (name, "CORE", 4))
8890 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
8891 start + desc_offset);
8892 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
8893 switch (nhdr.n_type)
8896 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
8897 start + desc_offset);
8901 handle_file_note (ebl->elf, nhdr.n_descsz,
8902 start + desc_offset);
8906 handle_core_note (ebl, &nhdr, name, desc);
8909 handle_core_note (ebl, &nhdr, name, desc);
8912 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
8916 if (offset == data->d_size)
8920 error (EXIT_FAILURE, 0,
8921 gettext ("cannot get content of note section: %s"),
8926 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
8928 /* If we have section headers, just look for SHT_NOTE sections.
8929 In a debuginfo file, the program headers are not reliable. */
8932 /* Get the section header string table index. */
8934 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
8935 error (EXIT_FAILURE, 0,
8936 gettext ("cannot get section header string table index"));
8938 Elf_Scn *scn = NULL;
8939 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8942 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8944 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
8945 /* Not what we are looking for. */
8949 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8951 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
8952 shdr->sh_size, shdr->sh_offset);
8954 handle_notes_data (ebl, ehdr, shdr->sh_offset,
8955 elf_getdata (scn, NULL));
8960 /* We have to look through the program header to find the note
8961 sections. There can be more than one. */
8962 for (size_t cnt = 0; cnt < phnum; ++cnt)
8965 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
8967 if (phdr == NULL || phdr->p_type != PT_NOTE)
8968 /* Not what we are looking for. */
8972 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8973 phdr->p_filesz, phdr->p_offset);
8975 handle_notes_data (ebl, ehdr, phdr->p_offset,
8976 elf_getdata_rawchunk (ebl->elf,
8977 phdr->p_offset, phdr->p_filesz,
8984 hex_dump (const uint8_t *data, size_t len)
8989 printf (" 0x%08Zx ", pos);
8991 const size_t chunk = MIN (len - pos, 16);
8993 for (size_t i = 0; i < chunk; ++i)
8995 printf ("%02x ", data[pos + i]);
8997 printf ("%02x", data[pos + i]);
9000 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9002 for (size_t i = 0; i < chunk; ++i)
9004 unsigned char b = data[pos + i];
9005 printf ("%c", isprint (b) ? b : '.');
9014 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9016 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9017 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9018 elf_ndxscn (scn), name);
9021 Elf_Data *data = elf_rawdata (scn, NULL);
9023 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9024 elf_ndxscn (scn), name, elf_errmsg (-1));
9027 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9028 " bytes at offset %#0" PRIx64 ":\n"),
9029 elf_ndxscn (scn), name,
9030 shdr->sh_size, shdr->sh_offset);
9031 hex_dump (data->d_buf, data->d_size);
9037 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9039 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9040 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9041 elf_ndxscn (scn), name);
9044 Elf_Data *data = elf_rawdata (scn, NULL);
9046 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9047 elf_ndxscn (scn), name, elf_errmsg (-1));
9050 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9051 " bytes at offset %#0" PRIx64 ":\n"),
9052 elf_ndxscn (scn), name,
9053 shdr->sh_size, shdr->sh_offset);
9055 const char *start = data->d_buf;
9056 const char *const limit = start + data->d_size;
9059 const char *end = memchr (start, '\0', limit - start);
9060 const size_t pos = start - (const char *) data->d_buf;
9061 if (unlikely (end == NULL))
9063 printf (" [%6Zx]- %.*s\n",
9064 pos, (int) (limit - start), start);
9067 printf (" [%6Zx] %s\n", pos, start);
9069 } while (start < limit);
9075 for_each_section_argument (Elf *elf, const struct section_argument *list,
9076 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9079 /* Get the section header string table index. */
9081 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9082 error (EXIT_FAILURE, 0,
9083 gettext ("cannot get section header string table index"));
9085 for (const struct section_argument *a = list; a != NULL; a = a->next)
9089 const char *name = NULL;
9092 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9093 if (endp != a->arg && *endp == '\0')
9095 scn = elf_getscn (elf, shndx);
9098 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9102 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9103 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9105 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9109 /* Need to look up the section by name. */
9112 while ((scn = elf_nextscn (elf, scn)) != NULL)
9114 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9116 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9119 if (!strcmp (name, a->arg))
9122 (*dump) (scn, &shdr_mem, name);
9126 if (unlikely (!found) && !a->implicit)
9127 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9133 dump_data (Ebl *ebl)
9135 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9139 dump_strings (Ebl *ebl)
9141 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9145 print_strings (Ebl *ebl)
9147 /* Get the section header string table index. */
9149 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9150 error (EXIT_FAILURE, 0,
9151 gettext ("cannot get section header string table index"));
9157 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9159 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9162 if (shdr_mem.sh_type != SHT_PROGBITS
9163 || !(shdr_mem.sh_flags & SHF_STRINGS))
9166 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9170 print_string_section (scn, &shdr_mem, name);
9175 dump_archive_index (Elf *elf, const char *fname)
9178 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9181 int result = elf_errno ();
9182 if (unlikely (result != ELF_E_NO_INDEX))
9183 error (EXIT_FAILURE, 0,
9184 gettext ("cannot get symbol index of archive '%s': %s"),
9185 fname, elf_errmsg (result));
9187 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9191 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9195 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9197 if (s->as_off != as_off)
9202 if (unlikely (elf_rand (elf, as_off) == 0)
9203 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9205 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9208 error (EXIT_FAILURE, 0,
9209 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9210 as_off, fname, elf_errmsg (-1));
9212 const Elf_Arhdr *h = elf_getarhdr (subelf);
9214 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9219 printf ("\t%s\n", s->as_name);
9223 #include "debugpred.h"