1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2015 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1999.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
43 #include <sys/param.h>
48 #include "../libelf/libelfP.h"
49 #include "../libelf/common.h"
50 #include "../libebl/libeblP.h"
51 #include "../libdw/libdwP.h"
52 #include "../libdwfl/libdwflP.h"
53 #include "../libdw/memory-access.h"
55 #include "../libdw/known-dwarf.h"
58 /* Name and version of program. */
59 static void print_version (FILE *stream, struct argp_state *state);
60 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
62 /* Bug report address. */
63 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
65 /* argp key value for --elf-section, non-ascii. */
66 #define ELF_INPUT_SECTION 256
68 /* Definitions of arguments for argp functions. */
69 static const struct argp_option options[] =
71 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
72 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
73 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
75 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
76 { "all", 'a', NULL, 0,
77 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
78 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
79 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
80 { "histogram", 'I', NULL, 0,
81 N_("Display histogram of bucket list lengths"), 0 },
82 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
83 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
84 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
85 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
86 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
87 { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
88 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
89 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
90 { "arch-specific", 'A', NULL, 0,
91 N_("Display architecture specific information, if any"), 0 },
92 { "exception", 'e', NULL, 0,
93 N_("Display sections for exception handling"), 0 },
95 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
96 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
97 N_("Display DWARF section content. SECTION can be one of abbrev, "
98 "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
99 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
100 { "hex-dump", 'x', "SECTION", 0,
101 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
102 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
103 N_("Print string contents of sections"), 0 },
104 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
105 { "archive-index", 'c', NULL, 0,
106 N_("Display the symbol index of an archive"), 0 },
108 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
109 { "numeric-addresses", 'N', NULL, 0,
110 N_("Do not find symbol names for addresses in DWARF data"), 0 },
111 { "unresolved-address-offsets", 'U', NULL, 0,
112 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
113 { "wide", 'W', NULL, 0,
114 N_("Ignored for compatibility (lines always wide)"), 0 },
115 { NULL, 0, NULL, 0, NULL, 0 }
118 /* Short description of program. */
119 static const char doc[] = N_("\
120 Print information from ELF file in human-readable form.");
122 /* Strings for arguments in help texts. */
123 static const char args_doc[] = N_("FILE...");
125 /* Prototype for option handler. */
126 static error_t parse_opt (int key, char *arg, struct argp_state *state);
128 /* Data structure to communicate with argp functions. */
129 static struct argp argp =
131 options, parse_opt, args_doc, doc, NULL, NULL, NULL
134 /* If non-null, the section from which we should read to (compressed) ELF. */
135 static const char *elf_input_section = NULL;
137 /* Flags set by the option controlling the output. */
139 /* True if dynamic segment should be printed. */
140 static bool print_dynamic_table;
142 /* True if the file header should be printed. */
143 static bool print_file_header;
145 /* True if the program headers should be printed. */
146 static bool print_program_header;
148 /* True if relocations should be printed. */
149 static bool print_relocations;
151 /* True if the section headers should be printed. */
152 static bool print_section_header;
154 /* True if the symbol table should be printed. */
155 static bool print_symbol_table;
157 /* True if the version information should be printed. */
158 static bool print_version_info;
160 /* True if section groups should be printed. */
161 static bool print_section_groups;
163 /* True if bucket list length histogram should be printed. */
164 static bool print_histogram;
166 /* True if the architecture specific data should be printed. */
167 static bool print_arch;
169 /* True if note section content should be printed. */
170 static bool print_notes;
172 /* True if SHF_STRINGS section content should be printed. */
173 static bool print_string_sections;
175 /* True if archive index should be printed. */
176 static bool print_archive_index;
178 /* True if any of the control options except print_archive_index is set. */
179 static bool any_control_option;
181 /* True if we should print addresses from DWARF in symbolic form. */
182 static bool print_address_names = true;
184 /* True if we should print raw values instead of relativized addresses. */
185 static bool print_unresolved_addresses = false;
187 /* True if we should print the .debug_aranges section using libdw. */
188 static bool decodedaranges = false;
190 /* True if we should print the .debug_aranges section using libdw. */
191 static bool decodedline = false;
193 /* Select printing of debugging sections. */
194 static enum section_e
196 section_abbrev = 1, /* .debug_abbrev */
197 section_aranges = 2, /* .debug_aranges */
198 section_frame = 4, /* .debug_frame or .eh_frame & al. */
199 section_info = 8, /* .debug_info, .debug_types */
200 section_types = section_info,
201 section_line = 16, /* .debug_line */
202 section_loc = 32, /* .debug_loc */
203 section_pubnames = 64, /* .debug_pubnames */
204 section_str = 128, /* .debug_str */
205 section_macinfo = 256, /* .debug_macinfo */
206 section_ranges = 512, /* .debug_ranges */
207 section_exception = 1024, /* .eh_frame & al. */
208 section_gdb_index = 2048, /* .gdb_index */
209 section_macro = 4096, /* .debug_macro */
210 section_all = (section_abbrev | section_aranges | section_frame
211 | section_info | section_line | section_loc
212 | section_pubnames | section_str | section_macinfo
213 | section_ranges | section_exception | section_gdb_index
215 } print_debug_sections, implicit_debug_sections;
217 /* Select hex dumping of sections. */
218 static struct section_argument *dump_data_sections;
219 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
221 /* Select string dumping of sections. */
222 static struct section_argument *string_sections;
223 static struct section_argument **string_sections_tail = &string_sections;
225 struct section_argument
227 struct section_argument *next;
232 /* Numbers of sections and program headers in the file. */
237 /* Declarations of local functions. */
238 static void process_file (int fd, const char *fname, bool only_one);
239 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
240 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
241 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
242 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
243 static void print_scngrp (Ebl *ebl);
244 static void print_dynamic (Ebl *ebl);
245 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
246 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
248 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
250 static void print_symtab (Ebl *ebl, int type);
251 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
252 static void print_verinfo (Ebl *ebl);
253 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
254 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
255 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
257 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
258 static void handle_hash (Ebl *ebl);
259 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
260 static void print_liblist (Ebl *ebl);
261 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
262 static void dump_data (Ebl *ebl);
263 static void dump_strings (Ebl *ebl);
264 static void print_strings (Ebl *ebl);
265 static void dump_archive_index (Elf *, const char *);
269 main (int argc, char *argv[])
272 setlocale (LC_ALL, "");
274 /* Initialize the message catalog. */
275 textdomain (PACKAGE_TARNAME);
277 /* Parse and process arguments. */
279 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
281 /* Before we start tell the ELF library which version we are using. */
282 elf_version (EV_CURRENT);
284 /* Now process all the files given at the command line. */
285 bool only_one = remaining + 1 == argc;
289 int fd = open (argv[remaining], O_RDONLY);
292 error (0, errno, gettext ("cannot open input file"));
296 process_file (fd, argv[remaining], only_one);
300 while (++remaining < argc);
302 return error_message_count != 0;
306 /* Handle program arguments. */
308 parse_opt (int key, char *arg,
309 struct argp_state *state __attribute__ ((unused)))
311 void add_dump_section (const char *name, bool implicit)
313 struct section_argument *a = xmalloc (sizeof *a);
316 a->implicit = implicit;
317 struct section_argument ***tailp
318 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
326 print_file_header = true;
327 print_program_header = true;
328 print_relocations = true;
329 print_section_header = true;
330 print_symbol_table = true;
331 print_version_info = true;
332 print_dynamic_table = true;
333 print_section_groups = true;
334 print_histogram = true;
337 implicit_debug_sections |= section_exception;
338 add_dump_section (".strtab", true);
339 add_dump_section (".dynstr", true);
340 add_dump_section (".comment", true);
341 any_control_option = true;
345 any_control_option = true;
348 print_dynamic_table = true;
349 any_control_option = true;
352 print_debug_sections |= section_exception;
353 any_control_option = true;
356 print_section_groups = true;
357 any_control_option = true;
360 print_file_header = true;
361 any_control_option = true;
364 print_histogram = true;
365 any_control_option = true;
368 print_program_header = true;
369 any_control_option = true;
373 any_control_option = true;
376 print_relocations = true;
377 any_control_option = true;
380 print_section_header = true;
381 any_control_option = true;
384 print_symbol_table = true;
385 any_control_option = true;
388 print_version_info = true;
389 any_control_option = true;
392 print_archive_index = true;
396 print_debug_sections = section_all;
397 else if (strcmp (arg, "abbrev") == 0)
398 print_debug_sections |= section_abbrev;
399 else if (strcmp (arg, "aranges") == 0)
400 print_debug_sections |= section_aranges;
401 else if (strcmp (arg, "decodedaranges") == 0)
403 print_debug_sections |= section_aranges;
404 decodedaranges = true;
406 else if (strcmp (arg, "ranges") == 0)
408 print_debug_sections |= section_ranges;
409 implicit_debug_sections |= section_info;
411 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
412 print_debug_sections |= section_frame;
413 else if (strcmp (arg, "info") == 0)
414 print_debug_sections |= section_info;
415 else if (strcmp (arg, "loc") == 0)
417 print_debug_sections |= section_loc;
418 implicit_debug_sections |= section_info;
420 else if (strcmp (arg, "line") == 0)
421 print_debug_sections |= section_line;
422 else if (strcmp (arg, "decodedline") == 0)
424 print_debug_sections |= section_line;
427 else if (strcmp (arg, "pubnames") == 0)
428 print_debug_sections |= section_pubnames;
429 else if (strcmp (arg, "str") == 0)
430 print_debug_sections |= section_str;
431 else if (strcmp (arg, "macinfo") == 0)
432 print_debug_sections |= section_macinfo;
433 else if (strcmp (arg, "macro") == 0)
434 print_debug_sections |= section_macro;
435 else if (strcmp (arg, "exception") == 0)
436 print_debug_sections |= section_exception;
437 else if (strcmp (arg, "gdb_index") == 0)
438 print_debug_sections |= section_gdb_index;
441 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
443 argp_help (&argp, stderr, ARGP_HELP_SEE,
444 program_invocation_short_name);
447 any_control_option = true;
450 any_control_option = true;
453 print_string_sections = true;
458 add_dump_section (arg, false);
459 any_control_option = true;
462 print_address_names = false;
465 print_unresolved_addresses = true;
467 case ARGP_KEY_NO_ARGS:
468 fputs (gettext ("Missing file name.\n"), stderr);
471 if (! any_control_option && ! print_archive_index)
473 fputs (gettext ("No operation specified.\n"), stderr);
475 argp_help (&argp, stderr, ARGP_HELP_SEE,
476 program_invocation_short_name);
480 case 'W': /* Ignored. */
482 case ELF_INPUT_SECTION:
484 elf_input_section = ".gnu_debugdata";
486 elf_input_section = arg;
489 return ARGP_ERR_UNKNOWN;
495 /* Print the version information. */
497 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
499 fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
500 fprintf (stream, gettext ("\
501 Copyright (C) %s Red Hat, Inc.\n\
502 This is free software; see the source for copying conditions. There is NO\n\
503 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
505 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
509 /* Create a file descriptor to read the data from the
510 elf_input_section given a file descriptor to an ELF file. */
512 open_input_section (int fd)
517 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
520 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
525 if (elf_getshdrnum (elf, &shnums) < 0)
527 error (0, 0, gettext ("cannot determine number of sections: %s"),
534 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
536 error (0, 0, gettext ("cannot get section header string table index"));
540 for (cnt = 0; cnt < shnums; ++cnt)
542 Elf_Scn *scn = elf_getscn (elf, cnt);
545 error (0, 0, gettext ("cannot get section: %s"),
551 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
552 if (unlikely (shdr == NULL))
554 error (0, 0, gettext ("cannot get section header: %s"),
559 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
562 error (0, 0, gettext ("cannot get section name"));
566 if (strcmp (sname, elf_input_section) == 0)
568 Elf_Data *data = elf_rawdata (scn, NULL);
571 error (0, 0, gettext ("cannot get %s content: %s"),
572 sname, elf_errmsg (-1));
576 /* Create (and immediately unlink) a temporary file to store
577 section data in to create a file descriptor for it. */
578 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
579 static const char suffix[] = "/readelfXXXXXX";
580 int tmplen = strlen (tmpdir) + sizeof (suffix);
581 char *tempname = alloca (tmplen);
582 sprintf (tempname, "%s%s", tmpdir, suffix);
584 int sfd = mkstemp (tempname);
587 error (0, 0, gettext ("cannot create temp file '%s'"),
593 ssize_t size = data->d_size;
594 if (write_retry (sfd, data->d_buf, size) != size)
596 error (0, 0, gettext ("cannot write section data"));
600 if (elf_end (elf) != 0)
602 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
607 if (lseek (sfd, 0, SEEK_SET) == -1)
609 error (0, 0, gettext ("error while rewinding file descriptor"));
617 /* Named section not found. */
618 if (elf_end (elf) != 0)
619 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
624 /* Check if the file is an archive, and if so dump its index. */
626 check_archive_index (int fd, const char *fname, bool only_one)
628 /* Create an `Elf' descriptor. */
629 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
631 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
635 if (elf_kind (elf) == ELF_K_AR)
638 printf ("\n%s:\n\n", fname);
639 dump_archive_index (elf, fname);
643 gettext ("'%s' is not an archive, cannot print archive index"),
646 /* Now we can close the descriptor. */
647 if (elf_end (elf) != 0)
648 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
653 /* Trivial callback used for checking if we opened an archive. */
655 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
656 void **userdata __attribute__ ((unused)),
657 const char *name __attribute__ ((unused)),
658 Dwarf_Addr base __attribute__ ((unused)),
662 return DWARF_CB_ABORT;
663 *(bool *) arg = true;
667 struct process_dwflmod_args
674 process_dwflmod (Dwfl_Module *dwflmod,
675 void **userdata __attribute__ ((unused)),
676 const char *name __attribute__ ((unused)),
677 Dwarf_Addr base __attribute__ ((unused)),
680 const struct process_dwflmod_args *a = arg;
682 /* Print the file name. */
686 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
688 printf ("\n%s:\n\n", fname);
691 process_elf_file (dwflmod, a->fd);
696 /* Stub libdwfl callback, only the ELF handle already open is ever used.
697 Only used for finding the alternate debug file if the Dwarf comes from
698 the main file. We are not interested in separate debuginfo. */
700 find_no_debuginfo (Dwfl_Module *mod,
704 const char *file_name,
705 const char *debuglink_file,
706 GElf_Word debuglink_crc,
707 char **debuginfo_file_name)
710 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
712 /* We are only interested if the Dwarf has been setup on the main
713 elf file but is only missing the alternate debug link. If dwbias
714 hasn't even been setup, this is searching for separate debuginfo
715 for the main elf. We don't care in that case. */
716 if (dwbias == (Dwarf_Addr) -1)
719 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
720 file_name, debuglink_file,
721 debuglink_crc, debuginfo_file_name);
724 /* Process one input file. */
726 process_file (int fd, const char *fname, bool only_one)
728 if (print_archive_index)
729 check_archive_index (fd, fname, only_one);
731 if (!any_control_option)
734 if (elf_input_section != NULL)
736 /* Replace fname and fd with section content. */
737 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
738 sprintf (fnname, "%s:%s", fname, elf_input_section);
739 fd = open_input_section (fd);
742 error (0, 0, gettext ("No such section '%s' in '%s'"),
743 elf_input_section, fname);
749 /* Duplicate an fd for dwfl_report_offline to swallow. */
750 int dwfl_fd = dup (fd);
751 if (unlikely (dwfl_fd < 0))
752 error (EXIT_FAILURE, errno, "dup");
754 /* Use libdwfl in a trivial way to open the libdw handle for us.
755 This takes care of applying relocations to DWARF data in ET_REL files. */
756 static const Dwfl_Callbacks callbacks =
758 .section_address = dwfl_offline_section_address,
759 .find_debuginfo = find_no_debuginfo
761 Dwfl *dwfl = dwfl_begin (&callbacks);
762 if (likely (dwfl != NULL))
763 /* Let 0 be the logical address of the file (or first in archive). */
764 dwfl->offline_next_address = 0;
765 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
768 if (fstat64 (dwfl_fd, &st) != 0)
769 error (0, errno, gettext ("cannot stat input file"));
770 else if (unlikely (st.st_size == 0))
771 error (0, 0, gettext ("input file is empty"));
773 error (0, 0, gettext ("failed reading '%s': %s"),
774 fname, dwfl_errmsg (-1));
775 close (dwfl_fd); /* Consumed on success, not on failure. */
779 dwfl_report_end (dwfl, NULL, NULL);
783 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
785 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
788 /* Process the one or more modules gleaned from this file. */
789 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
790 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
794 /* Need to close the replaced fd if we created it. Caller takes
796 if (elf_input_section != NULL)
801 /* Process one ELF file. */
803 process_elf_file (Dwfl_Module *dwflmod, int fd)
806 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
809 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
814 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
818 Ebl *ebl = ebl_openbackend (elf);
819 if (unlikely (ebl == NULL))
822 error (0, errno, gettext ("cannot create EBL handle"));
826 /* Determine the number of sections. */
827 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
828 error (EXIT_FAILURE, 0,
829 gettext ("cannot determine number of sections: %s"),
832 /* Determine the number of phdrs. */
833 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
834 error (EXIT_FAILURE, 0,
835 gettext ("cannot determine number of program headers: %s"),
838 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs
839 and may have applied relocation to some sections.
840 So we need to get a fresh Elf handle on the file to display those. */
841 bool print_unrelocated = (print_section_header
843 || dump_data_sections != NULL
846 Elf *pure_elf = NULL;
848 if (ehdr->e_type == ET_REL && print_unrelocated)
850 /* Read the file afresh. */
851 off64_t aroff = elf_getaroff (elf);
852 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
855 /* Archive member. */
856 (void) elf_rand (pure_elf, aroff);
857 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
861 if (pure_elf == NULL)
863 pure_ebl = ebl_openbackend (pure_elf);
864 if (pure_ebl == NULL)
868 if (print_file_header)
869 print_ehdr (ebl, ehdr);
870 if (print_section_header)
871 print_shdr (pure_ebl, ehdr);
872 if (print_program_header)
873 print_phdr (ebl, ehdr);
874 if (print_section_groups)
876 if (print_dynamic_table)
878 if (print_relocations)
879 print_relocs (pure_ebl, ehdr);
882 if (print_symbol_table)
883 print_symtab (ebl, SHT_DYNSYM);
884 if (print_version_info)
886 if (print_symbol_table)
887 print_symtab (ebl, SHT_SYMTAB);
891 print_attributes (ebl, ehdr);
892 if (dump_data_sections != NULL)
893 dump_data (pure_ebl);
894 if (string_sections != NULL)
896 if ((print_debug_sections | implicit_debug_sections) != 0)
897 print_debug (dwflmod, ebl, ehdr);
899 handle_notes (pure_ebl, ehdr);
900 if (print_string_sections)
903 ebl_closebackend (ebl);
907 ebl_closebackend (pure_ebl);
913 /* Print file type. */
915 print_file_type (unsigned short int e_type)
917 if (likely (e_type <= ET_CORE))
919 static const char *const knowntypes[] =
922 N_("REL (Relocatable file)"),
923 N_("EXEC (Executable file)"),
924 N_("DYN (Shared object file)"),
925 N_("CORE (Core file)")
927 puts (gettext (knowntypes[e_type]));
929 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
930 printf (gettext ("OS Specific: (%x)\n"), e_type);
931 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
932 printf (gettext ("Processor Specific: (%x)\n"), e_type);
938 /* Print ELF header. */
940 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
942 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
943 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
944 printf (" %02hhx", ehdr->e_ident[cnt]);
946 printf (gettext ("\n Class: %s\n"),
947 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
948 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
951 printf (gettext (" Data: %s\n"),
952 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
953 ? "2's complement, little endian"
954 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
955 ? "2's complement, big endian" : "\?\?\?");
957 printf (gettext (" Ident Version: %hhd %s\n"),
958 ehdr->e_ident[EI_VERSION],
959 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
963 printf (gettext (" OS/ABI: %s\n"),
964 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
966 printf (gettext (" ABI Version: %hhd\n"),
967 ehdr->e_ident[EI_ABIVERSION]);
969 fputs_unlocked (gettext (" Type: "), stdout);
970 print_file_type (ehdr->e_type);
972 printf (gettext (" Machine: %s\n"), ebl->name);
974 printf (gettext (" Version: %d %s\n"),
976 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
978 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
981 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
982 ehdr->e_phoff, gettext ("(bytes into file)"));
984 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
985 ehdr->e_shoff, gettext ("(bytes into file)"));
987 printf (gettext (" Flags: %s\n"),
988 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
990 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
991 ehdr->e_ehsize, gettext ("(bytes)"));
993 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
994 ehdr->e_phentsize, gettext ("(bytes)"));
996 printf (gettext (" Number of program headers entries: %" PRId16),
998 if (ehdr->e_phnum == PN_XNUM)
1001 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1003 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1004 (uint32_t) shdr->sh_info);
1006 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1008 fputc_unlocked ('\n', stdout);
1010 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1011 ehdr->e_shentsize, gettext ("(bytes)"));
1013 printf (gettext (" Number of section headers entries: %" PRId16),
1015 if (ehdr->e_shnum == 0)
1018 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1020 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1021 (uint32_t) shdr->sh_size);
1023 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1025 fputc_unlocked ('\n', stdout);
1027 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1030 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1032 /* We managed to get the zeroth section. */
1033 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1034 (uint32_t) shdr->sh_link);
1037 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1038 buf[sizeof (buf) - 1] = '\0';
1041 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1045 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1051 get_visibility_type (int value)
1069 /* Print the section headers. */
1071 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1076 if (! print_file_header)
1078 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1080 ehdr->e_shnum, ehdr->e_shoff);
1082 /* Get the section header string table index. */
1083 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1084 error (EXIT_FAILURE, 0,
1085 gettext ("cannot get section header string table index"));
1087 puts (gettext ("Section Headers:"));
1089 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1090 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1092 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1094 for (cnt = 0; cnt < shnum; ++cnt)
1096 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1098 if (unlikely (scn == NULL))
1099 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1102 /* Get the section header. */
1104 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1105 if (unlikely (shdr == NULL))
1106 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1111 if (shdr->sh_flags & SHF_WRITE)
1113 if (shdr->sh_flags & SHF_ALLOC)
1115 if (shdr->sh_flags & SHF_EXECINSTR)
1117 if (shdr->sh_flags & SHF_MERGE)
1119 if (shdr->sh_flags & SHF_STRINGS)
1121 if (shdr->sh_flags & SHF_INFO_LINK)
1123 if (shdr->sh_flags & SHF_LINK_ORDER)
1125 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1127 if (shdr->sh_flags & SHF_GROUP)
1129 if (shdr->sh_flags & SHF_TLS)
1131 if (shdr->sh_flags & SHF_ORDERED)
1133 if (shdr->sh_flags & SHF_EXCLUDE)
1138 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1139 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1142 elf_strptr (ebl->elf, shstrndx, shdr->sh_name)
1144 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1145 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1146 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1147 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1148 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1149 shdr->sh_addralign);
1152 fputc_unlocked ('\n', stdout);
1156 /* Print the program header. */
1158 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1161 /* No program header, this is OK in relocatable objects. */
1164 puts (gettext ("Program Headers:"));
1165 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1167 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1170 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1172 /* Process all program headers. */
1173 bool has_relro = false;
1174 GElf_Addr relro_from = 0;
1175 GElf_Addr relro_to = 0;
1176 for (size_t cnt = 0; cnt < phnum; ++cnt)
1180 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1182 /* If for some reason the header cannot be returned show this. */
1183 if (unlikely (phdr == NULL))
1189 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1190 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1191 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1193 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1194 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1197 phdr->p_flags & PF_R ? 'R' : ' ',
1198 phdr->p_flags & PF_W ? 'W' : ' ',
1199 phdr->p_flags & PF_X ? 'E' : ' ',
1202 if (phdr->p_type == PT_INTERP)
1204 /* If we are sure the file offset is valid then we can show
1205 the user the name of the interpreter. We check whether
1206 there is a section at the file offset. Normally there
1207 would be a section called ".interp". But in separate
1208 .debug files it is a NOBITS section (and so doesn't match
1209 with gelf_offscn). Which probably means the offset is
1210 not valid another reason could be because the ELF file
1211 just doesn't contain any section headers, in that case
1212 just play it safe and don't display anything. */
1214 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1216 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1219 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1221 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1222 && filedata != NULL && phdr->p_offset < maxsize
1223 && phdr->p_filesz <= maxsize - phdr->p_offset
1224 && memchr (filedata + phdr->p_offset, '\0',
1225 phdr->p_filesz) != NULL)
1226 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1227 filedata + phdr->p_offset);
1229 else if (phdr->p_type == PT_GNU_RELRO)
1232 relro_from = phdr->p_vaddr;
1233 relro_to = relro_from + phdr->p_memsz;
1237 if (ehdr->e_shnum == 0)
1238 /* No sections in the file. Punt. */
1241 /* Get the section header string table index. */
1243 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1244 error (EXIT_FAILURE, 0,
1245 gettext ("cannot get section header string table index"));
1247 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1249 for (size_t cnt = 0; cnt < phnum; ++cnt)
1251 /* Print the segment number. */
1252 printf (" %2.2zu ", cnt);
1255 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1256 /* This must not happen. */
1257 if (unlikely (phdr == NULL))
1258 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1261 /* Iterate over the sections. */
1262 bool in_relro = false;
1264 for (size_t inner = 1; inner < shnum; ++inner)
1266 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1267 /* This should not happen. */
1268 if (unlikely (scn == NULL))
1269 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1272 /* Get the section header. */
1274 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1275 if (unlikely (shdr == NULL))
1276 error (EXIT_FAILURE, 0,
1277 gettext ("cannot get section header: %s"),
1280 if (shdr->sh_size > 0
1281 /* Compare allocated sections by VMA, unallocated
1282 sections by file offset. */
1283 && (shdr->sh_flags & SHF_ALLOC
1284 ? (shdr->sh_addr >= phdr->p_vaddr
1285 && (shdr->sh_addr + shdr->sh_size
1286 <= phdr->p_vaddr + phdr->p_memsz))
1287 : (shdr->sh_offset >= phdr->p_offset
1288 && (shdr->sh_offset + shdr->sh_size
1289 <= phdr->p_offset + phdr->p_filesz))))
1291 if (has_relro && !in_relro
1292 && shdr->sh_addr >= relro_from
1293 && shdr->sh_addr + shdr->sh_size <= relro_to)
1295 fputs_unlocked (" [RELRO:", stdout);
1298 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1300 fputs_unlocked ("]", stdout);
1303 else if (has_relro && in_relro
1304 && shdr->sh_addr + shdr->sh_size > relro_to)
1305 fputs_unlocked ("] <RELRO:", stdout);
1306 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1310 fputs_unlocked (" [RO:", stdout);
1316 /* Determine the segment this section is part of. */
1318 GElf_Phdr *phdr2 = NULL;
1319 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1321 GElf_Phdr phdr2_mem;
1322 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1324 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1325 && shdr->sh_addr >= phdr2->p_vaddr
1326 && (shdr->sh_addr + shdr->sh_size
1327 <= phdr2->p_vaddr + phdr2->p_memsz))
1333 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1335 fputs_unlocked (" [RO:", stdout);
1338 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1340 fputs_unlocked ("]", stdout);
1347 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1349 /* Signal that this sectin is only partially covered. */
1350 if (has_relro && in_relro
1351 && shdr->sh_addr + shdr->sh_size > relro_to)
1353 fputs_unlocked (">", stdout);
1358 if (in_relro || in_ro)
1359 fputs_unlocked ("]", stdout);
1361 /* Finish the line. */
1362 fputc_unlocked ('\n', stdout);
1368 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1370 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1375 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1377 /* Get the data of the section. */
1378 Elf_Data *data = elf_getdata (scn, NULL);
1380 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1381 GElf_Shdr symshdr_mem;
1382 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1383 Elf_Data *symdata = elf_getdata (symscn, NULL);
1385 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1389 /* Get the section header string table index. */
1391 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1392 error (EXIT_FAILURE, 0,
1393 gettext ("cannot get section header string table index"));
1395 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1398 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1400 printf ((grpref[0] & GRP_COMDAT)
1402 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1404 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1405 data->d_size / sizeof (Elf32_Word) - 1)
1407 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1408 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1409 data->d_size / sizeof (Elf32_Word) - 1),
1411 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1413 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1414 ?: gettext ("<INVALID SYMBOL>"),
1415 data->d_size / sizeof (Elf32_Word) - 1);
1417 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1419 GElf_Shdr grpshdr_mem;
1420 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1424 printf (" [%2u] %s\n",
1427 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1428 ? str : gettext ("<INVALID SECTION>"));
1434 print_scngrp (Ebl *ebl)
1436 /* Find all relocation sections and handle them. */
1437 Elf_Scn *scn = NULL;
1439 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1441 /* Handle the section if it is a symbol table. */
1443 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1445 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1446 handle_scngrp (ebl, scn, shdr);
1451 static const struct flags
1457 { DF_ORIGIN, "ORIGIN" },
1458 { DF_SYMBOLIC, "SYMBOLIC" },
1459 { DF_TEXTREL, "TEXTREL" },
1460 { DF_BIND_NOW, "BIND_NOW" },
1461 { DF_STATIC_TLS, "STATIC_TLS" }
1463 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1465 static const struct flags dt_flags_1[] =
1467 { DF_1_NOW, "NOW" },
1468 { DF_1_GLOBAL, "GLOBAL" },
1469 { DF_1_GROUP, "GROUP" },
1470 { DF_1_NODELETE, "NODELETE" },
1471 { DF_1_LOADFLTR, "LOADFLTR" },
1472 { DF_1_INITFIRST, "INITFIRST" },
1473 { DF_1_NOOPEN, "NOOPEN" },
1474 { DF_1_ORIGIN, "ORIGIN" },
1475 { DF_1_DIRECT, "DIRECT" },
1476 { DF_1_TRANS, "TRANS" },
1477 { DF_1_INTERPOSE, "INTERPOSE" },
1478 { DF_1_NODEFLIB, "NODEFLIB" },
1479 { DF_1_NODUMP, "NODUMP" },
1480 { DF_1_CONFALT, "CONFALT" },
1481 { DF_1_ENDFILTEE, "ENDFILTEE" },
1482 { DF_1_DISPRELDNE, "DISPRELDNE" },
1483 { DF_1_DISPRELPND, "DISPRELPND" },
1485 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1487 static const struct flags dt_feature_1[] =
1489 { DTF_1_PARINIT, "PARINIT" },
1490 { DTF_1_CONFEXP, "CONFEXP" }
1492 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1493 / sizeof (dt_feature_1[0]));
1495 static const struct flags dt_posflag_1[] =
1497 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1498 { DF_P1_GROUPPERM, "GROUPPERM" }
1500 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1501 / sizeof (dt_posflag_1[0]));
1505 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1511 for (cnt = 0; cnt < nflags; ++cnt)
1512 if (d_val & flags[cnt].mask)
1515 putchar_unlocked (' ');
1516 fputs_unlocked (flags[cnt].str, stdout);
1517 d_val &= ~flags[cnt].mask;
1524 putchar_unlocked (' ');
1525 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1528 putchar_unlocked ('\n');
1533 print_dt_flags (int class, GElf_Xword d_val)
1535 print_flags (class, d_val, dt_flags, ndt_flags);
1540 print_dt_flags_1 (int class, GElf_Xword d_val)
1542 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1547 print_dt_feature_1 (int class, GElf_Xword d_val)
1549 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1554 print_dt_posflag_1 (int class, GElf_Xword d_val)
1556 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1561 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1563 int class = gelf_getclass (ebl->elf);
1564 GElf_Shdr glink_mem;
1571 /* Get the data of the section. */
1572 data = elf_getdata (scn, NULL);
1576 /* Get the section header string table index. */
1577 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1578 error (EXIT_FAILURE, 0,
1579 gettext ("cannot get section header string table index"));
1581 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1583 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1585 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1588 printf (ngettext ("\
1589 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1591 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1592 shdr->sh_size / sh_entsize),
1593 (unsigned long int) (shdr->sh_size / sh_entsize),
1594 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1596 (int) shdr->sh_link,
1597 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1598 fputs_unlocked (gettext (" Type Value\n"), stdout);
1600 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1603 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1609 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1617 /* No further output. */
1618 fputc_unlocked ('\n', stdout);
1622 printf (gettext ("Shared library: [%s]\n"),
1623 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1627 printf (gettext ("Library soname: [%s]\n"),
1628 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1632 printf (gettext ("Library rpath: [%s]\n"),
1633 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1637 printf (gettext ("Library runpath: [%s]\n"),
1638 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1651 case DT_INIT_ARRAYSZ:
1652 case DT_FINI_ARRAYSZ:
1655 case DT_GNU_CONFLICTSZ:
1656 case DT_GNU_LIBLISTSZ:
1657 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1664 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1668 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1670 puts (tagname ?: "???");
1674 print_dt_flags (class, dyn->d_un.d_val);
1678 print_dt_flags_1 (class, dyn->d_un.d_val);
1682 print_dt_feature_1 (class, dyn->d_un.d_val);
1686 print_dt_posflag_1 (class, dyn->d_un.d_val);
1690 printf ("%#0*" PRIx64 "\n",
1691 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1698 /* Print the dynamic segment. */
1700 print_dynamic (Ebl *ebl)
1702 for (size_t i = 0; i < phnum; ++i)
1705 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1707 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1709 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1711 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1712 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1713 handle_dynamic (ebl, scn, shdr);
1720 /* Print relocations. */
1722 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1724 /* Find all relocation sections and handle them. */
1725 Elf_Scn *scn = NULL;
1727 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1729 /* Handle the section if it is a symbol table. */
1731 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1733 if (likely (shdr != NULL))
1735 if (shdr->sh_type == SHT_REL)
1736 handle_relocs_rel (ebl, ehdr, scn, shdr);
1737 else if (shdr->sh_type == SHT_RELA)
1738 handle_relocs_rela (ebl, ehdr, scn, shdr);
1744 /* Handle a relocation section. */
1746 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1748 int class = gelf_getclass (ebl->elf);
1749 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1750 int nentries = shdr->sh_size / sh_entsize;
1752 /* Get the data of the section. */
1753 Elf_Data *data = elf_getdata (scn, NULL);
1757 /* Get the symbol table information. */
1758 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1759 GElf_Shdr symshdr_mem;
1760 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1761 Elf_Data *symdata = elf_getdata (symscn, NULL);
1763 /* Get the section header of the section the relocations are for. */
1764 GElf_Shdr destshdr_mem;
1765 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1768 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1770 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1775 /* Search for the optional extended section index table. */
1776 Elf_Data *xndxdata = NULL;
1777 int xndxscnidx = elf_scnshndx (scn);
1778 if (unlikely (xndxscnidx > 0))
1779 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1781 /* Get the section header string table index. */
1783 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1784 error (EXIT_FAILURE, 0,
1785 gettext ("cannot get section header string table index"));
1787 if (shdr->sh_info != 0)
1788 printf (ngettext ("\
1789 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1791 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1794 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1795 (unsigned int) shdr->sh_info,
1796 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1800 /* The .rel.dyn section does not refer to a specific section but
1801 instead of section index zero. Do not try to print a section
1803 printf (ngettext ("\
1804 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1806 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1808 (unsigned int) elf_ndxscn (scn),
1809 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1812 fputs_unlocked (class == ELFCLASS32
1814 Offset Type Value Name\n")
1816 Offset Type Value Name\n"),
1819 int is_statically_linked = 0;
1820 for (int cnt = 0; cnt < nentries; ++cnt)
1823 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1824 if (likely (rel != NULL))
1829 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1830 GELF_R_SYM (rel->r_info),
1832 if (unlikely (sym == NULL))
1834 /* As a special case we have to handle relocations in static
1835 executables. This only happens for IRELATIVE relocations
1836 (so far). There is no symbol table. */
1837 if (is_statically_linked == 0)
1839 /* Find the program header and look for a PT_INTERP entry. */
1840 is_statically_linked = -1;
1841 if (ehdr->e_type == ET_EXEC)
1843 is_statically_linked = 1;
1845 for (size_t inner = 0; inner < phnum; ++inner)
1848 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1850 if (phdr != NULL && phdr->p_type == PT_INTERP)
1852 is_statically_linked = -1;
1859 if (is_statically_linked > 0 && shdr->sh_link == 0)
1861 %#0*" PRIx64 " %-20s %*s %s\n",
1862 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1863 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1864 /* Avoid the leading R_ which isn't carrying any
1866 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1867 buf, sizeof (buf)) + 2
1868 : gettext ("<INVALID RELOC>"),
1869 class == ELFCLASS32 ? 10 : 18, "",
1870 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1872 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1873 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1874 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1875 /* Avoid the leading R_ which isn't carrying any
1877 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1878 buf, sizeof (buf)) + 2
1879 : gettext ("<INVALID RELOC>"),
1880 gettext ("INVALID SYMBOL"),
1881 (long int) GELF_R_SYM (rel->r_info));
1883 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1884 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1885 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1886 likely (ebl_reloc_type_check (ebl,
1887 GELF_R_TYPE (rel->r_info)))
1888 /* Avoid the leading R_ which isn't carrying any
1890 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1891 buf, sizeof (buf)) + 2
1892 : gettext ("<INVALID RELOC>"),
1893 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1894 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1897 /* This is a relocation against a STT_SECTION symbol. */
1898 GElf_Shdr secshdr_mem;
1900 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
1901 sym->st_shndx == SHN_XINDEX
1902 ? xndx : sym->st_shndx),
1905 if (unlikely (secshdr == NULL))
1906 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1907 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1908 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1909 /* Avoid the leading R_ which isn't carrying any
1911 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1912 buf, sizeof (buf)) + 2
1913 : gettext ("<INVALID RELOC>"),
1914 gettext ("INVALID SECTION"),
1915 (long int) (sym->st_shndx == SHN_XINDEX
1916 ? xndx : sym->st_shndx));
1918 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1919 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1920 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1921 /* Avoid the leading R_ which isn't carrying any
1923 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1924 buf, sizeof (buf)) + 2
1925 : gettext ("<INVALID RELOC>"),
1926 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1927 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
1934 /* Handle a relocation section. */
1936 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1938 int class = gelf_getclass (ebl->elf);
1939 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1940 int nentries = shdr->sh_size / sh_entsize;
1942 /* Get the data of the section. */
1943 Elf_Data *data = elf_getdata (scn, NULL);
1947 /* Get the symbol table information. */
1948 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1949 GElf_Shdr symshdr_mem;
1950 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1951 Elf_Data *symdata = elf_getdata (symscn, NULL);
1953 /* Get the section header of the section the relocations are for. */
1954 GElf_Shdr destshdr_mem;
1955 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1958 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1960 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1965 /* Search for the optional extended section index table. */
1966 Elf_Data *xndxdata = NULL;
1967 int xndxscnidx = elf_scnshndx (scn);
1968 if (unlikely (xndxscnidx > 0))
1969 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1971 /* Get the section header string table index. */
1973 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1974 error (EXIT_FAILURE, 0,
1975 gettext ("cannot get section header string table index"));
1977 if (shdr->sh_info != 0)
1978 printf (ngettext ("\
1979 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1981 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1984 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1985 (unsigned int) shdr->sh_info,
1986 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1990 /* The .rela.dyn section does not refer to a specific section but
1991 instead of section index zero. Do not try to print a section
1993 printf (ngettext ("\
1994 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1996 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1998 (unsigned int) elf_ndxscn (scn),
1999 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2002 fputs_unlocked (class == ELFCLASS32
2004 Offset Type Value Addend Name\n")
2006 Offset Type Value Addend Name\n"),
2009 int is_statically_linked = 0;
2010 for (int cnt = 0; cnt < nentries; ++cnt)
2013 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2014 if (likely (rel != NULL))
2019 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2020 GELF_R_SYM (rel->r_info),
2023 if (unlikely (sym == NULL))
2025 /* As a special case we have to handle relocations in static
2026 executables. This only happens for IRELATIVE relocations
2027 (so far). There is no symbol table. */
2028 if (is_statically_linked == 0)
2030 /* Find the program header and look for a PT_INTERP entry. */
2031 is_statically_linked = -1;
2032 if (ehdr->e_type == ET_EXEC)
2034 is_statically_linked = 1;
2036 for (size_t inner = 0; inner < phnum; ++inner)
2039 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2041 if (phdr != NULL && phdr->p_type == PT_INTERP)
2043 is_statically_linked = -1;
2050 if (is_statically_linked > 0 && shdr->sh_link == 0)
2052 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2053 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2054 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2055 /* Avoid the leading R_ which isn't carrying any
2057 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2058 buf, sizeof (buf)) + 2
2059 : gettext ("<INVALID RELOC>"),
2060 class == ELFCLASS32 ? 10 : 18, "",
2062 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2064 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2065 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2066 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2067 /* Avoid the leading R_ which isn't carrying any
2069 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2070 buf, sizeof (buf)) + 2
2071 : gettext ("<INVALID RELOC>"),
2072 gettext ("INVALID SYMBOL"),
2073 (long int) GELF_R_SYM (rel->r_info));
2075 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2077 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2078 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2079 likely (ebl_reloc_type_check (ebl,
2080 GELF_R_TYPE (rel->r_info)))
2081 /* Avoid the leading R_ which isn't carrying any
2083 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2084 buf, sizeof (buf)) + 2
2085 : gettext ("<INVALID RELOC>"),
2086 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2088 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2091 /* This is a relocation against a STT_SECTION symbol. */
2092 GElf_Shdr secshdr_mem;
2094 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2095 sym->st_shndx == SHN_XINDEX
2096 ? xndx : sym->st_shndx),
2099 if (unlikely (secshdr == NULL))
2100 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2101 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2102 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2103 /* Avoid the leading R_ which isn't carrying any
2105 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2106 buf, sizeof (buf)) + 2
2107 : gettext ("<INVALID RELOC>"),
2108 gettext ("INVALID SECTION"),
2109 (long int) (sym->st_shndx == SHN_XINDEX
2110 ? xndx : sym->st_shndx));
2113 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2114 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2115 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2116 /* Avoid the leading R_ which isn't carrying any
2118 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2119 buf, sizeof (buf)) + 2
2120 : gettext ("<INVALID RELOC>"),
2121 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2123 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2130 /* Print the program header. */
2132 print_symtab (Ebl *ebl, int type)
2134 /* Find the symbol table(s). For this we have to search through the
2136 Elf_Scn *scn = NULL;
2138 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2140 /* Handle the section if it is a symbol table. */
2142 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2144 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2145 handle_symtab (ebl, scn, shdr);
2151 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2153 Elf_Data *versym_data = NULL;
2154 Elf_Data *verneed_data = NULL;
2155 Elf_Data *verdef_data = NULL;
2156 Elf_Data *xndx_data = NULL;
2157 int class = gelf_getclass (ebl->elf);
2158 Elf32_Word verneed_stridx = 0;
2159 Elf32_Word verdef_stridx = 0;
2161 /* Get the data of the section. */
2162 Elf_Data *data = elf_getdata (scn, NULL);
2166 /* Find out whether we have other sections we might need. */
2167 Elf_Scn *runscn = NULL;
2168 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2170 GElf_Shdr runshdr_mem;
2171 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2173 if (likely (runshdr != NULL))
2175 if (runshdr->sh_type == SHT_GNU_versym
2176 && runshdr->sh_link == elf_ndxscn (scn))
2177 /* Bingo, found the version information. Now get the data. */
2178 versym_data = elf_getdata (runscn, NULL);
2179 else if (runshdr->sh_type == SHT_GNU_verneed)
2181 /* This is the information about the needed versions. */
2182 verneed_data = elf_getdata (runscn, NULL);
2183 verneed_stridx = runshdr->sh_link;
2185 else if (runshdr->sh_type == SHT_GNU_verdef)
2187 /* This is the information about the defined versions. */
2188 verdef_data = elf_getdata (runscn, NULL);
2189 verdef_stridx = runshdr->sh_link;
2191 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2192 && runshdr->sh_link == elf_ndxscn (scn))
2193 /* Extended section index. */
2194 xndx_data = elf_getdata (runscn, NULL);
2198 /* Get the section header string table index. */
2200 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2201 error (EXIT_FAILURE, 0,
2202 gettext ("cannot get section header string table index"));
2204 GElf_Shdr glink_mem;
2205 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2208 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2211 /* Now we can compute the number of entries in the section. */
2212 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2213 ? sizeof (Elf32_Sym)
2214 : sizeof (Elf64_Sym));
2216 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2217 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2219 (unsigned int) elf_ndxscn (scn),
2220 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2221 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2222 " %lu local symbols String table: [%2u] '%s'\n",
2224 (unsigned long int) shdr->sh_info,
2225 (unsigned int) shdr->sh_link,
2226 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2228 fputs_unlocked (class == ELFCLASS32
2230 Num: Value Size Type Bind Vis Ndx Name\n")
2232 Num: Value Size Type Bind Vis Ndx Name\n"),
2235 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2242 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2244 if (unlikely (sym == NULL))
2247 /* Determine the real section index. */
2248 if (likely (sym->st_shndx != SHN_XINDEX))
2249 xndx = sym->st_shndx;
2252 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2254 class == ELFCLASS32 ? 8 : 16,
2257 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2258 typebuf, sizeof (typebuf)),
2259 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2260 bindbuf, sizeof (bindbuf)),
2261 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2262 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2263 sizeof (scnbuf), NULL, shnum),
2264 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2266 if (versym_data != NULL)
2268 /* Get the version information. */
2269 GElf_Versym versym_mem;
2270 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2272 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2274 bool is_nobits = false;
2275 bool check_def = xndx != SHN_UNDEF;
2277 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2279 GElf_Shdr symshdr_mem;
2280 GElf_Shdr *symshdr =
2281 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2283 is_nobits = (symshdr != NULL
2284 && symshdr->sh_type == SHT_NOBITS);
2287 if (is_nobits || ! check_def)
2289 /* We must test both. */
2290 GElf_Vernaux vernaux_mem;
2291 GElf_Vernaux *vernaux = NULL;
2292 size_t vn_offset = 0;
2294 GElf_Verneed verneed_mem;
2295 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2297 while (verneed != NULL)
2299 size_t vna_offset = vn_offset;
2301 vernaux = gelf_getvernaux (verneed_data,
2302 vna_offset += verneed->vn_aux,
2304 while (vernaux != NULL
2305 && vernaux->vna_other != *versym
2306 && vernaux->vna_next != 0)
2308 /* Update the offset. */
2309 vna_offset += vernaux->vna_next;
2311 vernaux = (vernaux->vna_next == 0
2313 : gelf_getvernaux (verneed_data,
2318 /* Check whether we found the version. */
2319 if (vernaux != NULL && vernaux->vna_other == *versym)
2323 vn_offset += verneed->vn_next;
2324 verneed = (verneed->vn_next == 0
2326 : gelf_getverneed (verneed_data, vn_offset,
2330 if (vernaux != NULL && vernaux->vna_other == *versym)
2333 elf_strptr (ebl->elf, verneed_stridx,
2335 (unsigned int) vernaux->vna_other);
2338 else if (unlikely (! is_nobits))
2339 error (0, 0, gettext ("bad dynamic symbol"));
2344 if (check_def && *versym != 0x8001)
2346 /* We must test both. */
2347 size_t vd_offset = 0;
2349 GElf_Verdef verdef_mem;
2350 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2352 while (verdef != NULL)
2354 if (verdef->vd_ndx == (*versym & 0x7fff))
2355 /* Found the definition. */
2358 vd_offset += verdef->vd_next;
2359 verdef = (verdef->vd_next == 0
2361 : gelf_getverdef (verdef_data, vd_offset,
2367 GElf_Verdaux verdaux_mem;
2368 GElf_Verdaux *verdaux
2369 = gelf_getverdaux (verdef_data,
2370 vd_offset + verdef->vd_aux,
2373 if (verdaux != NULL)
2374 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2375 elf_strptr (ebl->elf, verdef_stridx,
2376 verdaux->vda_name));
2382 putchar_unlocked ('\n');
2387 /* Print version information. */
2389 print_verinfo (Ebl *ebl)
2391 /* Find the version information sections. For this we have to
2392 search through the section table. */
2393 Elf_Scn *scn = NULL;
2395 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2397 /* Handle the section if it is part of the versioning handling. */
2399 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2401 if (likely (shdr != NULL))
2403 if (shdr->sh_type == SHT_GNU_verneed)
2404 handle_verneed (ebl, scn, shdr);
2405 else if (shdr->sh_type == SHT_GNU_verdef)
2406 handle_verdef (ebl, scn, shdr);
2407 else if (shdr->sh_type == SHT_GNU_versym)
2408 handle_versym (ebl, scn, shdr);
2415 get_ver_flags (unsigned int flags)
2417 static char buf[32];
2421 return gettext ("none");
2423 if (flags & VER_FLG_BASE)
2424 endp = stpcpy (buf, "BASE ");
2428 if (flags & VER_FLG_WEAK)
2431 endp = stpcpy (endp, "| ");
2433 endp = stpcpy (endp, "WEAK ");
2436 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2438 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2439 buf[sizeof (buf) - 1] = '\0';
2447 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2449 int class = gelf_getclass (ebl->elf);
2451 /* Get the data of the section. */
2452 Elf_Data *data = elf_getdata (scn, NULL);
2456 /* Get the section header string table index. */
2458 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2459 error (EXIT_FAILURE, 0,
2460 gettext ("cannot get section header string table index"));
2462 GElf_Shdr glink_mem;
2463 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2466 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2469 printf (ngettext ("\
2470 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2472 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2474 (unsigned int) elf_ndxscn (scn),
2475 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2476 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2478 (unsigned int) shdr->sh_link,
2479 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2481 unsigned int offset = 0;
2482 for (int cnt = shdr->sh_info; --cnt >= 0; )
2484 /* Get the data at the next offset. */
2485 GElf_Verneed needmem;
2486 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2487 if (unlikely (need == NULL))
2490 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2491 offset, (unsigned short int) need->vn_version,
2492 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2493 (unsigned short int) need->vn_cnt);
2495 unsigned int auxoffset = offset + need->vn_aux;
2496 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2498 GElf_Vernaux auxmem;
2499 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2500 if (unlikely (aux == NULL))
2503 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2505 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2506 get_ver_flags (aux->vna_flags),
2507 (unsigned short int) aux->vna_other);
2509 if (aux->vna_next == 0)
2512 auxoffset += aux->vna_next;
2515 /* Find the next offset. */
2516 if (need->vn_next == 0)
2519 offset += need->vn_next;
2525 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2527 /* Get the data of the section. */
2528 Elf_Data *data = elf_getdata (scn, NULL);
2532 /* Get the section header string table index. */
2534 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2535 error (EXIT_FAILURE, 0,
2536 gettext ("cannot get section header string table index"));
2538 GElf_Shdr glink_mem;
2539 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2542 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2545 int class = gelf_getclass (ebl->elf);
2546 printf (ngettext ("\
2547 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2549 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2551 (unsigned int) elf_ndxscn (scn),
2552 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2554 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2556 (unsigned int) shdr->sh_link,
2557 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2559 unsigned int offset = 0;
2560 for (int cnt = shdr->sh_info; --cnt >= 0; )
2562 /* Get the data at the next offset. */
2564 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2565 if (unlikely (def == NULL))
2568 unsigned int auxoffset = offset + def->vd_aux;
2569 GElf_Verdaux auxmem;
2570 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2571 if (unlikely (aux == NULL))
2575 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2576 offset, def->vd_version,
2577 get_ver_flags (def->vd_flags),
2580 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2582 auxoffset += aux->vda_next;
2583 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2585 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2586 if (unlikely (aux == NULL))
2589 printf (gettext (" %#06x: Parent %d: %s\n"),
2591 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2593 if (aux->vda_next == 0)
2596 auxoffset += aux->vda_next;
2599 /* Find the next offset. */
2600 if (def->vd_next == 0)
2602 offset += def->vd_next;
2608 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2610 int class = gelf_getclass (ebl->elf);
2611 const char **vername;
2612 const char **filename;
2614 /* Get the data of the section. */
2615 Elf_Data *data = elf_getdata (scn, NULL);
2619 /* Get the section header string table index. */
2621 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2622 error (EXIT_FAILURE, 0,
2623 gettext ("cannot get section header string table index"));
2625 /* We have to find the version definition section and extract the
2627 Elf_Scn *defscn = NULL;
2628 Elf_Scn *needscn = NULL;
2630 Elf_Scn *verscn = NULL;
2631 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2633 GElf_Shdr vershdr_mem;
2634 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2636 if (likely (vershdr != NULL))
2638 if (vershdr->sh_type == SHT_GNU_verdef)
2640 else if (vershdr->sh_type == SHT_GNU_verneed)
2646 if (defscn != NULL || needscn != NULL)
2648 /* We have a version information (better should have). Now get
2649 the version names. First find the maximum version number. */
2653 /* Run through the version definitions and find the highest
2655 unsigned int offset = 0;
2657 GElf_Shdr defshdrmem;
2660 defdata = elf_getdata (defscn, NULL);
2661 if (unlikely (defdata == NULL))
2664 defshdr = gelf_getshdr (defscn, &defshdrmem);
2665 if (unlikely (defshdr == NULL))
2668 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2673 /* Get the data at the next offset. */
2674 def = gelf_getverdef (defdata, offset, &defmem);
2675 if (unlikely (def == NULL))
2678 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2680 if (def->vd_next == 0)
2682 offset += def->vd_next;
2685 if (needscn != NULL)
2687 unsigned int offset = 0;
2689 GElf_Shdr needshdrmem;
2690 GElf_Shdr *needshdr;
2692 needdata = elf_getdata (needscn, NULL);
2693 if (unlikely (needdata == NULL))
2696 needshdr = gelf_getshdr (needscn, &needshdrmem);
2697 if (unlikely (needshdr == NULL))
2700 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2702 GElf_Verneed needmem;
2704 unsigned int auxoffset;
2707 /* Get the data at the next offset. */
2708 need = gelf_getverneed (needdata, offset, &needmem);
2709 if (unlikely (need == NULL))
2712 /* Run through the auxiliary entries. */
2713 auxoffset = offset + need->vn_aux;
2714 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2716 GElf_Vernaux auxmem;
2719 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2720 if (unlikely (aux == NULL))
2723 nvername = MAX (nvername,
2724 (size_t) (aux->vna_other & 0x7fff));
2726 if (aux->vna_next == 0)
2728 auxoffset += aux->vna_next;
2731 if (need->vn_next == 0)
2733 offset += need->vn_next;
2737 /* This is the number of versions we know about. */
2740 /* Allocate the array. */
2741 vername = (const char **) alloca (nvername * sizeof (const char *));
2742 memset(vername, 0, nvername * sizeof (const char *));
2743 filename = (const char **) alloca (nvername * sizeof (const char *));
2744 memset(filename, 0, nvername * sizeof (const char *));
2746 /* Run through the data structures again and collect the strings. */
2749 /* Run through the version definitions and find the highest
2751 unsigned int offset = 0;
2753 GElf_Shdr defshdrmem;
2756 defdata = elf_getdata (defscn, NULL);
2757 if (unlikely (defdata == NULL))
2760 defshdr = gelf_getshdr (defscn, &defshdrmem);
2761 if (unlikely (defshdr == NULL))
2764 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2767 /* Get the data at the next offset. */
2769 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2770 if (unlikely (def == NULL))
2773 GElf_Verdaux auxmem;
2774 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2775 offset + def->vd_aux,
2777 if (unlikely (aux == NULL))
2780 vername[def->vd_ndx & 0x7fff]
2781 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2782 filename[def->vd_ndx & 0x7fff] = NULL;
2784 if (def->vd_next == 0)
2786 offset += def->vd_next;
2789 if (needscn != NULL)
2791 unsigned int offset = 0;
2793 Elf_Data *needdata = elf_getdata (needscn, NULL);
2794 GElf_Shdr needshdrmem;
2795 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2796 if (unlikely (needdata == NULL || needshdr == NULL))
2799 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2801 /* Get the data at the next offset. */
2802 GElf_Verneed needmem;
2803 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2805 if (unlikely (need == NULL))
2808 /* Run through the auxiliary entries. */
2809 unsigned int auxoffset = offset + need->vn_aux;
2810 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2812 GElf_Vernaux auxmem;
2813 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2815 if (unlikely (aux == NULL))
2818 vername[aux->vna_other & 0x7fff]
2819 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2820 filename[aux->vna_other & 0x7fff]
2821 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2823 if (aux->vna_next == 0)
2825 auxoffset += aux->vna_next;
2828 if (need->vn_next == 0)
2830 offset += need->vn_next;
2841 GElf_Shdr glink_mem;
2842 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2844 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2846 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2849 /* Print the header. */
2850 printf (ngettext ("\
2851 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2853 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2854 shdr->sh_size / sh_entsize),
2855 (unsigned int) elf_ndxscn (scn),
2856 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2857 (int) (shdr->sh_size / sh_entsize),
2858 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2860 (unsigned int) shdr->sh_link,
2861 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2863 /* Now we can finally look at the actual contents of this section. */
2864 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2867 printf ("\n %4d:", cnt);
2870 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2878 fputs_unlocked (gettext (" 0 *local* "),
2883 fputs_unlocked (gettext (" 1 *global* "),
2888 n = printf ("%4d%c%s",
2889 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2891 && (unsigned int) (*sym & 0x7fff) < nvername)
2892 ? vername[*sym & 0x7fff] : "???");
2893 if ((unsigned int) (*sym & 0x7fff) < nvername
2894 && filename != NULL && filename[*sym & 0x7fff] != NULL)
2895 n += printf ("(%s)", filename[*sym & 0x7fff]);
2896 printf ("%*s", MAX (0, 33 - (int) n), " ");
2900 putchar_unlocked ('\n');
2905 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2906 uint_fast32_t maxlength, Elf32_Word nbucket,
2907 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2909 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2911 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2912 ++counts[lengths[cnt]];
2914 GElf_Shdr glink_mem;
2915 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2920 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2925 printf (ngettext ("\
2926 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2928 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2930 (unsigned int) elf_ndxscn (scn),
2931 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2933 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2936 (unsigned int) shdr->sh_link,
2937 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2939 if (extrastr != NULL)
2940 fputs (extrastr, stdout);
2942 if (likely (nbucket > 0))
2944 uint64_t success = 0;
2946 /* xgettext:no-c-format */
2947 fputs_unlocked (gettext ("\
2948 Length Number % of total Coverage\n"), stdout);
2949 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
2950 counts[0], (counts[0] * 100.0) / nbucket);
2952 uint64_t nzero_counts = 0;
2953 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2955 nzero_counts += counts[cnt] * cnt;
2957 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
2958 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2959 (nzero_counts * 100.0) / nsyms);
2963 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2966 success += counts[cnt] * acc;
2970 Average number of tests: successful lookup: %f\n\
2971 unsuccessful lookup: %f\n"),
2972 (double) success / (double) nzero_counts,
2973 (double) nzero_counts / (double) nbucket);
2980 /* This function handles the traditional System V-style hash table format. */
2982 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2984 Elf_Data *data = elf_getdata (scn, NULL);
2985 if (unlikely (data == NULL))
2987 error (0, 0, gettext ("cannot get data for section %d: %s"),
2988 (int) elf_ndxscn (scn), elf_errmsg (-1));
2992 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
2995 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
2996 (int) elf_ndxscn (scn));
3000 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3001 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3003 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3004 if (used_buf > data->d_size)
3007 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3008 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3010 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3012 uint_fast32_t maxlength = 0;
3013 uint_fast32_t nsyms = 0;
3014 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3016 Elf32_Word inner = bucket[cnt];
3017 while (inner > 0 && inner < nchain)
3020 if (maxlength < ++lengths[cnt])
3023 inner = chain[inner];
3027 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3034 /* This function handles the incorrect, System V-style hash table
3035 format some 64-bit architectures use. */
3037 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3039 Elf_Data *data = elf_getdata (scn, NULL);
3040 if (unlikely (data == NULL))
3042 error (0, 0, gettext ("cannot get data for section %d: %s"),
3043 (int) elf_ndxscn (scn), elf_errmsg (-1));
3047 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3050 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3051 (int) elf_ndxscn (scn));
3055 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3056 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3058 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3060 || maxwords - 2 < nbucket
3061 || maxwords - 2 - nbucket < nchain)
3064 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3065 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3067 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3069 uint_fast32_t maxlength = 0;
3070 uint_fast32_t nsyms = 0;
3071 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3073 Elf64_Xword inner = bucket[cnt];
3074 while (inner > 0 && inner < nchain)
3077 if (maxlength < ++lengths[cnt])
3080 inner = chain[inner];
3084 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3091 /* This function handles the GNU-style hash table format. */
3093 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3095 Elf_Data *data = elf_getdata (scn, NULL);
3096 if (unlikely (data == NULL))
3098 error (0, 0, gettext ("cannot get data for section %d: %s"),
3099 (int) elf_ndxscn (scn), elf_errmsg (-1));
3103 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3106 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3107 (int) elf_ndxscn (scn));
3111 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3112 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3114 /* Next comes the size of the bitmap. It's measured in words for
3115 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3116 64 bit archs. There is always a bloom filter present, so zero is
3117 an invalid value. */
3118 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3119 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3122 if (bitmask_words == 0)
3125 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3127 /* Is there still room for the sym chain?
3128 Use uint64_t calculation to prevent 32bit overlow. */
3129 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3130 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3131 if (used_buf > data->d_size)
3134 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3136 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3137 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3138 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3141 /* Compute distribution of chain lengths. */
3142 uint_fast32_t maxlength = 0;
3143 uint_fast32_t nsyms = 0;
3144 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3145 if (bucket[cnt] != 0)
3147 Elf32_Word inner = bucket[cnt] - symbias;
3151 if (maxlength < ++lengths[cnt])
3153 if (inner > max_nsyms)
3156 while ((chain[inner++] & 1) == 0);
3159 /* Count bits in bitmask. */
3160 uint_fast32_t nbits = 0;
3161 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3163 uint_fast32_t word = bitmask[cnt];
3165 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3166 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3167 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3168 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3169 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3173 if (unlikely (asprintf (&str, gettext ("\
3175 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3176 (unsigned int) symbias,
3177 bitmask_words * sizeof (Elf32_Word),
3179 / (uint_fast32_t) (bitmask_words
3180 * sizeof (Elf32_Word) * 8)),
3181 (unsigned int) shift) == -1))
3182 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3184 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3192 /* Find the symbol table(s). For this we have to search through the
3195 handle_hash (Ebl *ebl)
3197 /* Get the section header string table index. */
3199 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3200 error (EXIT_FAILURE, 0,
3201 gettext ("cannot get section header string table index"));
3203 Elf_Scn *scn = NULL;
3204 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3206 /* Handle the section if it is a symbol table. */
3208 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3210 if (likely (shdr != NULL))
3212 if (shdr->sh_type == SHT_HASH)
3214 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3215 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3217 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3219 else if (shdr->sh_type == SHT_GNU_HASH)
3220 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3227 print_liblist (Ebl *ebl)
3229 /* Find the library list sections. For this we have to search
3230 through the section table. */
3231 Elf_Scn *scn = NULL;
3233 /* Get the section header string table index. */
3235 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3236 error (EXIT_FAILURE, 0,
3237 gettext ("cannot get section header string table index"));
3239 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3242 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3244 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3246 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3247 int nentries = shdr->sh_size / sh_entsize;
3248 printf (ngettext ("\
3249 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3251 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3254 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3258 Elf_Data *data = elf_getdata (scn, NULL);
3263 Library Time Stamp Checksum Version Flags"));
3265 for (int cnt = 0; cnt < nentries; ++cnt)
3268 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3269 if (unlikely (lib == NULL))
3272 time_t t = (time_t) lib->l_time_stamp;
3273 struct tm *tm = gmtime (&t);
3274 if (unlikely (tm == NULL))
3277 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3278 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3279 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3280 tm->tm_hour, tm->tm_min, tm->tm_sec,
3281 (unsigned int) lib->l_checksum,
3282 (unsigned int) lib->l_version,
3283 (unsigned int) lib->l_flags);
3290 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3292 /* Find the object attributes sections. For this we have to search
3293 through the section table. */
3294 Elf_Scn *scn = NULL;
3296 /* Get the section header string table index. */
3298 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3299 error (EXIT_FAILURE, 0,
3300 gettext ("cannot get section header string table index"));
3302 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3305 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3307 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3308 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3309 || ehdr->e_machine != EM_ARM)))
3313 \nObject attributes section [%2zu] '%s' of %" PRIu64
3314 " bytes at offset %#0" PRIx64 ":\n"),
3316 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3317 shdr->sh_size, shdr->sh_offset);
3319 Elf_Data *data = elf_rawdata (scn, NULL);
3320 if (unlikely (data == NULL || data->d_size == 0))
3323 const unsigned char *p = data->d_buf;
3325 /* There is only one 'version', A. */
3326 if (unlikely (*p++ != 'A'))
3329 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3331 inline size_t left (void)
3333 return (const unsigned char *) data->d_buf + data->d_size - p;
3336 /* Loop over the sections. */
3337 while (left () >= 4)
3339 /* Section length. */
3341 memcpy (&len, p, sizeof len);
3343 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3346 if (unlikely (len > left ()))
3349 /* Section vendor name. */
3350 const unsigned char *name = p + sizeof len;
3353 unsigned const char *q = memchr (name, '\0', len);
3354 if (unlikely (q == NULL))
3358 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3360 bool gnu_vendor = (q - name == sizeof "gnu"
3361 && !memcmp (name, "gnu", sizeof "gnu"));
3363 /* Loop over subsections. */
3364 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3368 const unsigned char *const sub = q;
3370 unsigned int subsection_tag;
3371 get_uleb128 (subsection_tag, q, p);
3372 if (unlikely (q >= p))
3375 uint32_t subsection_len;
3376 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3379 memcpy (&subsection_len, q, sizeof subsection_len);
3381 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3382 CONVERT (subsection_len);
3384 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3385 if (unlikely (subsection_len == 0
3386 || subsection_len >= (uint32_t) PTRDIFF_MAX
3387 || p - sub < (ptrdiff_t) subsection_len))
3390 const unsigned char *r = q + sizeof subsection_len;
3391 q = sub + subsection_len;
3393 switch (subsection_tag)
3396 /* Unknown subsection, print and skip. */
3397 printf (gettext (" %-4u %12" PRIu32 "\n"),
3398 subsection_tag, subsection_len);
3401 case 1: /* Tag_File */
3402 printf (gettext (" File: %11" PRIu32 "\n"),
3408 get_uleb128 (tag, r, q);
3409 if (unlikely (r >= q))
3412 /* GNU style tags have either a uleb128 value,
3413 when lowest bit is not set, or a string
3414 when the lowest bit is set.
3415 "compatibility" (32) is special. It has
3416 both a string and a uleb128 value. For
3417 non-gnu we assume 6 till 31 only take ints.
3418 XXX see arm backend, do we need a separate
3421 const char *string = NULL;
3422 if (tag == 32 || (tag & 1) == 0
3423 || (! gnu_vendor && (tag > 5 && tag < 32)))
3425 get_uleb128 (value, r, q);
3432 || (! gnu_vendor && tag > 32)))
3433 || (! gnu_vendor && tag > 3 && tag < 6))
3435 string = (const char *) r;
3436 r = memchr (r, '\0', q - r);
3442 const char *tag_name = NULL;
3443 const char *value_name = NULL;
3444 ebl_check_object_attribute (ebl, (const char *) name,
3446 &tag_name, &value_name);
3448 if (tag_name != NULL)
3451 printf (gettext (" %s: %" PRId64 ", %s\n"),
3452 tag_name, value, string);
3453 else if (string == NULL && value_name == NULL)
3454 printf (gettext (" %s: %" PRId64 "\n"),
3457 printf (gettext (" %s: %s\n"),
3458 tag_name, string ?: value_name);
3462 /* For "gnu" vendor 32 "compatibility" has
3463 already been handled above. */
3465 || strcmp ((const char *) name, "gnu"));
3467 printf (gettext (" %u: %" PRId64 "\n"),
3470 printf (gettext (" %u: %s\n"),
3482 format_dwarf_addr (Dwfl_Module *dwflmod,
3483 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3485 /* See if there is a name we can give for this address. */
3488 const char *name = (print_address_names && ! print_unresolved_addresses)
3489 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3493 if (print_unresolved_addresses)
3500 /* Relativize the address. */
3501 int n = dwfl_module_relocations (dwflmod);
3502 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3504 /* In an ET_REL file there is a section name to refer to. */
3506 : dwfl_module_relocation_info (dwflmod, i, NULL));
3513 ? (address_size == 0
3514 ? asprintf (&result,
3515 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3516 scn, address, name, off)
3517 : asprintf (&result,
3518 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3519 scn, 2 + address_size * 2, address,
3521 : (address_size == 0
3522 ? asprintf (&result,
3523 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3525 : asprintf (&result,
3526 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3527 2 + address_size * 2, address,
3530 ? (address_size == 0
3531 ? asprintf (&result,
3532 gettext ("%s+%#" PRIx64 " <%s>"),
3534 : asprintf (&result,
3535 gettext ("%s+%#0*" PRIx64 " <%s>"),
3536 scn, 2 + address_size * 2, address, name))
3537 : (address_size == 0
3538 ? asprintf (&result,
3539 gettext ("%#" PRIx64 " <%s>"),
3541 : asprintf (&result,
3542 gettext ("%#0*" PRIx64 " <%s>"),
3543 2 + address_size * 2, address, name))))
3545 ? (address_size == 0
3546 ? asprintf (&result,
3547 gettext ("%s+%#" PRIx64),
3549 : asprintf (&result,
3550 gettext ("%s+%#0*" PRIx64),
3551 scn, 2 + address_size * 2, address))
3552 : (address_size == 0
3553 ? asprintf (&result,
3556 : asprintf (&result,
3558 2 + address_size * 2, address)))) < 0)
3559 error (EXIT_FAILURE, 0, _("memory exhausted"));
3565 dwarf_tag_string (unsigned int tag)
3569 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3570 DWARF_ALL_KNOWN_DW_TAG
3571 #undef DWARF_ONE_KNOWN_DW_TAG
3579 dwarf_attr_string (unsigned int attrnum)
3583 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3584 DWARF_ALL_KNOWN_DW_AT
3585 #undef DWARF_ONE_KNOWN_DW_AT
3593 dwarf_form_string (unsigned int form)
3597 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3598 DWARF_ALL_KNOWN_DW_FORM
3599 #undef DWARF_ONE_KNOWN_DW_FORM
3607 dwarf_lang_string (unsigned int lang)
3611 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3612 DWARF_ALL_KNOWN_DW_LANG
3613 #undef DWARF_ONE_KNOWN_DW_LANG
3621 dwarf_inline_string (unsigned int code)
3623 static const char *const known[] =
3625 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3626 DWARF_ALL_KNOWN_DW_INL
3627 #undef DWARF_ONE_KNOWN_DW_INL
3630 if (likely (code < sizeof (known) / sizeof (known[0])))
3638 dwarf_encoding_string (unsigned int code)
3640 static const char *const known[] =
3642 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3643 DWARF_ALL_KNOWN_DW_ATE
3644 #undef DWARF_ONE_KNOWN_DW_ATE
3647 if (likely (code < sizeof (known) / sizeof (known[0])))
3655 dwarf_access_string (unsigned int code)
3657 static const char *const known[] =
3659 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3660 DWARF_ALL_KNOWN_DW_ACCESS
3661 #undef DWARF_ONE_KNOWN_DW_ACCESS
3664 if (likely (code < sizeof (known) / sizeof (known[0])))
3672 dwarf_visibility_string (unsigned int code)
3674 static const char *const known[] =
3676 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3677 DWARF_ALL_KNOWN_DW_VIS
3678 #undef DWARF_ONE_KNOWN_DW_VIS
3681 if (likely (code < sizeof (known) / sizeof (known[0])))
3689 dwarf_virtuality_string (unsigned int code)
3691 static const char *const known[] =
3693 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3694 DWARF_ALL_KNOWN_DW_VIRTUALITY
3695 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3698 if (likely (code < sizeof (known) / sizeof (known[0])))
3706 dwarf_identifier_case_string (unsigned int code)
3708 static const char *const known[] =
3710 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3711 DWARF_ALL_KNOWN_DW_ID
3712 #undef DWARF_ONE_KNOWN_DW_ID
3715 if (likely (code < sizeof (known) / sizeof (known[0])))
3723 dwarf_calling_convention_string (unsigned int code)
3725 static const char *const known[] =
3727 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3728 DWARF_ALL_KNOWN_DW_CC
3729 #undef DWARF_ONE_KNOWN_DW_CC
3732 if (likely (code < sizeof (known) / sizeof (known[0])))
3740 dwarf_ordering_string (unsigned int code)
3742 static const char *const known[] =
3744 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3745 DWARF_ALL_KNOWN_DW_ORD
3746 #undef DWARF_ONE_KNOWN_DW_ORD
3749 if (likely (code < sizeof (known) / sizeof (known[0])))
3757 dwarf_discr_list_string (unsigned int code)
3759 static const char *const known[] =
3761 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3762 DWARF_ALL_KNOWN_DW_DSC
3763 #undef DWARF_ONE_KNOWN_DW_DSC
3766 if (likely (code < sizeof (known) / sizeof (known[0])))
3774 dwarf_locexpr_opcode_string (unsigned int code)
3776 static const char *const known[] =
3778 /* Normally we can't affort building huge table of 64K entries,
3779 most of them zero, just because there are a couple defined
3780 values at the far end. In case of opcodes, it's OK. */
3781 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3782 DWARF_ALL_KNOWN_DW_OP
3783 #undef DWARF_ONE_KNOWN_DW_OP
3786 if (likely (code < sizeof (known) / sizeof (known[0])))
3793 /* Used by all dwarf_foo_name functions. */
3795 string_or_unknown (const char *known, unsigned int code,
3796 unsigned int lo_user, unsigned int hi_user,
3797 bool print_unknown_num)
3799 static char unknown_buf[20];
3801 if (likely (known != NULL))
3804 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3806 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3811 if (print_unknown_num)
3813 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3822 dwarf_tag_name (unsigned int tag)
3824 const char *ret = dwarf_tag_string (tag);
3825 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3829 dwarf_attr_name (unsigned int attr)
3831 const char *ret = dwarf_attr_string (attr);
3832 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3837 dwarf_form_name (unsigned int form)
3839 const char *ret = dwarf_form_string (form);
3840 return string_or_unknown (ret, form, 0, 0, true);
3845 dwarf_lang_name (unsigned int lang)
3847 const char *ret = dwarf_lang_string (lang);
3848 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3853 dwarf_inline_name (unsigned int code)
3855 const char *ret = dwarf_inline_string (code);
3856 return string_or_unknown (ret, code, 0, 0, false);
3861 dwarf_encoding_name (unsigned int code)
3863 const char *ret = dwarf_encoding_string (code);
3864 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3869 dwarf_access_name (unsigned int code)
3871 const char *ret = dwarf_access_string (code);
3872 return string_or_unknown (ret, code, 0, 0, false);
3877 dwarf_visibility_name (unsigned int code)
3879 const char *ret = dwarf_visibility_string (code);
3880 return string_or_unknown (ret, code, 0, 0, false);
3885 dwarf_virtuality_name (unsigned int code)
3887 const char *ret = dwarf_virtuality_string (code);
3888 return string_or_unknown (ret, code, 0, 0, false);
3893 dwarf_identifier_case_name (unsigned int code)
3895 const char *ret = dwarf_identifier_case_string (code);
3896 return string_or_unknown (ret, code, 0, 0, false);
3901 dwarf_calling_convention_name (unsigned int code)
3903 const char *ret = dwarf_calling_convention_string (code);
3904 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3909 dwarf_ordering_name (unsigned int code)
3911 const char *ret = dwarf_ordering_string (code);
3912 return string_or_unknown (ret, code, 0, 0, false);
3917 dwarf_discr_list_name (unsigned int code)
3919 const char *ret = dwarf_discr_list_string (code);
3920 return string_or_unknown (ret, code, 0, 0, false);
3925 print_block (size_t n, const void *block)
3928 puts (_("empty block"));
3931 printf (_("%zu byte block:"), n);
3932 const unsigned char *data = block;
3934 printf (" %02x", *data++);
3941 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3942 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3943 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3945 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3949 printf ("%*s(empty)\n", indent, "");
3953 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3954 #define CONSUME(n) NEED (n); else len -= (n)
3956 Dwarf_Word offset = 0;
3959 uint_fast8_t op = *data++;
3961 const char *op_name = dwarf_locexpr_opcode_string (op);
3962 if (unlikely (op_name == NULL))
3964 static char buf[20];
3965 if (op >= DW_OP_lo_user)
3966 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3968 snprintf (buf, sizeof buf, "??? (%#x)", op);
3975 /* Address operand. */
3979 addr = read_4ubyte_unaligned (dbg, data);
3980 else if (addrsize == 8)
3981 addr = read_8ubyte_unaligned (dbg, data);
3987 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3988 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3989 indent, "", (uintmax_t) offset, op_name, a);
3992 offset += 1 + addrsize;
3995 case DW_OP_call_ref:
3996 /* Offset operand. */
3997 if (ref_size != 4 && ref_size != 8)
3998 goto invalid; /* Cannot be used in CFA. */
4001 addr = read_4ubyte_unaligned (dbg, data);
4003 addr = read_8ubyte_unaligned (dbg, data);
4007 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4008 indent, "", (uintmax_t) offset,
4009 op_name, (uintmax_t) addr);
4010 offset += 1 + ref_size;
4013 case DW_OP_deref_size:
4014 case DW_OP_xderef_size:
4017 // XXX value might be modified by relocation
4019 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4020 indent, "", (uintmax_t) offset,
4021 op_name, *((uint8_t *) data));
4029 // XXX value might be modified by relocation
4030 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4031 indent, "", (uintmax_t) offset,
4032 op_name, read_2ubyte_unaligned (dbg, data));
4040 // XXX value might be modified by relocation
4041 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4042 indent, "", (uintmax_t) offset,
4043 op_name, read_4ubyte_unaligned (dbg, data));
4051 // XXX value might be modified by relocation
4052 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4053 indent, "", (uintmax_t) offset,
4054 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4062 // XXX value might be modified by relocation
4063 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4064 indent, "", (uintmax_t) offset,
4065 op_name, *((int8_t *) data));
4073 // XXX value might be modified by relocation
4074 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4075 indent, "", (uintmax_t) offset,
4076 op_name, read_2sbyte_unaligned (dbg, data));
4084 // XXX value might be modified by relocation
4085 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4086 indent, "", (uintmax_t) offset,
4087 op_name, read_4sbyte_unaligned (dbg, data));
4095 // XXX value might be modified by relocation
4096 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4097 indent, "", (uintmax_t) offset,
4098 op_name, read_8sbyte_unaligned (dbg, data));
4106 case DW_OP_plus_uconst:
4108 const unsigned char *start = data;
4111 get_uleb128 (uleb, data, data + len);
4112 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4113 indent, "", (uintmax_t) offset, op_name, uleb);
4114 CONSUME (data - start);
4115 offset += 1 + (data - start);
4118 case DW_OP_bit_piece:
4122 get_uleb128 (uleb, data, data + len);
4124 get_uleb128 (uleb2, data, data + len);
4125 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4126 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4127 CONSUME (data - start);
4128 offset += 1 + (data - start);
4132 case DW_OP_breg0 ... DW_OP_breg31:
4137 get_sleb128 (sleb, data, data + len);
4138 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4139 indent, "", (uintmax_t) offset, op_name, sleb);
4140 CONSUME (data - start);
4141 offset += 1 + (data - start);
4147 get_uleb128 (uleb, data, data + len);
4149 get_sleb128 (sleb, data, data + len);
4150 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4151 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4152 CONSUME (data - start);
4153 offset += 1 + (data - start);
4158 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4159 indent, "", (uintmax_t) offset, op_name,
4160 read_2ubyte_unaligned (dbg, data));
4167 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4168 indent, "", (uintmax_t) offset, op_name,
4169 read_4ubyte_unaligned (dbg, data));
4177 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4178 indent, "", (uintmax_t) offset, op_name,
4179 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4185 case DW_OP_implicit_value:
4188 get_uleb128 (uleb, data, data + len);
4189 printf ("%*s[%4" PRIuMAX "] %s: ",
4190 indent, "", (uintmax_t) offset, op_name);
4192 print_block (uleb, data);
4194 CONSUME (data - start);
4195 offset += 1 + (data - start);
4198 case DW_OP_GNU_implicit_pointer:
4199 /* DIE offset operand. */
4202 if (ref_size != 4 && ref_size != 8)
4203 goto invalid; /* Cannot be used in CFA. */
4205 addr = read_4ubyte_unaligned (dbg, data);
4207 addr = read_8ubyte_unaligned (dbg, data);
4209 /* Byte offset operand. */
4211 get_sleb128 (sleb, data, data + len);
4213 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4214 indent, "", (intmax_t) offset,
4215 op_name, (uintmax_t) addr, sleb);
4216 CONSUME (data - start);
4217 offset += 1 + (data - start);
4220 case DW_OP_GNU_entry_value:
4221 /* Size plus expression block. */
4224 get_uleb128 (uleb, data, data + len);
4225 printf ("%*s[%4" PRIuMAX "] %s:\n",
4226 indent, "", (uintmax_t) offset, op_name);
4228 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4229 addrsize, offset_size, cu, uleb, data);
4231 CONSUME (data - start);
4232 offset += 1 + (data - start);
4235 case DW_OP_GNU_const_type:
4236 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4237 unsigned size plus block. */
4240 get_uleb128 (uleb, data, data + len);
4241 if (! print_unresolved_addresses && cu != NULL)
4244 uint8_t usize = *(uint8_t *) data++;
4246 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4247 indent, "", (uintmax_t) offset, op_name, uleb);
4248 print_block (usize, data);
4250 CONSUME (data - start);
4251 offset += 1 + (data - start);
4254 case DW_OP_GNU_regval_type:
4255 /* uleb128 register number, uleb128 CU relative
4256 DW_TAG_base_type DIE offset. */
4259 get_uleb128 (uleb, data, data + len);
4261 get_uleb128 (uleb2, data, data + len);
4262 if (! print_unresolved_addresses && cu != NULL)
4264 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4265 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4266 CONSUME (data - start);
4267 offset += 1 + (data - start);
4270 case DW_OP_GNU_deref_type:
4271 /* 1-byte unsigned size of value, uleb128 CU relative
4272 DW_TAG_base_type DIE offset. */
4275 usize = *(uint8_t *) data++;
4277 get_uleb128 (uleb, data, data + len);
4278 if (! print_unresolved_addresses && cu != NULL)
4280 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4281 indent, "", (uintmax_t) offset,
4282 op_name, usize, uleb);
4283 CONSUME (data - start);
4284 offset += 1 + (data - start);
4287 case DW_OP_GNU_convert:
4288 case DW_OP_GNU_reinterpret:
4289 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4290 for conversion to untyped. */
4293 get_uleb128 (uleb, data, data + len);
4294 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4296 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4297 indent, "", (uintmax_t) offset, op_name, uleb);
4298 CONSUME (data - start);
4299 offset += 1 + (data - start);
4302 case DW_OP_GNU_parameter_ref:
4303 /* 4 byte CU relative reference to the abstract optimized away
4304 DW_TAG_formal_parameter. */
4306 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4307 if (! print_unresolved_addresses && cu != NULL)
4308 param_off += cu->start;
4309 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4310 indent, "", (uintmax_t) offset, op_name, param_off);
4318 printf ("%*s[%4" PRIuMAX "] %s\n",
4319 indent, "", (uintmax_t) offset, op_name);
4324 indent = indentrest;
4328 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4329 indent, "", (uintmax_t) offset, op_name);
4337 Dwarf_Off offset:(64 - 3);
4341 struct Dwarf_CU *cu;
4344 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4345 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4348 listptr_base (struct listptr *p)
4351 Dwarf_Die cu = CUDIE (p->cu);
4352 /* Find the base address of the compilation unit. It will normally
4353 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4354 address could be overridden by DW_AT_entry_pc. It's been
4355 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4356 compilation units with discontinuous ranges. */
4357 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4359 Dwarf_Attribute attr_mem;
4360 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4368 compare_listptr (const void *a, const void *b, void *arg)
4370 const char *name = arg;
4371 struct listptr *p1 = (void *) a;
4372 struct listptr *p2 = (void *) b;
4374 if (p1->offset < p2->offset)
4376 if (p1->offset > p2->offset)
4379 if (!p1->warned && !p2->warned)
4381 if (p1->addr64 != p2->addr64)
4383 p1->warned = p2->warned = true;
4385 gettext ("%s %#" PRIx64 " used with different address sizes"),
4386 name, (uint64_t) p1->offset);
4388 if (p1->dwarf64 != p2->dwarf64)
4390 p1->warned = p2->warned = true;
4392 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4393 name, (uint64_t) p1->offset);
4395 if (listptr_base (p1) != listptr_base (p2))
4397 p1->warned = p2->warned = true;
4399 gettext ("%s %#" PRIx64 " used with different base addresses"),
4400 name, (uint64_t) p1->offset);
4407 struct listptr_table
4411 struct listptr *table;
4414 static struct listptr_table known_loclistptr;
4415 static struct listptr_table known_rangelistptr;
4418 reset_listptr (struct listptr_table *table)
4420 free (table->table);
4421 table->table = NULL;
4422 table->n = table->alloc = 0;
4425 /* Returns false if offset doesn't fit. See struct listptr. */
4427 notice_listptr (enum section_e section, struct listptr_table *table,
4428 uint_fast8_t address_size, uint_fast8_t offset_size,
4429 struct Dwarf_CU *cu, Dwarf_Off offset)
4431 if (print_debug_sections & section)
4433 if (table->n == table->alloc)
4435 if (table->alloc == 0)
4439 table->table = xrealloc (table->table,
4440 table->alloc * sizeof table->table[0]);
4443 struct listptr *p = &table->table[table->n++];
4445 *p = (struct listptr)
4447 .addr64 = address_size == 8,
4448 .dwarf64 = offset_size == 8,
4453 if (p->offset != offset)
4463 sort_listptr (struct listptr_table *table, const char *name)
4466 qsort_r (table->table, table->n, sizeof table->table[0],
4467 &compare_listptr, (void *) name);
4471 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4472 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4473 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4474 unsigned char **readp, unsigned char *endp)
4479 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4482 struct listptr *p = &table->table[*idxp];
4484 if (*idxp == table->n
4485 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4488 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4493 if (p->offset != (Dwarf_Off) offset)
4495 *readp += p->offset - offset;
4496 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4497 offset, (Dwarf_Off) p->offset - offset);
4501 if (address_sizep != NULL)
4502 *address_sizep = listptr_address_size (p);
4503 if (offset_sizep != NULL)
4504 *offset_sizep = listptr_offset_size (p);
4506 *base = listptr_base (p);
4515 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4516 Ebl *ebl, GElf_Ehdr *ehdr,
4517 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4519 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4520 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4522 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4524 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4525 (uint64_t) shdr->sh_offset);
4527 Dwarf_Off offset = 0;
4528 while (offset < sh_size)
4530 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4536 Dwarf_Abbrev abbrev;
4538 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4541 if (unlikely (res < 0))
4544 *** error while reading abbreviation: %s\n"),
4549 /* This is the NUL byte at the end of the section. */
4554 /* We know these calls can never fail. */
4555 unsigned int code = dwarf_getabbrevcode (&abbrev);
4556 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4557 int has_children = dwarf_abbrevhaschildren (&abbrev);
4559 printf (gettext (" [%5u] offset: %" PRId64
4560 ", children: %s, tag: %s\n"),
4561 code, (int64_t) offset,
4562 has_children ? gettext ("yes") : gettext ("no"),
4563 dwarf_tag_name (tag));
4569 while (dwarf_getabbrevattr (&abbrev, cnt,
4570 &name, &form, &enoffset) == 0)
4572 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4573 dwarf_attr_name (name), dwarf_form_name (form),
4574 (uint64_t) enoffset);
4585 /* Print content of DWARF .debug_aranges section. We fortunately do
4586 not have to know a bit about the structure of the section, libdwarf
4587 takes care of it. */
4589 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4590 GElf_Shdr *shdr, Dwarf *dbg)
4592 Dwarf_Aranges *aranges;
4594 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4596 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4601 GElf_Shdr glink_mem;
4603 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4606 error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4611 printf (ngettext ("\
4612 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4614 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4616 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4617 (uint64_t) shdr->sh_offset, cnt);
4619 /* Compute floor(log16(cnt)). */
4628 for (size_t n = 0; n < cnt; ++n)
4630 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4631 if (unlikely (runp == NULL))
4633 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4641 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4642 printf (gettext (" [%*zu] ???\n"), digits, n);
4644 printf (gettext (" [%*zu] start: %0#*" PRIx64
4645 ", length: %5" PRIu64 ", CU DIE offset: %6"
4647 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4648 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4653 /* Print content of DWARF .debug_aranges section. */
4655 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4656 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4657 GElf_Shdr *shdr, Dwarf *dbg)
4661 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4665 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4667 if (unlikely (data == NULL))
4669 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4675 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4676 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4677 (uint64_t) shdr->sh_offset);
4679 const unsigned char *readp = data->d_buf;
4680 const unsigned char *readendp = readp + data->d_size;
4682 while (readp < readendp)
4684 const unsigned char *hdrstart = readp;
4685 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4687 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4688 if (readp + 4 > readendp)
4691 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4692 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4696 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4697 unsigned int length_bytes = 4;
4698 if (length == DWARF3_LENGTH_64_BIT)
4700 if (readp + 8 > readendp)
4702 length = read_8ubyte_unaligned_inc (dbg, readp);
4706 const unsigned char *nexthdr = readp + length;
4707 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4710 if (unlikely (length > (size_t) (readendp - readp)))
4716 if (readp + 2 > readendp)
4718 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4719 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4723 error (0, 0, gettext ("unsupported aranges version"));
4728 if (readp + length_bytes > readendp)
4730 if (length_bytes == 8)
4731 offset = read_8ubyte_unaligned_inc (dbg, readp);
4733 offset = read_4ubyte_unaligned_inc (dbg, readp);
4734 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4737 if (readp + 1 > readendp)
4739 unsigned int address_size = *readp++;
4740 printf (gettext (" Address size: %6" PRIu64 "\n"),
4741 (uint64_t) address_size);
4742 if (address_size != 4 && address_size != 8)
4744 error (0, 0, gettext ("unsupported address size"));
4748 unsigned int segment_size = *readp++;
4749 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4750 (uint64_t) segment_size);
4751 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4753 error (0, 0, gettext ("unsupported segment size"));
4757 /* Round the address to the next multiple of 2*address_size. */
4758 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4759 % (2 * address_size));
4761 while (readp < nexthdr)
4763 Dwarf_Word range_address;
4764 Dwarf_Word range_length;
4765 Dwarf_Word segment = 0;
4766 if (readp + 2 * address_size + segment_size > readendp)
4768 if (address_size == 4)
4770 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4771 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4775 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4776 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4779 if (segment_size == 4)
4780 segment = read_4ubyte_unaligned_inc (dbg, readp);
4781 else if (segment_size == 8)
4782 segment = read_8ubyte_unaligned_inc (dbg, readp);
4784 if (range_address == 0 && range_length == 0 && segment == 0)
4787 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4789 char *e = format_dwarf_addr (dwflmod, address_size,
4790 range_address + range_length - 1,
4792 if (segment_size != 0)
4793 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4794 (uint64_t) segment);
4796 printf (gettext (" %s..%s\n"), b, e);
4802 if (readp != nexthdr)
4804 size_t padding = nexthdr - readp;
4805 printf (gettext (" %Zu padding bytes\n"), padding);
4812 /* Print content of DWARF .debug_ranges section. */
4814 print_debug_ranges_section (Dwfl_Module *dwflmod,
4815 Ebl *ebl, GElf_Ehdr *ehdr,
4816 Elf_Scn *scn, GElf_Shdr *shdr,
4819 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4821 if (unlikely (data == NULL))
4823 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4829 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4830 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4831 (uint64_t) shdr->sh_offset);
4833 sort_listptr (&known_rangelistptr, "rangelistptr");
4834 size_t listptr_idx = 0;
4836 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4839 Dwarf_Addr base = 0;
4840 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4841 unsigned char *readp = data->d_buf;
4842 while (readp < endp)
4844 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4846 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4847 &address_size, NULL, &base, NULL,
4848 offset, &readp, endp))
4851 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4853 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4859 if (address_size == 8)
4861 begin = read_8ubyte_unaligned_inc (dbg, readp);
4862 end = read_8ubyte_unaligned_inc (dbg, readp);
4866 begin = read_4ubyte_unaligned_inc (dbg, readp);
4867 end = read_4ubyte_unaligned_inc (dbg, readp);
4868 if (begin == (Dwarf_Addr) (uint32_t) -1)
4869 begin = (Dwarf_Addr) -1l;
4872 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4874 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4875 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4879 else if (begin == 0 && end == 0) /* End of list entry. */
4882 printf (gettext (" [%6tx] empty list\n"), offset);
4887 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4889 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4891 /* We have an address range entry. */
4892 if (first) /* First address range entry in a list. */
4893 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4895 printf (gettext (" %s..%s\n"), b, e);
4904 #define REGNAMESZ 16
4906 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4907 char name[REGNAMESZ], int *bits, int *type)
4912 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4913 bits ?: &ignore, type ?: &ignore);
4917 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4919 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4921 *bits = loc != NULL ? loc->bits : 0;
4923 *type = DW_ATE_unsigned;
4924 set = "??? unrecognized";
4928 if (bits != NULL && *bits <= 0)
4929 *bits = loc != NULL ? loc->bits : 0;
4930 if (type != NULL && *type == DW_ATE_void)
4931 *type = DW_ATE_unsigned;
4938 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4939 Dwarf_Word vma_base, unsigned int code_align,
4941 unsigned int version, unsigned int ptr_size,
4942 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4944 char regnamebuf[REGNAMESZ];
4945 const char *regname (unsigned int regno)
4947 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4951 puts ("\n Program:");
4952 Dwarf_Word pc = vma_base;
4953 while (readp < endp)
4955 unsigned int opcode = *readp++;
4957 if (opcode < DW_CFA_advance_loc)
4958 /* Extended opcode. */
4969 case DW_CFA_set_loc:
4970 if ((uint64_t) (endp - readp) < 1)
4972 get_uleb128 (op1, readp, endp);
4974 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4976 case DW_CFA_advance_loc1:
4977 if ((uint64_t) (endp - readp) < 1)
4979 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4980 *readp, pc += *readp * code_align);
4983 case DW_CFA_advance_loc2:
4984 if ((uint64_t) (endp - readp) < 2)
4986 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4987 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4988 op1, pc += op1 * code_align);
4990 case DW_CFA_advance_loc4:
4991 if ((uint64_t) (endp - readp) < 4)
4993 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4994 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4995 op1, pc += op1 * code_align);
4997 case DW_CFA_offset_extended:
4998 if ((uint64_t) (endp - readp) < 1)
5000 get_uleb128 (op1, readp, endp);
5001 if ((uint64_t) (endp - readp) < 1)
5003 get_uleb128 (op2, readp, endp);
5004 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5006 op1, regname (op1), op2 * data_align);
5008 case DW_CFA_restore_extended:
5009 if ((uint64_t) (endp - readp) < 1)
5011 get_uleb128 (op1, readp, endp);
5012 printf (" restore_extended r%" PRIu64 " (%s)\n",
5013 op1, regname (op1));
5015 case DW_CFA_undefined:
5016 if ((uint64_t) (endp - readp) < 1)
5018 get_uleb128 (op1, readp, endp);
5019 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5021 case DW_CFA_same_value:
5022 if ((uint64_t) (endp - readp) < 1)
5024 get_uleb128 (op1, readp, endp);
5025 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5027 case DW_CFA_register:
5028 if ((uint64_t) (endp - readp) < 1)
5030 get_uleb128 (op1, readp, endp);
5031 if ((uint64_t) (endp - readp) < 1)
5033 get_uleb128 (op2, readp, endp);
5034 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5035 op1, regname (op1), op2, regname (op2));
5037 case DW_CFA_remember_state:
5038 puts (" remember_state");
5040 case DW_CFA_restore_state:
5041 puts (" restore_state");
5043 case DW_CFA_def_cfa:
5044 if ((uint64_t) (endp - readp) < 1)
5046 get_uleb128 (op1, readp, endp);
5047 if ((uint64_t) (endp - readp) < 1)
5049 get_uleb128 (op2, readp, endp);
5050 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5051 op1, regname (op1), op2);
5053 case DW_CFA_def_cfa_register:
5054 if ((uint64_t) (endp - readp) < 1)
5056 get_uleb128 (op1, readp, endp);
5057 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
5058 op1, regname (op1));
5060 case DW_CFA_def_cfa_offset:
5061 if ((uint64_t) (endp - readp) < 1)
5063 get_uleb128 (op1, readp, endp);
5064 printf (" def_cfa_offset %" PRIu64 "\n", op1);
5066 case DW_CFA_def_cfa_expression:
5067 if ((uint64_t) (endp - readp) < 1)
5069 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
5070 printf (" def_cfa_expression %" PRIu64 "\n", op1);
5071 if ((uint64_t) (endp - readp) < op1)
5074 fputs (gettext (" <INVALID DATA>\n"), stdout);
5077 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5081 case DW_CFA_expression:
5082 if ((uint64_t) (endp - readp) < 1)
5084 get_uleb128 (op1, readp, endp);
5085 if ((uint64_t) (endp - readp) < 1)
5087 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5088 printf (" expression r%" PRIu64 " (%s) \n",
5089 op1, regname (op1));
5090 if ((uint64_t) (endp - readp) < op2)
5092 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5096 case DW_CFA_offset_extended_sf:
5097 if ((uint64_t) (endp - readp) < 1)
5099 get_uleb128 (op1, readp, endp);
5100 if ((uint64_t) (endp - readp) < 1)
5102 get_sleb128 (sop2, readp, endp);
5103 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5105 op1, regname (op1), sop2 * data_align);
5107 case DW_CFA_def_cfa_sf:
5108 if ((uint64_t) (endp - readp) < 1)
5110 get_uleb128 (op1, readp, endp);
5111 if ((uint64_t) (endp - readp) < 1)
5113 get_sleb128 (sop2, readp, endp);
5114 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5115 op1, regname (op1), sop2 * data_align);
5117 case DW_CFA_def_cfa_offset_sf:
5118 if ((uint64_t) (endp - readp) < 1)
5120 get_sleb128 (sop1, readp, endp);
5121 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5123 case DW_CFA_val_offset:
5124 if ((uint64_t) (endp - readp) < 1)
5126 get_uleb128 (op1, readp, endp);
5127 if ((uint64_t) (endp - readp) < 1)
5129 get_uleb128 (op2, readp, endp);
5130 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5131 op1, op2 * data_align);
5133 case DW_CFA_val_offset_sf:
5134 if ((uint64_t) (endp - readp) < 1)
5136 get_uleb128 (op1, readp, endp);
5137 if ((uint64_t) (endp - readp) < 1)
5139 get_sleb128 (sop2, readp, endp);
5140 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5141 op1, sop2 * data_align);
5143 case DW_CFA_val_expression:
5144 if ((uint64_t) (endp - readp) < 1)
5146 get_uleb128 (op1, readp, endp);
5147 if ((uint64_t) (endp - readp) < 1)
5149 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5150 printf (" val_expression r%" PRIu64 " (%s)\n",
5151 op1, regname (op1));
5152 if ((uint64_t) (endp - readp) < op2)
5154 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5158 case DW_CFA_MIPS_advance_loc8:
5159 if ((uint64_t) (endp - readp) < 8)
5161 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5162 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5163 op1, pc += op1 * code_align);
5165 case DW_CFA_GNU_window_save:
5166 puts (" GNU_window_save");
5168 case DW_CFA_GNU_args_size:
5169 if ((uint64_t) (endp - readp) < 1)
5171 get_uleb128 (op1, readp, endp);
5172 printf (" args_size %" PRIu64 "\n", op1);
5175 printf (" ??? (%u)\n", opcode);
5178 else if (opcode < DW_CFA_offset)
5179 printf (" advance_loc %u to %#" PRIx64 "\n",
5180 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5181 else if (opcode < DW_CFA_restore)
5184 if ((uint64_t) (endp - readp) < 1)
5186 get_uleb128 (offset, readp, endp);
5187 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5188 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5191 printf (" restore r%u (%s)\n",
5192 opcode & 0x3f, regname (opcode & 0x3f));
5198 encoded_ptr_size (int encoding, unsigned int ptr_size)
5200 switch (encoding & 7)
5202 case DW_EH_PE_udata4:
5204 case DW_EH_PE_udata8:
5210 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5211 "assuming pointer size of %d.\n", encoding, ptr_size);
5217 print_encoding (unsigned int val)
5221 case DW_EH_PE_absptr:
5222 fputs ("absptr", stdout);
5224 case DW_EH_PE_uleb128:
5225 fputs ("uleb128", stdout);
5227 case DW_EH_PE_udata2:
5228 fputs ("udata2", stdout);
5230 case DW_EH_PE_udata4:
5231 fputs ("udata4", stdout);
5233 case DW_EH_PE_udata8:
5234 fputs ("udata8", stdout);
5236 case DW_EH_PE_sleb128:
5237 fputs ("sleb128", stdout);
5239 case DW_EH_PE_sdata2:
5240 fputs ("sdata2", stdout);
5242 case DW_EH_PE_sdata4:
5243 fputs ("sdata4", stdout);
5245 case DW_EH_PE_sdata8:
5246 fputs ("sdata8", stdout);
5249 /* We did not use any of the bits after all. */
5258 print_relinfo (unsigned int val)
5262 case DW_EH_PE_pcrel:
5263 fputs ("pcrel", stdout);
5265 case DW_EH_PE_textrel:
5266 fputs ("textrel", stdout);
5268 case DW_EH_PE_datarel:
5269 fputs ("datarel", stdout);
5271 case DW_EH_PE_funcrel:
5272 fputs ("funcrel", stdout);
5274 case DW_EH_PE_aligned:
5275 fputs ("aligned", stdout);
5286 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5288 printf ("(%s", pfx);
5290 if (fde_encoding == DW_EH_PE_omit)
5294 unsigned int w = fde_encoding;
5296 w = print_encoding (w);
5300 if (w != fde_encoding)
5301 fputc_unlocked (' ', stdout);
5303 w = print_relinfo (w);
5307 printf ("%s%x", w != fde_encoding ? " " : "", w);
5314 static const unsigned char *
5315 read_encoded (unsigned int encoding, const unsigned char *readp,
5316 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5318 if ((encoding & 0xf) == DW_EH_PE_absptr)
5319 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5320 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5322 switch (encoding & 0xf)
5324 case DW_EH_PE_uleb128:
5325 get_uleb128 (*res, readp, endp);
5327 case DW_EH_PE_sleb128:
5328 get_sleb128 (*res, readp, endp);
5330 case DW_EH_PE_udata2:
5331 if (readp + 2 > endp)
5333 *res = read_2ubyte_unaligned_inc (dbg, readp);
5335 case DW_EH_PE_udata4:
5336 if (readp + 4 > endp)
5338 *res = read_4ubyte_unaligned_inc (dbg, readp);
5340 case DW_EH_PE_udata8:
5341 if (readp + 8 > endp)
5343 *res = read_8ubyte_unaligned_inc (dbg, readp);
5345 case DW_EH_PE_sdata2:
5346 if (readp + 2 > endp)
5348 *res = read_2sbyte_unaligned_inc (dbg, readp);
5350 case DW_EH_PE_sdata4:
5351 if (readp + 4 > endp)
5353 *res = read_4sbyte_unaligned_inc (dbg, readp);
5355 case DW_EH_PE_sdata8:
5356 if (readp + 8 > endp)
5358 *res = read_8sbyte_unaligned_inc (dbg, readp);
5363 gettext ("invalid encoding"));
5371 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5372 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5375 /* We know this call will succeed since it did in the caller. */
5376 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5377 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5379 /* Needed if we find PC-relative addresses. */
5381 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5383 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5387 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5388 Elf_Data *data = (is_eh_frame
5389 ? elf_rawdata (scn, NULL)
5390 : dbg->sectiondata[IDX_debug_frame]);
5392 if (unlikely (data == NULL))
5394 error (0, 0, gettext ("cannot get %s content: %s"),
5395 scnname, elf_errmsg (-1));
5401 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5402 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5405 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5406 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5410 ptrdiff_t cie_offset;
5411 const char *augmentation;
5412 unsigned int code_alignment_factor;
5413 unsigned int data_alignment_factor;
5414 uint8_t address_size;
5415 uint8_t fde_encoding;
5416 uint8_t lsda_encoding;
5417 struct cieinfo *next;
5420 const unsigned char *readp = data->d_buf;
5421 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5423 while (readp < dataend)
5425 if (unlikely (readp + 4 > dataend))
5428 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5429 elf_ndxscn (scn), scnname);
5433 /* At the beginning there must be a CIE. There can be multiple,
5434 hence we test tis in a loop. */
5435 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5437 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5438 unsigned int length = 4;
5439 if (unlikely (unit_length == 0xffffffff))
5441 if (unlikely (readp + 8 > dataend))
5444 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5448 if (unlikely (unit_length == 0))
5450 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5454 Dwarf_Word maxsize = dataend - readp;
5455 if (unlikely (unit_length > maxsize))
5458 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5460 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5461 const unsigned char *const cieend = readp + unit_length;
5462 if (unlikely (cieend > dataend || readp + 8 > dataend))
5468 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5469 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5470 cie_id = DW_CIE_ID_64;
5473 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5475 uint_fast8_t version = 2;
5476 unsigned int code_alignment_factor;
5477 int data_alignment_factor;
5478 unsigned int fde_encoding = 0;
5479 unsigned int lsda_encoding = 0;
5480 Dwarf_Word initial_location = 0;
5481 Dwarf_Word vma_base = 0;
5483 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5486 const char *const augmentation = (const char *) readp;
5487 readp = memchr (readp, '\0', cieend - readp);
5488 if (unlikely (readp == NULL))
5492 uint_fast8_t segment_size = 0;
5495 if (cieend - readp < 5)
5497 ptr_size = *readp++;
5498 segment_size = *readp++;
5501 if (cieend - readp < 1)
5503 get_uleb128 (code_alignment_factor, readp, cieend);
5504 if (cieend - readp < 1)
5506 get_sleb128 (data_alignment_factor, readp, cieend);
5508 /* In some variant for unwind data there is another field. */
5509 if (strcmp (augmentation, "eh") == 0)
5510 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5512 unsigned int return_address_register;
5513 if (cieend - readp < 1)
5515 if (unlikely (version == 1))
5516 return_address_register = *readp++;
5518 get_uleb128 (return_address_register, readp, cieend);
5520 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5521 " CIE_id: %" PRIu64 "\n"
5523 " augmentation: \"%s\"\n",
5524 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5525 version, augmentation);
5527 printf (" address_size: %u\n"
5528 " segment_size: %u\n",
5529 ptr_size, segment_size);
5530 printf (" code_alignment_factor: %u\n"
5531 " data_alignment_factor: %d\n"
5532 " return_address_register: %u\n",
5533 code_alignment_factor,
5534 data_alignment_factor, return_address_register);
5536 if (augmentation[0] == 'z')
5538 unsigned int augmentationlen;
5539 get_uleb128 (augmentationlen, readp, cieend);
5541 if (augmentationlen > (size_t) (cieend - readp))
5543 error (0, 0, gettext ("invalid augmentation length"));
5548 const char *hdr = "Augmentation data:";
5549 const char *cp = augmentation + 1;
5550 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5552 printf (" %-26s%#x ", hdr, *readp);
5557 fde_encoding = *readp++;
5558 print_encoding_base (gettext ("FDE address encoding: "),
5561 else if (*cp == 'L')
5563 lsda_encoding = *readp++;
5564 print_encoding_base (gettext ("LSDA pointer encoding: "),
5567 else if (*cp == 'P')
5569 /* Personality. This field usually has a relocation
5570 attached pointing to __gcc_personality_v0. */
5571 const unsigned char *startp = readp;
5572 unsigned int encoding = *readp++;
5574 readp = read_encoded (encoding, readp,
5575 readp - 1 + augmentationlen,
5578 while (++startp < readp)
5579 printf ("%#x ", *startp);
5582 print_encoding (encoding);
5584 switch (encoding & 0xf)
5586 case DW_EH_PE_sleb128:
5587 case DW_EH_PE_sdata2:
5588 case DW_EH_PE_sdata4:
5589 printf ("%" PRId64 ")\n", val);
5592 printf ("%#" PRIx64 ")\n", val);
5597 printf ("(%x)\n", *readp++);
5603 if (likely (ptr_size == 4 || ptr_size == 8))
5605 struct cieinfo *newp = alloca (sizeof (*newp));
5606 newp->cie_offset = offset;
5607 newp->augmentation = augmentation;
5608 newp->fde_encoding = fde_encoding;
5609 newp->lsda_encoding = lsda_encoding;
5610 newp->address_size = ptr_size;
5611 newp->code_alignment_factor = code_alignment_factor;
5612 newp->data_alignment_factor = data_alignment_factor;
5619 struct cieinfo *cie = cies;
5622 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
5623 : cie_id == (Dwarf_Off) cie->cie_offset)
5627 if (unlikely (cie == NULL))
5629 puts ("invalid CIE reference in FDE");
5633 /* Initialize from CIE data. */
5634 fde_encoding = cie->fde_encoding;
5635 lsda_encoding = cie->lsda_encoding;
5636 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5637 code_alignment_factor = cie->code_alignment_factor;
5638 data_alignment_factor = cie->data_alignment_factor;
5640 const unsigned char *base = readp;
5641 // XXX There are sometimes relocations for this value
5642 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5643 Dwarf_Word address_range
5644 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5646 /* pcrel for an FDE address is relative to the runtime
5647 address of the start_address field itself. Sign extend
5648 if necessary to make sure the calculation is done on the
5649 full 64 bit address even when initial_location only holds
5650 the lower 32 bits. */
5651 Dwarf_Addr pc_start = initial_location;
5653 pc_start = (uint64_t) (int32_t) pc_start;
5654 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5655 pc_start += ((uint64_t) shdr->sh_addr
5656 + (base - (const unsigned char *) data->d_buf)
5659 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5660 pc_start, initial_location);
5661 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5662 " CIE_pointer: %" PRIu64 "\n"
5663 " initial_location: %s",
5664 offset, (uint64_t) unit_length,
5665 cie->cie_offset, (uint64_t) cie_id, a);
5667 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5669 vma_base = (((uint64_t) shdr->sh_offset
5670 + (base - (const unsigned char *) data->d_buf)
5671 + (uint64_t) initial_location)
5673 ? UINT64_C (0xffffffff)
5674 : UINT64_C (0xffffffffffffffff)));
5675 printf (gettext (" (offset: %#" PRIx64 ")"),
5676 (uint64_t) vma_base);
5679 printf ("\n address_range: %#" PRIx64,
5680 (uint64_t) address_range);
5681 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5682 printf (gettext (" (end offset: %#" PRIx64 ")"),
5683 ((uint64_t) vma_base + (uint64_t) address_range)
5685 ? UINT64_C (0xffffffff)
5686 : UINT64_C (0xffffffffffffffff)));
5689 if (cie->augmentation[0] == 'z')
5691 unsigned int augmentationlen;
5692 if (cieend - readp < 1)
5694 get_uleb128 (augmentationlen, readp, cieend);
5696 if (augmentationlen > (size_t) (cieend - readp))
5698 error (0, 0, gettext ("invalid augmentation length"));
5703 if (augmentationlen > 0)
5705 const char *hdr = "Augmentation data:";
5706 const char *cp = cie->augmentation + 1;
5709 && cp < cie->augmentation + augmentationlen + 1)
5713 uint64_t lsda_pointer;
5714 const unsigned char *p
5715 = read_encoded (lsda_encoding, &readp[u],
5716 &readp[augmentationlen],
5717 &lsda_pointer, dbg);
5720 %-26sLSDA pointer: %#" PRIx64 "\n"),
5727 while (u < augmentationlen)
5729 printf (" %-26s%#x\n", hdr, readp[u++]);
5734 readp += augmentationlen;
5738 /* Handle the initialization instructions. */
5739 if (ptr_size != 4 && ptr_size !=8)
5740 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5742 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5743 data_alignment_factor, version, ptr_size,
5752 Dwfl_Module *dwflmod;
5757 unsigned int version;
5758 unsigned int addrsize;
5759 unsigned int offset_size;
5760 struct Dwarf_CU *cu;
5765 attr_callback (Dwarf_Attribute *attrp, void *arg)
5767 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5768 const int level = cbargs->level;
5770 unsigned int attr = dwarf_whatattr (attrp);
5771 if (unlikely (attr == 0))
5773 if (!cbargs->silent)
5774 error (0, 0, gettext ("cannot get attribute code: %s"),
5776 return DWARF_CB_ABORT;
5779 unsigned int form = dwarf_whatform (attrp);
5780 if (unlikely (form == 0))
5782 if (!cbargs->silent)
5783 error (0, 0, gettext ("cannot get attribute form: %s"),
5785 return DWARF_CB_ABORT;
5791 if (!cbargs->silent)
5794 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5797 if (!cbargs->silent)
5798 error (0, 0, gettext ("cannot get attribute value: %s"),
5800 return DWARF_CB_ABORT;
5802 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5804 printf (" %*s%-20s (%s) %s\n",
5805 (int) (level * 2), "", dwarf_attr_name (attr),
5806 dwarf_form_name (form), a);
5811 case DW_FORM_indirect:
5813 case DW_FORM_string:
5814 case DW_FORM_GNU_strp_alt:
5817 const char *str = dwarf_formstring (attrp);
5818 if (unlikely (str == NULL))
5820 printf (" %*s%-20s (%s) \"%s\"\n",
5821 (int) (level * 2), "", dwarf_attr_name (attr),
5822 dwarf_form_name (form), str);
5825 case DW_FORM_ref_addr:
5826 case DW_FORM_ref_udata:
5831 case DW_FORM_GNU_ref_alt:
5835 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5838 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5839 (int) (level * 2), "", dwarf_attr_name (attr),
5840 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5843 case DW_FORM_ref_sig8:
5846 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5847 (int) (level * 2), "", dwarf_attr_name (attr),
5848 dwarf_form_name (form),
5849 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5852 case DW_FORM_sec_offset:
5858 case DW_FORM_data1:;
5860 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5863 const char *valuestr = NULL;
5866 /* This case can take either a constant or a loclistptr. */
5867 case DW_AT_data_member_location:
5868 if (form != DW_FORM_sec_offset
5869 && (cbargs->version >= 4
5870 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5872 if (!cbargs->silent)
5873 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5874 (int) (level * 2), "", dwarf_attr_name (attr),
5875 dwarf_form_name (form), (uintmax_t) num);
5878 /* else fallthrough */
5880 /* These cases always take a loclistptr and no constant. */
5881 case DW_AT_location:
5882 case DW_AT_data_location:
5883 case DW_AT_vtable_elem_location:
5884 case DW_AT_string_length:
5885 case DW_AT_use_location:
5886 case DW_AT_frame_base:
5887 case DW_AT_return_addr:
5888 case DW_AT_static_link:
5889 case DW_AT_GNU_call_site_value:
5890 case DW_AT_GNU_call_site_data_value:
5891 case DW_AT_GNU_call_site_target:
5892 case DW_AT_GNU_call_site_target_clobbered:
5894 bool nlpt = notice_listptr (section_loc, &known_loclistptr,
5895 cbargs->addrsize, cbargs->offset_size,
5897 if (!cbargs->silent)
5898 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
5899 (int) (level * 2), "", dwarf_attr_name (attr),
5900 dwarf_form_name (form), (uintmax_t) num,
5901 nlpt ? "" : " <WARNING offset too big>");
5907 bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
5908 cbargs->addrsize, cbargs->offset_size,
5910 if (!cbargs->silent)
5911 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
5912 (int) (level * 2), "", dwarf_attr_name (attr),
5913 dwarf_form_name (form), (uintmax_t) num,
5914 nlpt ? "" : " <WARNING offset too big>");
5918 case DW_AT_language:
5919 valuestr = dwarf_lang_name (num);
5921 case DW_AT_encoding:
5922 valuestr = dwarf_encoding_name (num);
5924 case DW_AT_accessibility:
5925 valuestr = dwarf_access_name (num);
5927 case DW_AT_visibility:
5928 valuestr = dwarf_visibility_name (num);
5930 case DW_AT_virtuality:
5931 valuestr = dwarf_virtuality_name (num);
5933 case DW_AT_identifier_case:
5934 valuestr = dwarf_identifier_case_name (num);
5936 case DW_AT_calling_convention:
5937 valuestr = dwarf_calling_convention_name (num);
5940 valuestr = dwarf_inline_name (num);
5942 case DW_AT_ordering:
5943 valuestr = dwarf_ordering_name (num);
5945 case DW_AT_discr_list:
5946 valuestr = dwarf_discr_list_name (num);
5956 /* When highpc is in constant form it is relative to lowpc.
5957 In that case also show the address. */
5959 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5961 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5963 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5964 (int) (level * 2), "", dwarf_attr_name (attr),
5965 dwarf_form_name (form), (uintmax_t) num, a);
5970 Dwarf_Sword snum = 0;
5971 if (form == DW_FORM_sdata)
5972 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5975 if (valuestr == NULL)
5977 printf (" %*s%-20s (%s)",
5978 (int) (level * 2), "", dwarf_attr_name (attr),
5979 dwarf_form_name (form));
5980 if (form == DW_FORM_sdata)
5981 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5983 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5987 printf (" %*s%-20s (%s) %s",
5988 (int) (level * 2), "", dwarf_attr_name (attr),
5989 dwarf_form_name (form), valuestr);
5990 if (form == DW_FORM_sdata)
5991 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5993 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6002 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6005 printf (" %*s%-20s (%s) %s\n",
6006 (int) (level * 2), "", dwarf_attr_name (attr),
6007 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
6010 case DW_FORM_flag_present:
6013 printf (" %*s%-20s (%s) %s\n",
6014 (int) (level * 2), "", dwarf_attr_name (attr),
6015 dwarf_form_name (form), nl_langinfo (YESSTR));
6018 case DW_FORM_exprloc:
6019 case DW_FORM_block4:
6020 case DW_FORM_block2:
6021 case DW_FORM_block1:
6026 if (unlikely (dwarf_formblock (attrp, &block) != 0))
6029 printf (" %*s%-20s (%s) ",
6030 (int) (level * 2), "", dwarf_attr_name (attr),
6031 dwarf_form_name (form));
6036 if (form != DW_FORM_exprloc)
6038 print_block (block.length, block.data);
6043 case DW_AT_location:
6044 case DW_AT_data_location:
6045 case DW_AT_data_member_location:
6046 case DW_AT_vtable_elem_location:
6047 case DW_AT_string_length:
6048 case DW_AT_use_location:
6049 case DW_AT_frame_base:
6050 case DW_AT_return_addr:
6051 case DW_AT_static_link:
6052 case DW_AT_allocated:
6053 case DW_AT_associated:
6054 case DW_AT_bit_size:
6055 case DW_AT_bit_offset:
6056 case DW_AT_bit_stride:
6057 case DW_AT_byte_size:
6058 case DW_AT_byte_stride:
6060 case DW_AT_lower_bound:
6061 case DW_AT_upper_bound:
6062 case DW_AT_GNU_call_site_value:
6063 case DW_AT_GNU_call_site_data_value:
6064 case DW_AT_GNU_call_site_target:
6065 case DW_AT_GNU_call_site_target_clobbered:
6067 print_ops (cbargs->dwflmod, cbargs->dbg,
6068 12 + level * 2, 12 + level * 2,
6069 cbargs->version, cbargs->addrsize, cbargs->offset_size,
6070 attrp->cu, block.length, block.data);
6078 printf (" %*s%-20s (form: %#x) ???\n",
6079 (int) (level * 2), "", dwarf_attr_name (attr),
6088 print_debug_units (Dwfl_Module *dwflmod,
6089 Ebl *ebl, GElf_Ehdr *ehdr,
6090 Elf_Scn *scn, GElf_Shdr *shdr,
6091 Dwarf *dbg, bool debug_types)
6093 const bool silent = !(print_debug_sections & section_info);
6094 const char *secname = section_name (ebl, ehdr, shdr);
6098 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6099 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6101 /* If the section is empty we don't have to do anything. */
6102 if (!silent && shdr->sh_size == 0)
6106 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6108 Dwarf_Off offset = 0;
6110 /* New compilation unit. */
6113 Dwarf_Off abbroffset;
6120 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6121 &abbroffset, &addrsize, &offsize,
6122 debug_types ? &typesig : NULL,
6123 debug_types ? &typeoff : NULL) != 0)
6129 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6130 " Version: %" PRIu16 ", Abbreviation section offset: %"
6131 PRIu64 ", Address size: %" PRIu8
6132 ", Offset size: %" PRIu8
6133 "\n Type signature: %#" PRIx64
6134 ", Type offset: %#" PRIx64 "\n"),
6135 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6136 typesig, (uint64_t) typeoff);
6138 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6139 " Version: %" PRIu16 ", Abbreviation section offset: %"
6140 PRIu64 ", Address size: %" PRIu8
6141 ", Offset size: %" PRIu8 "\n"),
6142 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6145 struct attrcb_args args =
6151 .addrsize = addrsize,
6152 .offset_size = offsize
6159 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6160 (dbg, offset, &dies[level]) == NULL))
6163 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6164 " in section '%s': %s"),
6165 (uint64_t) offset, secname, dwarf_errmsg (-1));
6169 args.cu = dies[0].cu;
6173 offset = dwarf_dieoffset (&dies[level]);
6174 if (unlikely (offset == ~0ul))
6177 error (0, 0, gettext ("cannot get DIE offset: %s"),
6182 int tag = dwarf_tag (&dies[level]);
6183 if (unlikely (tag == DW_TAG_invalid))
6186 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6187 " in section '%s': %s"),
6188 (uint64_t) offset, secname, dwarf_errmsg (-1));
6193 printf (" [%6" PRIx64 "] %*s%s\n",
6194 (uint64_t) offset, (int) (level * 2), "",
6195 dwarf_tag_name (tag));
6197 /* Print the attribute values. */
6199 args.die = &dies[level];
6200 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6202 /* Make room for the next level's DIE. */
6203 if (level + 1 == maxdies)
6204 dies = (Dwarf_Die *) xrealloc (dies,
6206 * sizeof (Dwarf_Die));
6208 int res = dwarf_child (&dies[level], &dies[level + 1]);
6211 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6215 if (unlikely (res == -1))
6218 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6223 else if (unlikely (res < 0))
6226 error (0, 0, gettext ("cannot get next DIE: %s"),
6244 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6245 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6247 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6251 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6252 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6254 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6259 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6260 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6263 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6264 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6265 (uint64_t) shdr->sh_offset);
6268 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6271 Dwarf_Off ncuoffset = 0;
6273 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6274 NULL, NULL, NULL) == 0)
6277 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6282 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6285 printf (" CU [%" PRIx64 "] %s\n",
6286 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6287 printf (" line:col SBPE* disc isa op address"
6288 " (Statement Block Prologue Epilogue *End)\n");
6289 const char *last_file = "";
6290 for (size_t n = 0; n < nlines; n++)
6292 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6295 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6298 Dwarf_Word mtime, length;
6299 const char *file = dwarf_linesrc (line, &mtime, &length);
6302 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6305 else if (strcmp (last_file, file) != 0)
6307 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6308 file, mtime, length);
6313 bool statement, endseq, block, prologue_end, epilogue_begin;
6314 unsigned int lineop, isa, disc;
6316 dwarf_lineaddr (line, &address);
6317 dwarf_lineno (line, &lineno);
6318 dwarf_linecol (line, &colno);
6319 dwarf_lineop_index (line, &lineop);
6320 dwarf_linebeginstatement (line, &statement);
6321 dwarf_lineendsequence (line, &endseq);
6322 dwarf_lineblock (line, &block);
6323 dwarf_lineprologueend (line, &prologue_end);
6324 dwarf_lineepiloguebegin (line, &epilogue_begin);
6325 dwarf_lineisa (line, &isa);
6326 dwarf_linediscriminator (line, &disc);
6328 /* End sequence is special, it is one byte past. */
6329 char *a = format_dwarf_addr (dwflmod, address_size,
6330 address - (endseq ? 1 : 0), address);
6331 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6333 (statement ? 'S' : ' '),
6334 (block ? 'B' : ' '),
6335 (prologue_end ? 'P' : ' '),
6336 (epilogue_begin ? 'E' : ' '),
6337 (endseq ? '*' : ' '),
6338 disc, isa, lineop, a);
6349 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6350 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6354 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6359 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6360 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6361 (uint64_t) shdr->sh_offset);
6363 if (shdr->sh_size == 0)
6366 /* There is no functionality in libdw to read the information in the
6367 way it is represented here. Hardcode the decoder. */
6368 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6369 if (unlikely (data == NULL || data->d_buf == NULL))
6371 error (0, 0, gettext ("cannot get line data section data: %s"),
6376 const unsigned char *linep = (const unsigned char *) data->d_buf;
6377 const unsigned char *lineendp;
6380 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6382 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6384 printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6386 if (unlikely (linep + 4 > lineendp))
6388 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6389 unsigned int length = 4;
6390 if (unlikely (unit_length == 0xffffffff))
6392 if (unlikely (linep + 8 > lineendp))
6395 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6396 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6399 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6403 /* Check whether we have enough room in the section. */
6404 if (unlikely (unit_length > (size_t) (lineendp - linep)
6405 || unit_length < 2 + length + 5 * 1))
6407 lineendp = linep + unit_length;
6409 /* The next element of the header is the version identifier. */
6410 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6412 /* Next comes the header length. */
6413 Dwarf_Word header_length;
6415 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6417 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6418 //const unsigned char *header_start = linep;
6420 /* Next the minimum instruction length. */
6421 uint_fast8_t minimum_instr_len = *linep++;
6423 /* Next the maximum operations per instruction, in version 4 format. */
6424 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6426 /* Then the flag determining the default value of the is_stmt
6428 uint_fast8_t default_is_stmt = *linep++;
6430 /* Now the line base. */
6431 int_fast8_t line_base = *((const int_fast8_t *) linep);
6434 /* And the line range. */
6435 uint_fast8_t line_range = *linep++;
6437 /* The opcode base. */
6438 uint_fast8_t opcode_base = *linep++;
6440 /* Print what we got so far. */
6441 printf (gettext ("\n"
6442 " Length: %" PRIu64 "\n"
6443 " DWARF version: %" PRIuFAST16 "\n"
6444 " Prologue length: %" PRIu64 "\n"
6445 " Minimum instruction length: %" PRIuFAST8 "\n"
6446 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6447 " Initial value if '%s': %" PRIuFAST8 "\n"
6448 " Line base: %" PRIdFAST8 "\n"
6449 " Line range: %" PRIuFAST8 "\n"
6450 " Opcode base: %" PRIuFAST8 "\n"
6453 (uint64_t) unit_length, version, (uint64_t) header_length,
6454 minimum_instr_len, max_ops_per_instr,
6455 "is_stmt", default_is_stmt, line_base,
6456 line_range, opcode_base);
6458 if (unlikely (linep + opcode_base - 1 >= lineendp))
6462 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6463 linep - (const unsigned char *) data->d_buf,
6464 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6468 int opcode_base_l10 = 1;
6469 unsigned int tmp = opcode_base;
6475 const uint8_t *standard_opcode_lengths = linep - 1;
6476 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6477 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6478 " [%*" PRIuFAST8 "] %hhu arguments\n",
6479 (int) linep[cnt - 1]),
6480 opcode_base_l10, cnt, linep[cnt - 1]);
6481 linep += opcode_base - 1;
6482 if (unlikely (linep >= lineendp))
6485 puts (gettext ("\nDirectory table:"));
6488 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6489 if (unlikely (endp == NULL))
6492 printf (" %s\n", (char *) linep);
6496 /* Skip the final NUL byte. */
6499 if (unlikely (linep >= lineendp))
6501 puts (gettext ("\nFile name table:\n"
6502 " Entry Dir Time Size Name"));
6503 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6505 /* First comes the file name. */
6506 char *fname = (char *) linep;
6507 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6508 if (unlikely (endp == NULL))
6512 /* Then the index. */
6513 unsigned int diridx;
6514 if (lineendp - linep < 1)
6516 get_uleb128 (diridx, linep, lineendp);
6518 /* Next comes the modification time. */
6520 if (lineendp - linep < 1)
6522 get_uleb128 (mtime, linep, lineendp);
6524 /* Finally the length of the file. */
6526 if (lineendp - linep < 1)
6528 get_uleb128 (fsize, linep, lineendp);
6530 printf (" %-5u %-5u %-9u %-9u %s\n",
6531 cnt, diridx, mtime, fsize, fname);
6533 /* Skip the final NUL byte. */
6536 puts (gettext ("\nLine number statements:"));
6537 Dwarf_Word address = 0;
6538 unsigned int op_index = 0;
6540 uint_fast8_t is_stmt = default_is_stmt;
6542 /* Default address value, in case we do not find the CU. */
6544 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6546 /* Determine the CU this block is for. */
6548 Dwarf_Off ncuoffset = 0;
6550 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6551 NULL, NULL, NULL) == 0)
6554 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6556 Dwarf_Attribute stmt_list;
6557 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6560 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6562 if (lineoff == start_offset)
6565 address_size = cudie.cu->address_size;
6570 /* Apply the "operation advance" from a special opcode
6571 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6572 unsigned int op_addr_advance;
6574 inline void advance_pc (unsigned int op_advance)
6576 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6577 / max_ops_per_instr);
6578 address += op_advance;
6579 show_op_index = (op_index > 0 ||
6580 (op_index + op_advance) % max_ops_per_instr > 0);
6581 op_index = (op_index + op_advance) % max_ops_per_instr;
6584 if (max_ops_per_instr == 0)
6587 gettext ("invalid maximum operations per instruction is zero"));
6592 while (linep < lineendp)
6594 size_t offset = linep - (const unsigned char *) data->d_buf;
6598 /* Read the opcode. */
6599 unsigned int opcode = *linep++;
6601 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6602 /* Is this a special opcode? */
6603 if (likely (opcode >= opcode_base))
6605 if (unlikely (line_range == 0))
6608 /* Yes. Handling this is quite easy since the opcode value
6611 opcode = (desired line increment - line_base)
6612 + (line_range * address advance) + opcode_base
6614 int line_increment = (line_base
6615 + (opcode - opcode_base) % line_range);
6617 /* Perform the increments. */
6618 line += line_increment;
6619 advance_pc ((opcode - opcode_base) / line_range);
6621 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6624 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6625 opcode, op_addr_advance, a, op_index,
6626 line_increment, line);
6629 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6630 opcode, op_addr_advance, a, line_increment, line);
6633 else if (opcode == 0)
6635 /* This an extended opcode. */
6636 if (unlikely (linep + 2 > lineendp))
6640 unsigned int len = *linep++;
6642 if (unlikely (linep + len > lineendp))
6645 /* The sub-opcode. */
6648 printf (gettext (" extended opcode %u: "), opcode);
6652 case DW_LNE_end_sequence:
6653 puts (gettext (" end of sequence"));
6655 /* Reset the registers we care about. */
6659 is_stmt = default_is_stmt;
6662 case DW_LNE_set_address:
6664 if (unlikely ((size_t) (lineendp - linep) < address_size))
6666 if (address_size == 4)
6667 address = read_4ubyte_unaligned_inc (dbg, linep);
6669 address = read_8ubyte_unaligned_inc (dbg, linep);
6671 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6672 printf (gettext (" set address to %s\n"), a);
6677 case DW_LNE_define_file:
6679 char *fname = (char *) linep;
6680 unsigned char *endp = memchr (linep, '\0',
6682 if (unlikely (endp == NULL))
6686 unsigned int diridx;
6687 if (lineendp - linep < 1)
6689 get_uleb128 (diridx, linep, lineendp);
6691 if (lineendp - linep < 1)
6693 get_uleb128 (mtime, linep, lineendp);
6694 Dwarf_Word filelength;
6695 if (lineendp - linep < 1)
6697 get_uleb128 (filelength, linep, lineendp);
6700 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6701 diridx, (uint64_t) mtime, (uint64_t) filelength,
6706 case DW_LNE_set_discriminator:
6707 /* Takes one ULEB128 parameter, the discriminator. */
6708 if (unlikely (standard_opcode_lengths[opcode] != 1))
6711 get_uleb128 (u128, linep, lineendp);
6712 printf (gettext (" set discriminator to %u\n"), u128);
6716 /* Unknown, ignore it. */
6717 puts (gettext (" unknown opcode"));
6722 else if (opcode <= DW_LNS_set_isa)
6724 /* This is a known standard opcode. */
6728 /* Takes no argument. */
6729 puts (gettext (" copy"));
6732 case DW_LNS_advance_pc:
6733 /* Takes one uleb128 parameter which is added to the
6735 get_uleb128 (u128, linep, lineendp);
6738 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6741 advance address by %u to %s, op_index to %u\n"),
6742 op_addr_advance, a, op_index);
6744 printf (gettext (" advance address by %u to %s\n"),
6745 op_addr_advance, a);
6750 case DW_LNS_advance_line:
6751 /* Takes one sleb128 parameter which is added to the
6753 get_sleb128 (s128, linep, lineendp);
6756 advance line by constant %d to %" PRId64 "\n"),
6757 s128, (int64_t) line);
6760 case DW_LNS_set_file:
6761 /* Takes one uleb128 parameter which is stored in file. */
6762 get_uleb128 (u128, linep, lineendp);
6763 printf (gettext (" set file to %" PRIu64 "\n"),
6767 case DW_LNS_set_column:
6768 /* Takes one uleb128 parameter which is stored in column. */
6769 if (unlikely (standard_opcode_lengths[opcode] != 1))
6772 get_uleb128 (u128, linep, lineendp);
6773 printf (gettext (" set column to %" PRIu64 "\n"),
6777 case DW_LNS_negate_stmt:
6778 /* Takes no argument. */
6779 is_stmt = 1 - is_stmt;
6780 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6781 "is_stmt", is_stmt);
6784 case DW_LNS_set_basic_block:
6785 /* Takes no argument. */
6786 puts (gettext (" set basic block flag"));
6789 case DW_LNS_const_add_pc:
6790 /* Takes no argument. */
6792 if (unlikely (line_range == 0))
6795 advance_pc ((255 - opcode_base) / line_range);
6797 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6800 advance address by constant %u to %s, op_index to %u\n"),
6801 op_addr_advance, a, op_index);
6804 advance address by constant %u to %s\n"),
6805 op_addr_advance, a);
6810 case DW_LNS_fixed_advance_pc:
6811 /* Takes one 16 bit parameter which is added to the
6813 if (unlikely (standard_opcode_lengths[opcode] != 1))
6816 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6820 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6822 advance address by fixed value %u to %s\n"),
6828 case DW_LNS_set_prologue_end:
6829 /* Takes no argument. */
6830 puts (gettext (" set prologue end flag"));
6833 case DW_LNS_set_epilogue_begin:
6834 /* Takes no argument. */
6835 puts (gettext (" set epilogue begin flag"));
6838 case DW_LNS_set_isa:
6839 /* Takes one uleb128 parameter which is stored in isa. */
6840 if (unlikely (standard_opcode_lengths[opcode] != 1))
6843 get_uleb128 (u128, linep, lineendp);
6844 printf (gettext (" set isa to %u\n"), u128);
6850 /* This is a new opcode the generator but not we know about.
6851 Read the parameters associated with it but then discard
6852 everything. Read all the parameters for this opcode. */
6853 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6854 " unknown opcode with %" PRIu8 " parameters:",
6855 standard_opcode_lengths[opcode]),
6856 standard_opcode_lengths[opcode]);
6857 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6859 get_uleb128 (u128, linep, lineendp);
6860 if (n != standard_opcode_lengths[opcode])
6861 putc_unlocked (',', stdout);
6862 printf (" %u", u128);
6865 /* Next round, ignore this opcode. */
6871 /* There must only be one data block. */
6872 assert (elf_getdata (scn, data) == NULL);
6877 print_debug_loc_section (Dwfl_Module *dwflmod,
6878 Ebl *ebl, GElf_Ehdr *ehdr,
6879 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6881 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6883 if (unlikely (data == NULL))
6885 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6891 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6892 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6893 (uint64_t) shdr->sh_offset);
6895 sort_listptr (&known_loclistptr, "loclistptr");
6896 size_t listptr_idx = 0;
6898 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6899 uint_fast8_t offset_size = 4;
6902 struct Dwarf_CU *cu = NULL;
6903 Dwarf_Addr base = 0;
6904 unsigned char *readp = data->d_buf;
6905 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6906 while (readp < endp)
6908 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6910 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6911 &address_size, &offset_size, &base,
6912 &cu, offset, &readp, endp))
6915 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6917 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6923 if (address_size == 8)
6925 begin = read_8ubyte_unaligned_inc (dbg, readp);
6926 end = read_8ubyte_unaligned_inc (dbg, readp);
6930 begin = read_4ubyte_unaligned_inc (dbg, readp);
6931 end = read_4ubyte_unaligned_inc (dbg, readp);
6932 if (begin == (Dwarf_Addr) (uint32_t) -1)
6933 begin = (Dwarf_Addr) -1l;
6936 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6938 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6939 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6943 else if (begin == 0 && end == 0) /* End of list entry. */
6946 printf (gettext (" [%6tx] empty list\n"), offset);
6951 /* We have a location expression entry. */
6952 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6954 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6956 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6959 if (first) /* First entry in a list. */
6960 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6962 printf (gettext (" %s..%s"), b, e);
6967 if (endp - readp <= (ptrdiff_t) len)
6969 fputs (gettext (" <INVALID DATA>\n"), stdout);
6973 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6974 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6987 struct mac_culist *next;
6992 mac_compare (const void *p1, const void *p2)
6994 struct mac_culist *m1 = (struct mac_culist *) p1;
6995 struct mac_culist *m2 = (struct mac_culist *) p2;
6997 if (m1->offset < m2->offset)
6999 if (m1->offset > m2->offset)
7006 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7007 Ebl *ebl, GElf_Ehdr *ehdr,
7008 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7011 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7012 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7013 (uint64_t) shdr->sh_offset);
7014 putc_unlocked ('\n', stdout);
7016 /* There is no function in libdw to iterate over the raw content of
7017 the section but it is easy enough to do. */
7018 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7019 if (unlikely (data == NULL || data->d_buf == NULL))
7021 error (0, 0, gettext ("cannot get macro information section data: %s"),
7026 /* Get the source file information for all CUs. */
7030 struct mac_culist *culist = NULL;
7032 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7035 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7038 Dwarf_Attribute attr;
7039 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7043 if (dwarf_formudata (&attr, &macoff) != 0)
7046 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7048 newp->offset = macoff;
7050 newp->next = culist;
7055 /* Convert the list into an array for easier consumption. */
7056 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7059 cus[nculist].offset = data->d_size;
7060 cus[nculist].files = (Dwarf_Files *) -1l;
7063 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7065 assert (cnt < nculist);
7067 culist = culist->next;
7070 /* Sort the array according to the offset in the .debug_macinfo
7071 section. Note we keep the sentinel at the end. */
7072 qsort (cus, nculist, sizeof (*cus), mac_compare);
7075 const unsigned char *readp = (const unsigned char *) data->d_buf;
7076 const unsigned char *readendp = readp + data->d_size;
7079 while (readp < readendp)
7081 unsigned int opcode = *readp++;
7083 unsigned int u128_2;
7084 const unsigned char *endp;
7088 case DW_MACINFO_define:
7089 case DW_MACINFO_undef:
7090 case DW_MACINFO_vendor_ext:
7091 /* For the first two opcodes the parameters are
7095 We can treat these cases together. */
7096 get_uleb128 (u128, readp, readendp);
7098 endp = memchr (readp, '\0', readendp - readp);
7099 if (unlikely (endp == NULL))
7102 %*s*** non-terminated string at end of section"),
7107 if (opcode == DW_MACINFO_define)
7108 printf ("%*s#define %s, line %u\n",
7109 level, "", (char *) readp, u128);
7110 else if (opcode == DW_MACINFO_undef)
7111 printf ("%*s#undef %s, line %u\n",
7112 level, "", (char *) readp, u128);
7114 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7119 case DW_MACINFO_start_file:
7120 /* The two parameters are line and file index, in this order. */
7121 get_uleb128 (u128, readp, readendp);
7122 if (readendp - readp < 1)
7125 %*s*** missing DW_MACINFO_start_file argument at end of section"),
7129 get_uleb128 (u128_2, readp, readendp);
7131 /* Find the CU DIE for this file. */
7132 size_t macoff = readp - (const unsigned char *) data->d_buf;
7133 const char *fname = "???";
7134 if (macoff >= cus[0].offset)
7136 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
7139 if (cus[0].files == NULL
7140 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7141 cus[0].files = (Dwarf_Files *) -1l;
7143 if (cus[0].files != (Dwarf_Files *) -1l)
7144 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7148 printf ("%*sstart_file %u, [%u] %s\n",
7149 level, "", u128, u128_2, fname);
7153 case DW_MACINFO_end_file:
7155 printf ("%*send_file\n", level, "");
7156 /* Nothing more to do. */
7160 // XXX gcc seems to generate files with a trailing zero.
7161 if (unlikely (opcode != 0 || readp != readendp))
7162 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7170 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7171 Ebl *ebl, GElf_Ehdr *ehdr,
7172 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7175 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7176 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7177 (uint64_t) shdr->sh_offset);
7178 putc_unlocked ('\n', stdout);
7180 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7181 if (unlikely (data == NULL || data->d_buf == NULL))
7183 error (0, 0, gettext ("cannot get macro information section data: %s"),
7188 /* Get the source file information for all CUs. Uses same
7189 datastructure as macinfo. But uses offset field to directly
7190 match .debug_line offset. And just stored in a list. */
7194 struct mac_culist *culist = NULL;
7196 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7199 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7202 Dwarf_Attribute attr;
7203 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7207 if (dwarf_formudata (&attr, &lineoff) != 0)
7210 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7212 newp->offset = lineoff;
7214 newp->next = culist;
7219 const unsigned char *readp = (const unsigned char *) data->d_buf;
7220 const unsigned char *readendp = readp + data->d_size;
7222 while (readp < readendp)
7224 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7225 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7227 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7228 // optional vendor extension macro entry table.
7229 if (readp + 2 > readendp)
7232 error (0, 0, gettext ("invalid data"));
7235 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7236 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7238 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7239 // 5 when it gets standardized.
7242 printf (gettext (" unknown version, cannot parse section\n"));
7246 if (readp + 1 > readendp)
7248 const unsigned char flag = *readp++;
7249 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7251 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7252 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7253 Dwarf_Off line_offset = -1;
7256 if (offset_len == 8)
7257 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7259 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7260 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7264 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7265 memset (vendor, 0, sizeof vendor);
7268 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7269 // of arguments, for each argument 1 byte form code.
7270 if (readp + 1 > readendp)
7272 unsigned int tlen = *readp++;
7273 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7275 for (unsigned int i = 0; i < tlen; i++)
7277 if (readp + 1 > readendp)
7279 unsigned int opcode = *readp++;
7280 printf (gettext (" [%" PRIx8 "]"), opcode);
7281 if (opcode < DW_MACRO_GNU_lo_user
7282 || opcode > DW_MACRO_GNU_hi_user)
7284 // Record the start of description for this vendor opcode.
7285 // uleb128 nr args, 1 byte per arg form.
7286 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7287 if (readp + 1 > readendp)
7289 unsigned int args = *readp++;
7292 printf (gettext (" %" PRIu8 " arguments:"), args);
7295 if (readp + 1 > readendp)
7297 unsigned int form = *readp++;
7298 printf (" %s", dwarf_form_string (form));
7299 if (form != DW_FORM_data1
7300 && form != DW_FORM_data2
7301 && form != DW_FORM_data4
7302 && form != DW_FORM_data8
7303 && form != DW_FORM_sdata
7304 && form != DW_FORM_udata
7305 && form != DW_FORM_block
7306 && form != DW_FORM_block1
7307 && form != DW_FORM_block2
7308 && form != DW_FORM_block4
7309 && form != DW_FORM_flag
7310 && form != DW_FORM_string
7311 && form != DW_FORM_strp
7312 && form != DW_FORM_sec_offset)
7316 putchar_unlocked (',');
7320 printf (gettext (" no arguments."));
7321 putchar_unlocked ('\n');
7324 putchar_unlocked ('\n');
7327 if (readp + 1 > readendp)
7329 unsigned int opcode = *readp++;
7333 unsigned int u128_2;
7334 const unsigned char *endp;
7339 case DW_MACRO_GNU_start_file:
7340 get_uleb128 (u128, readp, readendp);
7341 if (readp >= readendp)
7343 get_uleb128 (u128_2, readp, readendp);
7345 /* Find the CU DIE that matches this line offset. */
7346 const char *fname = "???";
7347 if (line_offset != (Dwarf_Off) -1)
7349 struct mac_culist *cu = culist;
7350 while (cu != NULL && line_offset != cu->offset)
7354 if (cu->files == NULL
7355 && dwarf_getsrcfiles (&cu->die, &cu->files,
7357 cu->files = (Dwarf_Files *) -1l;
7359 if (cu->files != (Dwarf_Files *) -1l)
7360 fname = (dwarf_filesrc (cu->files, u128_2,
7361 NULL, NULL) ?: "???");
7364 printf ("%*sstart_file %u, [%u] %s\n",
7365 level, "", u128, u128_2, fname);
7369 case DW_MACRO_GNU_end_file:
7371 printf ("%*send_file\n", level, "");
7374 case DW_MACRO_GNU_define:
7375 get_uleb128 (u128, readp, readendp);
7376 endp = memchr (readp, '\0', readendp - readp);
7379 printf ("%*s#define %s, line %u\n",
7380 level, "", readp, u128);
7384 case DW_MACRO_GNU_undef:
7385 get_uleb128 (u128, readp, readendp);
7386 endp = memchr (readp, '\0', readendp - readp);
7389 printf ("%*s#undef %s, line %u\n",
7390 level, "", readp, u128);
7394 case DW_MACRO_GNU_define_indirect:
7395 get_uleb128 (u128, readp, readendp);
7396 if (readp + offset_len > readendp)
7398 if (offset_len == 8)
7399 off = read_8ubyte_unaligned_inc (dbg, readp);
7401 off = read_4ubyte_unaligned_inc (dbg, readp);
7402 printf ("%*s#define %s, line %u (indirect)\n",
7403 level, "", dwarf_getstring (dbg, off, NULL), u128);
7406 case DW_MACRO_GNU_undef_indirect:
7407 get_uleb128 (u128, readp, readendp);
7408 if (readp + offset_len > readendp)
7410 if (offset_len == 8)
7411 off = read_8ubyte_unaligned_inc (dbg, readp);
7413 off = read_4ubyte_unaligned_inc (dbg, readp);
7414 printf ("%*s#undef %s, line %u (indirect)\n",
7415 level, "", dwarf_getstring (dbg, off, NULL), u128);
7418 case DW_MACRO_GNU_transparent_include:
7419 if (readp + offset_len > readendp)
7421 if (offset_len == 8)
7422 off = read_8ubyte_unaligned_inc (dbg, readp);
7424 off = read_4ubyte_unaligned_inc (dbg, readp);
7425 printf ("%*s#include offset 0x%" PRIx64 "\n",
7430 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7431 if (opcode < DW_MACRO_GNU_lo_user
7432 || opcode > DW_MACRO_GNU_lo_user
7433 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7436 const unsigned char *op_desc;
7437 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7439 // Just skip the arguments, we cannot really interpret them,
7440 // but print as much as we can.
7441 unsigned int args = *op_desc++;
7444 unsigned int form = *op_desc++;
7449 if (readp + 1 > readendp)
7452 printf (" %" PRIx8, (unsigned int) val);
7456 if (readp + 2 > readendp)
7458 val = read_2ubyte_unaligned_inc (dbg, readp);
7459 printf(" %" PRIx16, (unsigned int) val);
7463 if (readp + 4 > readendp)
7465 val = read_4ubyte_unaligned_inc (dbg, readp);
7466 printf (" %" PRIx32, (unsigned int) val);
7470 if (readp + 8 > readendp)
7472 val = read_8ubyte_unaligned_inc (dbg, readp);
7473 printf (" %" PRIx64, val);
7477 get_sleb128 (val, readp, readendp);
7478 printf (" %" PRIx64, val);
7482 get_uleb128 (val, readp, readendp);
7483 printf (" %" PRIx64, val);
7487 get_uleb128 (val, readp, readendp);
7488 printf (" block[%" PRIu64 "]", val);
7489 if (readp + val > readendp)
7494 case DW_FORM_block1:
7495 if (readp + 1 > readendp)
7498 printf (" block[%" PRIu64 "]", val);
7499 if (readp + val > readendp)
7503 case DW_FORM_block2:
7504 if (readp + 2 > readendp)
7506 val = read_2ubyte_unaligned_inc (dbg, readp);
7507 printf (" block[%" PRIu64 "]", val);
7508 if (readp + val > readendp)
7512 case DW_FORM_block4:
7513 if (readp + 2 > readendp)
7515 val =read_4ubyte_unaligned_inc (dbg, readp);
7516 printf (" block[%" PRIu64 "]", val);
7517 if (readp + val > readendp)
7522 if (readp + 1 > readendp)
7525 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7528 case DW_FORM_string:
7529 endp = memchr (readp, '\0', readendp - readp);
7532 printf (" %s", readp);
7537 if (readp + offset_len > readendp)
7539 if (offset_len == 8)
7540 val = read_8ubyte_unaligned_inc (dbg, readp);
7542 val = read_4ubyte_unaligned_inc (dbg, readp);
7543 printf (" %s", dwarf_getstring (dbg, val, NULL));
7546 case DW_FORM_sec_offset:
7547 if (readp + offset_len > readendp)
7549 if (offset_len == 8)
7550 val = read_8ubyte_unaligned_inc (dbg, readp);
7552 val = read_4ubyte_unaligned_inc (dbg, readp);
7553 printf (" %" PRIx64, val);
7557 error (0, 0, gettext ("vendor opcode not verified?"));
7563 putchar_unlocked (',');
7565 putchar_unlocked ('\n');
7568 if (readp + 1 > readendp)
7572 putchar_unlocked ('\n');
7578 /* Callback for printing global names. */
7580 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7583 int *np = (int *) arg;
7585 printf (gettext (" [%5d] DIE offset: %6" PRId64
7586 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7587 (*np)++, global->die_offset, global->cu_offset, global->name);
7593 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7595 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7596 Ebl *ebl, GElf_Ehdr *ehdr,
7597 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7599 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7600 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7601 (uint64_t) shdr->sh_offset);
7604 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7607 /* Print the content of the DWARF string section '.debug_str'. */
7609 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7610 Ebl *ebl, GElf_Ehdr *ehdr,
7611 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7613 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7614 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7616 /* Compute floor(log16(shdr->sh_size)). */
7617 GElf_Addr tmp = sh_size;
7624 digits = MAX (4, digits);
7626 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7629 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7630 /* TRANS: the debugstr| prefix makes the string unique. */
7631 digits + 2, sgettext ("debugstr|Offset"));
7633 Dwarf_Off offset = 0;
7634 while (offset < sh_size)
7637 const char *str = dwarf_getstring (dbg, offset, &len);
7638 if (unlikely (str == NULL))
7640 printf (gettext (" *** error while reading strings: %s\n"),
7645 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7652 /* Print the content of the call frame search table section
7655 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7656 Ebl *ebl __attribute__ ((unused)),
7657 GElf_Ehdr *ehdr __attribute__ ((unused)),
7658 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7661 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7664 Elf_Data *data = elf_rawdata (scn, NULL);
7666 if (unlikely (data == NULL))
7668 error (0, 0, gettext ("cannot get %s content: %s"),
7669 ".eh_frame_hdr", elf_errmsg (-1));
7673 const unsigned char *readp = data->d_buf;
7674 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7677 if (unlikely (readp + 4 > dataend))
7680 error (0, 0, gettext ("invalid data"));
7684 unsigned int version = *readp++;
7685 unsigned int eh_frame_ptr_enc = *readp++;
7686 unsigned int fde_count_enc = *readp++;
7687 unsigned int table_enc = *readp++;
7689 printf (" version: %u\n"
7690 " eh_frame_ptr_enc: %#x ",
7691 version, eh_frame_ptr_enc);
7692 print_encoding_base ("", eh_frame_ptr_enc);
7693 printf (" fde_count_enc: %#x ", fde_count_enc);
7694 print_encoding_base ("", fde_count_enc);
7695 printf (" table_enc: %#x ", table_enc);
7696 print_encoding_base ("", table_enc);
7698 uint64_t eh_frame_ptr = 0;
7699 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7701 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7703 if (unlikely (readp == NULL))
7706 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7707 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7708 printf (" (offset: %#" PRIx64 ")",
7709 /* +4 because of the 4 byte header of the section. */
7710 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7712 putchar_unlocked ('\n');
7715 uint64_t fde_count = 0;
7716 if (fde_count_enc != DW_EH_PE_omit)
7718 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7719 if (unlikely (readp == NULL))
7722 printf (" fde_count: %" PRIu64 "\n", fde_count);
7725 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7730 /* Optimize for the most common case. */
7731 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7732 while (fde_count > 0 && readp + 8 <= dataend)
7734 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7735 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7736 + (int64_t) initial_location);
7737 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7738 // XXX Possibly print symbol name or section offset for initial_offset
7739 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7740 " fde=[%6" PRIx64 "]\n",
7741 initial_location, initial_offset,
7742 address, address - (eh_frame_ptr + 4));
7745 while (0 && readp < dataend)
7752 /* Print the content of the exception handling table section
7755 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7756 Ebl *ebl __attribute__ ((unused)),
7757 GElf_Ehdr *ehdr __attribute__ ((unused)),
7759 GElf_Shdr *shdr __attribute__ ((unused)),
7760 Dwarf *dbg __attribute__ ((unused)))
7763 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7766 Elf_Data *data = elf_rawdata (scn, NULL);
7768 if (unlikely (data == NULL))
7770 error (0, 0, gettext ("cannot get %s content: %s"),
7771 ".gcc_except_table", elf_errmsg (-1));
7775 const unsigned char *readp = data->d_buf;
7776 const unsigned char *const dataend = readp + data->d_size;
7778 if (unlikely (readp + 1 > dataend))
7781 error (0, 0, gettext ("invalid data"));
7784 unsigned int lpstart_encoding = *readp++;
7785 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7786 print_encoding_base ("", lpstart_encoding);
7787 if (lpstart_encoding != DW_EH_PE_omit)
7790 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7791 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7794 if (unlikely (readp + 1 > dataend))
7796 unsigned int ttype_encoding = *readp++;
7797 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7798 print_encoding_base ("", ttype_encoding);
7799 const unsigned char *ttype_base = NULL;
7800 if (ttype_encoding != DW_EH_PE_omit)
7802 unsigned int ttype_base_offset;
7803 get_uleb128 (ttype_base_offset, readp, dataend);
7804 printf (" TType base offset: %#x\n", ttype_base_offset);
7805 if ((size_t) (dataend - readp) > ttype_base_offset)
7806 ttype_base = readp + ttype_base_offset;
7809 if (unlikely (readp + 1 > dataend))
7811 unsigned int call_site_encoding = *readp++;
7812 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7813 print_encoding_base ("", call_site_encoding);
7814 unsigned int call_site_table_len;
7815 get_uleb128 (call_site_table_len, readp, dataend);
7817 const unsigned char *const action_table = readp + call_site_table_len;
7818 if (unlikely (action_table > dataend))
7821 unsigned int max_action = 0;
7822 while (readp < action_table)
7825 puts (gettext ("\n Call site table:"));
7827 uint64_t call_site_start;
7828 readp = read_encoded (call_site_encoding, readp, dataend,
7829 &call_site_start, dbg);
7830 uint64_t call_site_length;
7831 readp = read_encoded (call_site_encoding, readp, dataend,
7832 &call_site_length, dbg);
7833 uint64_t landing_pad;
7834 readp = read_encoded (call_site_encoding, readp, dataend,
7836 unsigned int action;
7837 get_uleb128 (action, readp, dataend);
7838 max_action = MAX (action, max_action);
7839 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7840 " Call site length: %" PRIu64 "\n"
7841 " Landing pad: %#" PRIx64 "\n"
7843 u++, call_site_start, call_site_length, landing_pad, action);
7845 if (readp != action_table)
7848 unsigned int max_ar_filter = 0;
7851 puts ("\n Action table:");
7853 size_t maxdata = (size_t) (dataend - action_table);
7854 if (max_action > maxdata || maxdata - max_action < 1)
7856 invalid_action_table:
7857 fputs (gettext (" <INVALID DATA>\n"), stdout);
7861 const unsigned char *const action_table_end
7862 = action_table + max_action + 1;
7868 get_sleb128 (ar_filter, readp, action_table_end);
7869 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7870 max_ar_filter = ar_filter;
7872 if (readp >= action_table_end)
7873 goto invalid_action_table;
7874 get_sleb128 (ar_disp, readp, action_table_end);
7876 printf (" [%4u] ar_filter: % d\n"
7878 u, ar_filter, ar_disp);
7879 if (abs (ar_disp) & 1)
7880 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7881 else if (ar_disp != 0)
7884 putchar_unlocked ('\n');
7887 while (readp < action_table_end);
7890 if (max_ar_filter > 0 && ttype_base != NULL)
7892 unsigned char dsize;
7893 puts ("\n TType table:");
7895 // XXX Not *4, size of encoding;
7896 switch (ttype_encoding & 7)
7898 case DW_EH_PE_udata2:
7899 case DW_EH_PE_sdata2:
7902 case DW_EH_PE_udata4:
7903 case DW_EH_PE_sdata4:
7906 case DW_EH_PE_udata8:
7907 case DW_EH_PE_sdata8:
7911 error (1, 0, gettext ("invalid TType encoding"));
7915 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
7918 readp = ttype_base - max_ar_filter * dsize;
7922 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7924 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7926 while (readp < ttype_base);
7930 /* Print the content of the '.gdb_index' section.
7931 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7934 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7935 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7937 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7938 " contains %" PRId64 " bytes :\n"),
7939 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7940 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7942 Elf_Data *data = elf_rawdata (scn, NULL);
7944 if (unlikely (data == NULL))
7946 error (0, 0, gettext ("cannot get %s content: %s"),
7947 ".gdb_index", elf_errmsg (-1));
7951 // .gdb_index is always in little endian.
7952 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7955 const unsigned char *readp = data->d_buf;
7956 const unsigned char *const dataend = readp + data->d_size;
7958 if (unlikely (readp + 4 > dataend))
7961 error (0, 0, gettext ("invalid data"));
7965 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7966 printf (gettext (" Version: %" PRId32 "\n"), vers);
7968 // The only difference between version 4 and version 5 is the
7969 // hash used for generating the table. Version 6 contains symbols
7970 // for inlined functions, older versions didn't. Version 7 adds
7971 // symbol kinds. Version 8 just indicates that it correctly includes
7973 if (vers < 4 || vers > 8)
7975 printf (gettext (" unknown version, cannot parse section\n"));
7980 if (unlikely (readp + 4 > dataend))
7983 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7984 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7987 if (unlikely (readp + 4 > dataend))
7990 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7991 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7994 if (unlikely (readp + 4 > dataend))
7997 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7998 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
8001 if (unlikely (readp + 4 > dataend))
8004 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8005 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
8008 if (unlikely (readp + 4 > dataend))
8011 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8012 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8014 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
8018 readp = data->d_buf + cu_off;
8020 const unsigned char *nextp = data->d_buf + tu_off;
8021 if (tu_off >= data->d_size)
8024 size_t cu_nr = (nextp - readp) / 16;
8026 printf (gettext ("\n CU list at offset %#" PRIx32
8027 " contains %zu entries:\n"),
8031 while (dataend - readp >= 16 && n < cu_nr)
8033 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8036 uint64_t len = read_8ubyte_unaligned (dbg, readp);
8039 printf (" [%4zu] start: %0#8" PRIx64
8040 ", length: %5" PRIu64 "\n", n, off, len);
8044 readp = data->d_buf + tu_off;
8045 nextp = data->d_buf + addr_off;
8046 if (addr_off >= data->d_size)
8049 size_t tu_nr = (nextp - readp) / 24;
8051 printf (gettext ("\n TU list at offset %#" PRIx32
8052 " contains %zu entries:\n"),
8056 while (dataend - readp >= 24 && n < tu_nr)
8058 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8061 uint64_t type = read_8ubyte_unaligned (dbg, readp);
8064 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8067 printf (" [%4zu] CU offset: %5" PRId64
8068 ", type offset: %5" PRId64
8069 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8073 readp = data->d_buf + addr_off;
8074 nextp = data->d_buf + sym_off;
8075 if (sym_off >= data->d_size)
8078 size_t addr_nr = (nextp - readp) / 20;
8080 printf (gettext ("\n Address list at offset %#" PRIx32
8081 " contains %zu entries:\n"),
8085 while (dataend - readp >= 20 && n < addr_nr)
8087 uint64_t low = read_8ubyte_unaligned (dbg, readp);
8090 uint64_t high = read_8ubyte_unaligned (dbg, readp);
8093 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8096 char *l = format_dwarf_addr (dwflmod, 8, low, low);
8097 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8098 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8105 const unsigned char *const_start = data->d_buf + const_off;
8106 if (const_off >= data->d_size)
8109 readp = data->d_buf + sym_off;
8110 nextp = const_start;
8111 size_t sym_nr = (nextp - readp) / 8;
8113 printf (gettext ("\n Symbol table at offset %#" PRIx32
8114 " contains %zu slots:\n"),
8118 while (dataend - readp >= 8 && n < sym_nr)
8120 uint32_t name = read_4ubyte_unaligned (dbg, readp);
8123 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8126 if (name != 0 || vector != 0)
8128 const unsigned char *sym = const_start + name;
8129 if (unlikely ((size_t) (dataend - const_start) < name
8130 || memchr (sym, '\0', dataend - sym) == NULL))
8133 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8135 const unsigned char *readcus = const_start + vector;
8136 if (unlikely ((size_t) (dataend - const_start) < vector))
8138 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8141 uint32_t cu_kind, cu, kind;
8144 if (unlikely (readcus + 4 > dataend))
8146 cu_kind = read_4ubyte_unaligned (dbg, readcus);
8147 cu = cu_kind & ((1 << 24) - 1);
8148 kind = (cu_kind >> 28) & 7;
8149 is_static = cu_kind & (1U << 31);
8151 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8153 printf ("%" PRId32, cu);
8172 printf ("unknown-0x%" PRIx32, kind);
8175 printf (":%c)", (is_static ? 'S' : 'G'));
8187 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8189 /* Before we start the real work get a debug context descriptor. */
8191 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8195 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8199 if ((print_debug_sections & ~section_exception) != 0)
8200 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8205 /* Get the section header string table index. */
8207 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8208 error (EXIT_FAILURE, 0,
8209 gettext ("cannot get section header string table index"));
8211 /* Look through all the sections for the debugging sections to print. */
8212 Elf_Scn *scn = NULL;
8213 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8216 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8218 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8223 enum section_e bitmask;
8224 void (*fp) (Dwfl_Module *, Ebl *,
8225 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8226 } debug_sections[] =
8228 #define NEW_SECTION(name) \
8229 { ".debug_" #name, section_##name, print_debug_##name##_section }
8230 NEW_SECTION (abbrev),
8231 NEW_SECTION (aranges),
8232 NEW_SECTION (frame),
8234 NEW_SECTION (types),
8237 NEW_SECTION (pubnames),
8239 NEW_SECTION (macinfo),
8240 NEW_SECTION (macro),
8241 NEW_SECTION (ranges),
8242 { ".eh_frame", section_frame | section_exception,
8243 print_debug_frame_section },
8244 { ".eh_frame_hdr", section_frame | section_exception,
8245 print_debug_frame_hdr_section },
8246 { ".gcc_except_table", section_frame | section_exception,
8247 print_debug_exception_table },
8248 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8250 const int ndebug_sections = (sizeof (debug_sections)
8251 / sizeof (debug_sections[0]));
8252 const char *name = elf_strptr (ebl->elf, shstrndx,
8258 for (n = 0; n < ndebug_sections; ++n)
8259 if (strcmp (name, debug_sections[n].name) == 0
8261 || (name[0] == '.' && name[1] == 'z'
8262 && debug_sections[n].name[1] == 'd'
8263 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8267 if ((print_debug_sections | implicit_debug_sections)
8268 & debug_sections[n].bitmask)
8269 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8275 reset_listptr (&known_loclistptr);
8276 reset_listptr (&known_rangelistptr);
8280 #define ITEM_INDENT 4
8281 #define WRAP_COLUMN 75
8283 /* Print "NAME: FORMAT", wrapping when output text would make the line
8284 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8285 but this function is also used for registers which should be printed
8286 aligned. Fortunately registers output uses fixed fields width (such
8287 as %11d) for the alignment.
8289 Line breaks should not depend on the particular values although that
8290 may happen in some cases of the core items. */
8293 __attribute__ ((format (printf, 6, 7)))
8294 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8295 size_t name_width, const char *name, const char *format, ...)
8297 size_t len = strlen (name);
8298 if (name_width < len)
8303 va_start (ap, format);
8304 int out_len = vasprintf (&out, format, ap);
8307 error (EXIT_FAILURE, 0, _("memory exhausted"));
8309 size_t n = name_width + sizeof ": " - 1 + out_len;
8313 printf ("%*s", ITEM_INDENT, "");
8314 colno = ITEM_INDENT + n;
8316 else if (colno + 2 + n < wrap)
8318 printf ("%c ", sep);
8323 printf ("\n%*s", ITEM_INDENT, "");
8324 colno = ITEM_INDENT + n;
8327 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8335 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8336 void *value, const void *data, size_t size)
8338 Elf_Data valuedata =
8342 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8343 .d_version = EV_CURRENT,
8348 .d_buf = (void *) data,
8349 .d_size = valuedata.d_size,
8350 .d_version = EV_CURRENT,
8353 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8354 ? elf32_xlatetom : elf64_xlatetom)
8355 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8357 error (EXIT_FAILURE, 0,
8358 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8360 return data + indata.d_size;
8363 typedef uint8_t GElf_Byte;
8366 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8367 unsigned int colno, size_t *repeated_size)
8369 uint_fast16_t count = item->count ?: 1;
8372 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8373 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8374 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8375 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8376 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8377 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8379 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8380 union { TYPES; } value;
8383 void *data = &value;
8384 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8385 size_t convsize = size;
8386 if (repeated_size != NULL)
8388 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8390 data = alloca (*repeated_size);
8391 count *= *repeated_size / size;
8392 convsize = count * size;
8393 *repeated_size -= convsize;
8395 else if (item->count != 0 || item->format != '\n')
8396 *repeated_size -= size;
8399 convert (core, item->type, count, data, desc + item->offset, convsize);
8401 Elf_Type type = item->type;
8402 if (type == ELF_T_ADDR)
8403 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8405 switch (item->format)
8408 assert (count == 1);
8411 #define DO_TYPE(NAME, Name, hex, dec) \
8412 case ELF_T_##NAME: \
8413 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8414 0, item->name, dec, value.Name[0]); \
8424 assert (count == 1);
8427 #define DO_TYPE(NAME, Name, hex, dec) \
8428 case ELF_T_##NAME: \
8429 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8430 0, item->name, hex, value.Name[0]); \
8441 assert (size % sizeof (unsigned int) == 0);
8442 unsigned int nbits = count * size * 8;
8443 unsigned int pop = 0;
8444 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8445 pop += __builtin_popcount (*i);
8446 bool negate = pop > nbits / 2;
8447 const unsigned int bias = item->format == 'b';
8450 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8454 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8456 assert (size == sizeof (unsigned int) * 2);
8457 for (unsigned int *i = data;
8458 (void *) i < data + count * size; i += 2)
8460 unsigned int w = i[1];
8466 unsigned int lastbit = 0;
8467 unsigned int run = 0;
8468 for (const unsigned int *i = data;
8469 (void *) i < data + count * size; ++i)
8471 unsigned int bit = ((void *) i - data) * 8;
8472 unsigned int w = negate ? ~*i : *i;
8479 if (lastbit != 0 && lastbit + 1 == bit)
8484 p += sprintf (p, "%u", bit - bias);
8486 p += sprintf (p, ",%u", bit - bias);
8488 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8495 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8496 p += sprintf (p, "-%u", lastbit - bias);
8498 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8499 negate ? "~<%s>" : "<%s>", printed);
8504 case (char) ('T'|0x80):
8505 assert (count == 2);
8510 #define DO_TYPE(NAME, Name, hex, dec) \
8511 case ELF_T_##NAME: \
8512 sec = value.Name[0]; \
8513 usec = value.Name[1]; \
8520 if (unlikely (item->format == (char) ('T'|0x80)))
8522 /* This is a hack for an ill-considered 64-bit ABI where
8523 tv_usec is actually a 32-bit field with 32 bits of padding
8524 rounding out struct timeval. We've already converted it as
8525 a 64-bit field. For little-endian, this just means the
8526 high half is the padding; it's presumably zero, but should
8527 be ignored anyway. For big-endian, it means the 32-bit
8528 field went into the high half of USEC. */
8530 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8531 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8536 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8537 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8541 assert (count == 1);
8542 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8543 "%c", value.Byte[0]);
8547 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8548 "%.*s", (int) count, value.Byte);
8552 /* This is a list of strings separated by '\n'. */
8553 assert (item->count == 0);
8554 assert (repeated_size != NULL);
8555 assert (item->name == NULL);
8556 if (unlikely (item->offset >= *repeated_size))
8559 const char *s = desc + item->offset;
8560 size = *repeated_size - item->offset;
8564 const char *eol = memchr (s, '\n', size);
8568 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8571 size -= eol + 1 - s;
8575 colno = WRAP_COLUMN;
8582 error (0, 0, "XXX not handling format '%c' for %s",
8583 item->format, item->name);
8593 /* Sort items by group, and by layout offset within each group. */
8595 compare_core_items (const void *a, const void *b)
8597 const Ebl_Core_Item *const *p1 = a;
8598 const Ebl_Core_Item *const *p2 = b;
8599 const Ebl_Core_Item *item1 = *p1;
8600 const Ebl_Core_Item *item2 = *p2;
8602 return ((item1->group == item2->group ? 0
8603 : strcmp (item1->group, item2->group))
8604 ?: (int) item1->offset - (int) item2->offset);
8607 /* Sort item groups by layout offset of the first item in the group. */
8609 compare_core_item_groups (const void *a, const void *b)
8611 const Ebl_Core_Item *const *const *p1 = a;
8612 const Ebl_Core_Item *const *const *p2 = b;
8613 const Ebl_Core_Item *const *group1 = *p1;
8614 const Ebl_Core_Item *const *group2 = *p2;
8615 const Ebl_Core_Item *item1 = *group1;
8616 const Ebl_Core_Item *item2 = *group2;
8618 return (int) item1->offset - (int) item2->offset;
8622 handle_core_items (Elf *core, const void *desc, size_t descsz,
8623 const Ebl_Core_Item *items, size_t nitems)
8627 unsigned int colno = 0;
8629 /* FORMAT '\n' makes sense to be present only as a single item as it
8630 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8631 if present as a single item but they can be also processed with other
8633 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8634 || items[0].format == 'B'))
8636 assert (items[0].offset == 0);
8637 size_t size = descsz;
8638 colno = handle_core_item (core, items, desc, colno, &size);
8639 /* If SIZE is not zero here there is some remaining data. But we do not
8640 know how to process it anyway. */
8643 for (size_t i = 0; i < nitems; ++i)
8644 assert (items[i].format != '\n');
8646 /* Sort to collect the groups together. */
8647 const Ebl_Core_Item *sorted_items[nitems];
8648 for (size_t i = 0; i < nitems; ++i)
8649 sorted_items[i] = &items[i];
8650 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8652 /* Collect the unique groups and sort them. */
8653 const Ebl_Core_Item **groups[nitems];
8654 groups[0] = &sorted_items[0];
8656 for (size_t i = 1; i < nitems; ++i)
8657 if (sorted_items[i]->group != sorted_items[i - 1]->group
8658 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8659 groups[ngroups++] = &sorted_items[i];
8660 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8662 /* Write out all the groups. */
8663 const void *last = desc;
8666 for (size_t i = 0; i < ngroups; ++i)
8668 for (const Ebl_Core_Item **item = groups[i];
8669 (item < &sorted_items[nitems]
8670 && ((*item)->group == groups[i][0]->group
8671 || !strcmp ((*item)->group, groups[i][0]->group)));
8673 colno = handle_core_item (core, *item, desc, colno, NULL);
8675 /* Force a line break at the end of the group. */
8676 colno = WRAP_COLUMN;
8682 /* This set of items consumed a certain amount of the note's data.
8683 If there is more data there, we have another unit of the same size.
8684 Loop to print that out too. */
8685 const Ebl_Core_Item *item = &items[nitems - 1];
8686 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8687 item->count ?: 1, EV_CURRENT);
8696 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8700 /* For just one repeat, print it unabridged twice. */
8705 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8706 ITEM_INDENT, "", reps);
8716 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8719 desc += regloc->offset;
8727 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8728 const Ebl_Register_Location *regloc, const void *desc,
8731 if (regloc->bits % 8 != 0)
8732 return handle_bit_registers (regloc, desc, colno);
8734 desc += regloc->offset;
8736 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8738 char name[REGNAMESZ];
8741 register_info (ebl, reg, regloc, name, &bits, &type);
8744 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8745 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8746 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8747 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8749 #define BITS(bits, xtype, sfmt, ufmt) \
8750 uint##bits##_t b##bits; int##bits##_t b##bits##s
8751 union { TYPES; uint64_t b128[2]; } value;
8756 case DW_ATE_unsigned:
8758 case DW_ATE_address:
8761 #define BITS(bits, xtype, sfmt, ufmt) \
8763 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8764 if (type == DW_ATE_signed) \
8765 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8767 sfmt, value.b##bits##s); \
8769 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8771 ufmt, value.b##bits); \
8777 assert (type == DW_ATE_unsigned);
8778 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8779 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8780 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8782 "0x%.16" PRIx64 "%.16" PRIx64,
8783 value.b128[!be], value.b128[be]);
8793 /* Print each byte in hex, the whole thing in native byte order. */
8794 assert (bits % 8 == 0);
8795 const uint8_t *bytes = desc;
8797 char hex[bits / 4 + 1];
8798 hex[bits / 4] = '\0';
8800 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8802 bytes += bits / 8 - 1;
8806 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8808 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8809 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8811 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8812 maxregname, name, "0x%s", hex);
8815 desc += regloc->pad;
8824 struct register_info
8826 const Ebl_Register_Location *regloc;
8828 char name[REGNAMESZ];
8835 register_bitpos (const struct register_info *r)
8837 return (r->regloc->offset * 8
8838 + ((r->regno - r->regloc->regno)
8839 * (r->regloc->bits + r->regloc->pad * 8)));
8843 compare_sets_by_info (const struct register_info *r1,
8844 const struct register_info *r2)
8846 return ((int) r2->bits - (int) r1->bits
8847 ?: register_bitpos (r1) - register_bitpos (r2));
8850 /* Sort registers by set, and by size and layout offset within each set. */
8852 compare_registers (const void *a, const void *b)
8854 const struct register_info *r1 = a;
8855 const struct register_info *r2 = b;
8857 /* Unused elements sort last. */
8858 if (r1->regloc == NULL)
8859 return r2->regloc == NULL ? 0 : 1;
8860 if (r2->regloc == NULL)
8863 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8864 ?: compare_sets_by_info (r1, r2));
8867 /* Sort register sets by layout offset of the first register in the set. */
8869 compare_register_sets (const void *a, const void *b)
8871 const struct register_info *const *p1 = a;
8872 const struct register_info *const *p2 = b;
8873 return compare_sets_by_info (*p1, *p2);
8877 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8878 const Ebl_Register_Location *reglocs, size_t nregloc)
8883 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8886 for (size_t i = 0; i < nregloc; ++i)
8887 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8888 maxnreg = reglocs[i].regno + reglocs[i].count;
8889 assert (maxnreg > 0);
8892 struct register_info regs[maxnreg];
8893 memset (regs, 0, sizeof regs);
8895 /* Sort to collect the sets together. */
8897 for (size_t i = 0; i < nregloc; ++i)
8898 for (int reg = reglocs[i].regno;
8899 reg < reglocs[i].regno + reglocs[i].count;
8902 assert (reg < maxnreg);
8905 struct register_info *info = ®s[reg];
8906 info->regloc = ®locs[i];
8908 info->set = register_info (ebl, reg, ®locs[i],
8909 info->name, &info->bits, &info->type);
8911 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8913 /* Collect the unique sets and sort them. */
8914 inline bool same_set (const struct register_info *a,
8915 const struct register_info *b)
8917 return (a < ®s[maxnreg] && a->regloc != NULL
8918 && b < ®s[maxnreg] && b->regloc != NULL
8919 && a->bits == b->bits
8920 && (a->set == b->set || !strcmp (a->set, b->set)));
8922 struct register_info *sets[maxreg + 1];
8925 for (int i = 1; i <= maxreg; ++i)
8926 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8927 sets[nsets++] = ®s[i];
8928 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8930 /* Write out all the sets. */
8931 unsigned int colno = 0;
8932 for (size_t i = 0; i < nsets; ++i)
8934 /* Find the longest name of a register in this set. */
8936 const struct register_info *end;
8937 for (end = sets[i]; same_set (sets[i], end); ++end)
8939 size_t len = strlen (end->name);
8944 for (const struct register_info *reg = sets[i];
8946 reg += reg->regloc->count ?: 1)
8947 colno = handle_core_register (ebl, core, maxname,
8948 reg->regloc, desc, colno);
8950 /* Force a line break at the end of the group. */
8951 colno = WRAP_COLUMN;
8958 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8960 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8963 error (EXIT_FAILURE, 0,
8964 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8966 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8967 for (size_t i = 0; i < nauxv; ++i)
8970 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8976 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8979 if (av->a_un.a_val == 0)
8980 printf (" %" PRIu64 "\n", av->a_type);
8982 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8983 av->a_type, av->a_un.a_val);
8988 case '\0': /* Normally zero. */
8989 if (av->a_un.a_val == 0)
8991 printf (" %s\n", name);
8996 case 'p': /* address */
8997 case 's': /* address of string */
8998 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
9001 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
9004 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
9008 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
9010 const char *pfx = "<";
9011 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9013 if (av->a_un.a_val & bit)
9015 printf ("%s%s", pfx, p);
9030 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9032 return ptr < end && (size_t) (end - ptr) >= sz;
9036 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9039 if (! buf_has_data (*ptrp, end, 4))
9042 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9047 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9050 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9051 if (! buf_has_data (*ptrp, end, sz))
9060 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9070 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9072 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9074 error (EXIT_FAILURE, 0,
9075 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9077 unsigned char const *ptr = data->d_buf;
9078 unsigned char const *const end = data->d_buf + data->d_size;
9080 /* Siginfo head is three ints: signal number, error number, origin
9082 int si_signo, si_errno, si_code;
9083 if (! buf_read_int (core, &ptr, end, &si_signo)
9084 || ! buf_read_int (core, &ptr, end, &si_errno)
9085 || ! buf_read_int (core, &ptr, end, &si_code))
9088 printf (" Not enough data in NT_SIGINFO note.\n");
9092 /* Next is a pointer-aligned union of structures. On 64-bit
9093 machines, that implies a word of padding. */
9094 if (gelf_getclass (core) == ELFCLASS64)
9097 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
9098 si_signo, si_errno, si_code);
9109 if (! buf_read_ulong (core, &ptr, end, &addr))
9111 printf (" fault address: %#" PRIx64 "\n", addr);
9117 else if (si_code == SI_USER)
9120 if (! buf_read_int (core, &ptr, end, &pid)
9121 || ! buf_read_int (core, &ptr, end, &uid))
9123 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
9128 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9130 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9132 error (EXIT_FAILURE, 0,
9133 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9135 unsigned char const *ptr = data->d_buf;
9136 unsigned char const *const end = data->d_buf + data->d_size;
9138 uint64_t count, page_size;
9139 if (! buf_read_ulong (core, &ptr, end, &count)
9140 || ! buf_read_ulong (core, &ptr, end, &page_size))
9143 printf (" Not enough data in NT_FILE note.\n");
9147 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9148 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9149 if (count > maxcount)
9152 /* Where file names are stored. */
9153 unsigned char const *const fstart = ptr + 3 * count * addrsize;
9154 char const *fptr = (char *) fstart;
9156 printf (" %" PRId64 " files:\n", count);
9157 for (uint64_t i = 0; i < count; ++i)
9159 uint64_t mstart, mend, moffset;
9160 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9161 || ! buf_read_ulong (core, &ptr, fstart, &mend)
9162 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9165 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9169 int ct = printf (" %08" PRIx64 "-%08" PRIx64
9170 " %08" PRIx64 " %" PRId64,
9171 mstart, mend, moffset * page_size, mend - mstart);
9172 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9179 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9180 const char *name, const void *desc)
9182 GElf_Word regs_offset;
9184 const Ebl_Register_Location *reglocs;
9186 const Ebl_Core_Item *items;
9188 if (! ebl_core_note (ebl, nhdr, name,
9189 ®s_offset, &nregloc, ®locs, &nitems, &items))
9192 /* Pass 0 for DESCSZ when there are registers in the note,
9193 so that the ITEMS array does not describe the whole thing.
9194 For non-register notes, the actual descsz might be a multiple
9195 of the unit size, not just exactly the unit size. */
9196 unsigned int colno = handle_core_items (ebl->elf, desc,
9197 nregloc == 0 ? nhdr->n_descsz : 0,
9200 putchar_unlocked ('\n');
9202 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9205 putchar_unlocked ('\n');
9209 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9210 GElf_Off start, Elf_Data *data)
9212 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
9221 while (offset < data->d_size
9222 && (offset = gelf_getnote (data, offset,
9223 &nhdr, &name_offset, &desc_offset)) > 0)
9225 const char *name = data->d_buf + name_offset;
9226 const char *desc = data->d_buf + desc_offset;
9230 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
9231 (int) nhdr.n_namesz, name, nhdr.n_descsz,
9232 ehdr->e_type == ET_CORE
9233 ? ebl_core_note_type_name (ebl, nhdr.n_type,
9235 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9236 buf2, sizeof (buf2)));
9238 /* Filter out invalid entries. */
9239 if (memchr (name, '\0', nhdr.n_namesz) != NULL
9240 /* XXX For now help broken Linux kernels. */
9243 if (ehdr->e_type == ET_CORE)
9245 if (nhdr.n_type == NT_AUXV
9246 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9247 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9248 && !memcmp (name, "CORE", 4))
9249 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9250 start + desc_offset);
9251 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9252 switch (nhdr.n_type)
9255 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9256 start + desc_offset);
9260 handle_file_note (ebl->elf, nhdr.n_descsz,
9261 start + desc_offset);
9265 handle_core_note (ebl, &nhdr, name, desc);
9268 handle_core_note (ebl, &nhdr, name, desc);
9271 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9275 if (offset == data->d_size)
9279 error (EXIT_FAILURE, 0,
9280 gettext ("cannot get content of note section: %s"),
9285 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9287 /* If we have section headers, just look for SHT_NOTE sections.
9288 In a debuginfo file, the program headers are not reliable. */
9291 /* Get the section header string table index. */
9293 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9294 error (EXIT_FAILURE, 0,
9295 gettext ("cannot get section header string table index"));
9297 Elf_Scn *scn = NULL;
9298 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9301 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9303 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9304 /* Not what we are looking for. */
9308 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9310 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9311 shdr->sh_size, shdr->sh_offset);
9313 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9314 elf_getdata (scn, NULL));
9319 /* We have to look through the program header to find the note
9320 sections. There can be more than one. */
9321 for (size_t cnt = 0; cnt < phnum; ++cnt)
9324 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9326 if (phdr == NULL || phdr->p_type != PT_NOTE)
9327 /* Not what we are looking for. */
9331 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9332 phdr->p_filesz, phdr->p_offset);
9334 handle_notes_data (ebl, ehdr, phdr->p_offset,
9335 elf_getdata_rawchunk (ebl->elf,
9336 phdr->p_offset, phdr->p_filesz,
9343 hex_dump (const uint8_t *data, size_t len)
9348 printf (" 0x%08Zx ", pos);
9350 const size_t chunk = MIN (len - pos, 16);
9352 for (size_t i = 0; i < chunk; ++i)
9354 printf ("%02x ", data[pos + i]);
9356 printf ("%02x", data[pos + i]);
9359 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9361 for (size_t i = 0; i < chunk; ++i)
9363 unsigned char b = data[pos + i];
9364 printf ("%c", isprint (b) ? b : '.');
9373 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9375 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9376 printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9377 elf_ndxscn (scn), name);
9380 Elf_Data *data = elf_rawdata (scn, NULL);
9382 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9383 elf_ndxscn (scn), name, elf_errmsg (-1));
9386 printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9387 " bytes at offset %#0" PRIx64 ":\n"),
9388 elf_ndxscn (scn), name,
9389 shdr->sh_size, shdr->sh_offset);
9390 hex_dump (data->d_buf, data->d_size);
9396 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9398 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9399 printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9400 elf_ndxscn (scn), name);
9403 Elf_Data *data = elf_rawdata (scn, NULL);
9405 error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9406 elf_ndxscn (scn), name, elf_errmsg (-1));
9409 printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9410 " bytes at offset %#0" PRIx64 ":\n"),
9411 elf_ndxscn (scn), name,
9412 shdr->sh_size, shdr->sh_offset);
9414 const char *start = data->d_buf;
9415 const char *const limit = start + data->d_size;
9418 const char *end = memchr (start, '\0', limit - start);
9419 const size_t pos = start - (const char *) data->d_buf;
9420 if (unlikely (end == NULL))
9422 printf (" [%6Zx]- %.*s\n",
9423 pos, (int) (limit - start), start);
9426 printf (" [%6Zx] %s\n", pos, start);
9428 } while (start < limit);
9434 for_each_section_argument (Elf *elf, const struct section_argument *list,
9435 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9438 /* Get the section header string table index. */
9440 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9441 error (EXIT_FAILURE, 0,
9442 gettext ("cannot get section header string table index"));
9444 for (const struct section_argument *a = list; a != NULL; a = a->next)
9448 const char *name = NULL;
9451 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9452 if (endp != a->arg && *endp == '\0')
9454 scn = elf_getscn (elf, shndx);
9457 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9461 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9462 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9464 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9468 /* Need to look up the section by name. */
9471 while ((scn = elf_nextscn (elf, scn)) != NULL)
9473 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9475 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9478 if (!strcmp (name, a->arg))
9481 (*dump) (scn, &shdr_mem, name);
9485 if (unlikely (!found) && !a->implicit)
9486 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9492 dump_data (Ebl *ebl)
9494 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9498 dump_strings (Ebl *ebl)
9500 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9504 print_strings (Ebl *ebl)
9506 /* Get the section header string table index. */
9508 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9509 error (EXIT_FAILURE, 0,
9510 gettext ("cannot get section header string table index"));
9516 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9518 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9521 if (shdr_mem.sh_type != SHT_PROGBITS
9522 || !(shdr_mem.sh_flags & SHF_STRINGS))
9525 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9529 print_string_section (scn, &shdr_mem, name);
9534 dump_archive_index (Elf *elf, const char *fname)
9537 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9540 int result = elf_errno ();
9541 if (unlikely (result != ELF_E_NO_INDEX))
9542 error (EXIT_FAILURE, 0,
9543 gettext ("cannot get symbol index of archive '%s': %s"),
9544 fname, elf_errmsg (result));
9546 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9550 printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9554 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9556 if (s->as_off != as_off)
9561 if (unlikely (elf_rand (elf, as_off) == 0)
9562 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9564 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9567 error (EXIT_FAILURE, 0,
9568 gettext ("cannot extract member at offset %Zu in '%s': %s"),
9569 as_off, fname, elf_errmsg (-1));
9571 const Elf_Arhdr *h = elf_getarhdr (subelf);
9573 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9578 printf ("\t%s\n", s->as_name);
9582 #include "debugpred.h"