1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2013 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 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1196 filedata + phdr->p_offset);
1198 else if (phdr->p_type == PT_GNU_RELRO)
1201 relro_from = phdr->p_vaddr;
1202 relro_to = relro_from + phdr->p_memsz;
1206 if (ehdr->e_shnum == 0)
1207 /* No sections in the file. Punt. */
1210 /* Get the section header string table index. */
1212 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1213 error (EXIT_FAILURE, 0,
1214 gettext ("cannot get section header string table index"));
1216 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1218 for (size_t cnt = 0; cnt < phnum; ++cnt)
1220 /* Print the segment number. */
1221 printf (" %2.2zu ", cnt);
1224 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1225 /* This must not happen. */
1226 if (unlikely (phdr == NULL))
1227 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1230 /* Iterate over the sections. */
1231 bool in_relro = false;
1233 for (size_t inner = 1; inner < shnum; ++inner)
1235 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1236 /* This should not happen. */
1237 if (unlikely (scn == NULL))
1238 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1241 /* Get the section header. */
1243 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1244 if (unlikely (shdr == NULL))
1245 error (EXIT_FAILURE, 0,
1246 gettext ("cannot get section header: %s"),
1249 if (shdr->sh_size > 0
1250 /* Compare allocated sections by VMA, unallocated
1251 sections by file offset. */
1252 && (shdr->sh_flags & SHF_ALLOC
1253 ? (shdr->sh_addr >= phdr->p_vaddr
1254 && (shdr->sh_addr + shdr->sh_size
1255 <= phdr->p_vaddr + phdr->p_memsz))
1256 : (shdr->sh_offset >= phdr->p_offset
1257 && (shdr->sh_offset + shdr->sh_size
1258 <= phdr->p_offset + phdr->p_filesz))))
1260 if (has_relro && !in_relro
1261 && shdr->sh_addr >= relro_from
1262 && shdr->sh_addr + shdr->sh_size <= relro_to)
1264 fputs_unlocked (" [RELRO:", stdout);
1267 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1269 fputs_unlocked ("]", stdout);
1272 else if (has_relro && in_relro
1273 && shdr->sh_addr + shdr->sh_size > relro_to)
1274 fputs_unlocked ("] <RELRO:", stdout);
1275 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1279 fputs_unlocked (" [RO:", stdout);
1285 /* Determine the segment this section is part of. */
1287 GElf_Phdr *phdr2 = NULL;
1288 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1290 GElf_Phdr phdr2_mem;
1291 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1293 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1294 && shdr->sh_addr >= phdr2->p_vaddr
1295 && (shdr->sh_addr + shdr->sh_size
1296 <= phdr2->p_vaddr + phdr2->p_memsz))
1302 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1304 fputs_unlocked (" [RO:", stdout);
1307 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1309 fputs_unlocked ("]", stdout);
1316 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1318 /* Signal that this sectin is only partially covered. */
1319 if (has_relro && in_relro
1320 && shdr->sh_addr + shdr->sh_size > relro_to)
1322 fputs_unlocked (">", stdout);
1327 if (in_relro || in_ro)
1328 fputs_unlocked ("]", stdout);
1330 /* Finish the line. */
1331 fputc_unlocked ('\n', stdout);
1337 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1339 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1344 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1346 /* Get the data of the section. */
1347 Elf_Data *data = elf_getdata (scn, NULL);
1349 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1350 GElf_Shdr symshdr_mem;
1351 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1352 Elf_Data *symdata = elf_getdata (symscn, NULL);
1354 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1358 /* Get the section header string table index. */
1360 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1361 error (EXIT_FAILURE, 0,
1362 gettext ("cannot get section header string table index"));
1364 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1367 printf ((grpref[0] & GRP_COMDAT)
1369 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1371 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1372 data->d_size / sizeof (Elf32_Word) - 1)
1374 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1375 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1376 data->d_size / sizeof (Elf32_Word) - 1),
1378 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1379 elf_strptr (ebl->elf, symshdr->sh_link,
1380 gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
1381 ?: gettext ("<INVALID SYMBOL>"),
1382 data->d_size / sizeof (Elf32_Word) - 1);
1384 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1386 GElf_Shdr grpshdr_mem;
1387 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1391 printf (" [%2u] %s\n",
1394 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1395 ? str : gettext ("<INVALID SECTION>"));
1401 print_scngrp (Ebl *ebl)
1403 /* Find all relocation sections and handle them. */
1404 Elf_Scn *scn = NULL;
1406 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1408 /* Handle the section if it is a symbol table. */
1410 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1412 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1413 handle_scngrp (ebl, scn, shdr);
1418 static const struct flags
1424 { DF_ORIGIN, "ORIGIN" },
1425 { DF_SYMBOLIC, "SYMBOLIC" },
1426 { DF_TEXTREL, "TEXTREL" },
1427 { DF_BIND_NOW, "BIND_NOW" },
1428 { DF_STATIC_TLS, "STATIC_TLS" }
1430 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1432 static const struct flags dt_flags_1[] =
1434 { DF_1_NOW, "NOW" },
1435 { DF_1_GLOBAL, "GLOBAL" },
1436 { DF_1_GROUP, "GROUP" },
1437 { DF_1_NODELETE, "NODELETE" },
1438 { DF_1_LOADFLTR, "LOADFLTR" },
1439 { DF_1_INITFIRST, "INITFIRST" },
1440 { DF_1_NOOPEN, "NOOPEN" },
1441 { DF_1_ORIGIN, "ORIGIN" },
1442 { DF_1_DIRECT, "DIRECT" },
1443 { DF_1_TRANS, "TRANS" },
1444 { DF_1_INTERPOSE, "INTERPOSE" },
1445 { DF_1_NODEFLIB, "NODEFLIB" },
1446 { DF_1_NODUMP, "NODUMP" },
1447 { DF_1_CONFALT, "CONFALT" },
1448 { DF_1_ENDFILTEE, "ENDFILTEE" },
1449 { DF_1_DISPRELDNE, "DISPRELDNE" },
1450 { DF_1_DISPRELPND, "DISPRELPND" },
1452 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1454 static const struct flags dt_feature_1[] =
1456 { DTF_1_PARINIT, "PARINIT" },
1457 { DTF_1_CONFEXP, "CONFEXP" }
1459 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1460 / sizeof (dt_feature_1[0]));
1462 static const struct flags dt_posflag_1[] =
1464 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1465 { DF_P1_GROUPPERM, "GROUPPERM" }
1467 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1468 / sizeof (dt_posflag_1[0]));
1472 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1478 for (cnt = 0; cnt < nflags; ++cnt)
1479 if (d_val & flags[cnt].mask)
1482 putchar_unlocked (' ');
1483 fputs_unlocked (flags[cnt].str, stdout);
1484 d_val &= ~flags[cnt].mask;
1491 putchar_unlocked (' ');
1492 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1495 putchar_unlocked ('\n');
1500 print_dt_flags (int class, GElf_Xword d_val)
1502 print_flags (class, d_val, dt_flags, ndt_flags);
1507 print_dt_flags_1 (int class, GElf_Xword d_val)
1509 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1514 print_dt_feature_1 (int class, GElf_Xword d_val)
1516 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1521 print_dt_posflag_1 (int class, GElf_Xword d_val)
1523 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1528 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1530 int class = gelf_getclass (ebl->elf);
1536 /* Get the data of the section. */
1537 data = elf_getdata (scn, NULL);
1541 /* Get the section header string table index. */
1542 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1543 error (EXIT_FAILURE, 0,
1544 gettext ("cannot get section header string table index"));
1546 printf (ngettext ("\
1547 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1549 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1550 shdr->sh_size / shdr->sh_entsize),
1551 (unsigned long int) (shdr->sh_size / shdr->sh_entsize),
1552 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1554 (int) shdr->sh_link,
1555 elf_strptr (ebl->elf, shstrndx,
1556 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1558 fputs_unlocked (gettext (" Type Value\n"), stdout);
1560 for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1563 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1569 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1577 /* No further output. */
1578 fputc_unlocked ('\n', stdout);
1582 printf (gettext ("Shared library: [%s]\n"),
1583 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1587 printf (gettext ("Library soname: [%s]\n"),
1588 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1592 printf (gettext ("Library rpath: [%s]\n"),
1593 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1597 printf (gettext ("Library runpath: [%s]\n"),
1598 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1611 case DT_INIT_ARRAYSZ:
1612 case DT_FINI_ARRAYSZ:
1615 case DT_GNU_CONFLICTSZ:
1616 case DT_GNU_LIBLISTSZ:
1617 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1624 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1628 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1630 puts (tagname ?: "???");
1634 print_dt_flags (class, dyn->d_un.d_val);
1638 print_dt_flags_1 (class, dyn->d_un.d_val);
1642 print_dt_feature_1 (class, dyn->d_un.d_val);
1646 print_dt_posflag_1 (class, dyn->d_un.d_val);
1650 printf ("%#0*" PRIx64 "\n",
1651 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1658 /* Print the dynamic segment. */
1660 print_dynamic (Ebl *ebl)
1662 for (size_t i = 0; i < phnum; ++i)
1665 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1667 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1669 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1671 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1672 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1673 handle_dynamic (ebl, scn, shdr);
1680 /* Print relocations. */
1682 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1684 /* Find all relocation sections and handle them. */
1685 Elf_Scn *scn = NULL;
1687 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1689 /* Handle the section if it is a symbol table. */
1691 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1693 if (likely (shdr != NULL))
1695 if (shdr->sh_type == SHT_REL)
1696 handle_relocs_rel (ebl, ehdr, scn, shdr);
1697 else if (shdr->sh_type == SHT_RELA)
1698 handle_relocs_rela (ebl, ehdr, scn, shdr);
1704 /* Handle a relocation section. */
1706 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1708 int class = gelf_getclass (ebl->elf);
1709 int nentries = shdr->sh_size / shdr->sh_entsize;
1711 /* Get the data of the section. */
1712 Elf_Data *data = elf_getdata (scn, NULL);
1716 /* Get the symbol table information. */
1717 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1718 GElf_Shdr symshdr_mem;
1719 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1720 Elf_Data *symdata = elf_getdata (symscn, NULL);
1722 /* Get the section header of the section the relocations are for. */
1723 GElf_Shdr destshdr_mem;
1724 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1727 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1729 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1734 /* Search for the optional extended section index table. */
1735 Elf_Data *xndxdata = NULL;
1736 int xndxscnidx = elf_scnshndx (scn);
1737 if (unlikely (xndxscnidx > 0))
1738 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1740 /* Get the section header string table index. */
1742 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1743 error (EXIT_FAILURE, 0,
1744 gettext ("cannot get section header string table index"));
1746 if (shdr->sh_info != 0)
1747 printf (ngettext ("\
1748 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1750 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1753 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1754 (unsigned int) shdr->sh_info,
1755 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1759 /* The .rel.dyn section does not refer to a specific section but
1760 instead of section index zero. Do not try to print a section
1762 printf (ngettext ("\
1763 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1765 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1767 (unsigned int) elf_ndxscn (scn),
1768 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1771 fputs_unlocked (class == ELFCLASS32
1773 Offset Type Value Name\n")
1775 Offset Type Value Name\n"),
1778 int is_statically_linked = 0;
1779 for (int cnt = 0; cnt < nentries; ++cnt)
1782 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1783 if (likely (rel != NULL))
1788 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1789 GELF_R_SYM (rel->r_info),
1791 if (unlikely (sym == NULL))
1793 /* As a special case we have to handle relocations in static
1794 executables. This only happens for IRELATIVE relocations
1795 (so far). There is no symbol table. */
1796 if (is_statically_linked == 0)
1798 /* Find the program header and look for a PT_INTERP entry. */
1799 is_statically_linked = -1;
1800 if (ehdr->e_type == ET_EXEC)
1802 is_statically_linked = 1;
1804 for (size_t inner = 0; inner < phnum; ++inner)
1807 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1809 if (phdr != NULL && phdr->p_type == PT_INTERP)
1811 is_statically_linked = -1;
1818 if (is_statically_linked > 0 && shdr->sh_link == 0)
1820 %#0*" PRIx64 " %-20s %*s %s\n",
1821 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1822 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1823 /* Avoid the leading R_ which isn't carrying any
1825 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1826 buf, sizeof (buf)) + 2
1827 : gettext ("<INVALID RELOC>"),
1828 class == ELFCLASS32 ? 10 : 18, "",
1829 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1831 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1832 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1833 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1834 /* Avoid the leading R_ which isn't carrying any
1836 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1837 buf, sizeof (buf)) + 2
1838 : gettext ("<INVALID RELOC>"),
1839 gettext ("INVALID SYMBOL"),
1840 (long int) GELF_R_SYM (rel->r_info));
1842 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1843 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1844 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1845 likely (ebl_reloc_type_check (ebl,
1846 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 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1853 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1856 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
1857 sym->st_shndx == SHN_XINDEX
1858 ? xndx : sym->st_shndx),
1861 if (unlikely (destshdr == NULL))
1862 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1863 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1864 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1865 /* Avoid the leading R_ which isn't carrying any
1867 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1868 buf, sizeof (buf)) + 2
1869 : gettext ("<INVALID RELOC>"),
1870 gettext ("INVALID SECTION"),
1871 (long int) (sym->st_shndx == SHN_XINDEX
1872 ? xndx : sym->st_shndx));
1874 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1875 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1876 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1877 /* Avoid the leading R_ which isn't carrying any
1879 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1880 buf, sizeof (buf)) + 2
1881 : gettext ("<INVALID RELOC>"),
1882 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1883 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1890 /* Handle a relocation section. */
1892 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1894 int class = gelf_getclass (ebl->elf);
1895 int nentries = shdr->sh_size / shdr->sh_entsize;
1897 /* Get the data of the section. */
1898 Elf_Data *data = elf_getdata (scn, NULL);
1902 /* Get the symbol table information. */
1903 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1904 GElf_Shdr symshdr_mem;
1905 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1906 Elf_Data *symdata = elf_getdata (symscn, NULL);
1908 /* Get the section header of the section the relocations are for. */
1909 GElf_Shdr destshdr_mem;
1910 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1913 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1915 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1920 /* Search for the optional extended section index table. */
1921 Elf_Data *xndxdata = NULL;
1922 int xndxscnidx = elf_scnshndx (scn);
1923 if (unlikely (xndxscnidx > 0))
1924 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1926 /* Get the section header string table index. */
1928 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1929 error (EXIT_FAILURE, 0,
1930 gettext ("cannot get section header string table index"));
1932 printf (ngettext ("\
1933 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1935 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1938 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1939 (unsigned int) shdr->sh_info,
1940 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1943 fputs_unlocked (class == ELFCLASS32
1945 Offset Type Value Addend Name\n")
1947 Offset Type Value Addend Name\n"),
1950 int is_statically_linked = 0;
1951 for (int cnt = 0; cnt < nentries; ++cnt)
1954 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
1955 if (likely (rel != NULL))
1960 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1961 GELF_R_SYM (rel->r_info),
1964 if (unlikely (sym == NULL))
1966 /* As a special case we have to handle relocations in static
1967 executables. This only happens for IRELATIVE relocations
1968 (so far). There is no symbol table. */
1969 if (is_statically_linked == 0)
1971 /* Find the program header and look for a PT_INTERP entry. */
1972 is_statically_linked = -1;
1973 if (ehdr->e_type == ET_EXEC)
1975 is_statically_linked = 1;
1977 for (size_t inner = 0; inner < phnum; ++inner)
1980 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1982 if (phdr != NULL && phdr->p_type == PT_INTERP)
1984 is_statically_linked = -1;
1991 if (is_statically_linked > 0 && shdr->sh_link == 0)
1993 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
1994 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1995 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1996 /* Avoid the leading R_ which isn't carrying any
1998 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1999 buf, sizeof (buf)) + 2
2000 : gettext ("<INVALID RELOC>"),
2001 class == ELFCLASS32 ? 10 : 18, "",
2003 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2005 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2006 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2007 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2008 /* Avoid the leading R_ which isn't carrying any
2010 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2011 buf, sizeof (buf)) + 2
2012 : gettext ("<INVALID RELOC>"),
2013 gettext ("INVALID SYMBOL"),
2014 (long int) GELF_R_SYM (rel->r_info));
2016 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2018 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2019 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2020 likely (ebl_reloc_type_check (ebl,
2021 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 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2029 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2032 destshdr = gelf_getshdr (elf_getscn (ebl->elf,
2033 sym->st_shndx == SHN_XINDEX
2034 ? xndx : sym->st_shndx),
2037 if (unlikely (shdr == NULL))
2038 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2039 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2040 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2041 /* Avoid the leading R_ which isn't carrying any
2043 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2044 buf, sizeof (buf)) + 2
2045 : gettext ("<INVALID RELOC>"),
2046 gettext ("INVALID SECTION"),
2047 (long int) (sym->st_shndx == SHN_XINDEX
2048 ? xndx : sym->st_shndx));
2051 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2052 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2053 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2054 /* Avoid the leading R_ which isn't carrying any
2056 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2057 buf, sizeof (buf)) + 2
2058 : gettext ("<INVALID RELOC>"),
2059 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2061 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2068 /* Print the program header. */
2070 print_symtab (Ebl *ebl, int type)
2072 /* Find the symbol table(s). For this we have to search through the
2074 Elf_Scn *scn = NULL;
2076 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2078 /* Handle the section if it is a symbol table. */
2080 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2082 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2083 handle_symtab (ebl, scn, shdr);
2089 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2091 Elf_Data *versym_data = NULL;
2092 Elf_Data *verneed_data = NULL;
2093 Elf_Data *verdef_data = NULL;
2094 Elf_Data *xndx_data = NULL;
2095 int class = gelf_getclass (ebl->elf);
2096 Elf32_Word verneed_stridx = 0;
2097 Elf32_Word verdef_stridx = 0;
2099 /* Get the data of the section. */
2100 Elf_Data *data = elf_getdata (scn, NULL);
2104 /* Find out whether we have other sections we might need. */
2105 Elf_Scn *runscn = NULL;
2106 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2108 GElf_Shdr runshdr_mem;
2109 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2111 if (likely (runshdr != NULL))
2113 if (runshdr->sh_type == SHT_GNU_versym
2114 && runshdr->sh_link == elf_ndxscn (scn))
2115 /* Bingo, found the version information. Now get the data. */
2116 versym_data = elf_getdata (runscn, NULL);
2117 else if (runshdr->sh_type == SHT_GNU_verneed)
2119 /* This is the information about the needed versions. */
2120 verneed_data = elf_getdata (runscn, NULL);
2121 verneed_stridx = runshdr->sh_link;
2123 else if (runshdr->sh_type == SHT_GNU_verdef)
2125 /* This is the information about the defined versions. */
2126 verdef_data = elf_getdata (runscn, NULL);
2127 verdef_stridx = runshdr->sh_link;
2129 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2130 && runshdr->sh_link == elf_ndxscn (scn))
2131 /* Extended section index. */
2132 xndx_data = elf_getdata (runscn, NULL);
2136 /* Get the section header string table index. */
2138 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2139 error (EXIT_FAILURE, 0,
2140 gettext ("cannot get section header string table index"));
2142 /* Now we can compute the number of entries in the section. */
2143 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2144 ? sizeof (Elf32_Sym)
2145 : sizeof (Elf64_Sym));
2147 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2148 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2150 (unsigned int) elf_ndxscn (scn),
2151 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2153 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2154 " %lu local symbols String table: [%2u] '%s'\n",
2156 (unsigned long int) shdr->sh_info,
2157 (unsigned int) shdr->sh_link,
2158 elf_strptr (ebl->elf, shstrndx,
2159 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2162 fputs_unlocked (class == ELFCLASS32
2164 Num: Value Size Type Bind Vis Ndx Name\n")
2166 Num: Value Size Type Bind Vis Ndx Name\n"),
2169 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2176 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2178 if (unlikely (sym == NULL))
2181 /* Determine the real section index. */
2182 if (likely (sym->st_shndx != SHN_XINDEX))
2183 xndx = sym->st_shndx;
2186 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2188 class == ELFCLASS32 ? 8 : 16,
2191 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2192 typebuf, sizeof (typebuf)),
2193 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2194 bindbuf, sizeof (bindbuf)),
2195 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2196 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2197 sizeof (scnbuf), NULL, shnum),
2198 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2200 if (versym_data != NULL)
2202 /* Get the version information. */
2203 GElf_Versym versym_mem;
2204 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2206 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2208 bool is_nobits = false;
2209 bool check_def = xndx != SHN_UNDEF;
2211 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2213 GElf_Shdr symshdr_mem;
2214 GElf_Shdr *symshdr =
2215 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2217 is_nobits = (symshdr != NULL
2218 && symshdr->sh_type == SHT_NOBITS);
2221 if (is_nobits || ! check_def)
2223 /* We must test both. */
2224 GElf_Vernaux vernaux_mem;
2225 GElf_Vernaux *vernaux = NULL;
2226 size_t vn_offset = 0;
2228 GElf_Verneed verneed_mem;
2229 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2231 while (verneed != NULL)
2233 size_t vna_offset = vn_offset;
2235 vernaux = gelf_getvernaux (verneed_data,
2236 vna_offset += verneed->vn_aux,
2238 while (vernaux != NULL
2239 && vernaux->vna_other != *versym
2240 && vernaux->vna_next != 0)
2242 /* Update the offset. */
2243 vna_offset += vernaux->vna_next;
2245 vernaux = (vernaux->vna_next == 0
2247 : gelf_getvernaux (verneed_data,
2252 /* Check whether we found the version. */
2253 if (vernaux != NULL && vernaux->vna_other == *versym)
2257 vn_offset += verneed->vn_next;
2258 verneed = (verneed->vn_next == 0
2260 : gelf_getverneed (verneed_data, vn_offset,
2264 if (vernaux != NULL && vernaux->vna_other == *versym)
2267 elf_strptr (ebl->elf, verneed_stridx,
2269 (unsigned int) vernaux->vna_other);
2272 else if (unlikely (! is_nobits))
2273 error (0, 0, gettext ("bad dynamic symbol"));
2278 if (check_def && *versym != 0x8001)
2280 /* We must test both. */
2281 size_t vd_offset = 0;
2283 GElf_Verdef verdef_mem;
2284 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2286 while (verdef != NULL)
2288 if (verdef->vd_ndx == (*versym & 0x7fff))
2289 /* Found the definition. */
2292 vd_offset += verdef->vd_next;
2293 verdef = (verdef->vd_next == 0
2295 : gelf_getverdef (verdef_data, vd_offset,
2301 GElf_Verdaux verdaux_mem;
2302 GElf_Verdaux *verdaux
2303 = gelf_getverdaux (verdef_data,
2304 vd_offset + verdef->vd_aux,
2307 if (verdaux != NULL)
2308 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2309 elf_strptr (ebl->elf, verdef_stridx,
2310 verdaux->vda_name));
2316 putchar_unlocked ('\n');
2321 /* Print version information. */
2323 print_verinfo (Ebl *ebl)
2325 /* Find the version information sections. For this we have to
2326 search through the section table. */
2327 Elf_Scn *scn = NULL;
2329 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2331 /* Handle the section if it is part of the versioning handling. */
2333 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2335 if (likely (shdr != NULL))
2337 if (shdr->sh_type == SHT_GNU_verneed)
2338 handle_verneed (ebl, scn, shdr);
2339 else if (shdr->sh_type == SHT_GNU_verdef)
2340 handle_verdef (ebl, scn, shdr);
2341 else if (shdr->sh_type == SHT_GNU_versym)
2342 handle_versym (ebl, scn, shdr);
2349 get_ver_flags (unsigned int flags)
2351 static char buf[32];
2355 return gettext ("none");
2357 if (flags & VER_FLG_BASE)
2358 endp = stpcpy (buf, "BASE ");
2362 if (flags & VER_FLG_WEAK)
2365 endp = stpcpy (endp, "| ");
2367 endp = stpcpy (endp, "WEAK ");
2370 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2372 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2373 buf[sizeof (buf) - 1] = '\0';
2381 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2383 int class = gelf_getclass (ebl->elf);
2385 /* Get the data of the section. */
2386 Elf_Data *data = elf_getdata (scn, NULL);
2390 /* Get the section header string table index. */
2392 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2393 error (EXIT_FAILURE, 0,
2394 gettext ("cannot get section header string table index"));
2397 printf (ngettext ("\
2398 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2400 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2402 (unsigned int) elf_ndxscn (scn),
2403 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2404 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2406 (unsigned int) shdr->sh_link,
2407 elf_strptr (ebl->elf, shstrndx,
2408 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2411 unsigned int offset = 0;
2412 for (int cnt = shdr->sh_info; --cnt >= 0; )
2414 /* Get the data at the next offset. */
2415 GElf_Verneed needmem;
2416 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2417 if (unlikely (need == NULL))
2420 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2421 offset, (unsigned short int) need->vn_version,
2422 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2423 (unsigned short int) need->vn_cnt);
2425 unsigned int auxoffset = offset + need->vn_aux;
2426 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2428 GElf_Vernaux auxmem;
2429 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2430 if (unlikely (aux == NULL))
2433 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2435 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2436 get_ver_flags (aux->vna_flags),
2437 (unsigned short int) aux->vna_other);
2439 auxoffset += aux->vna_next;
2442 /* Find the next offset. */
2443 offset += need->vn_next;
2449 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2451 /* Get the data of the section. */
2452 Elf_Data *data = elf_getdata (scn, NULL);
2456 /* Get the section header string table index. */
2458 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2459 error (EXIT_FAILURE, 0,
2460 gettext ("cannot get section header string table index"));
2462 int class = gelf_getclass (ebl->elf);
2464 printf (ngettext ("\
2465 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2467 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2469 (unsigned int) elf_ndxscn (scn),
2470 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2472 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2474 (unsigned int) shdr->sh_link,
2475 elf_strptr (ebl->elf, shstrndx,
2476 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2479 unsigned int offset = 0;
2480 for (int cnt = shdr->sh_info; --cnt >= 0; )
2482 /* Get the data at the next offset. */
2484 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2485 if (unlikely (def == NULL))
2488 unsigned int auxoffset = offset + def->vd_aux;
2489 GElf_Verdaux auxmem;
2490 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2491 if (unlikely (aux == NULL))
2495 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2496 offset, def->vd_version,
2497 get_ver_flags (def->vd_flags),
2500 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2502 auxoffset += aux->vda_next;
2503 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2505 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2506 if (unlikely (aux == NULL))
2509 printf (gettext (" %#06x: Parent %d: %s\n"),
2511 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2513 auxoffset += aux->vda_next;
2516 /* Find the next offset. */
2517 offset += def->vd_next;
2523 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2525 int class = gelf_getclass (ebl->elf);
2526 const char **vername;
2527 const char **filename;
2529 /* Get the data of the section. */
2530 Elf_Data *data = elf_getdata (scn, NULL);
2534 /* Get the section header string table index. */
2536 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2537 error (EXIT_FAILURE, 0,
2538 gettext ("cannot get section header string table index"));
2540 /* We have to find the version definition section and extract the
2542 Elf_Scn *defscn = NULL;
2543 Elf_Scn *needscn = NULL;
2545 Elf_Scn *verscn = NULL;
2546 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2548 GElf_Shdr vershdr_mem;
2549 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2551 if (likely (vershdr != NULL))
2553 if (vershdr->sh_type == SHT_GNU_verdef)
2555 else if (vershdr->sh_type == SHT_GNU_verneed)
2561 if (defscn != NULL || needscn != NULL)
2563 /* We have a version information (better should have). Now get
2564 the version names. First find the maximum version number. */
2568 /* Run through the version definitions and find the highest
2570 unsigned int offset = 0;
2572 GElf_Shdr defshdrmem;
2575 defdata = elf_getdata (defscn, NULL);
2576 if (unlikely (defdata == NULL))
2579 defshdr = gelf_getshdr (defscn, &defshdrmem);
2580 if (unlikely (defshdr == NULL))
2583 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2588 /* Get the data at the next offset. */
2589 def = gelf_getverdef (defdata, offset, &defmem);
2590 if (unlikely (def == NULL))
2593 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2595 offset += def->vd_next;
2598 if (needscn != NULL)
2600 unsigned int offset = 0;
2602 GElf_Shdr needshdrmem;
2603 GElf_Shdr *needshdr;
2605 needdata = elf_getdata (needscn, NULL);
2606 if (unlikely (needdata == NULL))
2609 needshdr = gelf_getshdr (needscn, &needshdrmem);
2610 if (unlikely (needshdr == NULL))
2613 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2615 GElf_Verneed needmem;
2617 unsigned int auxoffset;
2620 /* Get the data at the next offset. */
2621 need = gelf_getverneed (needdata, offset, &needmem);
2622 if (unlikely (need == NULL))
2625 /* Run through the auxiliary entries. */
2626 auxoffset = offset + need->vn_aux;
2627 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2629 GElf_Vernaux auxmem;
2632 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2633 if (unlikely (aux == NULL))
2636 nvername = MAX (nvername,
2637 (size_t) (aux->vna_other & 0x7fff));
2639 auxoffset += aux->vna_next;
2642 offset += need->vn_next;
2646 /* This is the number of versions we know about. */
2649 /* Allocate the array. */
2650 vername = (const char **) alloca (nvername * sizeof (const char *));
2651 filename = (const char **) alloca (nvername * sizeof (const char *));
2653 /* Run through the data structures again and collect the strings. */
2656 /* Run through the version definitions and find the highest
2658 unsigned int offset = 0;
2660 GElf_Shdr defshdrmem;
2663 defdata = elf_getdata (defscn, NULL);
2664 if (unlikely (defdata == NULL))
2667 defshdr = gelf_getshdr (defscn, &defshdrmem);
2668 if (unlikely (defshdr == NULL))
2671 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2674 /* Get the data at the next offset. */
2676 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2677 GElf_Verdaux auxmem;
2678 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2679 offset + def->vd_aux,
2681 if (unlikely (def == NULL || aux == NULL))
2684 vername[def->vd_ndx & 0x7fff]
2685 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2686 filename[def->vd_ndx & 0x7fff] = NULL;
2688 offset += def->vd_next;
2691 if (needscn != NULL)
2693 unsigned int offset = 0;
2695 Elf_Data *needdata = elf_getdata (needscn, NULL);
2696 GElf_Shdr needshdrmem;
2697 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2698 if (unlikely (needdata == NULL || needshdr == NULL))
2701 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2703 /* Get the data at the next offset. */
2704 GElf_Verneed needmem;
2705 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2707 if (unlikely (need == NULL))
2710 /* Run through the auxiliary entries. */
2711 unsigned int auxoffset = offset + need->vn_aux;
2712 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2714 GElf_Vernaux auxmem;
2715 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2717 if (unlikely (aux == NULL))
2720 vername[aux->vna_other & 0x7fff]
2721 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2722 filename[aux->vna_other & 0x7fff]
2723 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2725 auxoffset += aux->vna_next;
2728 offset += need->vn_next;
2739 /* Print the header. */
2741 printf (ngettext ("\
2742 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2744 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2745 shdr->sh_size / shdr->sh_entsize),
2746 (unsigned int) elf_ndxscn (scn),
2747 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2748 (int) (shdr->sh_size / shdr->sh_entsize),
2749 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2751 (unsigned int) shdr->sh_link,
2752 elf_strptr (ebl->elf, shstrndx,
2753 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2756 /* Now we can finally look at the actual contents of this section. */
2757 for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
2760 printf ("\n %4d:", cnt);
2763 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2771 fputs_unlocked (gettext (" 0 *local* "),
2776 fputs_unlocked (gettext (" 1 *global* "),
2781 n = printf ("%4d%c%s",
2782 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2783 (unsigned int) (*sym & 0x7fff) < nvername
2784 ? vername[*sym & 0x7fff] : "???");
2785 if ((unsigned int) (*sym & 0x7fff) < nvername
2786 && filename[*sym & 0x7fff] != NULL)
2787 n += printf ("(%s)", filename[*sym & 0x7fff]);
2788 printf ("%*s", MAX (0, 33 - (int) n), " ");
2792 putchar_unlocked ('\n');
2797 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2798 uint_fast32_t maxlength, Elf32_Word nbucket,
2799 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2801 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2803 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2804 ++counts[lengths[cnt]];
2807 printf (ngettext ("\
2808 \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",
2810 \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",
2812 (unsigned int) elf_ndxscn (scn),
2813 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2815 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2818 (unsigned int) shdr->sh_link,
2819 elf_strptr (ebl->elf, shstrndx,
2820 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2823 if (extrastr != NULL)
2824 fputs (extrastr, stdout);
2826 if (likely (nbucket > 0))
2828 uint64_t success = 0;
2830 /* xgettext:no-c-format */
2831 fputs_unlocked (gettext ("\
2832 Length Number % of total Coverage\n"), stdout);
2833 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2834 counts[0], (counts[0] * 100.0) / nbucket);
2836 uint64_t nzero_counts = 0;
2837 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2839 nzero_counts += counts[cnt] * cnt;
2841 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2842 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2843 (nzero_counts * 100.0) / nsyms);
2847 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2850 success += counts[cnt] * acc;
2854 Average number of tests: successful lookup: %f\n\
2855 unsuccessful lookup: %f\n"),
2856 (double) success / (double) nzero_counts,
2857 (double) nzero_counts / (double) nbucket);
2864 /* This function handles the traditional System V-style hash table format. */
2866 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2868 Elf_Data *data = elf_getdata (scn, NULL);
2869 if (unlikely (data == NULL))
2871 error (0, 0, gettext ("cannot get data for section %d: %s"),
2872 (int) elf_ndxscn (scn), elf_errmsg (-1));
2876 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2877 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2878 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2879 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2881 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2883 uint_fast32_t maxlength = 0;
2884 uint_fast32_t nsyms = 0;
2885 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2887 Elf32_Word inner = bucket[cnt];
2888 while (inner > 0 && inner < nchain)
2891 if (maxlength < ++lengths[cnt])
2894 inner = chain[inner];
2898 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2905 /* This function handles the incorrect, System V-style hash table
2906 format some 64-bit architectures use. */
2908 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2910 Elf_Data *data = elf_getdata (scn, NULL);
2911 if (unlikely (data == NULL))
2913 error (0, 0, gettext ("cannot get data for section %d: %s"),
2914 (int) elf_ndxscn (scn), elf_errmsg (-1));
2918 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
2919 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
2920 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
2921 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
2923 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2925 uint_fast32_t maxlength = 0;
2926 uint_fast32_t nsyms = 0;
2927 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
2929 Elf64_Xword inner = bucket[cnt];
2930 while (inner > 0 && inner < nchain)
2933 if (maxlength < ++lengths[cnt])
2936 inner = chain[inner];
2940 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2947 /* This function handles the GNU-style hash table format. */
2949 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2951 Elf_Data *data = elf_getdata (scn, NULL);
2952 if (unlikely (data == NULL))
2954 error (0, 0, gettext ("cannot get data for section %d: %s"),
2955 (int) elf_ndxscn (scn), elf_errmsg (-1));
2959 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2960 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
2962 /* Next comes the size of the bitmap. It's measured in words for
2963 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
2965 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
2966 if (gelf_getclass (ebl->elf) == ELFCLASS64)
2969 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
2971 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2973 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
2974 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
2975 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
2978 /* Compute distribution of chain lengths. */
2979 uint_fast32_t maxlength = 0;
2980 uint_fast32_t nsyms = 0;
2981 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2982 if (bucket[cnt] != 0)
2984 Elf32_Word inner = bucket[cnt] - symbias;
2988 if (maxlength < ++lengths[cnt])
2991 while ((chain[inner++] & 1) == 0);
2994 /* Count bits in bitmask. */
2995 uint_fast32_t nbits = 0;
2996 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
2998 uint_fast32_t word = bitmask[cnt];
3000 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3001 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3002 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3003 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3004 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3008 if (unlikely (asprintf (&str, gettext ("\
3010 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3011 (unsigned int) symbias,
3012 bitmask_words * sizeof (Elf32_Word),
3014 / (uint_fast32_t) (bitmask_words
3015 * sizeof (Elf32_Word) * 8)),
3016 (unsigned int) shift) == -1))
3017 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3019 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3027 /* Find the symbol table(s). For this we have to search through the
3030 handle_hash (Ebl *ebl)
3032 /* Get the section header string table index. */
3034 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3035 error (EXIT_FAILURE, 0,
3036 gettext ("cannot get section header string table index"));
3038 Elf_Scn *scn = NULL;
3039 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3041 /* Handle the section if it is a symbol table. */
3043 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3045 if (likely (shdr != NULL))
3047 if (shdr->sh_type == SHT_HASH)
3049 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3050 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3052 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3054 else if (shdr->sh_type == SHT_GNU_HASH)
3055 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3062 print_liblist (Ebl *ebl)
3064 /* Find the library list sections. For this we have to search
3065 through the section table. */
3066 Elf_Scn *scn = NULL;
3068 /* Get the section header string table index. */
3070 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3071 error (EXIT_FAILURE, 0,
3072 gettext ("cannot get section header string table index"));
3074 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3077 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3079 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3081 int nentries = shdr->sh_size / shdr->sh_entsize;
3082 printf (ngettext ("\
3083 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3085 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3088 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3092 Elf_Data *data = elf_getdata (scn, NULL);
3097 Library Time Stamp Checksum Version Flags"));
3099 for (int cnt = 0; cnt < nentries; ++cnt)
3102 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3103 if (unlikely (lib == NULL))
3106 time_t t = (time_t) lib->l_time_stamp;
3107 struct tm *tm = gmtime (&t);
3108 if (unlikely (tm == NULL))
3111 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3112 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3113 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3114 tm->tm_hour, tm->tm_min, tm->tm_sec,
3115 (unsigned int) lib->l_checksum,
3116 (unsigned int) lib->l_version,
3117 (unsigned int) lib->l_flags);
3124 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3126 /* Find the object attributes sections. For this we have to search
3127 through the section table. */
3128 Elf_Scn *scn = NULL;
3130 /* Get the section header string table index. */
3132 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3133 error (EXIT_FAILURE, 0,
3134 gettext ("cannot get section header string table index"));
3136 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3139 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3141 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3142 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3143 || ehdr->e_machine != EM_ARM)))
3147 \nObject attributes section [%2zu] '%s' of %" PRIu64
3148 " bytes at offset %#0" PRIx64 ":\n"),
3150 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3151 shdr->sh_size, shdr->sh_offset);
3153 Elf_Data *data = elf_rawdata (scn, NULL);
3157 const unsigned char *p = data->d_buf;
3159 if (unlikely (*p++ != 'A'))
3162 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3164 inline size_t left (void)
3166 return (const unsigned char *) data->d_buf + data->d_size - p;
3169 while (left () >= 4)
3172 memcpy (&len, p, sizeof len);
3174 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3177 if (unlikely (len > left ()))
3180 const unsigned char *name = p + sizeof len;
3183 unsigned const char *q = memchr (name, '\0', len);
3184 if (unlikely (q == NULL))
3188 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3190 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3191 || (q - name == sizeof "gnu"
3192 && !memcmp (name, "gnu", sizeof "gnu")))
3195 const unsigned char *const sub = q;
3197 unsigned int subsection_tag;
3198 get_uleb128 (subsection_tag, q);
3199 if (unlikely (q >= p))
3202 uint32_t subsection_len;
3203 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3206 memcpy (&subsection_len, q, sizeof subsection_len);
3208 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3209 CONVERT (subsection_len);
3211 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3214 const unsigned char *r = q + sizeof subsection_len;
3215 q = sub + subsection_len;
3217 switch (subsection_tag)
3220 printf (gettext (" %-4u %12" PRIu32 "\n"),
3221 subsection_tag, subsection_len);
3224 case 1: /* Tag_File */
3225 printf (gettext (" File: %11" PRIu32 "\n"),
3231 get_uleb128 (tag, r);
3232 if (unlikely (r >= q))
3236 const char *string = NULL;
3237 if (tag == 32 || (tag & 1) == 0)
3239 get_uleb128 (value, r);
3243 if (tag == 32 || (tag & 1) != 0)
3245 r = memchr (r, '\0', q - r);
3251 const char *tag_name = NULL;
3252 const char *value_name = NULL;
3253 ebl_check_object_attribute (ebl, (const char *) name,
3255 &tag_name, &value_name);
3257 if (tag_name != NULL)
3260 printf (gettext (" %s: %" PRId64 ", %s\n"),
3261 tag_name, value, string);
3262 else if (string == NULL && value_name == NULL)
3263 printf (gettext (" %s: %" PRId64 "\n"),
3266 printf (gettext (" %s: %s\n"),
3267 tag_name, string ?: value_name);
3273 printf (gettext (" %u: %" PRId64 "\n"),
3276 printf (gettext (" %u: %s\n"),
3288 format_dwarf_addr (Dwfl_Module *dwflmod,
3289 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3291 /* See if there is a name we can give for this address. */
3293 const char *name = (print_address_names && ! print_unresolved_addresses)
3294 ? dwfl_module_addrsym (dwflmod, address, &sym, NULL) : NULL;
3296 sym.st_value = address - sym.st_value;
3299 if (print_unresolved_addresses)
3306 /* Relativize the address. */
3307 int n = dwfl_module_relocations (dwflmod);
3308 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3310 /* In an ET_REL file there is a section name to refer to. */
3312 : dwfl_module_relocation_info (dwflmod, i, NULL));
3317 ? (sym.st_value != 0
3319 ? (address_size == 0
3320 ? asprintf (&result,
3321 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3322 scn, address, name, sym.st_value)
3323 : asprintf (&result,
3324 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3325 scn, 2 + address_size * 2, address,
3326 name, sym.st_value))
3327 : (address_size == 0
3328 ? asprintf (&result,
3329 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3330 address, name, sym.st_value)
3331 : asprintf (&result,
3332 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3333 2 + address_size * 2, address,
3334 name, sym.st_value)))
3336 ? (address_size == 0
3337 ? asprintf (&result,
3338 gettext ("%s+%#" PRIx64 " <%s>"),
3340 : asprintf (&result,
3341 gettext ("%s+%#0*" PRIx64 " <%s>"),
3342 scn, 2 + address_size * 2, address, name))
3343 : (address_size == 0
3344 ? asprintf (&result,
3345 gettext ("%#" PRIx64 " <%s>"),
3347 : asprintf (&result,
3348 gettext ("%#0*" PRIx64 " <%s>"),
3349 2 + address_size * 2, address, name))))
3351 ? (address_size == 0
3352 ? asprintf (&result,
3353 gettext ("%s+%#" PRIx64),
3355 : asprintf (&result,
3356 gettext ("%s+%#0*" PRIx64),
3357 scn, 2 + address_size * 2, address))
3358 : (address_size == 0
3359 ? asprintf (&result,
3362 : asprintf (&result,
3364 2 + address_size * 2, address)))) < 0)
3365 error (EXIT_FAILURE, 0, _("memory exhausted"));
3371 dwarf_tag_string (unsigned int tag)
3375 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3377 #undef ONE_KNOWN_DW_TAG
3385 dwarf_attr_string (unsigned int attrnum)
3389 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3391 #undef ONE_KNOWN_DW_AT
3399 dwarf_form_string (unsigned int form)
3403 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3404 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3406 #undef ONE_KNOWN_DW_FORM
3407 #undef ONE_KNOWN_DW_FORM_DESC
3415 dwarf_lang_string (unsigned int lang)
3419 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3421 #undef ONE_KNOWN_DW_LANG_DESC
3429 dwarf_inline_string (unsigned int code)
3431 static const char *const known[] =
3433 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3435 #undef ONE_KNOWN_DW_INL
3438 if (likely (code < sizeof (known) / sizeof (known[0])))
3446 dwarf_encoding_string (unsigned int code)
3448 static const char *const known[] =
3450 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3452 #undef ONE_KNOWN_DW_ATE
3455 if (likely (code < sizeof (known) / sizeof (known[0])))
3463 dwarf_access_string (unsigned int code)
3465 static const char *const known[] =
3467 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3469 #undef ONE_KNOWN_DW_ACCESS
3472 if (likely (code < sizeof (known) / sizeof (known[0])))
3480 dwarf_visibility_string (unsigned int code)
3482 static const char *const known[] =
3484 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3486 #undef ONE_KNOWN_DW_VIS
3489 if (likely (code < sizeof (known) / sizeof (known[0])))
3497 dwarf_virtuality_string (unsigned int code)
3499 static const char *const known[] =
3501 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3502 ALL_KNOWN_DW_VIRTUALITY
3503 #undef ONE_KNOWN_DW_VIRTUALITY
3506 if (likely (code < sizeof (known) / sizeof (known[0])))
3514 dwarf_identifier_case_string (unsigned int code)
3516 static const char *const known[] =
3518 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3520 #undef ONE_KNOWN_DW_ID
3523 if (likely (code < sizeof (known) / sizeof (known[0])))
3531 dwarf_calling_convention_string (unsigned int code)
3533 static const char *const known[] =
3535 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3537 #undef ONE_KNOWN_DW_CC
3540 if (likely (code < sizeof (known) / sizeof (known[0])))
3548 dwarf_ordering_string (unsigned int code)
3550 static const char *const known[] =
3552 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3554 #undef ONE_KNOWN_DW_ORD
3557 if (likely (code < sizeof (known) / sizeof (known[0])))
3565 dwarf_discr_list_string (unsigned int code)
3567 static const char *const known[] =
3569 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3571 #undef ONE_KNOWN_DW_DSC
3574 if (likely (code < sizeof (known) / sizeof (known[0])))
3582 dwarf_locexpr_opcode_string (unsigned int code)
3584 static const char *const known[] =
3586 /* Normally we can't affort building huge table of 64K entries,
3587 most of them zero, just because there are a couple defined
3588 values at the far end. In case of opcodes, it's OK. */
3589 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3590 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3592 #undef ONE_KNOWN_DW_OP
3593 #undef ONE_KNOWN_DW_OP_DESC
3596 if (likely (code < sizeof (known) / sizeof (known[0])))
3603 /* Used by all dwarf_foo_name functions. */
3605 string_or_unknown (const char *known, unsigned int code,
3606 unsigned int lo_user, unsigned int hi_user,
3607 bool print_unknown_num)
3609 static char unknown_buf[20];
3611 if (likely (known != NULL))
3614 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3616 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3621 if (print_unknown_num)
3623 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3632 dwarf_tag_name (unsigned int tag)
3634 const char *ret = dwarf_tag_string (tag);
3635 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3639 dwarf_attr_name (unsigned int attr)
3641 const char *ret = dwarf_attr_string (attr);
3642 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3647 dwarf_form_name (unsigned int form)
3649 const char *ret = dwarf_form_string (form);
3650 return string_or_unknown (ret, form, 0, 0, true);
3655 dwarf_lang_name (unsigned int lang)
3657 const char *ret = dwarf_lang_string (lang);
3658 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3663 dwarf_inline_name (unsigned int code)
3665 const char *ret = dwarf_inline_string (code);
3666 return string_or_unknown (ret, code, 0, 0, false);
3671 dwarf_encoding_name (unsigned int code)
3673 const char *ret = dwarf_encoding_string (code);
3674 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3679 dwarf_access_name (unsigned int code)
3681 const char *ret = dwarf_access_string (code);
3682 return string_or_unknown (ret, code, 0, 0, false);
3687 dwarf_visibility_name (unsigned int code)
3689 const char *ret = dwarf_visibility_string (code);
3690 return string_or_unknown (ret, code, 0, 0, false);
3695 dwarf_virtuality_name (unsigned int code)
3697 const char *ret = dwarf_virtuality_string (code);
3698 return string_or_unknown (ret, code, 0, 0, false);
3703 dwarf_identifier_case_name (unsigned int code)
3705 const char *ret = dwarf_identifier_case_string (code);
3706 return string_or_unknown (ret, code, 0, 0, false);
3711 dwarf_calling_convention_name (unsigned int code)
3713 const char *ret = dwarf_calling_convention_string (code);
3714 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3719 dwarf_ordering_name (unsigned int code)
3721 const char *ret = dwarf_ordering_string (code);
3722 return string_or_unknown (ret, code, 0, 0, false);
3727 dwarf_discr_list_name (unsigned int code)
3729 const char *ret = dwarf_discr_list_string (code);
3730 return string_or_unknown (ret, code, 0, 0, false);
3735 print_block (size_t n, const void *block)
3738 puts (_("empty block"));
3741 printf (_("%zu byte block:"), n);
3742 const unsigned char *data = block;
3744 printf (" %02x", *data++);
3751 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3752 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3753 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3755 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3759 printf ("%*s(empty)\n", indent, "");
3763 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3764 #define CONSUME(n) NEED (n); else len -= (n)
3766 Dwarf_Word offset = 0;
3769 uint_fast8_t op = *data++;
3771 const char *op_name = dwarf_locexpr_opcode_string (op);
3772 if (unlikely (op_name == NULL))
3774 static char buf[20];
3775 if (op >= DW_OP_lo_user)
3776 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3778 snprintf (buf, sizeof buf, "??? (%#x)", op);
3785 /* Address operand. */
3789 addr = read_4ubyte_unaligned (dbg, data);
3792 assert (addrsize == 8);
3793 addr = read_8ubyte_unaligned (dbg, data);
3798 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3799 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3800 indent, "", (uintmax_t) offset, op_name, a);
3803 offset += 1 + addrsize;
3806 case DW_OP_call_ref:
3807 /* Offset operand. */
3810 addr = read_4ubyte_unaligned (dbg, data);
3813 assert (ref_size == 8);
3814 addr = read_8ubyte_unaligned (dbg, data);
3819 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
3820 indent, "", (uintmax_t) offset,
3821 op_name, (uintmax_t) addr);
3822 offset += 1 + ref_size;
3825 case DW_OP_deref_size:
3826 case DW_OP_xderef_size:
3829 // XXX value might be modified by relocation
3831 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
3832 indent, "", (uintmax_t) offset,
3833 op_name, *((uint8_t *) data));
3841 // XXX value might be modified by relocation
3842 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3843 indent, "", (uintmax_t) offset,
3844 op_name, read_2ubyte_unaligned (dbg, data));
3852 // XXX value might be modified by relocation
3853 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3854 indent, "", (uintmax_t) offset,
3855 op_name, read_4ubyte_unaligned (dbg, data));
3863 // XXX value might be modified by relocation
3864 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3865 indent, "", (uintmax_t) offset,
3866 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
3874 // XXX value might be modified by relocation
3875 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
3876 indent, "", (uintmax_t) offset,
3877 op_name, *((int8_t *) data));
3885 // XXX value might be modified by relocation
3886 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
3887 indent, "", (uintmax_t) offset,
3888 op_name, read_2sbyte_unaligned (dbg, data));
3896 // XXX value might be modified by relocation
3897 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
3898 indent, "", (uintmax_t) offset,
3899 op_name, read_4sbyte_unaligned (dbg, data));
3907 // XXX value might be modified by relocation
3908 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3909 indent, "", (uintmax_t) offset,
3910 op_name, read_8sbyte_unaligned (dbg, data));
3918 case DW_OP_plus_uconst:
3920 const unsigned char *start = data;
3923 get_uleb128 (uleb, data); /* XXX check overrun */
3924 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3925 indent, "", (uintmax_t) offset, op_name, uleb);
3926 CONSUME (data - start);
3927 offset += 1 + (data - start);
3930 case DW_OP_bit_piece:
3934 get_uleb128 (uleb, data); /* XXX check overrun */
3935 get_uleb128 (uleb2, data); /* XXX check overrun */
3936 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
3937 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
3938 CONSUME (data - start);
3939 offset += 1 + (data - start);
3943 case DW_OP_breg0 ... DW_OP_breg31:
3948 get_sleb128 (sleb, data); /* XXX check overrun */
3949 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3950 indent, "", (uintmax_t) offset, op_name, sleb);
3951 CONSUME (data - start);
3952 offset += 1 + (data - start);
3958 get_uleb128 (uleb, data); /* XXX check overrun */
3959 get_sleb128 (sleb, data); /* XXX check overrun */
3960 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
3961 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
3962 CONSUME (data - start);
3963 offset += 1 + (data - start);
3968 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3969 indent, "", (uintmax_t) offset, op_name,
3970 read_2ubyte_unaligned (dbg, data));
3977 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3978 indent, "", (uintmax_t) offset, op_name,
3979 read_4ubyte_unaligned (dbg, data));
3987 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
3988 indent, "", (uintmax_t) offset, op_name,
3989 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
3995 case DW_OP_implicit_value:
3998 get_uleb128 (uleb, data); /* XXX check overrun */
3999 printf ("%*s[%4" PRIuMAX "] %s: ",
4000 indent, "", (uintmax_t) offset, op_name);
4002 print_block (uleb, data);
4004 CONSUME (data - start);
4005 offset += 1 + (data - start);
4008 case DW_OP_GNU_implicit_pointer:
4009 /* DIE offset operand. */
4011 NEED (ref_size + 1);
4013 addr = read_4ubyte_unaligned (dbg, data);
4016 assert (ref_size == 8);
4017 addr = read_8ubyte_unaligned (dbg, data);
4020 /* Byte offset operand. */
4021 get_sleb128 (sleb, data); /* XXX check overrun */
4023 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4024 indent, "", (intmax_t) offset,
4025 op_name, (uintmax_t) addr, sleb);
4026 CONSUME (data - start);
4027 offset += 1 + (data - start);
4030 case DW_OP_GNU_entry_value:
4031 /* Size plus expression block. */
4034 get_uleb128 (uleb, data); /* XXX check overrun */
4035 printf ("%*s[%4" PRIuMAX "] %s:\n",
4036 indent, "", (uintmax_t) offset, op_name);
4038 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4039 addrsize, offset_size, cu, uleb, data);
4041 CONSUME (data - start);
4042 offset += 1 + (data - start);
4045 case DW_OP_GNU_const_type:
4046 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4047 unsigned size plus block. */
4050 get_uleb128 (uleb, data); /* XXX check overrun */
4051 if (! print_unresolved_addresses && cu != NULL)
4053 uint8_t usize = *(uint8_t *) data++;
4055 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4056 indent, "", (uintmax_t) offset, op_name, uleb);
4057 print_block (usize, data);
4059 CONSUME (data - start);
4060 offset += 1 + (data - start);
4063 case DW_OP_GNU_regval_type:
4064 /* uleb128 register number, uleb128 CU relative
4065 DW_TAG_base_type DIE offset. */
4068 get_uleb128 (uleb, data); /* XXX check overrun */
4069 get_uleb128 (uleb2, data); /* XXX check overrun */
4070 if (! print_unresolved_addresses && cu != NULL)
4072 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4073 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4074 CONSUME (data - start);
4075 offset += 1 + (data - start);
4078 case DW_OP_GNU_deref_type:
4079 /* 1-byte unsigned size of value, uleb128 CU relative
4080 DW_TAG_base_type DIE offset. */
4083 usize = *(uint8_t *) data++;
4084 get_uleb128 (uleb, data); /* XXX check overrun */
4085 if (! print_unresolved_addresses && cu != NULL)
4087 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4088 indent, "", (uintmax_t) offset,
4089 op_name, usize, uleb);
4090 CONSUME (data - start);
4091 offset += 1 + (data - start);
4094 case DW_OP_GNU_convert:
4095 case DW_OP_GNU_reinterpret:
4096 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4097 for conversion to untyped. */
4100 get_uleb128 (uleb, data); /* XXX check overrun */
4101 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4103 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4104 indent, "", (uintmax_t) offset, op_name, uleb);
4105 CONSUME (data - start);
4106 offset += 1 + (data - start);
4109 case DW_OP_GNU_parameter_ref:
4110 /* 4 byte CU relative reference to the abstract optimized away
4111 DW_TAG_formal_parameter. */
4113 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4114 if (! print_unresolved_addresses && cu != NULL)
4115 param_off += cu->start;
4116 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4117 indent, "", (uintmax_t) offset, op_name, param_off);
4125 printf ("%*s[%4" PRIuMAX "] %s\n",
4126 indent, "", (uintmax_t) offset, op_name);
4131 indent = indentrest;
4135 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4136 indent, "", (uintmax_t) offset, op_name);
4144 Dwarf_Off offset:(64 - 3);
4148 struct Dwarf_CU *cu;
4151 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4152 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4155 listptr_base (struct listptr *p)
4158 Dwarf_Die cu = CUDIE (p->cu);
4159 /* Find the base address of the compilation unit. It will normally
4160 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4161 address could be overridden by DW_AT_entry_pc. It's been
4162 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4163 compilation units with discontinuous ranges. */
4164 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4166 Dwarf_Attribute attr_mem;
4167 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4175 compare_listptr (const void *a, const void *b, void *arg)
4177 const char *name = arg;
4178 struct listptr *p1 = (void *) a;
4179 struct listptr *p2 = (void *) b;
4181 if (p1->offset < p2->offset)
4183 if (p1->offset > p2->offset)
4186 if (!p1->warned && !p2->warned)
4188 if (p1->addr64 != p2->addr64)
4190 p1->warned = p2->warned = true;
4192 gettext ("%s %#" PRIx64 " used with different address sizes"),
4193 name, (uint64_t) p1->offset);
4195 if (p1->dwarf64 != p2->dwarf64)
4197 p1->warned = p2->warned = true;
4199 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4200 name, (uint64_t) p1->offset);
4202 if (listptr_base (p1) != listptr_base (p2))
4204 p1->warned = p2->warned = true;
4206 gettext ("%s %#" PRIx64 " used with different base addresses"),
4207 name, (uint64_t) p1->offset);
4214 struct listptr_table
4218 struct listptr *table;
4221 static struct listptr_table known_loclistptr;
4222 static struct listptr_table known_rangelistptr;
4225 reset_listptr (struct listptr_table *table)
4227 free (table->table);
4228 table->table = NULL;
4229 table->n = table->alloc = 0;
4233 notice_listptr (enum section_e section, struct listptr_table *table,
4234 uint_fast8_t address_size, uint_fast8_t offset_size,
4235 struct Dwarf_CU *cu, Dwarf_Off offset)
4237 if (print_debug_sections & section)
4239 if (table->n == table->alloc)
4241 if (table->alloc == 0)
4245 table->table = xrealloc (table->table,
4246 table->alloc * sizeof table->table[0]);
4249 struct listptr *p = &table->table[table->n++];
4251 *p = (struct listptr)
4253 .addr64 = address_size == 8,
4254 .dwarf64 = offset_size == 8,
4258 assert (p->offset == offset);
4263 sort_listptr (struct listptr_table *table, const char *name)
4266 qsort_r (table->table, table->n, sizeof table->table[0],
4267 &compare_listptr, (void *) name);
4271 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4272 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4273 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4274 unsigned char **readp, unsigned char *endp)
4279 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4282 struct listptr *p = &table->table[*idxp];
4284 if (*idxp == table->n
4285 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4288 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4293 if (p->offset != (Dwarf_Off) offset)
4295 *readp += p->offset - offset;
4296 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4297 offset, (Dwarf_Off) p->offset - offset);
4301 if (address_sizep != NULL)
4302 *address_sizep = listptr_address_size (p);
4303 if (offset_sizep != NULL)
4304 *offset_sizep = listptr_offset_size (p);
4306 *base = listptr_base (p);
4315 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4316 Ebl *ebl, GElf_Ehdr *ehdr,
4317 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4319 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4320 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4322 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4324 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4325 (uint64_t) shdr->sh_offset);
4327 Dwarf_Off offset = 0;
4328 while (offset < sh_size)
4330 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4336 Dwarf_Abbrev abbrev;
4338 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4341 if (unlikely (res < 0))
4344 *** error while reading abbreviation: %s\n"),
4349 /* This is the NUL byte at the end of the section. */
4354 /* We know these calls can never fail. */
4355 unsigned int code = dwarf_getabbrevcode (&abbrev);
4356 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4357 int has_children = dwarf_abbrevhaschildren (&abbrev);
4359 printf (gettext (" [%5u] offset: %" PRId64
4360 ", children: %s, tag: %s\n"),
4361 code, (int64_t) offset,
4362 has_children ? gettext ("yes") : gettext ("no"),
4363 dwarf_tag_name (tag));
4369 while (dwarf_getabbrevattr (&abbrev, cnt,
4370 &name, &form, &enoffset) == 0)
4372 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4373 dwarf_attr_name (name), dwarf_form_name (form),
4374 (uint64_t) enoffset);
4385 /* Print content of DWARF .debug_aranges section. We fortunately do
4386 not have to know a bit about the structure of the section, libdwarf
4387 takes care of it. */
4389 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4390 GElf_Shdr *shdr, Dwarf *dbg)
4392 Dwarf_Aranges *aranges;
4394 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4396 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4401 printf (ngettext ("\
4402 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4404 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4406 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4407 (uint64_t) shdr->sh_offset, cnt);
4409 /* Compute floor(log16(cnt)). */
4418 for (size_t n = 0; n < cnt; ++n)
4420 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4421 if (unlikely (runp == NULL))
4423 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4431 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4432 printf (gettext (" [%*zu] ???\n"), digits, n);
4434 printf (gettext (" [%*zu] start: %0#*" PRIx64
4435 ", length: %5" PRIu64 ", CU DIE offset: %6"
4437 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4438 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4443 /* Print content of DWARF .debug_aranges section. */
4445 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4446 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4447 GElf_Shdr *shdr, Dwarf *dbg)
4451 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4455 Elf_Data *data = elf_rawdata (scn, NULL);
4457 if (unlikely (data == NULL))
4459 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4465 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4466 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4467 (uint64_t) shdr->sh_offset);
4469 const unsigned char *readp = data->d_buf;
4470 const unsigned char *readendp = readp + data->d_size;
4472 while (readp < readendp)
4474 const unsigned char *hdrstart = readp;
4475 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4477 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4478 if (readp + 4 > readendp)
4481 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4482 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4486 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4487 unsigned int length_bytes = 4;
4488 if (length == DWARF3_LENGTH_64_BIT)
4490 if (readp + 8 > readendp)
4492 length = read_8ubyte_unaligned_inc (dbg, readp);
4496 const unsigned char *nexthdr = readp + length;
4497 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4500 if (nexthdr > readendp)
4506 if (readp + 2 > readendp)
4508 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4509 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4513 error (0, 0, gettext ("unsupported aranges version"));
4518 if (readp + length_bytes > readendp)
4520 if (length_bytes == 8)
4521 offset = read_8ubyte_unaligned_inc (dbg, readp);
4523 offset = read_4ubyte_unaligned_inc (dbg, readp);
4524 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4527 if (readp + 1 > readendp)
4529 unsigned int address_size = *readp++;
4530 printf (gettext (" Address size: %6" PRIu64 "\n"),
4531 (uint64_t) address_size);
4532 if (address_size != 4 && address_size != 8)
4534 error (0, 0, gettext ("unsupported address size"));
4538 unsigned int segment_size = *readp++;
4539 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4540 (uint64_t) segment_size);
4541 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4543 error (0, 0, gettext ("unsupported segment size"));
4547 /* Round the address to the next multiple of 2*address_size. */
4548 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4549 % (2 * address_size));
4551 while (readp < nexthdr)
4553 Dwarf_Word range_address;
4554 Dwarf_Word range_length;
4555 Dwarf_Word segment = 0;
4556 if (readp + 2 * address_size + segment_size > readendp)
4558 if (address_size == 4)
4560 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4561 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4565 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4566 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4569 if (segment_size == 4)
4570 segment = read_4ubyte_unaligned_inc (dbg, readp);
4571 else if (segment_size == 8)
4572 segment = read_8ubyte_unaligned_inc (dbg, readp);
4574 if (range_address == 0 && range_length == 0 && segment == 0)
4577 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4579 char *e = format_dwarf_addr (dwflmod, address_size,
4580 range_address + range_length - 1,
4582 if (segment_size != 0)
4583 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4584 (uint64_t) segment);
4586 printf (gettext (" %s..%s\n"), b, e);
4592 if (readp != nexthdr)
4594 size_t padding = nexthdr - readp;
4595 printf (gettext (" %Zu padding bytes\n"), padding);
4602 /* Print content of DWARF .debug_ranges section. */
4604 print_debug_ranges_section (Dwfl_Module *dwflmod,
4605 Ebl *ebl, GElf_Ehdr *ehdr,
4606 Elf_Scn *scn, GElf_Shdr *shdr,
4609 Elf_Data *data = elf_rawdata (scn, NULL);
4611 if (unlikely (data == NULL))
4613 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4619 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4620 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4621 (uint64_t) shdr->sh_offset);
4623 sort_listptr (&known_rangelistptr, "rangelistptr");
4624 size_t listptr_idx = 0;
4626 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4629 Dwarf_Addr base = 0;
4630 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4631 unsigned char *readp = data->d_buf;
4632 while (readp < endp)
4634 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4636 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4637 &address_size, NULL, &base, NULL,
4638 offset, &readp, endp))
4641 if (unlikely (data->d_size - offset < address_size * 2))
4643 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4649 if (address_size == 8)
4651 begin = read_8ubyte_unaligned_inc (dbg, readp);
4652 end = read_8ubyte_unaligned_inc (dbg, readp);
4656 begin = read_4ubyte_unaligned_inc (dbg, readp);
4657 end = read_4ubyte_unaligned_inc (dbg, readp);
4658 if (begin == (Dwarf_Addr) (uint32_t) -1)
4659 begin = (Dwarf_Addr) -1l;
4662 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4664 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4665 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4669 else if (begin == 0 && end == 0) /* End of list entry. */
4672 printf (gettext (" [%6tx] empty list\n"), offset);
4677 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4679 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4681 /* We have an address range entry. */
4682 if (first) /* First address range entry in a list. */
4683 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4685 printf (gettext (" %s..%s\n"), b, e);
4694 #define REGNAMESZ 16
4696 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4697 char name[REGNAMESZ], int *bits, int *type)
4702 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4703 bits ?: &ignore, type ?: &ignore);
4707 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4709 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4711 *bits = loc != NULL ? loc->bits : 0;
4713 *type = DW_ATE_unsigned;
4714 set = "??? unrecognized";
4718 if (bits != NULL && *bits <= 0)
4719 *bits = loc != NULL ? loc->bits : 0;
4720 if (type != NULL && *type == DW_ATE_void)
4721 *type = DW_ATE_unsigned;
4728 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4729 Dwarf_Word vma_base, unsigned int code_align,
4731 unsigned int version, unsigned int ptr_size,
4732 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4734 char regnamebuf[REGNAMESZ];
4735 const char *regname (unsigned int regno)
4737 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4741 puts ("\n Program:");
4742 Dwarf_Word pc = vma_base;
4743 while (readp < endp)
4745 unsigned int opcode = *readp++;
4747 if (opcode < DW_CFA_advance_loc)
4748 /* Extended opcode. */
4759 case DW_CFA_set_loc:
4760 // XXX overflow check
4761 get_uleb128 (op1, readp);
4763 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4765 case DW_CFA_advance_loc1:
4766 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4767 *readp, pc += *readp * code_align);
4770 case DW_CFA_advance_loc2:
4771 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4772 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4773 op1, pc += op1 * code_align);
4775 case DW_CFA_advance_loc4:
4776 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4777 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4778 op1, pc += op1 * code_align);
4780 case DW_CFA_offset_extended:
4781 // XXX overflow check
4782 get_uleb128 (op1, readp);
4783 get_uleb128 (op2, readp);
4784 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4786 op1, regname (op1), op2 * data_align);
4788 case DW_CFA_restore_extended:
4789 // XXX overflow check
4790 get_uleb128 (op1, readp);
4791 printf (" restore_extended r%" PRIu64 " (%s)\n",
4792 op1, regname (op1));
4794 case DW_CFA_undefined:
4795 // XXX overflow check
4796 get_uleb128 (op1, readp);
4797 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4799 case DW_CFA_same_value:
4800 // XXX overflow check
4801 get_uleb128 (op1, readp);
4802 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4804 case DW_CFA_register:
4805 // XXX overflow check
4806 get_uleb128 (op1, readp);
4807 get_uleb128 (op2, readp);
4808 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4809 op1, regname (op1), op2, regname (op2));
4811 case DW_CFA_remember_state:
4812 puts (" remember_state");
4814 case DW_CFA_restore_state:
4815 puts (" restore_state");
4817 case DW_CFA_def_cfa:
4818 // XXX overflow check
4819 get_uleb128 (op1, readp);
4820 get_uleb128 (op2, readp);
4821 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4822 op1, regname (op1), op2);
4824 case DW_CFA_def_cfa_register:
4825 // XXX overflow check
4826 get_uleb128 (op1, readp);
4827 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
4828 op1, regname (op1));
4830 case DW_CFA_def_cfa_offset:
4831 // XXX overflow check
4832 get_uleb128 (op1, readp);
4833 printf (" def_cfa_offset %" PRIu64 "\n", op1);
4835 case DW_CFA_def_cfa_expression:
4836 // XXX overflow check
4837 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */
4838 printf (" def_cfa_expression %" PRIu64 "\n", op1);
4839 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4843 case DW_CFA_expression:
4844 // XXX overflow check
4845 get_uleb128 (op1, readp);
4846 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4847 printf (" expression r%" PRIu64 " (%s) \n",
4848 op1, regname (op1));
4849 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4853 case DW_CFA_offset_extended_sf:
4854 // XXX overflow check
4855 get_uleb128 (op1, readp);
4856 get_sleb128 (sop2, readp);
4857 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
4859 op1, regname (op1), sop2 * data_align);
4861 case DW_CFA_def_cfa_sf:
4862 // XXX overflow check
4863 get_uleb128 (op1, readp);
4864 get_sleb128 (sop2, readp);
4865 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
4866 op1, regname (op1), sop2 * data_align);
4868 case DW_CFA_def_cfa_offset_sf:
4869 // XXX overflow check
4870 get_sleb128 (sop1, readp);
4871 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
4873 case DW_CFA_val_offset:
4874 // XXX overflow check
4875 get_uleb128 (op1, readp);
4876 get_uleb128 (op2, readp);
4877 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
4878 op1, op2 * data_align);
4880 case DW_CFA_val_offset_sf:
4881 // XXX overflow check
4882 get_uleb128 (op1, readp);
4883 get_sleb128 (sop2, readp);
4884 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
4885 op1, sop2 * data_align);
4887 case DW_CFA_val_expression:
4888 // XXX overflow check
4889 get_uleb128 (op1, readp);
4890 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */
4891 printf (" val_expression r%" PRIu64 " (%s)\n",
4892 op1, regname (op1));
4893 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
4897 case DW_CFA_MIPS_advance_loc8:
4898 op1 = read_8ubyte_unaligned_inc (dbg, readp);
4899 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
4900 op1, pc += op1 * code_align);
4902 case DW_CFA_GNU_window_save:
4903 puts (" GNU_window_save");
4905 case DW_CFA_GNU_args_size:
4906 // XXX overflow check
4907 get_uleb128 (op1, readp);
4908 printf (" args_size %" PRIu64 "\n", op1);
4911 printf (" ??? (%u)\n", opcode);
4914 else if (opcode < DW_CFA_offset)
4915 printf (" advance_loc %u to %#" PRIx64 "\n",
4916 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
4917 else if (opcode < DW_CFA_restore)
4920 // XXX overflow check
4921 get_uleb128 (offset, readp);
4922 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
4923 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
4926 printf (" restore r%u (%s)\n",
4927 opcode & 0x3f, regname (opcode & 0x3f));
4933 encoded_ptr_size (int encoding, unsigned int ptr_size)
4935 switch (encoding & 7)
4950 print_encoding (unsigned int val)
4954 case DW_EH_PE_absptr:
4955 fputs ("absptr", stdout);
4957 case DW_EH_PE_uleb128:
4958 fputs ("uleb128", stdout);
4960 case DW_EH_PE_udata2:
4961 fputs ("udata2", stdout);
4963 case DW_EH_PE_udata4:
4964 fputs ("udata4", stdout);
4966 case DW_EH_PE_udata8:
4967 fputs ("udata8", stdout);
4969 case DW_EH_PE_sleb128:
4970 fputs ("sleb128", stdout);
4972 case DW_EH_PE_sdata2:
4973 fputs ("sdata2", stdout);
4975 case DW_EH_PE_sdata4:
4976 fputs ("sdata4", stdout);
4978 case DW_EH_PE_sdata8:
4979 fputs ("sdata8", stdout);
4982 /* We did not use any of the bits after all. */
4991 print_relinfo (unsigned int val)
4995 case DW_EH_PE_pcrel:
4996 fputs ("pcrel", stdout);
4998 case DW_EH_PE_textrel:
4999 fputs ("textrel", stdout);
5001 case DW_EH_PE_datarel:
5002 fputs ("datarel", stdout);
5004 case DW_EH_PE_funcrel:
5005 fputs ("funcrel", stdout);
5007 case DW_EH_PE_aligned:
5008 fputs ("aligned", stdout);
5019 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5021 printf ("(%s", pfx);
5023 if (fde_encoding == DW_EH_PE_omit)
5027 unsigned int w = fde_encoding;
5029 w = print_encoding (w);
5033 if (w != fde_encoding)
5034 fputc_unlocked (' ', stdout);
5036 w = print_relinfo (w);
5040 printf ("%s%x", w != fde_encoding ? " " : "", w);
5047 static const unsigned char *
5048 read_encoded (unsigned int encoding, const unsigned char *readp,
5049 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5051 if ((encoding & 0xf) == DW_EH_PE_absptr)
5052 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5053 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5055 switch (encoding & 0xf)
5057 case DW_EH_PE_uleb128:
5058 // XXX buffer overrun check
5059 get_uleb128 (*res, readp);
5061 case DW_EH_PE_sleb128:
5062 // XXX buffer overrun check
5063 get_sleb128 (*res, readp);
5065 case DW_EH_PE_udata2:
5066 if (readp + 2 > endp)
5068 *res = read_2ubyte_unaligned_inc (dbg, readp);
5070 case DW_EH_PE_udata4:
5071 if (readp + 4 > endp)
5073 *res = read_4ubyte_unaligned_inc (dbg, readp);
5075 case DW_EH_PE_udata8:
5076 if (readp + 8 > endp)
5078 *res = read_8ubyte_unaligned_inc (dbg, readp);
5080 case DW_EH_PE_sdata2:
5081 if (readp + 2 > endp)
5083 *res = read_2sbyte_unaligned_inc (dbg, readp);
5085 case DW_EH_PE_sdata4:
5086 if (readp + 4 > endp)
5088 *res = read_4sbyte_unaligned_inc (dbg, readp);
5090 case DW_EH_PE_sdata8:
5091 if (readp + 8 > endp)
5093 *res = read_8sbyte_unaligned_inc (dbg, readp);
5098 gettext ("invalid encoding"));
5106 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5107 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5110 /* We know this call will succeed since it did in the caller. */
5111 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5112 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5114 /* Needed if we find PC-relative addresses. */
5116 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5118 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5122 Elf_Data *data = elf_rawdata (scn, NULL);
5124 if (unlikely (data == NULL))
5126 error (0, 0, gettext ("cannot get %s content: %s"),
5127 scnname, elf_errmsg (-1));
5130 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5134 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5135 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5138 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5139 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5143 ptrdiff_t cie_offset;
5144 const char *augmentation;
5145 unsigned int code_alignment_factor;
5146 unsigned int data_alignment_factor;
5147 uint8_t address_size;
5148 uint8_t fde_encoding;
5149 uint8_t lsda_encoding;
5150 struct cieinfo *next;
5153 const unsigned char *readp = data->d_buf;
5154 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5156 while (readp < dataend)
5158 if (unlikely (readp + 4 > dataend))
5161 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5162 elf_ndxscn (scn), scnname);
5166 /* At the beginning there must be a CIE. There can be multiple,
5167 hence we test tis in a loop. */
5168 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5170 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5171 unsigned int length = 4;
5172 if (unlikely (unit_length == 0xffffffff))
5174 if (unlikely (readp + 8 > dataend))
5177 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5181 if (unlikely (unit_length == 0))
5183 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5187 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5189 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5190 const unsigned char *const cieend = readp + unit_length;
5191 if (unlikely (cieend > dataend || readp + 8 > dataend))
5197 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5198 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5199 cie_id = DW_CIE_ID_64;
5202 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5204 uint_fast8_t version = 2;
5205 unsigned int code_alignment_factor;
5206 int data_alignment_factor;
5207 unsigned int fde_encoding = 0;
5208 unsigned int lsda_encoding = 0;
5209 Dwarf_Word initial_location = 0;
5210 Dwarf_Word vma_base = 0;
5212 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5215 const char *const augmentation = (const char *) readp;
5216 readp = memchr (readp, '\0', cieend - readp);
5217 if (unlikely (readp == NULL))
5221 uint_fast8_t segment_size = 0;
5224 if (cieend - readp < 5)
5226 ptr_size = *readp++;
5227 segment_size = *readp++;
5230 // XXX Check overflow
5231 get_uleb128 (code_alignment_factor, readp);
5232 // XXX Check overflow
5233 get_sleb128 (data_alignment_factor, readp);
5235 /* In some variant for unwind data there is another field. */
5236 if (strcmp (augmentation, "eh") == 0)
5237 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5239 unsigned int return_address_register;
5240 if (unlikely (version == 1))
5241 return_address_register = *readp++;
5243 // XXX Check overflow
5244 get_uleb128 (return_address_register, readp);
5246 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5247 " CIE_id: %" PRIu64 "\n"
5249 " augmentation: \"%s\"\n",
5250 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5251 version, augmentation);
5253 printf (" address_size: %u\n"
5254 " segment_size: %u\n",
5255 ptr_size, segment_size);
5256 printf (" code_alignment_factor: %u\n"
5257 " data_alignment_factor: %d\n"
5258 " return_address_register: %u\n",
5259 code_alignment_factor,
5260 data_alignment_factor, return_address_register);
5262 if (augmentation[0] == 'z')
5264 unsigned int augmentationlen;
5265 get_uleb128 (augmentationlen, readp);
5267 if (augmentationlen > (size_t) (dataend - readp))
5268 error (1, 0, gettext ("invalid augmentation length"));
5270 const char *hdr = "Augmentation data:";
5271 const char *cp = augmentation + 1;
5274 printf (" %-26s%#x ", hdr, *readp);
5279 fde_encoding = *readp++;
5280 print_encoding_base (gettext ("FDE address encoding: "),
5283 else if (*cp == 'L')
5285 lsda_encoding = *readp++;
5286 print_encoding_base (gettext ("LSDA pointer encoding: "),
5289 else if (*cp == 'P')
5291 /* Personality. This field usually has a relocation
5292 attached pointing to __gcc_personality_v0. */
5293 const unsigned char *startp = readp;
5294 unsigned int encoding = *readp++;
5296 readp = read_encoded (encoding, readp,
5297 readp - 1 + augmentationlen,
5300 while (++startp < readp)
5301 printf ("%#x ", *startp);
5304 print_encoding (encoding);
5306 switch (encoding & 0xf)
5308 case DW_EH_PE_sleb128:
5309 case DW_EH_PE_sdata2:
5310 case DW_EH_PE_sdata4:
5311 printf ("%" PRId64 ")\n", val);
5314 printf ("%#" PRIx64 ")\n", val);
5319 printf ("(%x)\n", *readp++);
5325 if (likely (ptr_size == 4 || ptr_size == 8))
5327 struct cieinfo *newp = alloca (sizeof (*newp));
5328 newp->cie_offset = offset;
5329 newp->augmentation = augmentation;
5330 newp->fde_encoding = fde_encoding;
5331 newp->lsda_encoding = lsda_encoding;
5332 newp->address_size = ptr_size;
5333 newp->code_alignment_factor = code_alignment_factor;
5334 newp->data_alignment_factor = data_alignment_factor;
5341 struct cieinfo *cie = cies;
5344 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5345 : (ptrdiff_t) cie_id == cie->cie_offset)
5349 if (unlikely (cie == NULL))
5351 puts ("invalid CIE reference in FDE");
5355 /* Initialize from CIE data. */
5356 fde_encoding = cie->fde_encoding;
5357 lsda_encoding = cie->lsda_encoding;
5358 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5359 code_alignment_factor = cie->code_alignment_factor;
5360 data_alignment_factor = cie->data_alignment_factor;
5362 const unsigned char *base = readp;
5363 // XXX There are sometimes relocations for this value
5364 initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5365 Dwarf_Word address_range
5366 = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5368 /* pcrel for an FDE address is relative to the runtime
5369 address of the start_address field itself. Sign extend
5370 if necessary to make sure the calculation is done on the
5371 full 64 bit address even when initial_location only holds
5372 the lower 32 bits. */
5373 Dwarf_Addr pc_start = initial_location;
5375 pc_start = (uint64_t) (int32_t) pc_start;
5376 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5377 pc_start += ((uint64_t) shdr->sh_addr
5378 + (base - (const unsigned char *) data->d_buf)
5381 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5382 pc_start, initial_location);
5383 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5384 " CIE_pointer: %" PRIu64 "\n"
5385 " initial_location: %s",
5386 offset, (uint64_t) unit_length,
5387 cie->cie_offset, (uint64_t) cie_id, a);
5389 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5391 vma_base = (((uint64_t) shdr->sh_offset
5392 + (base - (const unsigned char *) data->d_buf)
5393 + (uint64_t) initial_location)
5395 ? UINT64_C (0xffffffff)
5396 : UINT64_C (0xffffffffffffffff)));
5397 printf (gettext (" (offset: %#" PRIx64 ")"),
5398 (uint64_t) vma_base);
5401 printf ("\n address_range: %#" PRIx64,
5402 (uint64_t) address_range);
5403 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5404 printf (gettext (" (end offset: %#" PRIx64 ")"),
5405 ((uint64_t) vma_base + (uint64_t) address_range)
5407 ? UINT64_C (0xffffffff)
5408 : UINT64_C (0xffffffffffffffff)));
5411 if (cie->augmentation[0] == 'z')
5413 unsigned int augmentationlen;
5414 get_uleb128 (augmentationlen, readp);
5416 if (augmentationlen > 0)
5418 const char *hdr = "Augmentation data:";
5419 const char *cp = cie->augmentation + 1;
5425 uint64_t lsda_pointer;
5426 const unsigned char *p
5427 = read_encoded (lsda_encoding, &readp[u],
5428 &readp[augmentationlen],
5429 &lsda_pointer, dbg);
5432 %-26sLSDA pointer: %#" PRIx64 "\n"),
5439 while (u < augmentationlen)
5441 printf (" %-26s%#x\n", hdr, readp[u++]);
5446 readp += augmentationlen;
5450 /* Handle the initialization instructions. */
5451 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5452 data_alignment_factor, version, ptr_size,
5461 Dwfl_Module *dwflmod;
5466 unsigned int version;
5467 unsigned int addrsize;
5468 unsigned int offset_size;
5469 struct Dwarf_CU *cu;
5474 attr_callback (Dwarf_Attribute *attrp, void *arg)
5476 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5477 const int level = cbargs->level;
5479 unsigned int attr = dwarf_whatattr (attrp);
5480 if (unlikely (attr == 0))
5482 if (!cbargs->silent)
5483 error (0, 0, gettext ("cannot get attribute code: %s"),
5485 return DWARF_CB_ABORT;
5488 unsigned int form = dwarf_whatform (attrp);
5489 if (unlikely (form == 0))
5491 if (!cbargs->silent)
5492 error (0, 0, gettext ("cannot get attribute form: %s"),
5494 return DWARF_CB_ABORT;
5500 if (!cbargs->silent)
5503 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5506 if (!cbargs->silent)
5507 error (0, 0, gettext ("cannot get attribute value: %s"),
5509 return DWARF_CB_ABORT;
5511 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5513 printf (" %*s%-20s (%s) %s\n",
5514 (int) (level * 2), "", dwarf_attr_name (attr),
5515 dwarf_form_name (form), a);
5520 case DW_FORM_indirect:
5522 case DW_FORM_string:
5523 case DW_FORM_GNU_strp_alt:
5526 const char *str = dwarf_formstring (attrp);
5527 if (unlikely (str == NULL))
5529 printf (" %*s%-20s (%s) \"%s\"\n",
5530 (int) (level * 2), "", dwarf_attr_name (attr),
5531 dwarf_form_name (form), str);
5534 case DW_FORM_ref_addr:
5535 case DW_FORM_ref_udata:
5540 case DW_FORM_GNU_ref_alt:
5544 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5547 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5548 (int) (level * 2), "", dwarf_attr_name (attr),
5549 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5552 case DW_FORM_ref_sig8:
5555 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5556 (int) (level * 2), "", dwarf_attr_name (attr),
5557 dwarf_form_name (form),
5558 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5561 case DW_FORM_sec_offset:
5567 case DW_FORM_data1:;
5569 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5572 const char *valuestr = NULL;
5575 /* This case can take either a constant or a loclistptr. */
5576 case DW_AT_data_member_location:
5577 if (form != DW_FORM_sec_offset
5578 && (cbargs->version >= 4
5579 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5581 if (!cbargs->silent)
5582 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5583 (int) (level * 2), "", dwarf_attr_name (attr),
5584 dwarf_form_name (form), (uintmax_t) num);
5587 /* else fallthrough */
5589 /* These cases always take a loclistptr and no constant. */
5590 case DW_AT_location:
5591 case DW_AT_data_location:
5592 case DW_AT_vtable_elem_location:
5593 case DW_AT_string_length:
5594 case DW_AT_use_location:
5595 case DW_AT_frame_base:
5596 case DW_AT_return_addr:
5597 case DW_AT_static_link:
5598 case DW_AT_GNU_call_site_value:
5599 case DW_AT_GNU_call_site_data_value:
5600 case DW_AT_GNU_call_site_target:
5601 case DW_AT_GNU_call_site_target_clobbered:
5602 notice_listptr (section_loc, &known_loclistptr,
5603 cbargs->addrsize, cbargs->offset_size,
5605 if (!cbargs->silent)
5606 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5607 (int) (level * 2), "", dwarf_attr_name (attr),
5608 dwarf_form_name (form), (uintmax_t) num);
5612 notice_listptr (section_ranges, &known_rangelistptr,
5613 cbargs->addrsize, cbargs->offset_size,
5615 if (!cbargs->silent)
5616 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5617 (int) (level * 2), "", dwarf_attr_name (attr),
5618 dwarf_form_name (form), (uintmax_t) num);
5621 case DW_AT_language:
5622 valuestr = dwarf_lang_name (num);
5624 case DW_AT_encoding:
5625 valuestr = dwarf_encoding_name (num);
5627 case DW_AT_accessibility:
5628 valuestr = dwarf_access_name (num);
5630 case DW_AT_visibility:
5631 valuestr = dwarf_visibility_name (num);
5633 case DW_AT_virtuality:
5634 valuestr = dwarf_virtuality_name (num);
5636 case DW_AT_identifier_case:
5637 valuestr = dwarf_identifier_case_name (num);
5639 case DW_AT_calling_convention:
5640 valuestr = dwarf_calling_convention_name (num);
5643 valuestr = dwarf_inline_name (num);
5645 case DW_AT_ordering:
5646 valuestr = dwarf_ordering_name (num);
5648 case DW_AT_discr_list:
5649 valuestr = dwarf_discr_list_name (num);
5659 /* When highpc is in constant form it is relative to lowpc.
5660 In that case also show the address. */
5662 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5664 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5666 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5667 (int) (level * 2), "", dwarf_attr_name (attr),
5668 dwarf_form_name (form), (uintmax_t) num, a);
5671 else if (valuestr == NULL)
5672 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
5673 (int) (level * 2), "", dwarf_attr_name (attr),
5674 dwarf_form_name (form), (uintmax_t) num);
5676 printf (" %*s%-20s (%s) %s (%" PRIuMAX ")\n",
5677 (int) (level * 2), "", dwarf_attr_name (attr),
5678 dwarf_form_name (form), valuestr, (uintmax_t) num);
5685 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5688 printf (" %*s%-20s (%s) %s\n",
5689 (int) (level * 2), "", dwarf_attr_name (attr),
5690 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5693 case DW_FORM_flag_present:
5696 printf (" %*s%-20s (%s) %s\n",
5697 (int) (level * 2), "", dwarf_attr_name (attr),
5698 dwarf_form_name (form), nl_langinfo (YESSTR));
5701 case DW_FORM_exprloc:
5702 case DW_FORM_block4:
5703 case DW_FORM_block2:
5704 case DW_FORM_block1:
5709 if (unlikely (dwarf_formblock (attrp, &block) != 0))
5712 printf (" %*s%-20s (%s) ",
5713 (int) (level * 2), "", dwarf_attr_name (attr),
5714 dwarf_form_name (form));
5719 if (form != DW_FORM_exprloc)
5721 print_block (block.length, block.data);
5726 case DW_AT_location:
5727 case DW_AT_data_location:
5728 case DW_AT_data_member_location:
5729 case DW_AT_vtable_elem_location:
5730 case DW_AT_string_length:
5731 case DW_AT_use_location:
5732 case DW_AT_frame_base:
5733 case DW_AT_return_addr:
5734 case DW_AT_static_link:
5735 case DW_AT_allocated:
5736 case DW_AT_associated:
5737 case DW_AT_bit_size:
5738 case DW_AT_bit_offset:
5739 case DW_AT_bit_stride:
5740 case DW_AT_byte_size:
5741 case DW_AT_byte_stride:
5743 case DW_AT_lower_bound:
5744 case DW_AT_upper_bound:
5745 case DW_AT_GNU_call_site_value:
5746 case DW_AT_GNU_call_site_data_value:
5747 case DW_AT_GNU_call_site_target:
5748 case DW_AT_GNU_call_site_target_clobbered:
5750 print_ops (cbargs->dwflmod, cbargs->dbg,
5751 12 + level * 2, 12 + level * 2,
5752 cbargs->version, cbargs->addrsize, cbargs->offset_size,
5753 attrp->cu, block.length, block.data);
5761 printf (" %*s%-20s (form: %#x) ???\n",
5762 (int) (level * 2), "", dwarf_attr_name (attr),
5771 print_debug_units (Dwfl_Module *dwflmod,
5772 Ebl *ebl, GElf_Ehdr *ehdr,
5773 Elf_Scn *scn, GElf_Shdr *shdr,
5774 Dwarf *dbg, bool debug_types)
5776 const bool silent = !(print_debug_sections & section_info);
5777 const char *secname = section_name (ebl, ehdr, shdr);
5781 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5782 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5784 /* If the section is empty we don't have to do anything. */
5785 if (!silent && shdr->sh_size == 0)
5789 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5791 Dwarf_Off offset = 0;
5793 /* New compilation unit. */
5796 Dwarf_Off abbroffset;
5803 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5804 &abbroffset, &addrsize, &offsize,
5805 debug_types ? &typesig : NULL,
5806 debug_types ? &typeoff : NULL) != 0)
5812 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5813 " Version: %" PRIu16 ", Abbreviation section offset: %"
5814 PRIu64 ", Address size: %" PRIu8
5815 ", Offset size: %" PRIu8
5816 "\n Type signature: %#" PRIx64
5817 ", Type offset: %#" PRIx64 "\n"),
5818 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5819 typesig, (uint64_t) typeoff);
5821 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5822 " Version: %" PRIu16 ", Abbreviation section offset: %"
5823 PRIu64 ", Address size: %" PRIu8
5824 ", Offset size: %" PRIu8 "\n"),
5825 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5828 struct attrcb_args args =
5834 .addrsize = addrsize,
5835 .offset_size = offsize
5842 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
5843 (dbg, offset, &dies[level]) == NULL))
5846 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
5847 " in section '%s': %s"),
5848 (uint64_t) offset, secname, dwarf_errmsg (-1));
5852 args.cu = dies[0].cu;
5856 offset = dwarf_dieoffset (&dies[level]);
5857 if (unlikely (offset == ~0ul))
5860 error (0, 0, gettext ("cannot get DIE offset: %s"),
5865 int tag = dwarf_tag (&dies[level]);
5866 if (unlikely (tag == DW_TAG_invalid))
5869 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
5870 " in section '%s': %s"),
5871 (uint64_t) offset, secname, dwarf_errmsg (-1));
5876 printf (" [%6" PRIx64 "] %*s%s\n",
5877 (uint64_t) offset, (int) (level * 2), "",
5878 dwarf_tag_name (tag));
5880 /* Print the attribute values. */
5882 args.die = &dies[level];
5883 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
5885 /* Make room for the next level's DIE. */
5886 if (level + 1 == maxdies)
5887 dies = (Dwarf_Die *) xrealloc (dies,
5889 * sizeof (Dwarf_Die));
5891 int res = dwarf_child (&dies[level], &dies[level + 1]);
5894 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
5898 if (unlikely (res == -1))
5901 error (0, 0, gettext ("cannot get next DIE: %s\n"),
5906 else if (unlikely (res < 0))
5909 error (0, 0, gettext ("cannot get next DIE: %s"),
5927 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5928 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5930 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
5934 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5935 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5937 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
5942 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5943 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5946 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
5947 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
5948 (uint64_t) shdr->sh_offset);
5951 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5954 Dwarf_Off ncuoffset = 0;
5956 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
5957 NULL, NULL, NULL) == 0)
5960 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
5965 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
5968 printf (" CU [%" PRIx64 "] %s\n",
5969 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
5970 printf (" line:col SBPE* disc isa op address"
5971 " (Statement Block Prologue Epilogue *End)\n");
5972 const char *last_file = "";
5973 for (size_t n = 0; n < nlines; n++)
5975 Dwarf_Line *line = dwarf_onesrcline (lines, n);
5976 Dwarf_Word mtime, length;
5977 const char *file = dwarf_linesrc (line, &mtime, &length);
5978 if (strcmp (last_file, file) != 0)
5980 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
5981 file, mtime, length);
5986 bool statement, endseq, block, prologue_end, epilogue_begin;
5987 unsigned int lineop, isa, disc;
5989 dwarf_lineaddr (line, &address);
5990 dwarf_lineno (line, &lineno);
5991 dwarf_linecol (line, &colno);
5992 dwarf_lineop_index (line, &lineop);
5993 dwarf_linebeginstatement (line, &statement);
5994 dwarf_lineendsequence (line, &endseq);
5995 dwarf_lineblock (line, &block);
5996 dwarf_lineprologueend (line, &prologue_end);
5997 dwarf_lineepiloguebegin (line, &epilogue_begin);
5998 dwarf_lineisa (line, &isa);
5999 dwarf_linediscriminator (line, &disc);
6001 /* End sequence is special, it is one byte past. */
6002 char *a = format_dwarf_addr (dwflmod, address_size,
6003 address - (endseq ? 1 : 0), address);
6004 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6006 (statement ? 'S' : ' '),
6007 (block ? 'B' : ' '),
6008 (prologue_end ? 'P' : ' '),
6009 (epilogue_begin ? 'E' : ' '),
6010 (endseq ? '*' : ' '),
6011 disc, isa, lineop, a);
6022 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6023 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6027 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6032 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6033 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6034 (uint64_t) shdr->sh_offset);
6036 if (shdr->sh_size == 0)
6039 /* There is no functionality in libdw to read the information in the
6040 way it is represented here. Hardcode the decoder. */
6041 Elf_Data *data = elf_getdata (scn, NULL);
6042 if (unlikely (data == NULL || data->d_buf == NULL))
6044 error (0, 0, gettext ("cannot get line data section data: %s"),
6049 const unsigned char *linep = (const unsigned char *) data->d_buf;
6050 const unsigned char *lineendp;
6053 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6055 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6057 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6059 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6060 unsigned int length = 4;
6061 if (unlikely (unit_length == 0xffffffff))
6063 if (unlikely (linep + 8 > lineendp))
6066 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6067 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6070 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6074 /* Check whether we have enough room in the section. */
6075 if (unit_length < 2 + length + 5 * 1
6076 || unlikely (linep + unit_length > lineendp))
6078 lineendp = linep + unit_length;
6080 /* The next element of the header is the version identifier. */
6081 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6083 /* Next comes the header length. */
6084 Dwarf_Word header_length;
6086 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6088 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6089 //const unsigned char *header_start = linep;
6091 /* Next the minimum instruction length. */
6092 uint_fast8_t minimum_instr_len = *linep++;
6094 /* Next the maximum operations per instruction, in version 4 format. */
6095 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6097 /* Then the flag determining the default value of the is_stmt
6099 uint_fast8_t default_is_stmt = *linep++;
6101 /* Now the line base. */
6102 int_fast8_t line_base = *((const int_fast8_t *) linep);
6105 /* And the line range. */
6106 uint_fast8_t line_range = *linep++;
6108 /* The opcode base. */
6109 uint_fast8_t opcode_base = *linep++;
6111 /* Print what we got so far. */
6112 printf (gettext ("\n"
6113 " Length: %" PRIu64 "\n"
6114 " DWARF version: %" PRIuFAST16 "\n"
6115 " Prologue length: %" PRIu64 "\n"
6116 " Minimum instruction length: %" PRIuFAST8 "\n"
6117 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6118 " Initial value if '%s': %" PRIuFAST8 "\n"
6119 " Line base: %" PRIdFAST8 "\n"
6120 " Line range: %" PRIuFAST8 "\n"
6121 " Opcode base: %" PRIuFAST8 "\n"
6124 (uint64_t) unit_length, version, (uint64_t) header_length,
6125 minimum_instr_len, max_ops_per_instr,
6126 "is_stmt", default_is_stmt, line_base,
6127 line_range, opcode_base);
6129 if (unlikely (linep + opcode_base - 1 >= lineendp))
6133 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6134 linep - (const unsigned char *) data->d_buf,
6135 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6139 int opcode_base_l10 = 1;
6140 unsigned int tmp = opcode_base;
6146 const uint8_t *standard_opcode_lengths = linep - 1;
6147 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6148 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6149 " [%*" PRIuFAST8 "] %hhu arguments\n",
6150 (int) linep[cnt - 1]),
6151 opcode_base_l10, cnt, linep[cnt - 1]);
6152 linep += opcode_base - 1;
6153 if (unlikely (linep >= lineendp))
6156 puts (gettext ("\nDirectory table:"));
6159 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6160 if (unlikely (endp == NULL))
6163 printf (" %s\n", (char *) linep);
6167 /* Skip the final NUL byte. */
6170 if (unlikely (linep >= lineendp))
6172 puts (gettext ("\nFile name table:\n"
6173 " Entry Dir Time Size Name"));
6174 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6176 /* First comes the file name. */
6177 char *fname = (char *) linep;
6178 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6179 if (unlikely (endp == NULL))
6183 /* Then the index. */
6184 unsigned int diridx;
6185 get_uleb128 (diridx, linep);
6187 /* Next comes the modification time. */
6189 get_uleb128 (mtime, linep);
6191 /* Finally the length of the file. */
6193 get_uleb128 (fsize, linep);
6195 printf (" %-5u %-5u %-9u %-9u %s\n",
6196 cnt, diridx, mtime, fsize, fname);
6198 /* Skip the final NUL byte. */
6201 puts (gettext ("\nLine number statements:"));
6202 Dwarf_Word address = 0;
6203 unsigned int op_index = 0;
6205 uint_fast8_t is_stmt = default_is_stmt;
6207 /* Default address value, in case we do not find the CU. */
6209 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6211 /* Determine the CU this block is for. */
6213 Dwarf_Off ncuoffset = 0;
6215 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6216 NULL, NULL, NULL) == 0)
6219 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6221 Dwarf_Attribute stmt_list;
6222 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6225 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6227 if (lineoff == start_offset)
6230 address_size = cudie.cu->address_size;
6235 /* Apply the "operation advance" from a special opcode
6236 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6237 unsigned int op_addr_advance;
6239 inline void advance_pc (unsigned int op_advance)
6241 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6242 / max_ops_per_instr);
6243 address += op_advance;
6244 show_op_index = (op_index > 0 ||
6245 (op_index + op_advance) % max_ops_per_instr > 0);
6246 op_index = (op_index + op_advance) % max_ops_per_instr;
6249 while (linep < lineendp)
6251 size_t offset = linep - (const unsigned char *) data->d_buf;
6255 /* Read the opcode. */
6256 unsigned int opcode = *linep++;
6258 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6259 /* Is this a special opcode? */
6260 if (likely (opcode >= opcode_base))
6262 /* Yes. Handling this is quite easy since the opcode value
6265 opcode = (desired line increment - line_base)
6266 + (line_range * address advance) + opcode_base
6268 int line_increment = (line_base
6269 + (opcode - opcode_base) % line_range);
6271 /* Perform the increments. */
6272 line += line_increment;
6273 advance_pc ((opcode - opcode_base) / line_range);
6275 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6278 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6279 opcode, op_addr_advance, a, op_index,
6280 line_increment, line);
6283 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6284 opcode, op_addr_advance, a, line_increment, line);
6287 else if (opcode == 0)
6289 /* This an extended opcode. */
6290 if (unlikely (linep + 2 > lineendp))
6294 unsigned int len = *linep++;
6296 if (unlikely (linep + len > lineendp))
6299 /* The sub-opcode. */
6302 printf (gettext (" extended opcode %u: "), opcode);
6306 case DW_LNE_end_sequence:
6307 puts (gettext (" end of sequence"));
6309 /* Reset the registers we care about. */
6313 is_stmt = default_is_stmt;
6316 case DW_LNE_set_address:
6318 if (address_size == 4)
6319 address = read_4ubyte_unaligned_inc (dbg, linep);
6321 address = read_8ubyte_unaligned_inc (dbg, linep);
6323 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6324 printf (gettext (" set address to %s\n"), a);
6329 case DW_LNE_define_file:
6331 char *fname = (char *) linep;
6332 unsigned char *endp = memchr (linep, '\0',
6334 if (unlikely (endp == NULL))
6338 unsigned int diridx;
6339 get_uleb128 (diridx, linep);
6341 get_uleb128 (mtime, linep);
6342 Dwarf_Word filelength;
6343 get_uleb128 (filelength, linep);
6346 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6347 diridx, (uint64_t) mtime, (uint64_t) filelength,
6352 case DW_LNE_set_discriminator:
6353 /* Takes one ULEB128 parameter, the discriminator. */
6354 if (unlikely (standard_opcode_lengths[opcode] != 1))
6357 get_uleb128 (u128, linep);
6358 printf (gettext (" set discriminator to %u\n"), u128);
6362 /* Unknown, ignore it. */
6363 puts (gettext (" unknown opcode"));
6368 else if (opcode <= DW_LNS_set_isa)
6370 /* This is a known standard opcode. */
6374 /* Takes no argument. */
6375 puts (gettext (" copy"));
6378 case DW_LNS_advance_pc:
6379 /* Takes one uleb128 parameter which is added to the
6381 get_uleb128 (u128, linep);
6384 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6387 advance address by %u to %s, op_index to %u\n"),
6388 op_addr_advance, a, op_index);
6390 printf (gettext (" advance address by %u to %s\n"),
6391 op_addr_advance, a);
6396 case DW_LNS_advance_line:
6397 /* Takes one sleb128 parameter which is added to the
6399 get_sleb128 (s128, linep);
6402 advance line by constant %d to %" PRId64 "\n"),
6403 s128, (int64_t) line);
6406 case DW_LNS_set_file:
6407 /* Takes one uleb128 parameter which is stored in file. */
6408 get_uleb128 (u128, linep);
6409 printf (gettext (" set file to %" PRIu64 "\n"),
6413 case DW_LNS_set_column:
6414 /* Takes one uleb128 parameter which is stored in column. */
6415 if (unlikely (standard_opcode_lengths[opcode] != 1))
6418 get_uleb128 (u128, linep);
6419 printf (gettext (" set column to %" PRIu64 "\n"),
6423 case DW_LNS_negate_stmt:
6424 /* Takes no argument. */
6425 is_stmt = 1 - is_stmt;
6426 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6427 "is_stmt", is_stmt);
6430 case DW_LNS_set_basic_block:
6431 /* Takes no argument. */
6432 puts (gettext (" set basic block flag"));
6435 case DW_LNS_const_add_pc:
6436 /* Takes no argument. */
6437 advance_pc ((255 - opcode_base) / line_range);
6439 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6442 advance address by constant %u to %s, op_index to %u\n"),
6443 op_addr_advance, a, op_index);
6446 advance address by constant %u to %s\n"),
6447 op_addr_advance, a);
6452 case DW_LNS_fixed_advance_pc:
6453 /* Takes one 16 bit parameter which is added to the
6455 if (unlikely (standard_opcode_lengths[opcode] != 1))
6458 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6462 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6464 advance address by fixed value %u to %s\n"),
6470 case DW_LNS_set_prologue_end:
6471 /* Takes no argument. */
6472 puts (gettext (" set prologue end flag"));
6475 case DW_LNS_set_epilogue_begin:
6476 /* Takes no argument. */
6477 puts (gettext (" set epilogue begin flag"));
6480 case DW_LNS_set_isa:
6481 /* Takes one uleb128 parameter which is stored in isa. */
6482 if (unlikely (standard_opcode_lengths[opcode] != 1))
6485 get_uleb128 (u128, linep);
6486 printf (gettext (" set isa to %u\n"), u128);
6492 /* This is a new opcode the generator but not we know about.
6493 Read the parameters associated with it but then discard
6494 everything. Read all the parameters for this opcode. */
6495 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6496 " unknown opcode with %" PRIu8 " parameters:",
6497 standard_opcode_lengths[opcode]),
6498 standard_opcode_lengths[opcode]);
6499 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6501 get_uleb128 (u128, linep);
6502 if (n != standard_opcode_lengths[opcode])
6503 putc_unlocked (',', stdout);
6504 printf (" %u", u128);
6507 /* Next round, ignore this opcode. */
6513 /* There must only be one data block. */
6514 assert (elf_getdata (scn, data) == NULL);
6519 print_debug_loc_section (Dwfl_Module *dwflmod,
6520 Ebl *ebl, GElf_Ehdr *ehdr,
6521 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6523 Elf_Data *data = elf_rawdata (scn, NULL);
6525 if (unlikely (data == NULL))
6527 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6533 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6534 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6535 (uint64_t) shdr->sh_offset);
6537 sort_listptr (&known_loclistptr, "loclistptr");
6538 size_t listptr_idx = 0;
6540 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6541 uint_fast8_t offset_size = 4;
6544 struct Dwarf_CU *cu = NULL;
6545 Dwarf_Addr base = 0;
6546 unsigned char *readp = data->d_buf;
6547 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6548 while (readp < endp)
6550 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6552 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6553 &address_size, &offset_size, &base,
6554 &cu, offset, &readp, endp))
6557 if (unlikely (data->d_size - offset < address_size * 2))
6559 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6565 if (address_size == 8)
6567 begin = read_8ubyte_unaligned_inc (dbg, readp);
6568 end = read_8ubyte_unaligned_inc (dbg, readp);
6572 begin = read_4ubyte_unaligned_inc (dbg, readp);
6573 end = read_4ubyte_unaligned_inc (dbg, readp);
6574 if (begin == (Dwarf_Addr) (uint32_t) -1)
6575 begin = (Dwarf_Addr) -1l;
6578 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6580 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6581 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6585 else if (begin == 0 && end == 0) /* End of list entry. */
6588 printf (gettext (" [%6tx] empty list\n"), offset);
6593 /* We have a location expression entry. */
6594 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6596 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6598 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6601 if (first) /* First entry in a list. */
6602 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6604 printf (gettext (" %s..%s"), b, e);
6609 if (endp - readp <= (ptrdiff_t) len)
6611 fputs (gettext (" <INVALID DATA>\n"), stdout);
6615 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6616 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6629 struct mac_culist *next;
6634 mac_compare (const void *p1, const void *p2)
6636 struct mac_culist *m1 = (struct mac_culist *) p1;
6637 struct mac_culist *m2 = (struct mac_culist *) p2;
6639 if (m1->offset < m2->offset)
6641 if (m1->offset > m2->offset)
6648 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6649 Ebl *ebl, GElf_Ehdr *ehdr,
6650 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6653 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6654 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6655 (uint64_t) shdr->sh_offset);
6656 putc_unlocked ('\n', stdout);
6658 /* There is no function in libdw to iterate over the raw content of
6659 the section but it is easy enough to do. */
6660 Elf_Data *data = elf_getdata (scn, NULL);
6661 if (unlikely (data == NULL || data->d_buf == NULL))
6663 error (0, 0, gettext ("cannot get macro information section data: %s"),
6668 /* Get the source file information for all CUs. */
6672 struct mac_culist *culist = NULL;
6674 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6677 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6680 Dwarf_Attribute attr;
6681 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6685 if (dwarf_formudata (&attr, &macoff) != 0)
6688 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6690 newp->offset = macoff;
6692 newp->next = culist;
6697 /* Convert the list into an array for easier consumption. */
6698 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6701 cus[nculist].offset = data->d_size;
6704 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6706 assert (cnt < nculist);
6708 culist = culist->next;
6711 /* Sort the array according to the offset in the .debug_macinfo
6712 section. Note we keep the sentinel at the end. */
6713 qsort (cus, nculist, sizeof (*cus), mac_compare);
6716 const unsigned char *readp = (const unsigned char *) data->d_buf;
6717 const unsigned char *readendp = readp + data->d_size;
6720 while (readp < readendp)
6722 unsigned int opcode = *readp++;
6724 unsigned int u128_2;
6725 const unsigned char *endp;
6729 case DW_MACINFO_define:
6730 case DW_MACINFO_undef:
6731 case DW_MACINFO_vendor_ext:
6732 /* For the first two opcodes the parameters are
6736 We can treat these cases together. */
6737 get_uleb128 (u128, readp);
6739 endp = memchr (readp, '\0', readendp - readp);
6740 if (unlikely (endp == NULL))
6743 %*s*** non-terminated string at end of section"),
6748 if (opcode == DW_MACINFO_define)
6749 printf ("%*s#define %s, line %u\n",
6750 level, "", (char *) readp, u128);
6751 else if (opcode == DW_MACINFO_undef)
6752 printf ("%*s#undef %s, line %u\n",
6753 level, "", (char *) readp, u128);
6755 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6760 case DW_MACINFO_start_file:
6761 /* The two parameters are line and file index, in this order. */
6762 get_uleb128 (u128, readp);
6763 get_uleb128 (u128_2, readp);
6765 /* Find the CU DIE for this file. */
6766 size_t macoff = readp - (const unsigned char *) data->d_buf;
6767 const char *fname = "???";
6768 if (macoff >= cus[0].offset)
6770 while (macoff >= cus[1].offset)
6773 if (cus[0].files == NULL
6774 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6775 cus[0].files = (Dwarf_Files *) -1l;
6777 if (cus[0].files != (Dwarf_Files *) -1l)
6778 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6782 printf ("%*sstart_file %u, [%u] %s\n",
6783 level, "", u128, u128_2, fname);
6787 case DW_MACINFO_end_file:
6789 printf ("%*send_file\n", level, "");
6790 /* Nothing more to do. */
6794 // XXX gcc seems to generate files with a trailing zero.
6795 if (unlikely (opcode != 0 || readp != readendp))
6796 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6804 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6805 Ebl *ebl, GElf_Ehdr *ehdr,
6806 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6809 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6810 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6811 (uint64_t) shdr->sh_offset);
6812 putc_unlocked ('\n', stdout);
6814 Elf_Data *data = elf_getdata (scn, NULL);
6815 if (unlikely (data == NULL || data->d_buf == NULL))
6817 error (0, 0, gettext ("cannot get macro information section data: %s"),
6822 /* Get the source file information for all CUs. Uses same
6823 datastructure as macinfo. But uses offset field to directly
6824 match .debug_line offset. And just stored in a list. */
6828 struct mac_culist *culist = NULL;
6830 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6833 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6836 Dwarf_Attribute attr;
6837 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
6841 if (dwarf_formudata (&attr, &lineoff) != 0)
6844 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6846 newp->offset = lineoff;
6848 newp->next = culist;
6853 const unsigned char *readp = (const unsigned char *) data->d_buf;
6854 const unsigned char *readendp = readp + data->d_size;
6856 while (readp < readendp)
6858 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
6859 (uint64_t) (readp - (const unsigned char *) data->d_buf));
6861 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
6862 // optional vendor extension macro entry table.
6863 if (readp + 2 > readendp)
6866 error (0, 0, gettext ("invalid data"));
6869 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
6870 printf (gettext (" Version: %" PRIu16 "\n"), vers);
6872 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
6873 // 5 when it gets standardized.
6876 printf (gettext (" unknown version, cannot parse section\n"));
6880 if (readp + 1 > readendp)
6882 const unsigned char flag = *readp++;
6883 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
6885 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
6886 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
6887 Dwarf_Off line_offset = -1;
6890 if (offset_len == 8)
6891 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
6893 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
6894 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
6898 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
6901 // 1 byte length, for each item, 1 byte opcode, uleb128 number
6902 // of arguments, for each argument 1 byte form code.
6903 if (readp + 1 > readendp)
6905 unsigned int tlen = *readp++;
6906 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
6908 for (unsigned int i = 0; i < tlen; i++)
6910 if (readp + 1 > readendp)
6912 unsigned int opcode = *readp++;
6913 printf (gettext (" [%" PRIx8 "]"), opcode);
6914 if (opcode < DW_MACRO_GNU_lo_user
6915 || opcode > DW_MACRO_GNU_hi_user)
6917 // Record the start of description for this vendor opcode.
6918 // uleb128 nr args, 1 byte per arg form.
6919 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
6920 if (readp + 1 > readendp)
6922 unsigned int args = *readp++;
6925 printf (gettext (" %" PRIu8 " arguments:"), args);
6928 if (readp + 1 > readendp)
6930 unsigned int form = *readp++;
6931 printf (" %s", dwarf_form_string (form));
6932 if (form != DW_FORM_data1
6933 && form != DW_FORM_data2
6934 && form != DW_FORM_data4
6935 && form != DW_FORM_data8
6936 && form != DW_FORM_sdata
6937 && form != DW_FORM_udata
6938 && form != DW_FORM_block
6939 && form != DW_FORM_block1
6940 && form != DW_FORM_block2
6941 && form != DW_FORM_block4
6942 && form != DW_FORM_flag
6943 && form != DW_FORM_string
6944 && form != DW_FORM_strp
6945 && form != DW_FORM_sec_offset)
6949 putchar_unlocked (',');
6953 printf (gettext (" no arguments."));
6954 putchar_unlocked ('\n');
6957 putchar_unlocked ('\n');
6960 if (readp + 1 > readendp)
6962 unsigned int opcode = *readp++;
6966 unsigned int u128_2;
6967 const unsigned char *endp;
6972 case DW_MACRO_GNU_start_file:
6973 get_uleb128 (u128, readp);
6974 get_uleb128 (u128_2, readp);
6976 /* Find the CU DIE that matches this line offset. */
6977 const char *fname = "???";
6978 if (line_offset != (Dwarf_Off) -1)
6980 struct mac_culist *cu = culist;
6981 while (cu != NULL && line_offset != cu->offset)
6985 if (cu->files == NULL
6986 && dwarf_getsrcfiles (&cu->die, &cu->files,
6988 cu->files = (Dwarf_Files *) -1l;
6990 if (cu->files != (Dwarf_Files *) -1l)
6991 fname = (dwarf_filesrc (cu->files, u128_2,
6992 NULL, NULL) ?: "???");
6995 printf ("%*sstart_file %u, [%u] %s\n",
6996 level, "", u128, u128_2, fname);
7000 case DW_MACRO_GNU_end_file:
7002 printf ("%*send_file\n", level, "");
7005 case DW_MACRO_GNU_define:
7006 get_uleb128 (u128, readp);
7007 endp = memchr (readp, '\0', readendp - readp);
7010 printf ("%*s#define %s, line %u\n",
7011 level, "", readp, u128);
7015 case DW_MACRO_GNU_undef:
7016 get_uleb128 (u128, readp);
7017 endp = memchr (readp, '\0', readendp - readp);
7020 printf ("%*s#undef %s, line %u\n",
7021 level, "", readp, u128);
7025 case DW_MACRO_GNU_define_indirect:
7026 get_uleb128 (u128, readp);
7027 if (readp + offset_len > readendp)
7029 if (offset_len == 8)
7030 off = read_8ubyte_unaligned_inc (dbg, readp);
7032 off = read_4ubyte_unaligned_inc (dbg, readp);
7033 printf ("%*s#define %s, line %u (indirect)\n",
7034 level, "", dwarf_getstring (dbg, off, NULL), u128);
7037 case DW_MACRO_GNU_undef_indirect:
7038 get_uleb128 (u128, readp);
7039 if (readp + offset_len > readendp)
7041 if (offset_len == 8)
7042 off = read_8ubyte_unaligned_inc (dbg, readp);
7044 off = read_4ubyte_unaligned_inc (dbg, readp);
7045 printf ("%*s#undef %s, line %u (indirect)\n",
7046 level, "", dwarf_getstring (dbg, off, NULL), u128);
7049 case DW_MACRO_GNU_transparent_include:
7050 if (readp + offset_len > readendp)
7052 if (offset_len == 8)
7053 off = read_8ubyte_unaligned_inc (dbg, readp);
7055 off = read_4ubyte_unaligned_inc (dbg, readp);
7056 printf ("%*s#include offset 0x%" PRIx64 "\n",
7061 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7062 if (opcode < DW_MACRO_GNU_lo_user
7063 || opcode > DW_MACRO_GNU_lo_user
7064 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7067 const unsigned char *op_desc;
7068 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7070 // Just skip the arguments, we cannot really interpret them,
7071 // but print as much as we can.
7072 unsigned int args = *op_desc++;
7075 unsigned int form = *op_desc++;
7080 if (readp + 1 > readendp)
7083 printf (" %" PRIx8, (unsigned int) val);
7087 if (readp + 2 > readendp)
7089 val = read_2ubyte_unaligned_inc (dbg, readp);
7090 printf(" %" PRIx16, (unsigned int) val);
7094 if (readp + 4 > readendp)
7096 val = read_4ubyte_unaligned_inc (dbg, readp);
7097 printf (" %" PRIx32, (unsigned int) val);
7101 if (readp + 8 > readendp)
7103 val = read_8ubyte_unaligned_inc (dbg, readp);
7104 printf (" %" PRIx64, val);
7108 get_sleb128 (val, readp);
7109 printf (" %" PRIx64, val);
7113 get_uleb128 (val, readp);
7114 printf (" %" PRIx64, val);
7118 get_uleb128 (val, readp);
7119 printf (" block[%" PRIu64 "]", val);
7120 if (readp + val > readendp)
7125 case DW_FORM_block1:
7126 if (readp + 1 > readendp)
7129 printf (" block[%" PRIu64 "]", val);
7130 if (readp + val > readendp)
7134 case DW_FORM_block2:
7135 if (readp + 2 > readendp)
7137 val = read_2ubyte_unaligned_inc (dbg, readp);
7138 printf (" block[%" PRIu64 "]", val);
7139 if (readp + val > readendp)
7143 case DW_FORM_block4:
7144 if (readp + 2 > readendp)
7146 val =read_4ubyte_unaligned_inc (dbg, readp);
7147 printf (" block[%" PRIu64 "]", val);
7148 if (readp + val > readendp)
7153 if (readp + 1 > readendp)
7156 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7159 case DW_FORM_string:
7160 endp = memchr (readp, '\0', readendp - readp);
7163 printf (" %s", readp);
7168 if (readp + offset_len > readendp)
7170 if (offset_len == 8)
7171 val = read_8ubyte_unaligned_inc (dbg, readp);
7173 val = read_4ubyte_unaligned_inc (dbg, readp);
7174 printf (" %s", dwarf_getstring (dbg, val, NULL));
7177 case DW_FORM_sec_offset:
7178 if (readp + offset_len > readendp)
7180 if (offset_len == 8)
7181 val = read_8ubyte_unaligned_inc (dbg, readp);
7183 val = read_4ubyte_unaligned_inc (dbg, readp);
7184 printf (" %" PRIx64, val);
7188 error (0, 0, gettext ("vendor opcode not verified?"));
7194 putchar_unlocked (',');
7196 putchar_unlocked ('\n');
7199 if (readp + 1 > readendp)
7203 putchar_unlocked ('\n');
7209 /* Callback for printing global names. */
7211 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7214 int *np = (int *) arg;
7216 printf (gettext (" [%5d] DIE offset: %6" PRId64
7217 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7218 (*np)++, global->die_offset, global->cu_offset, global->name);
7224 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7226 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7227 Ebl *ebl, GElf_Ehdr *ehdr,
7228 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7230 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7231 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7232 (uint64_t) shdr->sh_offset);
7235 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7238 /* Print the content of the DWARF string section '.debug_str'. */
7240 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7241 Ebl *ebl, GElf_Ehdr *ehdr,
7242 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7244 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7245 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7247 /* Compute floor(log16(shdr->sh_size)). */
7248 GElf_Addr tmp = sh_size;
7255 digits = MAX (4, digits);
7257 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7260 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7261 /* TRANS: the debugstr| prefix makes the string unique. */
7262 digits + 2, sgettext ("debugstr|Offset"));
7264 Dwarf_Off offset = 0;
7265 while (offset < sh_size)
7268 const char *str = dwarf_getstring (dbg, offset, &len);
7269 if (unlikely (str == NULL))
7271 printf (gettext (" *** error while reading strings: %s\n"),
7276 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7283 /* Print the content of the call frame search table section
7286 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7287 Ebl *ebl __attribute__ ((unused)),
7288 GElf_Ehdr *ehdr __attribute__ ((unused)),
7289 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7292 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7295 Elf_Data *data = elf_rawdata (scn, NULL);
7297 if (unlikely (data == NULL))
7299 error (0, 0, gettext ("cannot get %s content: %s"),
7300 ".eh_frame_hdr", elf_errmsg (-1));
7304 const unsigned char *readp = data->d_buf;
7305 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7308 if (unlikely (readp + 4 > dataend))
7311 error (0, 0, gettext ("invalid data"));
7315 unsigned int version = *readp++;
7316 unsigned int eh_frame_ptr_enc = *readp++;
7317 unsigned int fde_count_enc = *readp++;
7318 unsigned int table_enc = *readp++;
7320 printf (" version: %u\n"
7321 " eh_frame_ptr_enc: %#x ",
7322 version, eh_frame_ptr_enc);
7323 print_encoding_base ("", eh_frame_ptr_enc);
7324 printf (" fde_count_enc: %#x ", fde_count_enc);
7325 print_encoding_base ("", fde_count_enc);
7326 printf (" table_enc: %#x ", table_enc);
7327 print_encoding_base ("", table_enc);
7329 uint64_t eh_frame_ptr = 0;
7330 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7332 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7334 if (unlikely (readp == NULL))
7337 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7338 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7339 printf (" (offset: %#" PRIx64 ")",
7340 /* +4 because of the 4 byte header of the section. */
7341 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7343 putchar_unlocked ('\n');
7346 uint64_t fde_count = 0;
7347 if (fde_count_enc != DW_EH_PE_omit)
7349 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7350 if (unlikely (readp == NULL))
7353 printf (" fde_count: %" PRIu64 "\n", fde_count);
7356 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7361 /* Optimize for the most common case. */
7362 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7363 while (fde_count > 0 && readp + 8 <= dataend)
7365 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7366 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7367 + (int64_t) initial_location);
7368 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7369 // XXX Possibly print symbol name or section offset for initial_offset
7370 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7371 " fde=[%6" PRIx64 "]\n",
7372 initial_location, initial_offset,
7373 address, address - (eh_frame_ptr + 4));
7376 while (0 && readp < dataend)
7383 /* Print the content of the exception handling table section
7386 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7387 Ebl *ebl __attribute__ ((unused)),
7388 GElf_Ehdr *ehdr __attribute__ ((unused)),
7390 GElf_Shdr *shdr __attribute__ ((unused)),
7391 Dwarf *dbg __attribute__ ((unused)))
7394 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7397 Elf_Data *data = elf_rawdata (scn, NULL);
7399 if (unlikely (data == NULL))
7401 error (0, 0, gettext ("cannot get %s content: %s"),
7402 ".gcc_except_table", elf_errmsg (-1));
7406 const unsigned char *readp = data->d_buf;
7407 const unsigned char *const dataend = readp + data->d_size;
7409 if (unlikely (readp + 1 > dataend))
7412 error (0, 0, gettext ("invalid data"));
7415 unsigned int lpstart_encoding = *readp++;
7416 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7417 print_encoding_base ("", lpstart_encoding);
7418 if (lpstart_encoding != DW_EH_PE_omit)
7421 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7422 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7425 if (unlikely (readp + 1 > dataend))
7427 unsigned int ttype_encoding = *readp++;
7428 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7429 print_encoding_base ("", ttype_encoding);
7430 const unsigned char *ttype_base = NULL;
7431 if (ttype_encoding != DW_EH_PE_omit)
7433 unsigned int ttype_base_offset;
7434 get_uleb128 (ttype_base_offset, readp);
7435 printf (" TType base offset: %#x\n", ttype_base_offset);
7436 ttype_base = readp + ttype_base_offset;
7439 if (unlikely (readp + 1 > dataend))
7441 unsigned int call_site_encoding = *readp++;
7442 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7443 print_encoding_base ("", call_site_encoding);
7444 unsigned int call_site_table_len;
7445 get_uleb128 (call_site_table_len, readp);
7447 const unsigned char *const action_table = readp + call_site_table_len;
7448 if (unlikely (action_table > dataend))
7451 unsigned int max_action = 0;
7452 while (readp < action_table)
7455 puts (gettext ("\n Call site table:"));
7457 uint64_t call_site_start;
7458 readp = read_encoded (call_site_encoding, readp, dataend,
7459 &call_site_start, dbg);
7460 uint64_t call_site_length;
7461 readp = read_encoded (call_site_encoding, readp, dataend,
7462 &call_site_length, dbg);
7463 uint64_t landing_pad;
7464 readp = read_encoded (call_site_encoding, readp, dataend,
7466 unsigned int action;
7467 get_uleb128 (action, readp);
7468 max_action = MAX (action, max_action);
7469 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7470 " Call site length: %" PRIu64 "\n"
7471 " Landing pad: %#" PRIx64 "\n"
7473 u++, call_site_start, call_site_length, landing_pad, action);
7475 assert (readp == action_table);
7477 unsigned int max_ar_filter = 0;
7480 puts ("\n Action table:");
7482 const unsigned char *const action_table_end
7483 = action_table + max_action + 1;
7489 get_sleb128 (ar_filter, readp);
7490 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7491 max_ar_filter = ar_filter;
7493 get_sleb128 (ar_disp, readp);
7495 printf (" [%4u] ar_filter: % d\n"
7497 u, ar_filter, ar_disp);
7498 if (abs (ar_disp) & 1)
7499 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7500 else if (ar_disp != 0)
7503 putchar_unlocked ('\n');
7506 while (readp < action_table_end);
7509 if (max_ar_filter > 0)
7511 puts ("\n TType table:");
7513 // XXX Not *4, size of encoding;
7514 switch (ttype_encoding & 7)
7516 case DW_EH_PE_udata2:
7517 case DW_EH_PE_sdata2:
7518 readp = ttype_base - max_ar_filter * 2;
7520 case DW_EH_PE_udata4:
7521 case DW_EH_PE_sdata4:
7522 readp = ttype_base - max_ar_filter * 4;
7524 case DW_EH_PE_udata8:
7525 case DW_EH_PE_sdata8:
7526 readp = ttype_base - max_ar_filter * 8;
7529 error (1, 0, gettext ("invalid TType encoding"));
7535 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7537 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7539 while (readp < ttype_base);
7543 /* Print the content of the '.gdb_index' section.
7544 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7547 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7548 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7550 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7551 " contains %" PRId64 " bytes :\n"),
7552 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7553 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7555 Elf_Data *data = elf_rawdata (scn, NULL);
7557 if (unlikely (data == NULL))
7559 error (0, 0, gettext ("cannot get %s content: %s"),
7560 ".gdb_index", elf_errmsg (-1));
7564 // .gdb_index is always in little endian.
7565 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7568 const unsigned char *readp = data->d_buf;
7569 const unsigned char *const dataend = readp + data->d_size;
7571 if (unlikely (readp + 4 > dataend))
7574 error (0, 0, gettext ("invalid data"));
7578 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7579 printf (gettext (" Version: %" PRId32 "\n"), vers);
7581 // The only difference between version 4 and version 5 is the
7582 // hash used for generating the table. Version 6 contains symbols
7583 // for inlined functions, older versions didn't. Version 7 adds
7584 // symbol kinds. Version 8 just indicates that it correctly includes
7586 if (vers < 4 || vers > 8)
7588 printf (gettext (" unknown version, cannot parse section\n"));
7593 if (unlikely (readp + 4 > dataend))
7596 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7597 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7600 if (unlikely (readp + 4 > dataend))
7603 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7604 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7607 if (unlikely (readp + 4 > dataend))
7610 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7611 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
7614 if (unlikely (readp + 4 > dataend))
7617 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7618 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
7621 if (unlikely (readp + 4 > dataend))
7624 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7625 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7627 readp = data->d_buf + cu_off;
7629 const unsigned char *nextp = data->d_buf + tu_off;
7630 size_t cu_nr = (nextp - readp) / 16;
7632 printf (gettext ("\n CU list at offset %#" PRIx32
7633 " contains %zu entries:\n"),
7637 while (readp + 16 <= dataend && n < cu_nr)
7639 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7642 uint64_t len = read_8ubyte_unaligned (dbg, readp);
7645 printf (" [%4zu] start: %0#8" PRIx64
7646 ", length: %5" PRIu64 "\n", n, off, len);
7650 readp = data->d_buf + tu_off;
7651 nextp = data->d_buf + addr_off;
7652 size_t tu_nr = (nextp - readp) / 24;
7654 printf (gettext ("\n TU list at offset %#" PRIx32
7655 " contains %zu entries:\n"),
7659 while (readp + 24 <= dataend && n < tu_nr)
7661 uint64_t off = read_8ubyte_unaligned (dbg, readp);
7664 uint64_t type = read_8ubyte_unaligned (dbg, readp);
7667 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7670 printf (" [%4zu] CU offset: %5" PRId64
7671 ", type offset: %5" PRId64
7672 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7676 readp = data->d_buf + addr_off;
7677 nextp = data->d_buf + sym_off;
7678 size_t addr_nr = (nextp - readp) / 20;
7680 printf (gettext ("\n Address list at offset %#" PRIx32
7681 " contains %zu entries:\n"),
7685 while (readp + 20 <= dataend && n < addr_nr)
7687 uint64_t low = read_8ubyte_unaligned (dbg, readp);
7690 uint64_t high = read_8ubyte_unaligned (dbg, readp);
7693 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7696 char *l = format_dwarf_addr (dwflmod, 8, low, low);
7697 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7698 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7705 readp = data->d_buf + sym_off;
7706 nextp = data->d_buf + const_off;
7707 size_t sym_nr = (nextp - readp) / 8;
7709 printf (gettext ("\n Symbol table at offset %#" PRIx32
7710 " contains %zu slots:\n"),
7714 while (readp + 8 <= dataend && n < sym_nr)
7716 uint32_t name = read_4ubyte_unaligned (dbg, readp);
7719 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7722 if (name != 0 || vector != 0)
7724 const unsigned char *sym = data->d_buf + const_off + name;
7725 if (unlikely (sym > dataend))
7728 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7730 const unsigned char *readcus = data->d_buf + const_off + vector;
7731 if (unlikely (readcus + 8 > dataend))
7734 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7737 uint32_t cu_kind, cu, kind;
7740 cu_kind = read_4ubyte_unaligned (dbg, readcus);
7741 cu = cu_kind & ((1 << 24) - 1);
7742 kind = (cu_kind >> 28) & 7;
7743 is_static = cu_kind & (1 << 31);
7745 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
7747 printf ("%" PRId32, cu);
7766 printf ("unknown-0x%" PRIx32, kind);
7769 printf (":%c)", (is_static ? 'S' : 'G'));
7781 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7783 /* Before we start the real work get a debug context descriptor. */
7785 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7789 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7793 if ((print_debug_sections & ~section_exception) != 0)
7794 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7796 if ((print_debug_sections & section_exception) == 0)
7801 /* Get the section header string table index. */
7803 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7804 error (EXIT_FAILURE, 0,
7805 gettext ("cannot get section header string table index"));
7807 /* Look through all the sections for the debugging sections to print. */
7808 Elf_Scn *scn = NULL;
7809 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7812 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7814 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7819 enum section_e bitmask;
7820 void (*fp) (Dwfl_Module *, Ebl *,
7821 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7822 } debug_sections[] =
7824 #define NEW_SECTION(name) \
7825 { ".debug_" #name, section_##name, print_debug_##name##_section }
7826 NEW_SECTION (abbrev),
7827 NEW_SECTION (aranges),
7828 NEW_SECTION (frame),
7830 NEW_SECTION (types),
7833 NEW_SECTION (pubnames),
7835 NEW_SECTION (macinfo),
7836 NEW_SECTION (macro),
7837 NEW_SECTION (ranges),
7838 { ".eh_frame", section_frame | section_exception,
7839 print_debug_frame_section },
7840 { ".eh_frame_hdr", section_frame | section_exception,
7841 print_debug_frame_hdr_section },
7842 { ".gcc_except_table", section_frame | section_exception,
7843 print_debug_exception_table },
7844 { ".gdb_index", section_gdb_index, print_gdb_index_section }
7846 const int ndebug_sections = (sizeof (debug_sections)
7847 / sizeof (debug_sections[0]));
7848 const char *name = elf_strptr (ebl->elf, shstrndx,
7852 for (n = 0; n < ndebug_sections; ++n)
7853 if (strcmp (name, debug_sections[n].name) == 0
7855 || (name[0] == '.' && name[1] == 'z'
7856 && debug_sections[n].name[1] == 'd'
7857 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
7861 if ((print_debug_sections | implicit_debug_sections)
7862 & debug_sections[n].bitmask)
7863 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
7869 reset_listptr (&known_loclistptr);
7870 reset_listptr (&known_rangelistptr);
7874 #define ITEM_INDENT 4
7875 #define WRAP_COLUMN 75
7877 /* Print "NAME: FORMAT", wrapping when output text would make the line
7878 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
7879 but this function is also used for registers which should be printed
7880 aligned. Fortunately registers output uses fixed fields width (such
7881 as %11d) for the alignment.
7883 Line breaks should not depend on the particular values although that
7884 may happen in some cases of the core items. */
7887 __attribute__ ((format (printf, 6, 7)))
7888 print_core_item (unsigned int colno, char sep, unsigned int wrap,
7889 size_t name_width, const char *name, const char *format, ...)
7891 size_t len = strlen (name);
7892 if (name_width < len)
7897 va_start (ap, format);
7898 int out_len = vasprintf (&out, format, ap);
7901 error (EXIT_FAILURE, 0, _("memory exhausted"));
7903 size_t n = name_width + sizeof ": " - 1 + out_len;
7907 printf ("%*s", ITEM_INDENT, "");
7908 colno = ITEM_INDENT + n;
7910 else if (colno + 2 + n < wrap)
7912 printf ("%c ", sep);
7917 printf ("\n%*s", ITEM_INDENT, "");
7918 colno = ITEM_INDENT + n;
7921 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
7929 convert (Elf *core, Elf_Type type, uint_fast16_t count,
7930 void *value, const void *data, size_t size)
7932 Elf_Data valuedata =
7936 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
7937 .d_version = EV_CURRENT,
7942 .d_buf = (void *) data,
7943 .d_size = valuedata.d_size,
7944 .d_version = EV_CURRENT,
7947 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
7948 ? elf32_xlatetom : elf64_xlatetom)
7949 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
7951 error (EXIT_FAILURE, 0,
7952 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
7954 return data + indata.d_size;
7957 typedef uint8_t GElf_Byte;
7960 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
7961 unsigned int colno, size_t *repeated_size)
7963 uint_fast16_t count = item->count ?: 1;
7966 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
7967 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
7968 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
7969 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
7970 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
7971 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
7973 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
7974 union { TYPES; } value;
7977 void *data = &value;
7978 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
7979 size_t convsize = size;
7980 if (repeated_size != NULL)
7982 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
7984 data = alloca (*repeated_size);
7985 count *= *repeated_size / size;
7986 convsize = count * size;
7987 *repeated_size -= convsize;
7989 else if (item->count != 0 || item->format != '\n')
7990 *repeated_size -= size;
7993 convert (core, item->type, count, data, desc + item->offset, convsize);
7995 Elf_Type type = item->type;
7996 if (type == ELF_T_ADDR)
7997 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
7999 switch (item->format)
8002 assert (count == 1);
8005 #define DO_TYPE(NAME, Name, hex, dec) \
8006 case ELF_T_##NAME: \
8007 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8008 0, item->name, dec, value.Name[0]); \
8018 assert (count == 1);
8021 #define DO_TYPE(NAME, Name, hex, dec) \
8022 case ELF_T_##NAME: \
8023 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8024 0, item->name, hex, value.Name[0]); \
8035 assert (size % sizeof (unsigned int) == 0);
8036 unsigned int nbits = count * size * 8;
8037 unsigned int pop = 0;
8038 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8039 pop += __builtin_popcount (*i);
8040 bool negate = pop > nbits / 2;
8041 const unsigned int bias = item->format == 'b';
8044 char printed[(negate ? nbits - pop : pop) * 16];
8048 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8050 assert (size == sizeof (unsigned int) * 2);
8051 for (unsigned int *i = data;
8052 (void *) i < data + count * size; i += 2)
8054 unsigned int w = i[1];
8060 unsigned int lastbit = 0;
8061 unsigned int run = 0;
8062 for (const unsigned int *i = data;
8063 (void *) i < data + count * size; ++i)
8065 unsigned int bit = ((void *) i - data) * 8;
8066 unsigned int w = negate ? ~*i : *i;
8073 if (lastbit != 0 && lastbit + 1 == bit)
8078 p += sprintf (p, "%u", bit - bias);
8080 p += sprintf (p, ",%u", bit - bias);
8082 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8089 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8090 p += sprintf (p, "-%u", lastbit - bias);
8092 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8093 negate ? "~<%s>" : "<%s>", printed);
8098 case (char) ('T'|0x80):
8099 assert (count == 2);
8104 #define DO_TYPE(NAME, Name, hex, dec) \
8105 case ELF_T_##NAME: \
8106 sec = value.Name[0]; \
8107 usec = value.Name[1]; \
8114 if (unlikely (item->format == (char) ('T'|0x80)))
8116 /* This is a hack for an ill-considered 64-bit ABI where
8117 tv_usec is actually a 32-bit field with 32 bits of padding
8118 rounding out struct timeval. We've already converted it as
8119 a 64-bit field. For little-endian, this just means the
8120 high half is the padding; it's presumably zero, but should
8121 be ignored anyway. For big-endian, it means the 32-bit
8122 field went into the high half of USEC. */
8124 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8125 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8130 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8131 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8135 assert (count == 1);
8136 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8137 "%c", value.Byte[0]);
8141 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8142 "%.*s", (int) count, value.Byte);
8146 /* This is a list of strings separated by '\n'. */
8147 assert (item->count == 0);
8148 assert (repeated_size != NULL);
8149 assert (item->name == NULL);
8150 if (unlikely (item->offset >= *repeated_size))
8153 const char *s = desc + item->offset;
8154 size = *repeated_size - item->offset;
8158 const char *eol = memchr (s, '\n', size);
8162 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8165 size -= eol + 1 - s;
8169 colno = WRAP_COLUMN;
8173 error (0, 0, "XXX not handling format '%c' for %s",
8174 item->format, item->name);
8184 /* Sort items by group, and by layout offset within each group. */
8186 compare_core_items (const void *a, const void *b)
8188 const Ebl_Core_Item *const *p1 = a;
8189 const Ebl_Core_Item *const *p2 = b;
8190 const Ebl_Core_Item *item1 = *p1;
8191 const Ebl_Core_Item *item2 = *p2;
8193 return ((item1->group == item2->group ? 0
8194 : strcmp (item1->group, item2->group))
8195 ?: (int) item1->offset - (int) item2->offset);
8198 /* Sort item groups by layout offset of the first item in the group. */
8200 compare_core_item_groups (const void *a, const void *b)
8202 const Ebl_Core_Item *const *const *p1 = a;
8203 const Ebl_Core_Item *const *const *p2 = b;
8204 const Ebl_Core_Item *const *group1 = *p1;
8205 const Ebl_Core_Item *const *group2 = *p2;
8206 const Ebl_Core_Item *item1 = *group1;
8207 const Ebl_Core_Item *item2 = *group2;
8209 return (int) item1->offset - (int) item2->offset;
8213 handle_core_items (Elf *core, const void *desc, size_t descsz,
8214 const Ebl_Core_Item *items, size_t nitems)
8218 unsigned int colno = 0;
8220 /* FORMAT '\n' makes sense to be present only as a single item as it
8221 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8222 if present as a single item but they can be also processed with other
8224 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8225 || items[0].format == 'B'))
8227 assert (items[0].offset == 0);
8228 size_t size = descsz;
8229 colno = handle_core_item (core, items, desc, colno, &size);
8230 /* If SIZE is not zero here there is some remaining data. But we do not
8231 know how to process it anyway. */
8234 for (size_t i = 0; i < nitems; ++i)
8235 assert (items[i].format != '\n');
8237 /* Sort to collect the groups together. */
8238 const Ebl_Core_Item *sorted_items[nitems];
8239 for (size_t i = 0; i < nitems; ++i)
8240 sorted_items[i] = &items[i];
8241 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8243 /* Collect the unique groups and sort them. */
8244 const Ebl_Core_Item **groups[nitems];
8245 groups[0] = &sorted_items[0];
8247 for (size_t i = 1; i < nitems; ++i)
8248 if (sorted_items[i]->group != sorted_items[i - 1]->group
8249 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8250 groups[ngroups++] = &sorted_items[i];
8251 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8253 /* Write out all the groups. */
8254 const void *last = desc;
8257 for (size_t i = 0; i < ngroups; ++i)
8259 for (const Ebl_Core_Item **item = groups[i];
8260 (item < &sorted_items[nitems]
8261 && ((*item)->group == groups[i][0]->group
8262 || !strcmp ((*item)->group, groups[i][0]->group)));
8264 colno = handle_core_item (core, *item, desc, colno, NULL);
8266 /* Force a line break at the end of the group. */
8267 colno = WRAP_COLUMN;
8273 /* This set of items consumed a certain amount of the note's data.
8274 If there is more data there, we have another unit of the same size.
8275 Loop to print that out too. */
8276 const Ebl_Core_Item *item = &items[nitems - 1];
8277 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8278 item->count ?: 1, EV_CURRENT);
8287 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8291 /* For just one repeat, print it unabridged twice. */
8296 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8297 ITEM_INDENT, "", reps);
8307 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8310 desc += regloc->offset;
8318 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8319 const Ebl_Register_Location *regloc, const void *desc,
8322 if (regloc->bits % 8 != 0)
8323 return handle_bit_registers (regloc, desc, colno);
8325 desc += regloc->offset;
8327 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8329 char name[REGNAMESZ];
8332 register_info (ebl, reg, regloc, name, &bits, &type);
8335 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8336 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8337 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8338 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8340 #define BITS(bits, xtype, sfmt, ufmt) \
8341 uint##bits##_t b##bits; int##bits##_t b##bits##s
8342 union { TYPES; uint64_t b128[2]; } value;
8347 case DW_ATE_unsigned:
8349 case DW_ATE_address:
8352 #define BITS(bits, xtype, sfmt, ufmt) \
8354 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8355 if (type == DW_ATE_signed) \
8356 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8358 sfmt, value.b##bits##s); \
8360 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8362 ufmt, value.b##bits); \
8368 assert (type == DW_ATE_unsigned);
8369 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8370 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8371 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8373 "0x%.16" PRIx64 "%.16" PRIx64,
8374 value.b128[!be], value.b128[be]);
8384 /* Print each byte in hex, the whole thing in native byte order. */
8385 assert (bits % 8 == 0);
8386 const uint8_t *bytes = desc;
8388 char hex[bits / 4 + 1];
8389 hex[bits / 4] = '\0';
8391 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8393 bytes += bits / 8 - 1;
8397 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8399 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8400 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8402 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8403 maxregname, name, "0x%s", hex);
8406 desc += regloc->pad;
8415 struct register_info
8417 const Ebl_Register_Location *regloc;
8419 char name[REGNAMESZ];
8426 register_bitpos (const struct register_info *r)
8428 return (r->regloc->offset * 8
8429 + ((r->regno - r->regloc->regno)
8430 * (r->regloc->bits + r->regloc->pad * 8)));
8434 compare_sets_by_info (const struct register_info *r1,
8435 const struct register_info *r2)
8437 return ((int) r2->bits - (int) r1->bits
8438 ?: register_bitpos (r1) - register_bitpos (r2));
8441 /* Sort registers by set, and by size and layout offset within each set. */
8443 compare_registers (const void *a, const void *b)
8445 const struct register_info *r1 = a;
8446 const struct register_info *r2 = b;
8448 /* Unused elements sort last. */
8449 if (r1->regloc == NULL)
8450 return r2->regloc == NULL ? 0 : 1;
8451 if (r2->regloc == NULL)
8454 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8455 ?: compare_sets_by_info (r1, r2));
8458 /* Sort register sets by layout offset of the first register in the set. */
8460 compare_register_sets (const void *a, const void *b)
8462 const struct register_info *const *p1 = a;
8463 const struct register_info *const *p2 = b;
8464 return compare_sets_by_info (*p1, *p2);
8468 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8469 const Ebl_Register_Location *reglocs, size_t nregloc)
8474 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8477 for (size_t i = 0; i < nregloc; ++i)
8478 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8479 maxnreg = reglocs[i].regno + reglocs[i].count;
8480 assert (maxnreg > 0);
8483 struct register_info regs[maxnreg];
8484 memset (regs, 0, sizeof regs);
8486 /* Sort to collect the sets together. */
8488 for (size_t i = 0; i < nregloc; ++i)
8489 for (int reg = reglocs[i].regno;
8490 reg < reglocs[i].regno + reglocs[i].count;
8493 assert (reg < maxnreg);
8496 struct register_info *info = ®s[reg];
8497 info->regloc = ®locs[i];
8499 info->set = register_info (ebl, reg, ®locs[i],
8500 info->name, &info->bits, &info->type);
8502 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8504 /* Collect the unique sets and sort them. */
8505 inline bool same_set (const struct register_info *a,
8506 const struct register_info *b)
8508 return (a < ®s[maxnreg] && a->regloc != NULL
8509 && b < ®s[maxnreg] && b->regloc != NULL
8510 && a->bits == b->bits
8511 && (a->set == b->set || !strcmp (a->set, b->set)));
8513 struct register_info *sets[maxreg + 1];
8516 for (int i = 1; i <= maxreg; ++i)
8517 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8518 sets[nsets++] = ®s[i];
8519 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8521 /* Write out all the sets. */
8522 unsigned int colno = 0;
8523 for (size_t i = 0; i < nsets; ++i)
8525 /* Find the longest name of a register in this set. */
8527 const struct register_info *end;
8528 for (end = sets[i]; same_set (sets[i], end); ++end)
8530 size_t len = strlen (end->name);
8535 for (const struct register_info *reg = sets[i];
8537 reg += reg->regloc->count ?: 1)
8538 colno = handle_core_register (ebl, core, maxname,
8539 reg->regloc, desc, colno);
8541 /* Force a line break at the end of the group. */
8542 colno = WRAP_COLUMN;
8549 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8551 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8554 error (EXIT_FAILURE, 0,
8555 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8557 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8558 for (size_t i = 0; i < nauxv; ++i)
8561 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8567 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8570 if (av->a_un.a_val == 0)
8571 printf (" %" PRIu64 "\n", av->a_type);
8573 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8574 av->a_type, av->a_un.a_val);
8579 case '\0': /* Normally zero. */
8580 if (av->a_un.a_val == 0)
8582 printf (" %s\n", name);
8587 case 'p': /* address */
8588 case 's': /* address of string */
8589 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8592 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
8595 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
8599 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
8601 const char *pfx = "<";
8602 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8604 if (av->a_un.a_val & bit)
8606 printf ("%s%s", pfx, p);
8621 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8623 return ptr < end && (size_t) (end - ptr) >= sz;
8627 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8630 if (! buf_has_data (*ptrp, end, 4))
8633 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8638 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8641 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8642 if (! buf_has_data (*ptrp, end, sz))
8651 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sizeof u);
8661 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8663 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8665 error (EXIT_FAILURE, 0,
8666 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8668 unsigned char const *ptr = data->d_buf;
8669 unsigned char const *const end = data->d_buf + data->d_size;
8671 /* Siginfo head is three ints: signal number, error number, origin
8673 int si_signo, si_errno, si_code;
8674 if (! buf_read_int (core, &ptr, end, &si_signo)
8675 || ! buf_read_int (core, &ptr, end, &si_errno)
8676 || ! buf_read_int (core, &ptr, end, &si_code))
8679 printf (" Not enough data in NT_SIGINFO note.\n");
8683 /* Next is a pointer-aligned union of structures. On 64-bit
8684 machines, that implies a word of padding. */
8685 if (gelf_getclass (core) == ELFCLASS64)
8688 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
8689 si_signo, si_errno, si_code);
8700 if (! buf_read_ulong (core, &ptr, end, &addr))
8702 printf (" fault address: %#" PRIx64 "\n", addr);
8708 else if (si_code == SI_USER)
8711 if (! buf_read_int (core, &ptr, end, &pid)
8712 || ! buf_read_int (core, &ptr, end, &uid))
8714 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
8719 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8721 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8723 error (EXIT_FAILURE, 0,
8724 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8726 unsigned char const *ptr = data->d_buf;
8727 unsigned char const *const end = data->d_buf + data->d_size;
8729 uint64_t count, page_size;
8730 if (! buf_read_ulong (core, &ptr, end, &count)
8731 || ! buf_read_ulong (core, &ptr, end, &page_size))
8734 printf (" Not enough data in NT_FILE note.\n");
8738 /* Where file names are stored. */
8739 unsigned char const *const fstart
8740 = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8741 char const *fptr = (char *) fstart;
8743 printf (" %" PRId64 " files:\n", count);
8744 for (uint64_t i = 0; i < count; ++i)
8746 uint64_t mstart, mend, moffset;
8747 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
8748 || ! buf_read_ulong (core, &ptr, fstart, &mend)
8749 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
8752 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
8756 int ct = printf (" %08" PRIx64 "-%08" PRIx64
8757 " %08" PRIx64 " %" PRId64,
8758 mstart, mend, moffset * page_size, mend - mstart);
8759 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
8766 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8767 const char *name, const void *desc)
8769 GElf_Word regs_offset;
8771 const Ebl_Register_Location *reglocs;
8773 const Ebl_Core_Item *items;
8775 if (! ebl_core_note (ebl, nhdr, name,
8776 ®s_offset, &nregloc, ®locs, &nitems, &items))
8779 /* Pass 0 for DESCSZ when there are registers in the note,
8780 so that the ITEMS array does not describe the whole thing.
8781 For non-register notes, the actual descsz might be a multiple
8782 of the unit size, not just exactly the unit size. */
8783 unsigned int colno = handle_core_items (ebl->elf, desc,
8784 nregloc == 0 ? nhdr->n_descsz : 0,
8787 putchar_unlocked ('\n');
8789 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8792 putchar_unlocked ('\n');
8796 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8797 GElf_Off start, Elf_Data *data)
8799 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
8808 while (offset < data->d_size
8809 && (offset = gelf_getnote (data, offset,
8810 &nhdr, &name_offset, &desc_offset)) > 0)
8812 const char *name = data->d_buf + name_offset;
8813 const char *desc = data->d_buf + desc_offset;
8817 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
8818 (int) nhdr.n_namesz, name, nhdr.n_descsz,
8819 ehdr->e_type == ET_CORE
8820 ? ebl_core_note_type_name (ebl, nhdr.n_type,
8822 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8823 buf2, sizeof (buf2)));
8825 /* Filter out invalid entries. */
8826 if (memchr (name, '\0', nhdr.n_namesz) != NULL
8827 /* XXX For now help broken Linux kernels. */
8830 if (ehdr->e_type == ET_CORE)
8832 if (nhdr.n_type == NT_AUXV
8833 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
8834 || (nhdr.n_namesz == 5 && name[4] == '\0'))
8835 && !memcmp (name, "CORE", 4))
8836 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
8837 start + desc_offset);
8838 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
8839 switch (nhdr.n_type)
8842 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
8843 start + desc_offset);
8847 handle_file_note (ebl->elf, nhdr.n_descsz,
8848 start + desc_offset);
8852 handle_core_note (ebl, &nhdr, name, desc);
8855 handle_core_note (ebl, &nhdr, name, desc);
8858 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
8862 if (offset == data->d_size)
8866 error (EXIT_FAILURE, 0,
8867 gettext ("cannot get content of note section: %s"),
8872 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
8874 /* If we have section headers, just look for SHT_NOTE sections.
8875 In a debuginfo file, the program headers are not reliable. */
8878 /* Get the section header string table index. */
8880 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
8881 error (EXIT_FAILURE, 0,
8882 gettext ("cannot get section header string table index"));
8884 Elf_Scn *scn = NULL;
8885 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8888 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8890 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
8891 /* Not what we are looking for. */
8895 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8897 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
8898 shdr->sh_size, shdr->sh_offset);
8900 handle_notes_data (ebl, ehdr, shdr->sh_offset,
8901 elf_getdata (scn, NULL));
8906 /* We have to look through the program header to find the note
8907 sections. There can be more than one. */
8908 for (size_t cnt = 0; cnt < phnum; ++cnt)
8911 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
8913 if (phdr == NULL || phdr->p_type != PT_NOTE)
8914 /* Not what we are looking for. */
8918 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8919 phdr->p_filesz, phdr->p_offset);
8921 handle_notes_data (ebl, ehdr, phdr->p_offset,
8922 elf_getdata_rawchunk (ebl->elf,
8923 phdr->p_offset, phdr->p_filesz,
8930 hex_dump (const uint8_t *data, size_t len)
8935 printf (" 0x%08Zx ", pos);
8937 const size_t chunk = MIN (len - pos, 16);
8939 for (size_t i = 0; i < chunk; ++i)
8941 printf ("%02x ", data[pos + i]);
8943 printf ("%02x", data[pos + i]);
8946 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
8948 for (size_t i = 0; i < chunk; ++i)
8950 unsigned char b = data[pos + i];
8951 printf ("%c", isprint (b) ? b : '.');
8960 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
8962 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
8963 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
8964 elf_ndxscn (scn), name);
8967 Elf_Data *data = elf_rawdata (scn, NULL);
8969 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
8970 elf_ndxscn (scn), name, elf_errmsg (-1));
8973 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
8974 " bytes at offset %#0" PRIx64 ":\n"),
8975 elf_ndxscn (scn), name,
8976 shdr->sh_size, shdr->sh_offset);
8977 hex_dump (data->d_buf, data->d_size);
8983 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
8985 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
8986 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
8987 elf_ndxscn (scn), name);
8990 Elf_Data *data = elf_rawdata (scn, NULL);
8992 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
8993 elf_ndxscn (scn), name, elf_errmsg (-1));
8996 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
8997 " bytes at offset %#0" PRIx64 ":\n"),
8998 elf_ndxscn (scn), name,
8999 shdr->sh_size, shdr->sh_offset);
9001 const char *start = data->d_buf;
9002 const char *const limit = start + data->d_size;
9005 const char *end = memchr (start, '\0', limit - start);
9006 const size_t pos = start - (const char *) data->d_buf;
9007 if (unlikely (end == NULL))
9009 printf (" [%6Zx]- %.*s\n",
9010 pos, (int) (limit - start), start);
9013 printf (" [%6Zx] %s\n", pos, start);
9015 } while (start < limit);
9021 for_each_section_argument (Elf *elf, const struct section_argument *list,
9022 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9025 /* Get the section header string table index. */
9027 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9028 error (EXIT_FAILURE, 0,
9029 gettext ("cannot get section header string table index"));
9031 for (const struct section_argument *a = list; a != NULL; a = a->next)
9035 const char *name = NULL;
9038 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9039 if (endp != a->arg && *endp == '\0')
9041 scn = elf_getscn (elf, shndx);
9044 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9048 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9049 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9051 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9055 /* Need to look up the section by name. */
9058 while ((scn = elf_nextscn (elf, scn)) != NULL)
9060 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9062 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9065 if (!strcmp (name, a->arg))
9068 (*dump) (scn, &shdr_mem, name);
9072 if (unlikely (!found) && !a->implicit)
9073 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9079 dump_data (Ebl *ebl)
9081 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9085 dump_strings (Ebl *ebl)
9087 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9091 print_strings (Ebl *ebl)
9093 /* Get the section header string table index. */
9095 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9096 error (EXIT_FAILURE, 0,
9097 gettext ("cannot get section header string table index"));
9103 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9105 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9108 if (shdr_mem.sh_type != SHT_PROGBITS
9109 || !(shdr_mem.sh_flags & SHF_STRINGS))
9112 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9116 print_string_section (scn, &shdr_mem, name);
9121 dump_archive_index (Elf *elf, const char *fname)
9124 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9127 int result = elf_errno ();
9128 if (unlikely (result != ELF_E_NO_INDEX))
9129 error (EXIT_FAILURE, 0,
9130 gettext ("cannot get symbol index of archive '%s': %s"),
9131 fname, elf_errmsg (result));
9133 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9137 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9141 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9143 if (s->as_off != as_off)
9148 if (unlikely (elf_rand (elf, as_off) == 0)
9149 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9151 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9154 error (EXIT_FAILURE, 0,
9155 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9156 as_off, fname, elf_errmsg (-1));
9158 const Elf_Arhdr *h = elf_getarhdr (subelf);
9160 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9165 printf ("\t%s\n", s->as_name);
9169 #include "debugpred.h"