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_mem;
1319 GElf_Phdr *phdr2 = NULL;
1320 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
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 uint32_t *lengths = NULL;
3096 Elf_Data *data = elf_getdata (scn, NULL);
3097 if (unlikely (data == NULL))
3099 error (0, 0, gettext ("cannot get data for section %d: %s"),
3100 (int) elf_ndxscn (scn), elf_errmsg (-1));
3104 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3108 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3109 (int) elf_ndxscn (scn));
3113 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3114 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3116 /* Next comes the size of the bitmap. It's measured in words for
3117 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3118 64 bit archs. There is always a bloom filter present, so zero is
3119 an invalid value. */
3120 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3121 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3124 if (bitmask_words == 0)
3127 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3129 /* Is there still room for the sym chain?
3130 Use uint64_t calculation to prevent 32bit overlow. */
3131 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3132 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3133 if (used_buf > data->d_size)
3136 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3138 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3139 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3140 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3143 /* Compute distribution of chain lengths. */
3144 uint_fast32_t maxlength = 0;
3145 uint_fast32_t nsyms = 0;
3146 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3147 if (bucket[cnt] != 0)
3149 Elf32_Word inner = bucket[cnt] - symbias;
3153 if (maxlength < ++lengths[cnt])
3155 if (inner > max_nsyms)
3158 while ((chain[inner++] & 1) == 0);
3161 /* Count bits in bitmask. */
3162 uint_fast32_t nbits = 0;
3163 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3165 uint_fast32_t word = bitmask[cnt];
3167 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3168 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3169 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3170 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3171 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3175 if (unlikely (asprintf (&str, gettext ("\
3177 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3178 (unsigned int) symbias,
3179 bitmask_words * sizeof (Elf32_Word),
3181 / (uint_fast32_t) (bitmask_words
3182 * sizeof (Elf32_Word) * 8)),
3183 (unsigned int) shift) == -1))
3184 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3186 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3194 /* Find the symbol table(s). For this we have to search through the
3197 handle_hash (Ebl *ebl)
3199 /* Get the section header string table index. */
3201 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3202 error (EXIT_FAILURE, 0,
3203 gettext ("cannot get section header string table index"));
3205 Elf_Scn *scn = NULL;
3206 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3208 /* Handle the section if it is a symbol table. */
3210 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3212 if (likely (shdr != NULL))
3214 if (shdr->sh_type == SHT_HASH)
3216 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3217 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3219 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3221 else if (shdr->sh_type == SHT_GNU_HASH)
3222 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3229 print_liblist (Ebl *ebl)
3231 /* Find the library list sections. For this we have to search
3232 through the section table. */
3233 Elf_Scn *scn = NULL;
3235 /* Get the section header string table index. */
3237 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3238 error (EXIT_FAILURE, 0,
3239 gettext ("cannot get section header string table index"));
3241 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3244 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3246 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3248 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3249 int nentries = shdr->sh_size / sh_entsize;
3250 printf (ngettext ("\
3251 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3253 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3256 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3260 Elf_Data *data = elf_getdata (scn, NULL);
3265 Library Time Stamp Checksum Version Flags"));
3267 for (int cnt = 0; cnt < nentries; ++cnt)
3270 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3271 if (unlikely (lib == NULL))
3274 time_t t = (time_t) lib->l_time_stamp;
3275 struct tm *tm = gmtime (&t);
3276 if (unlikely (tm == NULL))
3279 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3280 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3281 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3282 tm->tm_hour, tm->tm_min, tm->tm_sec,
3283 (unsigned int) lib->l_checksum,
3284 (unsigned int) lib->l_version,
3285 (unsigned int) lib->l_flags);
3292 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3294 /* Find the object attributes sections. For this we have to search
3295 through the section table. */
3296 Elf_Scn *scn = NULL;
3298 /* Get the section header string table index. */
3300 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3301 error (EXIT_FAILURE, 0,
3302 gettext ("cannot get section header string table index"));
3304 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3307 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3309 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3310 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3311 || ehdr->e_machine != EM_ARM)))
3315 \nObject attributes section [%2zu] '%s' of %" PRIu64
3316 " bytes at offset %#0" PRIx64 ":\n"),
3318 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3319 shdr->sh_size, shdr->sh_offset);
3321 Elf_Data *data = elf_rawdata (scn, NULL);
3322 if (unlikely (data == NULL || data->d_size == 0))
3325 const unsigned char *p = data->d_buf;
3327 /* There is only one 'version', A. */
3328 if (unlikely (*p++ != 'A'))
3331 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3333 inline size_t left (void)
3335 return (const unsigned char *) data->d_buf + data->d_size - p;
3338 /* Loop over the sections. */
3339 while (left () >= 4)
3341 /* Section length. */
3343 memcpy (&len, p, sizeof len);
3345 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3348 if (unlikely (len > left ()))
3351 /* Section vendor name. */
3352 const unsigned char *name = p + sizeof len;
3355 unsigned const char *q = memchr (name, '\0', len);
3356 if (unlikely (q == NULL))
3360 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3362 bool gnu_vendor = (q - name == sizeof "gnu"
3363 && !memcmp (name, "gnu", sizeof "gnu"));
3365 /* Loop over subsections. */
3366 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3370 const unsigned char *const sub = q;
3372 unsigned int subsection_tag;
3373 get_uleb128 (subsection_tag, q, p);
3374 if (unlikely (q >= p))
3377 uint32_t subsection_len;
3378 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3381 memcpy (&subsection_len, q, sizeof subsection_len);
3383 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3384 CONVERT (subsection_len);
3386 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3387 if (unlikely (subsection_len == 0
3388 || subsection_len >= (uint32_t) PTRDIFF_MAX
3389 || p - sub < (ptrdiff_t) subsection_len))
3392 const unsigned char *r = q + sizeof subsection_len;
3393 q = sub + subsection_len;
3395 switch (subsection_tag)
3398 /* Unknown subsection, print and skip. */
3399 printf (gettext (" %-4u %12" PRIu32 "\n"),
3400 subsection_tag, subsection_len);
3403 case 1: /* Tag_File */
3404 printf (gettext (" File: %11" PRIu32 "\n"),
3410 get_uleb128 (tag, r, q);
3411 if (unlikely (r >= q))
3414 /* GNU style tags have either a uleb128 value,
3415 when lowest bit is not set, or a string
3416 when the lowest bit is set.
3417 "compatibility" (32) is special. It has
3418 both a string and a uleb128 value. For
3419 non-gnu we assume 6 till 31 only take ints.
3420 XXX see arm backend, do we need a separate
3423 const char *string = NULL;
3424 if (tag == 32 || (tag & 1) == 0
3425 || (! gnu_vendor && (tag > 5 && tag < 32)))
3427 get_uleb128 (value, r, q);
3434 || (! gnu_vendor && tag > 32)))
3435 || (! gnu_vendor && tag > 3 && tag < 6))
3437 string = (const char *) r;
3438 r = memchr (r, '\0', q - r);
3444 const char *tag_name = NULL;
3445 const char *value_name = NULL;
3446 ebl_check_object_attribute (ebl, (const char *) name,
3448 &tag_name, &value_name);
3450 if (tag_name != NULL)
3453 printf (gettext (" %s: %" PRId64 ", %s\n"),
3454 tag_name, value, string);
3455 else if (string == NULL && value_name == NULL)
3456 printf (gettext (" %s: %" PRId64 "\n"),
3459 printf (gettext (" %s: %s\n"),
3460 tag_name, string ?: value_name);
3464 /* For "gnu" vendor 32 "compatibility" has
3465 already been handled above. */
3467 || strcmp ((const char *) name, "gnu"));
3469 printf (gettext (" %u: %" PRId64 "\n"),
3472 printf (gettext (" %u: %s\n"),
3484 format_dwarf_addr (Dwfl_Module *dwflmod,
3485 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3487 /* See if there is a name we can give for this address. */
3490 const char *name = (print_address_names && ! print_unresolved_addresses)
3491 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3495 if (print_unresolved_addresses)
3502 /* Relativize the address. */
3503 int n = dwfl_module_relocations (dwflmod);
3504 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3506 /* In an ET_REL file there is a section name to refer to. */
3508 : dwfl_module_relocation_info (dwflmod, i, NULL));
3515 ? (address_size == 0
3516 ? asprintf (&result,
3517 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3518 scn, address, name, off)
3519 : asprintf (&result,
3520 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3521 scn, 2 + address_size * 2, address,
3523 : (address_size == 0
3524 ? asprintf (&result,
3525 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3527 : asprintf (&result,
3528 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3529 2 + address_size * 2, address,
3532 ? (address_size == 0
3533 ? asprintf (&result,
3534 gettext ("%s+%#" PRIx64 " <%s>"),
3536 : asprintf (&result,
3537 gettext ("%s+%#0*" PRIx64 " <%s>"),
3538 scn, 2 + address_size * 2, address, name))
3539 : (address_size == 0
3540 ? asprintf (&result,
3541 gettext ("%#" PRIx64 " <%s>"),
3543 : asprintf (&result,
3544 gettext ("%#0*" PRIx64 " <%s>"),
3545 2 + address_size * 2, address, name))))
3547 ? (address_size == 0
3548 ? asprintf (&result,
3549 gettext ("%s+%#" PRIx64),
3551 : asprintf (&result,
3552 gettext ("%s+%#0*" PRIx64),
3553 scn, 2 + address_size * 2, address))
3554 : (address_size == 0
3555 ? asprintf (&result,
3558 : asprintf (&result,
3560 2 + address_size * 2, address)))) < 0)
3561 error (EXIT_FAILURE, 0, _("memory exhausted"));
3567 dwarf_tag_string (unsigned int tag)
3571 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3572 DWARF_ALL_KNOWN_DW_TAG
3573 #undef DWARF_ONE_KNOWN_DW_TAG
3581 dwarf_attr_string (unsigned int attrnum)
3585 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3586 DWARF_ALL_KNOWN_DW_AT
3587 #undef DWARF_ONE_KNOWN_DW_AT
3595 dwarf_form_string (unsigned int form)
3599 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3600 DWARF_ALL_KNOWN_DW_FORM
3601 #undef DWARF_ONE_KNOWN_DW_FORM
3609 dwarf_lang_string (unsigned int lang)
3613 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3614 DWARF_ALL_KNOWN_DW_LANG
3615 #undef DWARF_ONE_KNOWN_DW_LANG
3623 dwarf_inline_string (unsigned int code)
3625 static const char *const known[] =
3627 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3628 DWARF_ALL_KNOWN_DW_INL
3629 #undef DWARF_ONE_KNOWN_DW_INL
3632 if (likely (code < sizeof (known) / sizeof (known[0])))
3640 dwarf_encoding_string (unsigned int code)
3642 static const char *const known[] =
3644 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3645 DWARF_ALL_KNOWN_DW_ATE
3646 #undef DWARF_ONE_KNOWN_DW_ATE
3649 if (likely (code < sizeof (known) / sizeof (known[0])))
3657 dwarf_access_string (unsigned int code)
3659 static const char *const known[] =
3661 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3662 DWARF_ALL_KNOWN_DW_ACCESS
3663 #undef DWARF_ONE_KNOWN_DW_ACCESS
3666 if (likely (code < sizeof (known) / sizeof (known[0])))
3674 dwarf_visibility_string (unsigned int code)
3676 static const char *const known[] =
3678 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3679 DWARF_ALL_KNOWN_DW_VIS
3680 #undef DWARF_ONE_KNOWN_DW_VIS
3683 if (likely (code < sizeof (known) / sizeof (known[0])))
3691 dwarf_virtuality_string (unsigned int code)
3693 static const char *const known[] =
3695 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3696 DWARF_ALL_KNOWN_DW_VIRTUALITY
3697 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3700 if (likely (code < sizeof (known) / sizeof (known[0])))
3708 dwarf_identifier_case_string (unsigned int code)
3710 static const char *const known[] =
3712 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3713 DWARF_ALL_KNOWN_DW_ID
3714 #undef DWARF_ONE_KNOWN_DW_ID
3717 if (likely (code < sizeof (known) / sizeof (known[0])))
3725 dwarf_calling_convention_string (unsigned int code)
3727 static const char *const known[] =
3729 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3730 DWARF_ALL_KNOWN_DW_CC
3731 #undef DWARF_ONE_KNOWN_DW_CC
3734 if (likely (code < sizeof (known) / sizeof (known[0])))
3742 dwarf_ordering_string (unsigned int code)
3744 static const char *const known[] =
3746 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3747 DWARF_ALL_KNOWN_DW_ORD
3748 #undef DWARF_ONE_KNOWN_DW_ORD
3751 if (likely (code < sizeof (known) / sizeof (known[0])))
3759 dwarf_discr_list_string (unsigned int code)
3761 static const char *const known[] =
3763 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3764 DWARF_ALL_KNOWN_DW_DSC
3765 #undef DWARF_ONE_KNOWN_DW_DSC
3768 if (likely (code < sizeof (known) / sizeof (known[0])))
3776 dwarf_locexpr_opcode_string (unsigned int code)
3778 static const char *const known[] =
3780 /* Normally we can't affort building huge table of 64K entries,
3781 most of them zero, just because there are a couple defined
3782 values at the far end. In case of opcodes, it's OK. */
3783 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3784 DWARF_ALL_KNOWN_DW_OP
3785 #undef DWARF_ONE_KNOWN_DW_OP
3788 if (likely (code < sizeof (known) / sizeof (known[0])))
3795 /* Used by all dwarf_foo_name functions. */
3797 string_or_unknown (const char *known, unsigned int code,
3798 unsigned int lo_user, unsigned int hi_user,
3799 bool print_unknown_num)
3801 static char unknown_buf[20];
3803 if (likely (known != NULL))
3806 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3808 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3813 if (print_unknown_num)
3815 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3824 dwarf_tag_name (unsigned int tag)
3826 const char *ret = dwarf_tag_string (tag);
3827 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3831 dwarf_attr_name (unsigned int attr)
3833 const char *ret = dwarf_attr_string (attr);
3834 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3839 dwarf_form_name (unsigned int form)
3841 const char *ret = dwarf_form_string (form);
3842 return string_or_unknown (ret, form, 0, 0, true);
3847 dwarf_lang_name (unsigned int lang)
3849 const char *ret = dwarf_lang_string (lang);
3850 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3855 dwarf_inline_name (unsigned int code)
3857 const char *ret = dwarf_inline_string (code);
3858 return string_or_unknown (ret, code, 0, 0, false);
3863 dwarf_encoding_name (unsigned int code)
3865 const char *ret = dwarf_encoding_string (code);
3866 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3871 dwarf_access_name (unsigned int code)
3873 const char *ret = dwarf_access_string (code);
3874 return string_or_unknown (ret, code, 0, 0, false);
3879 dwarf_visibility_name (unsigned int code)
3881 const char *ret = dwarf_visibility_string (code);
3882 return string_or_unknown (ret, code, 0, 0, false);
3887 dwarf_virtuality_name (unsigned int code)
3889 const char *ret = dwarf_virtuality_string (code);
3890 return string_or_unknown (ret, code, 0, 0, false);
3895 dwarf_identifier_case_name (unsigned int code)
3897 const char *ret = dwarf_identifier_case_string (code);
3898 return string_or_unknown (ret, code, 0, 0, false);
3903 dwarf_calling_convention_name (unsigned int code)
3905 const char *ret = dwarf_calling_convention_string (code);
3906 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3911 dwarf_ordering_name (unsigned int code)
3913 const char *ret = dwarf_ordering_string (code);
3914 return string_or_unknown (ret, code, 0, 0, false);
3919 dwarf_discr_list_name (unsigned int code)
3921 const char *ret = dwarf_discr_list_string (code);
3922 return string_or_unknown (ret, code, 0, 0, false);
3927 print_block (size_t n, const void *block)
3930 puts (_("empty block"));
3933 printf (_("%zu byte block:"), n);
3934 const unsigned char *data = block;
3936 printf (" %02x", *data++);
3943 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3944 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3945 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3947 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3951 printf ("%*s(empty)\n", indent, "");
3955 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
3956 #define CONSUME(n) NEED (n); else len -= (n)
3958 Dwarf_Word offset = 0;
3961 uint_fast8_t op = *data++;
3963 const char *op_name = dwarf_locexpr_opcode_string (op);
3964 if (unlikely (op_name == NULL))
3966 static char buf[20];
3967 if (op >= DW_OP_lo_user)
3968 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3970 snprintf (buf, sizeof buf, "??? (%#x)", op);
3977 /* Address operand. */
3981 addr = read_4ubyte_unaligned (dbg, data);
3982 else if (addrsize == 8)
3983 addr = read_8ubyte_unaligned (dbg, data);
3989 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3990 printf ("%*s[%4" PRIuMAX "] %s %s\n",
3991 indent, "", (uintmax_t) offset, op_name, a);
3994 offset += 1 + addrsize;
3997 case DW_OP_call_ref:
3998 /* Offset operand. */
3999 if (ref_size != 4 && ref_size != 8)
4000 goto invalid; /* Cannot be used in CFA. */
4003 addr = read_4ubyte_unaligned (dbg, data);
4005 addr = read_8ubyte_unaligned (dbg, data);
4009 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4010 indent, "", (uintmax_t) offset,
4011 op_name, (uintmax_t) addr);
4012 offset += 1 + ref_size;
4015 case DW_OP_deref_size:
4016 case DW_OP_xderef_size:
4019 // XXX value might be modified by relocation
4021 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4022 indent, "", (uintmax_t) offset,
4023 op_name, *((uint8_t *) data));
4031 // XXX value might be modified by relocation
4032 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4033 indent, "", (uintmax_t) offset,
4034 op_name, read_2ubyte_unaligned (dbg, data));
4042 // XXX value might be modified by relocation
4043 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4044 indent, "", (uintmax_t) offset,
4045 op_name, read_4ubyte_unaligned (dbg, data));
4053 // XXX value might be modified by relocation
4054 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4055 indent, "", (uintmax_t) offset,
4056 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4064 // XXX value might be modified by relocation
4065 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4066 indent, "", (uintmax_t) offset,
4067 op_name, *((int8_t *) data));
4075 // XXX value might be modified by relocation
4076 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4077 indent, "", (uintmax_t) offset,
4078 op_name, read_2sbyte_unaligned (dbg, data));
4086 // XXX value might be modified by relocation
4087 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4088 indent, "", (uintmax_t) offset,
4089 op_name, read_4sbyte_unaligned (dbg, data));
4097 // XXX value might be modified by relocation
4098 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4099 indent, "", (uintmax_t) offset,
4100 op_name, read_8sbyte_unaligned (dbg, data));
4108 case DW_OP_plus_uconst:
4110 const unsigned char *start = data;
4113 get_uleb128 (uleb, data, data + len);
4114 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4115 indent, "", (uintmax_t) offset, op_name, uleb);
4116 CONSUME (data - start);
4117 offset += 1 + (data - start);
4120 case DW_OP_bit_piece:
4124 get_uleb128 (uleb, data, data + len);
4126 get_uleb128 (uleb2, data, data + len);
4127 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4128 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4129 CONSUME (data - start);
4130 offset += 1 + (data - start);
4134 case DW_OP_breg0 ... DW_OP_breg31:
4139 get_sleb128 (sleb, data, data + len);
4140 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4141 indent, "", (uintmax_t) offset, op_name, sleb);
4142 CONSUME (data - start);
4143 offset += 1 + (data - start);
4149 get_uleb128 (uleb, data, data + len);
4151 get_sleb128 (sleb, data, data + len);
4152 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4153 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4154 CONSUME (data - start);
4155 offset += 1 + (data - start);
4160 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4161 indent, "", (uintmax_t) offset, op_name,
4162 read_2ubyte_unaligned (dbg, data));
4169 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4170 indent, "", (uintmax_t) offset, op_name,
4171 read_4ubyte_unaligned (dbg, data));
4179 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4180 indent, "", (uintmax_t) offset, op_name,
4181 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4187 case DW_OP_implicit_value:
4190 get_uleb128 (uleb, data, data + len);
4191 printf ("%*s[%4" PRIuMAX "] %s: ",
4192 indent, "", (uintmax_t) offset, op_name);
4194 print_block (uleb, data);
4196 CONSUME (data - start);
4197 offset += 1 + (data - start);
4200 case DW_OP_GNU_implicit_pointer:
4201 /* DIE offset operand. */
4204 if (ref_size != 4 && ref_size != 8)
4205 goto invalid; /* Cannot be used in CFA. */
4207 addr = read_4ubyte_unaligned (dbg, data);
4209 addr = read_8ubyte_unaligned (dbg, data);
4211 /* Byte offset operand. */
4213 get_sleb128 (sleb, data, data + len);
4215 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4216 indent, "", (intmax_t) offset,
4217 op_name, (uintmax_t) addr, sleb);
4218 CONSUME (data - start);
4219 offset += 1 + (data - start);
4222 case DW_OP_GNU_entry_value:
4223 /* Size plus expression block. */
4226 get_uleb128 (uleb, data, data + len);
4227 printf ("%*s[%4" PRIuMAX "] %s:\n",
4228 indent, "", (uintmax_t) offset, op_name);
4230 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4231 addrsize, offset_size, cu, uleb, data);
4233 CONSUME (data - start);
4234 offset += 1 + (data - start);
4237 case DW_OP_GNU_const_type:
4238 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4239 unsigned size plus block. */
4242 get_uleb128 (uleb, data, data + len);
4243 if (! print_unresolved_addresses && cu != NULL)
4246 uint8_t usize = *(uint8_t *) data++;
4248 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4249 indent, "", (uintmax_t) offset, op_name, uleb);
4250 print_block (usize, data);
4252 CONSUME (data - start);
4253 offset += 1 + (data - start);
4256 case DW_OP_GNU_regval_type:
4257 /* uleb128 register number, uleb128 CU relative
4258 DW_TAG_base_type DIE offset. */
4261 get_uleb128 (uleb, data, data + len);
4263 get_uleb128 (uleb2, data, data + len);
4264 if (! print_unresolved_addresses && cu != NULL)
4266 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4267 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4268 CONSUME (data - start);
4269 offset += 1 + (data - start);
4272 case DW_OP_GNU_deref_type:
4273 /* 1-byte unsigned size of value, uleb128 CU relative
4274 DW_TAG_base_type DIE offset. */
4277 usize = *(uint8_t *) data++;
4279 get_uleb128 (uleb, data, data + len);
4280 if (! print_unresolved_addresses && cu != NULL)
4282 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4283 indent, "", (uintmax_t) offset,
4284 op_name, usize, uleb);
4285 CONSUME (data - start);
4286 offset += 1 + (data - start);
4289 case DW_OP_GNU_convert:
4290 case DW_OP_GNU_reinterpret:
4291 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4292 for conversion to untyped. */
4295 get_uleb128 (uleb, data, data + len);
4296 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4298 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4299 indent, "", (uintmax_t) offset, op_name, uleb);
4300 CONSUME (data - start);
4301 offset += 1 + (data - start);
4304 case DW_OP_GNU_parameter_ref:
4305 /* 4 byte CU relative reference to the abstract optimized away
4306 DW_TAG_formal_parameter. */
4308 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4309 if (! print_unresolved_addresses && cu != NULL)
4310 param_off += cu->start;
4311 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4312 indent, "", (uintmax_t) offset, op_name, param_off);
4320 printf ("%*s[%4" PRIuMAX "] %s\n",
4321 indent, "", (uintmax_t) offset, op_name);
4326 indent = indentrest;
4330 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4331 indent, "", (uintmax_t) offset, op_name);
4339 Dwarf_Off offset:(64 - 3);
4343 struct Dwarf_CU *cu;
4346 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4347 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4350 listptr_base (struct listptr *p)
4353 Dwarf_Die cu = CUDIE (p->cu);
4354 /* Find the base address of the compilation unit. It will normally
4355 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4356 address could be overridden by DW_AT_entry_pc. It's been
4357 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4358 compilation units with discontinuous ranges. */
4359 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4361 Dwarf_Attribute attr_mem;
4362 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4370 compare_listptr (const void *a, const void *b, void *arg)
4372 const char *name = arg;
4373 struct listptr *p1 = (void *) a;
4374 struct listptr *p2 = (void *) b;
4376 if (p1->offset < p2->offset)
4378 if (p1->offset > p2->offset)
4381 if (!p1->warned && !p2->warned)
4383 if (p1->addr64 != p2->addr64)
4385 p1->warned = p2->warned = true;
4387 gettext ("%s %#" PRIx64 " used with different address sizes"),
4388 name, (uint64_t) p1->offset);
4390 if (p1->dwarf64 != p2->dwarf64)
4392 p1->warned = p2->warned = true;
4394 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4395 name, (uint64_t) p1->offset);
4397 if (listptr_base (p1) != listptr_base (p2))
4399 p1->warned = p2->warned = true;
4401 gettext ("%s %#" PRIx64 " used with different base addresses"),
4402 name, (uint64_t) p1->offset);
4409 struct listptr_table
4413 struct listptr *table;
4416 static struct listptr_table known_loclistptr;
4417 static struct listptr_table known_rangelistptr;
4420 reset_listptr (struct listptr_table *table)
4422 free (table->table);
4423 table->table = NULL;
4424 table->n = table->alloc = 0;
4427 /* Returns false if offset doesn't fit. See struct listptr. */
4429 notice_listptr (enum section_e section, struct listptr_table *table,
4430 uint_fast8_t address_size, uint_fast8_t offset_size,
4431 struct Dwarf_CU *cu, Dwarf_Off offset)
4433 if (print_debug_sections & section)
4435 if (table->n == table->alloc)
4437 if (table->alloc == 0)
4441 table->table = xrealloc (table->table,
4442 table->alloc * sizeof table->table[0]);
4445 struct listptr *p = &table->table[table->n++];
4447 *p = (struct listptr)
4449 .addr64 = address_size == 8,
4450 .dwarf64 = offset_size == 8,
4455 if (p->offset != offset)
4465 sort_listptr (struct listptr_table *table, const char *name)
4468 qsort_r (table->table, table->n, sizeof table->table[0],
4469 &compare_listptr, (void *) name);
4473 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4474 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4475 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4476 unsigned char **readp, unsigned char *endp)
4481 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4484 struct listptr *p = &table->table[*idxp];
4486 if (*idxp == table->n
4487 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4490 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4495 if (p->offset != (Dwarf_Off) offset)
4497 *readp += p->offset - offset;
4498 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4499 offset, (Dwarf_Off) p->offset - offset);
4503 if (address_sizep != NULL)
4504 *address_sizep = listptr_address_size (p);
4505 if (offset_sizep != NULL)
4506 *offset_sizep = listptr_offset_size (p);
4508 *base = listptr_base (p);
4517 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4518 Ebl *ebl, GElf_Ehdr *ehdr,
4519 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4521 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4522 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4524 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4526 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4527 (uint64_t) shdr->sh_offset);
4529 Dwarf_Off offset = 0;
4530 while (offset < sh_size)
4532 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4538 Dwarf_Abbrev abbrev;
4540 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4543 if (unlikely (res < 0))
4546 *** error while reading abbreviation: %s\n"),
4551 /* This is the NUL byte at the end of the section. */
4556 /* We know these calls can never fail. */
4557 unsigned int code = dwarf_getabbrevcode (&abbrev);
4558 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4559 int has_children = dwarf_abbrevhaschildren (&abbrev);
4561 printf (gettext (" [%5u] offset: %" PRId64
4562 ", children: %s, tag: %s\n"),
4563 code, (int64_t) offset,
4564 has_children ? gettext ("yes") : gettext ("no"),
4565 dwarf_tag_name (tag));
4571 while (dwarf_getabbrevattr (&abbrev, cnt,
4572 &name, &form, &enoffset) == 0)
4574 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4575 dwarf_attr_name (name), dwarf_form_name (form),
4576 (uint64_t) enoffset);
4587 /* Print content of DWARF .debug_aranges section. We fortunately do
4588 not have to know a bit about the structure of the section, libdwarf
4589 takes care of it. */
4591 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4592 GElf_Shdr *shdr, Dwarf *dbg)
4594 Dwarf_Aranges *aranges;
4596 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4598 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4603 GElf_Shdr glink_mem;
4605 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4608 error (0, 0, gettext ("invalid sh_link value in section %zu"),
4613 printf (ngettext ("\
4614 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4616 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4618 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4619 (uint64_t) shdr->sh_offset, cnt);
4621 /* Compute floor(log16(cnt)). */
4630 for (size_t n = 0; n < cnt; ++n)
4632 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4633 if (unlikely (runp == NULL))
4635 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4643 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4644 printf (gettext (" [%*zu] ???\n"), digits, n);
4646 printf (gettext (" [%*zu] start: %0#*" PRIx64
4647 ", length: %5" PRIu64 ", CU DIE offset: %6"
4649 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4650 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4655 /* Print content of DWARF .debug_aranges section. */
4657 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4658 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4659 GElf_Shdr *shdr, Dwarf *dbg)
4663 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4667 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4669 if (unlikely (data == NULL))
4671 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4677 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4678 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4679 (uint64_t) shdr->sh_offset);
4681 const unsigned char *readp = data->d_buf;
4682 const unsigned char *readendp = readp + data->d_size;
4684 while (readp < readendp)
4686 const unsigned char *hdrstart = readp;
4687 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4689 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
4690 if (readp + 4 > readendp)
4693 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4694 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4698 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4699 unsigned int length_bytes = 4;
4700 if (length == DWARF3_LENGTH_64_BIT)
4702 if (readp + 8 > readendp)
4704 length = read_8ubyte_unaligned_inc (dbg, readp);
4708 const unsigned char *nexthdr = readp + length;
4709 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4712 if (unlikely (length > (size_t) (readendp - readp)))
4718 if (readp + 2 > readendp)
4720 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4721 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4725 error (0, 0, gettext ("unsupported aranges version"));
4730 if (readp + length_bytes > readendp)
4732 if (length_bytes == 8)
4733 offset = read_8ubyte_unaligned_inc (dbg, readp);
4735 offset = read_4ubyte_unaligned_inc (dbg, readp);
4736 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4739 if (readp + 1 > readendp)
4741 unsigned int address_size = *readp++;
4742 printf (gettext (" Address size: %6" PRIu64 "\n"),
4743 (uint64_t) address_size);
4744 if (address_size != 4 && address_size != 8)
4746 error (0, 0, gettext ("unsupported address size"));
4750 unsigned int segment_size = *readp++;
4751 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4752 (uint64_t) segment_size);
4753 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4755 error (0, 0, gettext ("unsupported segment size"));
4759 /* Round the address to the next multiple of 2*address_size. */
4760 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4761 % (2 * address_size));
4763 while (readp < nexthdr)
4765 Dwarf_Word range_address;
4766 Dwarf_Word range_length;
4767 Dwarf_Word segment = 0;
4768 if (readp + 2 * address_size + segment_size > readendp)
4770 if (address_size == 4)
4772 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4773 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4777 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4778 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4781 if (segment_size == 4)
4782 segment = read_4ubyte_unaligned_inc (dbg, readp);
4783 else if (segment_size == 8)
4784 segment = read_8ubyte_unaligned_inc (dbg, readp);
4786 if (range_address == 0 && range_length == 0 && segment == 0)
4789 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4791 char *e = format_dwarf_addr (dwflmod, address_size,
4792 range_address + range_length - 1,
4794 if (segment_size != 0)
4795 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4796 (uint64_t) segment);
4798 printf (gettext (" %s..%s\n"), b, e);
4804 if (readp != nexthdr)
4806 size_t padding = nexthdr - readp;
4807 printf (gettext (" %zu padding bytes\n"), padding);
4814 /* Print content of DWARF .debug_ranges section. */
4816 print_debug_ranges_section (Dwfl_Module *dwflmod,
4817 Ebl *ebl, GElf_Ehdr *ehdr,
4818 Elf_Scn *scn, GElf_Shdr *shdr,
4821 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4823 if (unlikely (data == NULL))
4825 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4831 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4832 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4833 (uint64_t) shdr->sh_offset);
4835 sort_listptr (&known_rangelistptr, "rangelistptr");
4836 size_t listptr_idx = 0;
4838 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4841 Dwarf_Addr base = 0;
4842 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4843 unsigned char *readp = data->d_buf;
4844 while (readp < endp)
4846 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4848 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4849 &address_size, NULL, &base, NULL,
4850 offset, &readp, endp))
4853 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4855 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4861 if (address_size == 8)
4863 begin = read_8ubyte_unaligned_inc (dbg, readp);
4864 end = read_8ubyte_unaligned_inc (dbg, readp);
4868 begin = read_4ubyte_unaligned_inc (dbg, readp);
4869 end = read_4ubyte_unaligned_inc (dbg, readp);
4870 if (begin == (Dwarf_Addr) (uint32_t) -1)
4871 begin = (Dwarf_Addr) -1l;
4874 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4876 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4877 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4881 else if (begin == 0 && end == 0) /* End of list entry. */
4884 printf (gettext (" [%6tx] empty list\n"), offset);
4889 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4891 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4893 /* We have an address range entry. */
4894 if (first) /* First address range entry in a list. */
4895 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
4897 printf (gettext (" %s..%s\n"), b, e);
4906 #define REGNAMESZ 16
4908 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4909 char name[REGNAMESZ], int *bits, int *type)
4914 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4915 bits ?: &ignore, type ?: &ignore);
4919 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4921 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4923 *bits = loc != NULL ? loc->bits : 0;
4925 *type = DW_ATE_unsigned;
4926 set = "??? unrecognized";
4930 if (bits != NULL && *bits <= 0)
4931 *bits = loc != NULL ? loc->bits : 0;
4932 if (type != NULL && *type == DW_ATE_void)
4933 *type = DW_ATE_unsigned;
4940 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4941 Dwarf_Word vma_base, unsigned int code_align,
4943 unsigned int version, unsigned int ptr_size,
4944 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4946 char regnamebuf[REGNAMESZ];
4947 const char *regname (unsigned int regno)
4949 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4953 puts ("\n Program:");
4954 Dwarf_Word pc = vma_base;
4955 while (readp < endp)
4957 unsigned int opcode = *readp++;
4959 if (opcode < DW_CFA_advance_loc)
4960 /* Extended opcode. */
4971 case DW_CFA_set_loc:
4972 if ((uint64_t) (endp - readp) < 1)
4974 get_uleb128 (op1, readp, endp);
4976 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
4978 case DW_CFA_advance_loc1:
4979 if ((uint64_t) (endp - readp) < 1)
4981 printf (" advance_loc1 %u to %#" PRIx64 "\n",
4982 *readp, pc += *readp * code_align);
4985 case DW_CFA_advance_loc2:
4986 if ((uint64_t) (endp - readp) < 2)
4988 op1 = read_2ubyte_unaligned_inc (dbg, readp);
4989 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4990 op1, pc += op1 * code_align);
4992 case DW_CFA_advance_loc4:
4993 if ((uint64_t) (endp - readp) < 4)
4995 op1 = read_4ubyte_unaligned_inc (dbg, readp);
4996 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4997 op1, pc += op1 * code_align);
4999 case DW_CFA_offset_extended:
5000 if ((uint64_t) (endp - readp) < 1)
5002 get_uleb128 (op1, readp, endp);
5003 if ((uint64_t) (endp - readp) < 1)
5005 get_uleb128 (op2, readp, endp);
5006 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5008 op1, regname (op1), op2 * data_align);
5010 case DW_CFA_restore_extended:
5011 if ((uint64_t) (endp - readp) < 1)
5013 get_uleb128 (op1, readp, endp);
5014 printf (" restore_extended r%" PRIu64 " (%s)\n",
5015 op1, regname (op1));
5017 case DW_CFA_undefined:
5018 if ((uint64_t) (endp - readp) < 1)
5020 get_uleb128 (op1, readp, endp);
5021 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5023 case DW_CFA_same_value:
5024 if ((uint64_t) (endp - readp) < 1)
5026 get_uleb128 (op1, readp, endp);
5027 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5029 case DW_CFA_register:
5030 if ((uint64_t) (endp - readp) < 1)
5032 get_uleb128 (op1, readp, endp);
5033 if ((uint64_t) (endp - readp) < 1)
5035 get_uleb128 (op2, readp, endp);
5036 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5037 op1, regname (op1), op2, regname (op2));
5039 case DW_CFA_remember_state:
5040 puts (" remember_state");
5042 case DW_CFA_restore_state:
5043 puts (" restore_state");
5045 case DW_CFA_def_cfa:
5046 if ((uint64_t) (endp - readp) < 1)
5048 get_uleb128 (op1, readp, endp);
5049 if ((uint64_t) (endp - readp) < 1)
5051 get_uleb128 (op2, readp, endp);
5052 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5053 op1, regname (op1), op2);
5055 case DW_CFA_def_cfa_register:
5056 if ((uint64_t) (endp - readp) < 1)
5058 get_uleb128 (op1, readp, endp);
5059 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
5060 op1, regname (op1));
5062 case DW_CFA_def_cfa_offset:
5063 if ((uint64_t) (endp - readp) < 1)
5065 get_uleb128 (op1, readp, endp);
5066 printf (" def_cfa_offset %" PRIu64 "\n", op1);
5068 case DW_CFA_def_cfa_expression:
5069 if ((uint64_t) (endp - readp) < 1)
5071 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
5072 printf (" def_cfa_expression %" PRIu64 "\n", op1);
5073 if ((uint64_t) (endp - readp) < op1)
5076 fputs (gettext (" <INVALID DATA>\n"), stdout);
5079 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5083 case DW_CFA_expression:
5084 if ((uint64_t) (endp - readp) < 1)
5086 get_uleb128 (op1, readp, endp);
5087 if ((uint64_t) (endp - readp) < 1)
5089 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5090 printf (" expression r%" PRIu64 " (%s) \n",
5091 op1, regname (op1));
5092 if ((uint64_t) (endp - readp) < op2)
5094 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5098 case DW_CFA_offset_extended_sf:
5099 if ((uint64_t) (endp - readp) < 1)
5101 get_uleb128 (op1, readp, endp);
5102 if ((uint64_t) (endp - readp) < 1)
5104 get_sleb128 (sop2, readp, endp);
5105 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5107 op1, regname (op1), sop2 * data_align);
5109 case DW_CFA_def_cfa_sf:
5110 if ((uint64_t) (endp - readp) < 1)
5112 get_uleb128 (op1, readp, endp);
5113 if ((uint64_t) (endp - readp) < 1)
5115 get_sleb128 (sop2, readp, endp);
5116 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5117 op1, regname (op1), sop2 * data_align);
5119 case DW_CFA_def_cfa_offset_sf:
5120 if ((uint64_t) (endp - readp) < 1)
5122 get_sleb128 (sop1, readp, endp);
5123 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5125 case DW_CFA_val_offset:
5126 if ((uint64_t) (endp - readp) < 1)
5128 get_uleb128 (op1, readp, endp);
5129 if ((uint64_t) (endp - readp) < 1)
5131 get_uleb128 (op2, readp, endp);
5132 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5133 op1, op2 * data_align);
5135 case DW_CFA_val_offset_sf:
5136 if ((uint64_t) (endp - readp) < 1)
5138 get_uleb128 (op1, readp, endp);
5139 if ((uint64_t) (endp - readp) < 1)
5141 get_sleb128 (sop2, readp, endp);
5142 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5143 op1, sop2 * data_align);
5145 case DW_CFA_val_expression:
5146 if ((uint64_t) (endp - readp) < 1)
5148 get_uleb128 (op1, readp, endp);
5149 if ((uint64_t) (endp - readp) < 1)
5151 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5152 printf (" val_expression r%" PRIu64 " (%s)\n",
5153 op1, regname (op1));
5154 if ((uint64_t) (endp - readp) < op2)
5156 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5160 case DW_CFA_MIPS_advance_loc8:
5161 if ((uint64_t) (endp - readp) < 8)
5163 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5164 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5165 op1, pc += op1 * code_align);
5167 case DW_CFA_GNU_window_save:
5168 puts (" GNU_window_save");
5170 case DW_CFA_GNU_args_size:
5171 if ((uint64_t) (endp - readp) < 1)
5173 get_uleb128 (op1, readp, endp);
5174 printf (" args_size %" PRIu64 "\n", op1);
5177 printf (" ??? (%u)\n", opcode);
5180 else if (opcode < DW_CFA_offset)
5181 printf (" advance_loc %u to %#" PRIx64 "\n",
5182 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5183 else if (opcode < DW_CFA_restore)
5186 if ((uint64_t) (endp - readp) < 1)
5188 get_uleb128 (offset, readp, endp);
5189 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5190 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5193 printf (" restore r%u (%s)\n",
5194 opcode & 0x3f, regname (opcode & 0x3f));
5200 encoded_ptr_size (int encoding, unsigned int ptr_size)
5202 switch (encoding & 7)
5204 case DW_EH_PE_udata4:
5206 case DW_EH_PE_udata8:
5212 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5213 "assuming pointer size of %d.\n", encoding, ptr_size);
5219 print_encoding (unsigned int val)
5223 case DW_EH_PE_absptr:
5224 fputs ("absptr", stdout);
5226 case DW_EH_PE_uleb128:
5227 fputs ("uleb128", stdout);
5229 case DW_EH_PE_udata2:
5230 fputs ("udata2", stdout);
5232 case DW_EH_PE_udata4:
5233 fputs ("udata4", stdout);
5235 case DW_EH_PE_udata8:
5236 fputs ("udata8", stdout);
5238 case DW_EH_PE_sleb128:
5239 fputs ("sleb128", stdout);
5241 case DW_EH_PE_sdata2:
5242 fputs ("sdata2", stdout);
5244 case DW_EH_PE_sdata4:
5245 fputs ("sdata4", stdout);
5247 case DW_EH_PE_sdata8:
5248 fputs ("sdata8", stdout);
5251 /* We did not use any of the bits after all. */
5260 print_relinfo (unsigned int val)
5264 case DW_EH_PE_pcrel:
5265 fputs ("pcrel", stdout);
5267 case DW_EH_PE_textrel:
5268 fputs ("textrel", stdout);
5270 case DW_EH_PE_datarel:
5271 fputs ("datarel", stdout);
5273 case DW_EH_PE_funcrel:
5274 fputs ("funcrel", stdout);
5276 case DW_EH_PE_aligned:
5277 fputs ("aligned", stdout);
5288 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5290 printf ("(%s", pfx);
5292 if (fde_encoding == DW_EH_PE_omit)
5296 unsigned int w = fde_encoding;
5298 w = print_encoding (w);
5302 if (w != fde_encoding)
5303 fputc_unlocked (' ', stdout);
5305 w = print_relinfo (w);
5309 printf ("%s%x", w != fde_encoding ? " " : "", w);
5316 static const unsigned char *
5317 read_encoded (unsigned int encoding, const unsigned char *readp,
5318 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5320 if ((encoding & 0xf) == DW_EH_PE_absptr)
5321 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5322 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5324 switch (encoding & 0xf)
5326 case DW_EH_PE_uleb128:
5327 get_uleb128 (*res, readp, endp);
5329 case DW_EH_PE_sleb128:
5330 get_sleb128 (*res, readp, endp);
5332 case DW_EH_PE_udata2:
5333 if (readp + 2 > endp)
5335 *res = read_2ubyte_unaligned_inc (dbg, readp);
5337 case DW_EH_PE_udata4:
5338 if (readp + 4 > endp)
5340 *res = read_4ubyte_unaligned_inc (dbg, readp);
5342 case DW_EH_PE_udata8:
5343 if (readp + 8 > endp)
5345 *res = read_8ubyte_unaligned_inc (dbg, readp);
5347 case DW_EH_PE_sdata2:
5348 if (readp + 2 > endp)
5350 *res = read_2sbyte_unaligned_inc (dbg, readp);
5352 case DW_EH_PE_sdata4:
5353 if (readp + 4 > endp)
5355 *res = read_4sbyte_unaligned_inc (dbg, readp);
5357 case DW_EH_PE_sdata8:
5358 if (readp + 8 > endp)
5360 *res = read_8sbyte_unaligned_inc (dbg, readp);
5365 gettext ("invalid encoding"));
5373 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5374 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5377 /* We know this call will succeed since it did in the caller. */
5378 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5379 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5381 /* Needed if we find PC-relative addresses. */
5383 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5385 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5389 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5390 Elf_Data *data = (is_eh_frame
5391 ? elf_rawdata (scn, NULL)
5392 : dbg->sectiondata[IDX_debug_frame]);
5394 if (unlikely (data == NULL))
5396 error (0, 0, gettext ("cannot get %s content: %s"),
5397 scnname, elf_errmsg (-1));
5403 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5404 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5407 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5408 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5412 ptrdiff_t cie_offset;
5413 const char *augmentation;
5414 unsigned int code_alignment_factor;
5415 unsigned int data_alignment_factor;
5416 uint8_t address_size;
5417 uint8_t fde_encoding;
5418 uint8_t lsda_encoding;
5419 struct cieinfo *next;
5422 const unsigned char *readp = data->d_buf;
5423 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5425 while (readp < dataend)
5427 if (unlikely (readp + 4 > dataend))
5430 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5431 elf_ndxscn (scn), scnname);
5435 /* At the beginning there must be a CIE. There can be multiple,
5436 hence we test tis in a loop. */
5437 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5439 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5440 unsigned int length = 4;
5441 if (unlikely (unit_length == 0xffffffff))
5443 if (unlikely (readp + 8 > dataend))
5446 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5450 if (unlikely (unit_length == 0))
5452 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5456 Dwarf_Word maxsize = dataend - readp;
5457 if (unlikely (unit_length > maxsize))
5460 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5462 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5463 const unsigned char *const cieend = readp + unit_length;
5464 if (unlikely (cieend > dataend || readp + 8 > dataend))
5470 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5471 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5472 cie_id = DW_CIE_ID_64;
5475 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5477 uint_fast8_t version = 2;
5478 unsigned int code_alignment_factor;
5479 int data_alignment_factor;
5480 unsigned int fde_encoding = 0;
5481 unsigned int lsda_encoding = 0;
5482 Dwarf_Word initial_location = 0;
5483 Dwarf_Word vma_base = 0;
5485 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5488 const char *const augmentation = (const char *) readp;
5489 readp = memchr (readp, '\0', cieend - readp);
5490 if (unlikely (readp == NULL))
5494 uint_fast8_t segment_size = 0;
5497 if (cieend - readp < 5)
5499 ptr_size = *readp++;
5500 segment_size = *readp++;
5503 if (cieend - readp < 1)
5505 get_uleb128 (code_alignment_factor, readp, cieend);
5506 if (cieend - readp < 1)
5508 get_sleb128 (data_alignment_factor, readp, cieend);
5510 /* In some variant for unwind data there is another field. */
5511 if (strcmp (augmentation, "eh") == 0)
5512 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5514 unsigned int return_address_register;
5515 if (cieend - readp < 1)
5517 if (unlikely (version == 1))
5518 return_address_register = *readp++;
5520 get_uleb128 (return_address_register, readp, cieend);
5522 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5523 " CIE_id: %" PRIu64 "\n"
5525 " augmentation: \"%s\"\n",
5526 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5527 version, augmentation);
5529 printf (" address_size: %u\n"
5530 " segment_size: %u\n",
5531 ptr_size, segment_size);
5532 printf (" code_alignment_factor: %u\n"
5533 " data_alignment_factor: %d\n"
5534 " return_address_register: %u\n",
5535 code_alignment_factor,
5536 data_alignment_factor, return_address_register);
5538 if (augmentation[0] == 'z')
5540 unsigned int augmentationlen;
5541 get_uleb128 (augmentationlen, readp, cieend);
5543 if (augmentationlen > (size_t) (cieend - readp))
5545 error (0, 0, gettext ("invalid augmentation length"));
5550 const char *hdr = "Augmentation data:";
5551 const char *cp = augmentation + 1;
5552 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5554 printf (" %-26s%#x ", hdr, *readp);
5559 fde_encoding = *readp++;
5560 print_encoding_base (gettext ("FDE address encoding: "),
5563 else if (*cp == 'L')
5565 lsda_encoding = *readp++;
5566 print_encoding_base (gettext ("LSDA pointer encoding: "),
5569 else if (*cp == 'P')
5571 /* Personality. This field usually has a relocation
5572 attached pointing to __gcc_personality_v0. */
5573 const unsigned char *startp = readp;
5574 unsigned int encoding = *readp++;
5576 readp = read_encoded (encoding, readp,
5577 readp - 1 + augmentationlen,
5580 while (++startp < readp)
5581 printf ("%#x ", *startp);
5584 print_encoding (encoding);
5586 switch (encoding & 0xf)
5588 case DW_EH_PE_sleb128:
5589 case DW_EH_PE_sdata2:
5590 case DW_EH_PE_sdata4:
5591 printf ("%" PRId64 ")\n", val);
5594 printf ("%#" PRIx64 ")\n", val);
5599 printf ("(%x)\n", *readp++);
5605 if (likely (ptr_size == 4 || ptr_size == 8))
5607 struct cieinfo *newp = alloca (sizeof (*newp));
5608 newp->cie_offset = offset;
5609 newp->augmentation = augmentation;
5610 newp->fde_encoding = fde_encoding;
5611 newp->lsda_encoding = lsda_encoding;
5612 newp->address_size = ptr_size;
5613 newp->code_alignment_factor = code_alignment_factor;
5614 newp->data_alignment_factor = data_alignment_factor;
5621 struct cieinfo *cie = cies;
5624 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
5625 : cie_id == (Dwarf_Off) cie->cie_offset)
5629 if (unlikely (cie == NULL))
5631 puts ("invalid CIE reference in FDE");
5635 /* Initialize from CIE data. */
5636 fde_encoding = cie->fde_encoding;
5637 lsda_encoding = cie->lsda_encoding;
5638 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5639 code_alignment_factor = cie->code_alignment_factor;
5640 data_alignment_factor = cie->data_alignment_factor;
5642 const unsigned char *base = readp;
5643 // XXX There are sometimes relocations for this value
5644 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5645 Dwarf_Word address_range
5646 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5648 /* pcrel for an FDE address is relative to the runtime
5649 address of the start_address field itself. Sign extend
5650 if necessary to make sure the calculation is done on the
5651 full 64 bit address even when initial_location only holds
5652 the lower 32 bits. */
5653 Dwarf_Addr pc_start = initial_location;
5655 pc_start = (uint64_t) (int32_t) pc_start;
5656 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5657 pc_start += ((uint64_t) shdr->sh_addr
5658 + (base - (const unsigned char *) data->d_buf)
5661 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5662 pc_start, initial_location);
5663 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5664 " CIE_pointer: %" PRIu64 "\n"
5665 " initial_location: %s",
5666 offset, (uint64_t) unit_length,
5667 cie->cie_offset, (uint64_t) cie_id, a);
5669 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5671 vma_base = (((uint64_t) shdr->sh_offset
5672 + (base - (const unsigned char *) data->d_buf)
5673 + (uint64_t) initial_location)
5675 ? UINT64_C (0xffffffff)
5676 : UINT64_C (0xffffffffffffffff)));
5677 printf (gettext (" (offset: %#" PRIx64 ")"),
5678 (uint64_t) vma_base);
5681 printf ("\n address_range: %#" PRIx64,
5682 (uint64_t) address_range);
5683 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5684 printf (gettext (" (end offset: %#" PRIx64 ")"),
5685 ((uint64_t) vma_base + (uint64_t) address_range)
5687 ? UINT64_C (0xffffffff)
5688 : UINT64_C (0xffffffffffffffff)));
5691 if (cie->augmentation[0] == 'z')
5693 unsigned int augmentationlen;
5694 if (cieend - readp < 1)
5696 get_uleb128 (augmentationlen, readp, cieend);
5698 if (augmentationlen > (size_t) (cieend - readp))
5700 error (0, 0, gettext ("invalid augmentation length"));
5705 if (augmentationlen > 0)
5707 const char *hdr = "Augmentation data:";
5708 const char *cp = cie->augmentation + 1;
5711 && cp < cie->augmentation + augmentationlen + 1)
5715 uint64_t lsda_pointer;
5716 const unsigned char *p
5717 = read_encoded (lsda_encoding, &readp[u],
5718 &readp[augmentationlen],
5719 &lsda_pointer, dbg);
5722 %-26sLSDA pointer: %#" PRIx64 "\n"),
5729 while (u < augmentationlen)
5731 printf (" %-26s%#x\n", hdr, readp[u++]);
5736 readp += augmentationlen;
5740 /* Handle the initialization instructions. */
5741 if (ptr_size != 4 && ptr_size !=8)
5742 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5744 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5745 data_alignment_factor, version, ptr_size,
5754 Dwfl_Module *dwflmod;
5759 unsigned int version;
5760 unsigned int addrsize;
5761 unsigned int offset_size;
5762 struct Dwarf_CU *cu;
5767 attr_callback (Dwarf_Attribute *attrp, void *arg)
5769 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5770 const int level = cbargs->level;
5772 unsigned int attr = dwarf_whatattr (attrp);
5773 if (unlikely (attr == 0))
5775 if (!cbargs->silent)
5776 error (0, 0, gettext ("cannot get attribute code: %s"),
5778 return DWARF_CB_ABORT;
5781 unsigned int form = dwarf_whatform (attrp);
5782 if (unlikely (form == 0))
5784 if (!cbargs->silent)
5785 error (0, 0, gettext ("cannot get attribute form: %s"),
5787 return DWARF_CB_ABORT;
5793 if (!cbargs->silent)
5796 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5799 if (!cbargs->silent)
5800 error (0, 0, gettext ("cannot get attribute value: %s"),
5802 return DWARF_CB_ABORT;
5804 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5806 printf (" %*s%-20s (%s) %s\n",
5807 (int) (level * 2), "", dwarf_attr_name (attr),
5808 dwarf_form_name (form), a);
5813 case DW_FORM_indirect:
5815 case DW_FORM_string:
5816 case DW_FORM_GNU_strp_alt:
5819 const char *str = dwarf_formstring (attrp);
5820 if (unlikely (str == NULL))
5822 printf (" %*s%-20s (%s) \"%s\"\n",
5823 (int) (level * 2), "", dwarf_attr_name (attr),
5824 dwarf_form_name (form), str);
5827 case DW_FORM_ref_addr:
5828 case DW_FORM_ref_udata:
5833 case DW_FORM_GNU_ref_alt:
5837 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5840 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5841 (int) (level * 2), "", dwarf_attr_name (attr),
5842 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5845 case DW_FORM_ref_sig8:
5848 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5849 (int) (level * 2), "", dwarf_attr_name (attr),
5850 dwarf_form_name (form),
5851 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5854 case DW_FORM_sec_offset:
5860 case DW_FORM_data1:;
5862 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5865 const char *valuestr = NULL;
5868 /* This case can take either a constant or a loclistptr. */
5869 case DW_AT_data_member_location:
5870 if (form != DW_FORM_sec_offset
5871 && (cbargs->version >= 4
5872 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5874 if (!cbargs->silent)
5875 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5876 (int) (level * 2), "", dwarf_attr_name (attr),
5877 dwarf_form_name (form), (uintmax_t) num);
5880 /* else fallthrough */
5882 /* These cases always take a loclistptr and no constant. */
5883 case DW_AT_location:
5884 case DW_AT_data_location:
5885 case DW_AT_vtable_elem_location:
5886 case DW_AT_string_length:
5887 case DW_AT_use_location:
5888 case DW_AT_frame_base:
5889 case DW_AT_return_addr:
5890 case DW_AT_static_link:
5891 case DW_AT_GNU_call_site_value:
5892 case DW_AT_GNU_call_site_data_value:
5893 case DW_AT_GNU_call_site_target:
5894 case DW_AT_GNU_call_site_target_clobbered:
5896 bool nlpt = notice_listptr (section_loc, &known_loclistptr,
5897 cbargs->addrsize, cbargs->offset_size,
5899 if (!cbargs->silent)
5900 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
5901 (int) (level * 2), "", dwarf_attr_name (attr),
5902 dwarf_form_name (form), (uintmax_t) num,
5903 nlpt ? "" : " <WARNING offset too big>");
5909 bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
5910 cbargs->addrsize, cbargs->offset_size,
5912 if (!cbargs->silent)
5913 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
5914 (int) (level * 2), "", dwarf_attr_name (attr),
5915 dwarf_form_name (form), (uintmax_t) num,
5916 nlpt ? "" : " <WARNING offset too big>");
5920 case DW_AT_language:
5921 valuestr = dwarf_lang_name (num);
5923 case DW_AT_encoding:
5924 valuestr = dwarf_encoding_name (num);
5926 case DW_AT_accessibility:
5927 valuestr = dwarf_access_name (num);
5929 case DW_AT_visibility:
5930 valuestr = dwarf_visibility_name (num);
5932 case DW_AT_virtuality:
5933 valuestr = dwarf_virtuality_name (num);
5935 case DW_AT_identifier_case:
5936 valuestr = dwarf_identifier_case_name (num);
5938 case DW_AT_calling_convention:
5939 valuestr = dwarf_calling_convention_name (num);
5942 valuestr = dwarf_inline_name (num);
5944 case DW_AT_ordering:
5945 valuestr = dwarf_ordering_name (num);
5947 case DW_AT_discr_list:
5948 valuestr = dwarf_discr_list_name (num);
5958 /* When highpc is in constant form it is relative to lowpc.
5959 In that case also show the address. */
5961 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5963 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5965 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5966 (int) (level * 2), "", dwarf_attr_name (attr),
5967 dwarf_form_name (form), (uintmax_t) num, a);
5972 Dwarf_Sword snum = 0;
5973 if (form == DW_FORM_sdata)
5974 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5977 if (valuestr == NULL)
5979 printf (" %*s%-20s (%s)",
5980 (int) (level * 2), "", dwarf_attr_name (attr),
5981 dwarf_form_name (form));
5982 if (form == DW_FORM_sdata)
5983 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5985 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5989 printf (" %*s%-20s (%s) %s",
5990 (int) (level * 2), "", dwarf_attr_name (attr),
5991 dwarf_form_name (form), valuestr);
5992 if (form == DW_FORM_sdata)
5993 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5995 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6004 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6007 printf (" %*s%-20s (%s) %s\n",
6008 (int) (level * 2), "", dwarf_attr_name (attr),
6009 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
6012 case DW_FORM_flag_present:
6015 printf (" %*s%-20s (%s) %s\n",
6016 (int) (level * 2), "", dwarf_attr_name (attr),
6017 dwarf_form_name (form), nl_langinfo (YESSTR));
6020 case DW_FORM_exprloc:
6021 case DW_FORM_block4:
6022 case DW_FORM_block2:
6023 case DW_FORM_block1:
6028 if (unlikely (dwarf_formblock (attrp, &block) != 0))
6031 printf (" %*s%-20s (%s) ",
6032 (int) (level * 2), "", dwarf_attr_name (attr),
6033 dwarf_form_name (form));
6038 if (form != DW_FORM_exprloc)
6040 print_block (block.length, block.data);
6045 case DW_AT_location:
6046 case DW_AT_data_location:
6047 case DW_AT_data_member_location:
6048 case DW_AT_vtable_elem_location:
6049 case DW_AT_string_length:
6050 case DW_AT_use_location:
6051 case DW_AT_frame_base:
6052 case DW_AT_return_addr:
6053 case DW_AT_static_link:
6054 case DW_AT_allocated:
6055 case DW_AT_associated:
6056 case DW_AT_bit_size:
6057 case DW_AT_bit_offset:
6058 case DW_AT_bit_stride:
6059 case DW_AT_byte_size:
6060 case DW_AT_byte_stride:
6062 case DW_AT_lower_bound:
6063 case DW_AT_upper_bound:
6064 case DW_AT_GNU_call_site_value:
6065 case DW_AT_GNU_call_site_data_value:
6066 case DW_AT_GNU_call_site_target:
6067 case DW_AT_GNU_call_site_target_clobbered:
6069 print_ops (cbargs->dwflmod, cbargs->dbg,
6070 12 + level * 2, 12 + level * 2,
6071 cbargs->version, cbargs->addrsize, cbargs->offset_size,
6072 attrp->cu, block.length, block.data);
6080 printf (" %*s%-20s (form: %#x) ???\n",
6081 (int) (level * 2), "", dwarf_attr_name (attr),
6090 print_debug_units (Dwfl_Module *dwflmod,
6091 Ebl *ebl, GElf_Ehdr *ehdr,
6092 Elf_Scn *scn, GElf_Shdr *shdr,
6093 Dwarf *dbg, bool debug_types)
6095 const bool silent = !(print_debug_sections & section_info);
6096 const char *secname = section_name (ebl, ehdr, shdr);
6100 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6101 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6103 /* If the section is empty we don't have to do anything. */
6104 if (!silent && shdr->sh_size == 0)
6108 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6110 Dwarf_Off offset = 0;
6112 /* New compilation unit. */
6115 Dwarf_Off abbroffset;
6122 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6123 &abbroffset, &addrsize, &offsize,
6124 debug_types ? &typesig : NULL,
6125 debug_types ? &typeoff : NULL) != 0)
6131 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6132 " Version: %" PRIu16 ", Abbreviation section offset: %"
6133 PRIu64 ", Address size: %" PRIu8
6134 ", Offset size: %" PRIu8
6135 "\n Type signature: %#" PRIx64
6136 ", Type offset: %#" PRIx64 "\n"),
6137 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6138 typesig, (uint64_t) typeoff);
6140 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6141 " Version: %" PRIu16 ", Abbreviation section offset: %"
6142 PRIu64 ", Address size: %" PRIu8
6143 ", Offset size: %" PRIu8 "\n"),
6144 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6147 struct attrcb_args args =
6153 .addrsize = addrsize,
6154 .offset_size = offsize
6161 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6162 (dbg, offset, &dies[level]) == NULL))
6165 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6166 " in section '%s': %s"),
6167 (uint64_t) offset, secname, dwarf_errmsg (-1));
6171 args.cu = dies[0].cu;
6175 offset = dwarf_dieoffset (&dies[level]);
6176 if (unlikely (offset == ~0ul))
6179 error (0, 0, gettext ("cannot get DIE offset: %s"),
6184 int tag = dwarf_tag (&dies[level]);
6185 if (unlikely (tag == DW_TAG_invalid))
6188 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6189 " in section '%s': %s"),
6190 (uint64_t) offset, secname, dwarf_errmsg (-1));
6195 printf (" [%6" PRIx64 "] %*s%s\n",
6196 (uint64_t) offset, (int) (level * 2), "",
6197 dwarf_tag_name (tag));
6199 /* Print the attribute values. */
6201 args.die = &dies[level];
6202 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6204 /* Make room for the next level's DIE. */
6205 if (level + 1 == maxdies)
6206 dies = (Dwarf_Die *) xrealloc (dies,
6208 * sizeof (Dwarf_Die));
6210 int res = dwarf_child (&dies[level], &dies[level + 1]);
6213 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6217 if (unlikely (res == -1))
6220 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6225 else if (unlikely (res < 0))
6228 error (0, 0, gettext ("cannot get next DIE: %s"),
6246 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6247 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6249 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6253 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6254 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6256 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6261 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6262 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6265 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6266 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6267 (uint64_t) shdr->sh_offset);
6270 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6273 Dwarf_Off ncuoffset = 0;
6275 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6276 NULL, NULL, NULL) == 0)
6279 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6284 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6287 printf (" CU [%" PRIx64 "] %s\n",
6288 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6289 printf (" line:col SBPE* disc isa op address"
6290 " (Statement Block Prologue Epilogue *End)\n");
6291 const char *last_file = "";
6292 for (size_t n = 0; n < nlines; n++)
6294 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6297 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6300 Dwarf_Word mtime, length;
6301 const char *file = dwarf_linesrc (line, &mtime, &length);
6304 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6307 else if (strcmp (last_file, file) != 0)
6309 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6310 file, mtime, length);
6315 bool statement, endseq, block, prologue_end, epilogue_begin;
6316 unsigned int lineop, isa, disc;
6318 dwarf_lineaddr (line, &address);
6319 dwarf_lineno (line, &lineno);
6320 dwarf_linecol (line, &colno);
6321 dwarf_lineop_index (line, &lineop);
6322 dwarf_linebeginstatement (line, &statement);
6323 dwarf_lineendsequence (line, &endseq);
6324 dwarf_lineblock (line, &block);
6325 dwarf_lineprologueend (line, &prologue_end);
6326 dwarf_lineepiloguebegin (line, &epilogue_begin);
6327 dwarf_lineisa (line, &isa);
6328 dwarf_linediscriminator (line, &disc);
6330 /* End sequence is special, it is one byte past. */
6331 char *a = format_dwarf_addr (dwflmod, address_size,
6332 address - (endseq ? 1 : 0), address);
6333 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6335 (statement ? 'S' : ' '),
6336 (block ? 'B' : ' '),
6337 (prologue_end ? 'P' : ' '),
6338 (epilogue_begin ? 'E' : ' '),
6339 (endseq ? '*' : ' '),
6340 disc, isa, lineop, a);
6351 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6352 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6356 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6361 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6362 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6363 (uint64_t) shdr->sh_offset);
6365 if (shdr->sh_size == 0)
6368 /* There is no functionality in libdw to read the information in the
6369 way it is represented here. Hardcode the decoder. */
6370 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6371 if (unlikely (data == NULL || data->d_buf == NULL))
6373 error (0, 0, gettext ("cannot get line data section data: %s"),
6378 const unsigned char *linep = (const unsigned char *) data->d_buf;
6379 const unsigned char *lineendp;
6382 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6384 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6386 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
6388 if (unlikely (linep + 4 > lineendp))
6390 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6391 unsigned int length = 4;
6392 if (unlikely (unit_length == 0xffffffff))
6394 if (unlikely (linep + 8 > lineendp))
6397 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6398 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6401 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6405 /* Check whether we have enough room in the section. */
6406 if (unlikely (unit_length > (size_t) (lineendp - linep)
6407 || unit_length < 2 + length + 5 * 1))
6409 lineendp = linep + unit_length;
6411 /* The next element of the header is the version identifier. */
6412 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6414 /* Next comes the header length. */
6415 Dwarf_Word header_length;
6417 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6419 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6420 //const unsigned char *header_start = linep;
6422 /* Next the minimum instruction length. */
6423 uint_fast8_t minimum_instr_len = *linep++;
6425 /* Next the maximum operations per instruction, in version 4 format. */
6426 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6428 /* Then the flag determining the default value of the is_stmt
6430 uint_fast8_t default_is_stmt = *linep++;
6432 /* Now the line base. */
6433 int_fast8_t line_base = *((const int_fast8_t *) linep);
6436 /* And the line range. */
6437 uint_fast8_t line_range = *linep++;
6439 /* The opcode base. */
6440 uint_fast8_t opcode_base = *linep++;
6442 /* Print what we got so far. */
6443 printf (gettext ("\n"
6444 " Length: %" PRIu64 "\n"
6445 " DWARF version: %" PRIuFAST16 "\n"
6446 " Prologue length: %" PRIu64 "\n"
6447 " Minimum instruction length: %" PRIuFAST8 "\n"
6448 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6449 " Initial value if '%s': %" PRIuFAST8 "\n"
6450 " Line base: %" PRIdFAST8 "\n"
6451 " Line range: %" PRIuFAST8 "\n"
6452 " Opcode base: %" PRIuFAST8 "\n"
6455 (uint64_t) unit_length, version, (uint64_t) header_length,
6456 minimum_instr_len, max_ops_per_instr,
6457 "is_stmt", default_is_stmt, line_base,
6458 line_range, opcode_base);
6460 if (unlikely (linep + opcode_base - 1 >= lineendp))
6464 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6465 linep - (const unsigned char *) data->d_buf,
6466 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6470 int opcode_base_l10 = 1;
6471 unsigned int tmp = opcode_base;
6477 const uint8_t *standard_opcode_lengths = linep - 1;
6478 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6479 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6480 " [%*" PRIuFAST8 "] %hhu arguments\n",
6481 (int) linep[cnt - 1]),
6482 opcode_base_l10, cnt, linep[cnt - 1]);
6483 linep += opcode_base - 1;
6484 if (unlikely (linep >= lineendp))
6487 puts (gettext ("\nDirectory table:"));
6490 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6491 if (unlikely (endp == NULL))
6494 printf (" %s\n", (char *) linep);
6498 /* Skip the final NUL byte. */
6501 if (unlikely (linep >= lineendp))
6503 puts (gettext ("\nFile name table:\n"
6504 " Entry Dir Time Size Name"));
6505 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6507 /* First comes the file name. */
6508 char *fname = (char *) linep;
6509 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6510 if (unlikely (endp == NULL))
6514 /* Then the index. */
6515 unsigned int diridx;
6516 if (lineendp - linep < 1)
6518 get_uleb128 (diridx, linep, lineendp);
6520 /* Next comes the modification time. */
6522 if (lineendp - linep < 1)
6524 get_uleb128 (mtime, linep, lineendp);
6526 /* Finally the length of the file. */
6528 if (lineendp - linep < 1)
6530 get_uleb128 (fsize, linep, lineendp);
6532 printf (" %-5u %-5u %-9u %-9u %s\n",
6533 cnt, diridx, mtime, fsize, fname);
6535 /* Skip the final NUL byte. */
6538 puts (gettext ("\nLine number statements:"));
6539 Dwarf_Word address = 0;
6540 unsigned int op_index = 0;
6542 uint_fast8_t is_stmt = default_is_stmt;
6544 /* Default address value, in case we do not find the CU. */
6546 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6548 /* Determine the CU this block is for. */
6550 Dwarf_Off ncuoffset = 0;
6552 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6553 NULL, NULL, NULL) == 0)
6556 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6558 Dwarf_Attribute stmt_list;
6559 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6562 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6564 if (lineoff == start_offset)
6567 address_size = cudie.cu->address_size;
6572 /* Apply the "operation advance" from a special opcode
6573 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6574 unsigned int op_addr_advance;
6576 inline void advance_pc (unsigned int op_advance)
6578 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6579 / max_ops_per_instr);
6580 address += op_advance;
6581 show_op_index = (op_index > 0 ||
6582 (op_index + op_advance) % max_ops_per_instr > 0);
6583 op_index = (op_index + op_advance) % max_ops_per_instr;
6586 if (max_ops_per_instr == 0)
6589 gettext ("invalid maximum operations per instruction is zero"));
6594 while (linep < lineendp)
6596 size_t offset = linep - (const unsigned char *) data->d_buf;
6600 /* Read the opcode. */
6601 unsigned int opcode = *linep++;
6603 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6604 /* Is this a special opcode? */
6605 if (likely (opcode >= opcode_base))
6607 if (unlikely (line_range == 0))
6610 /* Yes. Handling this is quite easy since the opcode value
6613 opcode = (desired line increment - line_base)
6614 + (line_range * address advance) + opcode_base
6616 int line_increment = (line_base
6617 + (opcode - opcode_base) % line_range);
6619 /* Perform the increments. */
6620 line += line_increment;
6621 advance_pc ((opcode - opcode_base) / line_range);
6623 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6626 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6627 opcode, op_addr_advance, a, op_index,
6628 line_increment, line);
6631 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6632 opcode, op_addr_advance, a, line_increment, line);
6635 else if (opcode == 0)
6637 /* This an extended opcode. */
6638 if (unlikely (linep + 2 > lineendp))
6642 unsigned int len = *linep++;
6644 if (unlikely (linep + len > lineendp))
6647 /* The sub-opcode. */
6650 printf (gettext (" extended opcode %u: "), opcode);
6654 case DW_LNE_end_sequence:
6655 puts (gettext (" end of sequence"));
6657 /* Reset the registers we care about. */
6661 is_stmt = default_is_stmt;
6664 case DW_LNE_set_address:
6666 if (unlikely ((size_t) (lineendp - linep) < address_size))
6668 if (address_size == 4)
6669 address = read_4ubyte_unaligned_inc (dbg, linep);
6671 address = read_8ubyte_unaligned_inc (dbg, linep);
6673 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6674 printf (gettext (" set address to %s\n"), a);
6679 case DW_LNE_define_file:
6681 char *fname = (char *) linep;
6682 unsigned char *endp = memchr (linep, '\0',
6684 if (unlikely (endp == NULL))
6688 unsigned int diridx;
6689 if (lineendp - linep < 1)
6691 get_uleb128 (diridx, linep, lineendp);
6693 if (lineendp - linep < 1)
6695 get_uleb128 (mtime, linep, lineendp);
6696 Dwarf_Word filelength;
6697 if (lineendp - linep < 1)
6699 get_uleb128 (filelength, linep, lineendp);
6702 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6703 diridx, (uint64_t) mtime, (uint64_t) filelength,
6708 case DW_LNE_set_discriminator:
6709 /* Takes one ULEB128 parameter, the discriminator. */
6710 if (unlikely (standard_opcode_lengths[opcode] != 1))
6713 get_uleb128 (u128, linep, lineendp);
6714 printf (gettext (" set discriminator to %u\n"), u128);
6718 /* Unknown, ignore it. */
6719 puts (gettext (" unknown opcode"));
6724 else if (opcode <= DW_LNS_set_isa)
6726 /* This is a known standard opcode. */
6730 /* Takes no argument. */
6731 puts (gettext (" copy"));
6734 case DW_LNS_advance_pc:
6735 /* Takes one uleb128 parameter which is added to the
6737 get_uleb128 (u128, linep, lineendp);
6740 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6743 advance address by %u to %s, op_index to %u\n"),
6744 op_addr_advance, a, op_index);
6746 printf (gettext (" advance address by %u to %s\n"),
6747 op_addr_advance, a);
6752 case DW_LNS_advance_line:
6753 /* Takes one sleb128 parameter which is added to the
6755 get_sleb128 (s128, linep, lineendp);
6758 advance line by constant %d to %" PRId64 "\n"),
6759 s128, (int64_t) line);
6762 case DW_LNS_set_file:
6763 /* Takes one uleb128 parameter which is stored in file. */
6764 get_uleb128 (u128, linep, lineendp);
6765 printf (gettext (" set file to %" PRIu64 "\n"),
6769 case DW_LNS_set_column:
6770 /* Takes one uleb128 parameter which is stored in column. */
6771 if (unlikely (standard_opcode_lengths[opcode] != 1))
6774 get_uleb128 (u128, linep, lineendp);
6775 printf (gettext (" set column to %" PRIu64 "\n"),
6779 case DW_LNS_negate_stmt:
6780 /* Takes no argument. */
6781 is_stmt = 1 - is_stmt;
6782 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6783 "is_stmt", is_stmt);
6786 case DW_LNS_set_basic_block:
6787 /* Takes no argument. */
6788 puts (gettext (" set basic block flag"));
6791 case DW_LNS_const_add_pc:
6792 /* Takes no argument. */
6794 if (unlikely (line_range == 0))
6797 advance_pc ((255 - opcode_base) / line_range);
6799 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6802 advance address by constant %u to %s, op_index to %u\n"),
6803 op_addr_advance, a, op_index);
6806 advance address by constant %u to %s\n"),
6807 op_addr_advance, a);
6812 case DW_LNS_fixed_advance_pc:
6813 /* Takes one 16 bit parameter which is added to the
6815 if (unlikely (standard_opcode_lengths[opcode] != 1))
6818 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6822 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6824 advance address by fixed value %u to %s\n"),
6830 case DW_LNS_set_prologue_end:
6831 /* Takes no argument. */
6832 puts (gettext (" set prologue end flag"));
6835 case DW_LNS_set_epilogue_begin:
6836 /* Takes no argument. */
6837 puts (gettext (" set epilogue begin flag"));
6840 case DW_LNS_set_isa:
6841 /* Takes one uleb128 parameter which is stored in isa. */
6842 if (unlikely (standard_opcode_lengths[opcode] != 1))
6845 get_uleb128 (u128, linep, lineendp);
6846 printf (gettext (" set isa to %u\n"), u128);
6852 /* This is a new opcode the generator but not we know about.
6853 Read the parameters associated with it but then discard
6854 everything. Read all the parameters for this opcode. */
6855 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6856 " unknown opcode with %" PRIu8 " parameters:",
6857 standard_opcode_lengths[opcode]),
6858 standard_opcode_lengths[opcode]);
6859 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6861 get_uleb128 (u128, linep, lineendp);
6862 if (n != standard_opcode_lengths[opcode])
6863 putc_unlocked (',', stdout);
6864 printf (" %u", u128);
6867 /* Next round, ignore this opcode. */
6873 /* There must only be one data block. */
6874 assert (elf_getdata (scn, data) == NULL);
6879 print_debug_loc_section (Dwfl_Module *dwflmod,
6880 Ebl *ebl, GElf_Ehdr *ehdr,
6881 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6883 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6885 if (unlikely (data == NULL))
6887 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6893 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6894 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6895 (uint64_t) shdr->sh_offset);
6897 sort_listptr (&known_loclistptr, "loclistptr");
6898 size_t listptr_idx = 0;
6900 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6901 uint_fast8_t offset_size = 4;
6904 struct Dwarf_CU *cu = NULL;
6905 Dwarf_Addr base = 0;
6906 unsigned char *readp = data->d_buf;
6907 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6908 while (readp < endp)
6910 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6912 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6913 &address_size, &offset_size, &base,
6914 &cu, offset, &readp, endp))
6917 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6919 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6925 if (address_size == 8)
6927 begin = read_8ubyte_unaligned_inc (dbg, readp);
6928 end = read_8ubyte_unaligned_inc (dbg, readp);
6932 begin = read_4ubyte_unaligned_inc (dbg, readp);
6933 end = read_4ubyte_unaligned_inc (dbg, readp);
6934 if (begin == (Dwarf_Addr) (uint32_t) -1)
6935 begin = (Dwarf_Addr) -1l;
6938 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6940 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6941 printf (gettext (" [%6tx] base address %s\n"), offset, b);
6945 else if (begin == 0 && end == 0) /* End of list entry. */
6948 printf (gettext (" [%6tx] empty list\n"), offset);
6953 /* We have a location expression entry. */
6954 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6956 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6958 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6961 if (first) /* First entry in a list. */
6962 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
6964 printf (gettext (" %s..%s"), b, e);
6969 if (endp - readp <= (ptrdiff_t) len)
6971 fputs (gettext (" <INVALID DATA>\n"), stdout);
6975 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6976 3 /*XXX*/, address_size, offset_size, cu, len, readp);
6989 struct mac_culist *next;
6994 mac_compare (const void *p1, const void *p2)
6996 struct mac_culist *m1 = (struct mac_culist *) p1;
6997 struct mac_culist *m2 = (struct mac_culist *) p2;
6999 if (m1->offset < m2->offset)
7001 if (m1->offset > m2->offset)
7008 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7009 Ebl *ebl, GElf_Ehdr *ehdr,
7010 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7013 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7014 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7015 (uint64_t) shdr->sh_offset);
7016 putc_unlocked ('\n', stdout);
7018 /* There is no function in libdw to iterate over the raw content of
7019 the section but it is easy enough to do. */
7020 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7021 if (unlikely (data == NULL || data->d_buf == NULL))
7023 error (0, 0, gettext ("cannot get macro information section data: %s"),
7028 /* Get the source file information for all CUs. */
7032 struct mac_culist *culist = NULL;
7034 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7037 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7040 Dwarf_Attribute attr;
7041 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7045 if (dwarf_formudata (&attr, &macoff) != 0)
7048 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7050 newp->offset = macoff;
7052 newp->next = culist;
7057 /* Convert the list into an array for easier consumption. */
7058 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7061 cus[nculist].offset = data->d_size;
7062 cus[nculist].files = (Dwarf_Files *) -1l;
7065 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7067 assert (cnt < nculist);
7069 culist = culist->next;
7072 /* Sort the array according to the offset in the .debug_macinfo
7073 section. Note we keep the sentinel at the end. */
7074 qsort (cus, nculist, sizeof (*cus), mac_compare);
7077 const unsigned char *readp = (const unsigned char *) data->d_buf;
7078 const unsigned char *readendp = readp + data->d_size;
7081 while (readp < readendp)
7083 unsigned int opcode = *readp++;
7085 unsigned int u128_2;
7086 const unsigned char *endp;
7090 case DW_MACINFO_define:
7091 case DW_MACINFO_undef:
7092 case DW_MACINFO_vendor_ext:
7093 /* For the first two opcodes the parameters are
7097 We can treat these cases together. */
7098 get_uleb128 (u128, readp, readendp);
7100 endp = memchr (readp, '\0', readendp - readp);
7101 if (unlikely (endp == NULL))
7104 %*s*** non-terminated string at end of section"),
7109 if (opcode == DW_MACINFO_define)
7110 printf ("%*s#define %s, line %u\n",
7111 level, "", (char *) readp, u128);
7112 else if (opcode == DW_MACINFO_undef)
7113 printf ("%*s#undef %s, line %u\n",
7114 level, "", (char *) readp, u128);
7116 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7121 case DW_MACINFO_start_file:
7122 /* The two parameters are line and file index, in this order. */
7123 get_uleb128 (u128, readp, readendp);
7124 if (readendp - readp < 1)
7127 %*s*** missing DW_MACINFO_start_file argument at end of section"),
7131 get_uleb128 (u128_2, readp, readendp);
7133 /* Find the CU DIE for this file. */
7134 size_t macoff = readp - (const unsigned char *) data->d_buf;
7135 const char *fname = "???";
7136 if (macoff >= cus[0].offset)
7138 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
7141 if (cus[0].files == NULL
7142 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7143 cus[0].files = (Dwarf_Files *) -1l;
7145 if (cus[0].files != (Dwarf_Files *) -1l)
7146 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7150 printf ("%*sstart_file %u, [%u] %s\n",
7151 level, "", u128, u128_2, fname);
7155 case DW_MACINFO_end_file:
7157 printf ("%*send_file\n", level, "");
7158 /* Nothing more to do. */
7162 // XXX gcc seems to generate files with a trailing zero.
7163 if (unlikely (opcode != 0 || readp != readendp))
7164 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7172 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7173 Ebl *ebl, GElf_Ehdr *ehdr,
7174 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7177 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7178 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7179 (uint64_t) shdr->sh_offset);
7180 putc_unlocked ('\n', stdout);
7182 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7183 if (unlikely (data == NULL || data->d_buf == NULL))
7185 error (0, 0, gettext ("cannot get macro information section data: %s"),
7190 /* Get the source file information for all CUs. Uses same
7191 datastructure as macinfo. But uses offset field to directly
7192 match .debug_line offset. And just stored in a list. */
7196 struct mac_culist *culist = NULL;
7198 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7201 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7204 Dwarf_Attribute attr;
7205 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7209 if (dwarf_formudata (&attr, &lineoff) != 0)
7212 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7214 newp->offset = lineoff;
7216 newp->next = culist;
7221 const unsigned char *readp = (const unsigned char *) data->d_buf;
7222 const unsigned char *readendp = readp + data->d_size;
7224 while (readp < readendp)
7226 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7227 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7229 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7230 // optional vendor extension macro entry table.
7231 if (readp + 2 > readendp)
7234 error (0, 0, gettext ("invalid data"));
7237 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7238 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7240 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7241 // 5 when it gets standardized.
7244 printf (gettext (" unknown version, cannot parse section\n"));
7248 if (readp + 1 > readendp)
7250 const unsigned char flag = *readp++;
7251 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7253 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7254 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7255 Dwarf_Off line_offset = -1;
7258 if (offset_len == 8)
7259 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7261 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7262 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7266 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7267 memset (vendor, 0, sizeof vendor);
7270 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7271 // of arguments, for each argument 1 byte form code.
7272 if (readp + 1 > readendp)
7274 unsigned int tlen = *readp++;
7275 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7277 for (unsigned int i = 0; i < tlen; i++)
7279 if (readp + 1 > readendp)
7281 unsigned int opcode = *readp++;
7282 printf (gettext (" [%" PRIx8 "]"), opcode);
7283 if (opcode < DW_MACRO_GNU_lo_user
7284 || opcode > DW_MACRO_GNU_hi_user)
7286 // Record the start of description for this vendor opcode.
7287 // uleb128 nr args, 1 byte per arg form.
7288 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7289 if (readp + 1 > readendp)
7291 unsigned int args = *readp++;
7294 printf (gettext (" %" PRIu8 " arguments:"), args);
7297 if (readp + 1 > readendp)
7299 unsigned int form = *readp++;
7300 printf (" %s", dwarf_form_string (form));
7301 if (form != DW_FORM_data1
7302 && form != DW_FORM_data2
7303 && form != DW_FORM_data4
7304 && form != DW_FORM_data8
7305 && form != DW_FORM_sdata
7306 && form != DW_FORM_udata
7307 && form != DW_FORM_block
7308 && form != DW_FORM_block1
7309 && form != DW_FORM_block2
7310 && form != DW_FORM_block4
7311 && form != DW_FORM_flag
7312 && form != DW_FORM_string
7313 && form != DW_FORM_strp
7314 && form != DW_FORM_sec_offset)
7318 putchar_unlocked (',');
7322 printf (gettext (" no arguments."));
7323 putchar_unlocked ('\n');
7326 putchar_unlocked ('\n');
7329 if (readp + 1 > readendp)
7331 unsigned int opcode = *readp++;
7335 unsigned int u128_2;
7336 const unsigned char *endp;
7341 case DW_MACRO_GNU_start_file:
7342 get_uleb128 (u128, readp, readendp);
7343 if (readp >= readendp)
7345 get_uleb128 (u128_2, readp, readendp);
7347 /* Find the CU DIE that matches this line offset. */
7348 const char *fname = "???";
7349 if (line_offset != (Dwarf_Off) -1)
7351 struct mac_culist *cu = culist;
7352 while (cu != NULL && line_offset != cu->offset)
7356 if (cu->files == NULL
7357 && dwarf_getsrcfiles (&cu->die, &cu->files,
7359 cu->files = (Dwarf_Files *) -1l;
7361 if (cu->files != (Dwarf_Files *) -1l)
7362 fname = (dwarf_filesrc (cu->files, u128_2,
7363 NULL, NULL) ?: "???");
7366 printf ("%*sstart_file %u, [%u] %s\n",
7367 level, "", u128, u128_2, fname);
7371 case DW_MACRO_GNU_end_file:
7373 printf ("%*send_file\n", level, "");
7376 case DW_MACRO_GNU_define:
7377 get_uleb128 (u128, readp, readendp);
7378 endp = memchr (readp, '\0', readendp - readp);
7381 printf ("%*s#define %s, line %u\n",
7382 level, "", readp, u128);
7386 case DW_MACRO_GNU_undef:
7387 get_uleb128 (u128, readp, readendp);
7388 endp = memchr (readp, '\0', readendp - readp);
7391 printf ("%*s#undef %s, line %u\n",
7392 level, "", readp, u128);
7396 case DW_MACRO_GNU_define_indirect:
7397 get_uleb128 (u128, readp, readendp);
7398 if (readp + offset_len > readendp)
7400 if (offset_len == 8)
7401 off = read_8ubyte_unaligned_inc (dbg, readp);
7403 off = read_4ubyte_unaligned_inc (dbg, readp);
7404 printf ("%*s#define %s, line %u (indirect)\n",
7405 level, "", dwarf_getstring (dbg, off, NULL), u128);
7408 case DW_MACRO_GNU_undef_indirect:
7409 get_uleb128 (u128, readp, readendp);
7410 if (readp + offset_len > readendp)
7412 if (offset_len == 8)
7413 off = read_8ubyte_unaligned_inc (dbg, readp);
7415 off = read_4ubyte_unaligned_inc (dbg, readp);
7416 printf ("%*s#undef %s, line %u (indirect)\n",
7417 level, "", dwarf_getstring (dbg, off, NULL), u128);
7420 case DW_MACRO_GNU_transparent_include:
7421 if (readp + offset_len > readendp)
7423 if (offset_len == 8)
7424 off = read_8ubyte_unaligned_inc (dbg, readp);
7426 off = read_4ubyte_unaligned_inc (dbg, readp);
7427 printf ("%*s#include offset 0x%" PRIx64 "\n",
7432 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7433 if (opcode < DW_MACRO_GNU_lo_user
7434 || opcode > DW_MACRO_GNU_lo_user
7435 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7438 const unsigned char *op_desc;
7439 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7441 // Just skip the arguments, we cannot really interpret them,
7442 // but print as much as we can.
7443 unsigned int args = *op_desc++;
7446 unsigned int form = *op_desc++;
7451 if (readp + 1 > readendp)
7454 printf (" %" PRIx8, (unsigned int) val);
7458 if (readp + 2 > readendp)
7460 val = read_2ubyte_unaligned_inc (dbg, readp);
7461 printf(" %" PRIx16, (unsigned int) val);
7465 if (readp + 4 > readendp)
7467 val = read_4ubyte_unaligned_inc (dbg, readp);
7468 printf (" %" PRIx32, (unsigned int) val);
7472 if (readp + 8 > readendp)
7474 val = read_8ubyte_unaligned_inc (dbg, readp);
7475 printf (" %" PRIx64, val);
7479 get_sleb128 (val, readp, readendp);
7480 printf (" %" PRIx64, val);
7484 get_uleb128 (val, readp, readendp);
7485 printf (" %" PRIx64, val);
7489 get_uleb128 (val, readp, readendp);
7490 printf (" block[%" PRIu64 "]", val);
7491 if (readp + val > readendp)
7496 case DW_FORM_block1:
7497 if (readp + 1 > readendp)
7500 printf (" block[%" PRIu64 "]", val);
7501 if (readp + val > readendp)
7505 case DW_FORM_block2:
7506 if (readp + 2 > readendp)
7508 val = read_2ubyte_unaligned_inc (dbg, readp);
7509 printf (" block[%" PRIu64 "]", val);
7510 if (readp + val > readendp)
7514 case DW_FORM_block4:
7515 if (readp + 2 > readendp)
7517 val =read_4ubyte_unaligned_inc (dbg, readp);
7518 printf (" block[%" PRIu64 "]", val);
7519 if (readp + val > readendp)
7524 if (readp + 1 > readendp)
7527 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7530 case DW_FORM_string:
7531 endp = memchr (readp, '\0', readendp - readp);
7534 printf (" %s", readp);
7539 if (readp + offset_len > readendp)
7541 if (offset_len == 8)
7542 val = read_8ubyte_unaligned_inc (dbg, readp);
7544 val = read_4ubyte_unaligned_inc (dbg, readp);
7545 printf (" %s", dwarf_getstring (dbg, val, NULL));
7548 case DW_FORM_sec_offset:
7549 if (readp + offset_len > readendp)
7551 if (offset_len == 8)
7552 val = read_8ubyte_unaligned_inc (dbg, readp);
7554 val = read_4ubyte_unaligned_inc (dbg, readp);
7555 printf (" %" PRIx64, val);
7559 error (0, 0, gettext ("vendor opcode not verified?"));
7565 putchar_unlocked (',');
7567 putchar_unlocked ('\n');
7570 if (readp + 1 > readendp)
7574 putchar_unlocked ('\n');
7580 /* Callback for printing global names. */
7582 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7585 int *np = (int *) arg;
7587 printf (gettext (" [%5d] DIE offset: %6" PRId64
7588 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7589 (*np)++, global->die_offset, global->cu_offset, global->name);
7595 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7597 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7598 Ebl *ebl, GElf_Ehdr *ehdr,
7599 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7601 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7602 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7603 (uint64_t) shdr->sh_offset);
7606 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7609 /* Print the content of the DWARF string section '.debug_str'. */
7611 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7612 Ebl *ebl, GElf_Ehdr *ehdr,
7613 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7615 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7616 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7618 /* Compute floor(log16(shdr->sh_size)). */
7619 GElf_Addr tmp = sh_size;
7626 digits = MAX (4, digits);
7628 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7631 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7632 /* TRANS: the debugstr| prefix makes the string unique. */
7633 digits + 2, sgettext ("debugstr|Offset"));
7635 Dwarf_Off offset = 0;
7636 while (offset < sh_size)
7639 const char *str = dwarf_getstring (dbg, offset, &len);
7640 if (unlikely (str == NULL))
7642 printf (gettext (" *** error while reading strings: %s\n"),
7647 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7654 /* Print the content of the call frame search table section
7657 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7658 Ebl *ebl __attribute__ ((unused)),
7659 GElf_Ehdr *ehdr __attribute__ ((unused)),
7660 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7663 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7666 Elf_Data *data = elf_rawdata (scn, NULL);
7668 if (unlikely (data == NULL))
7670 error (0, 0, gettext ("cannot get %s content: %s"),
7671 ".eh_frame_hdr", elf_errmsg (-1));
7675 const unsigned char *readp = data->d_buf;
7676 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7679 if (unlikely (readp + 4 > dataend))
7682 error (0, 0, gettext ("invalid data"));
7686 unsigned int version = *readp++;
7687 unsigned int eh_frame_ptr_enc = *readp++;
7688 unsigned int fde_count_enc = *readp++;
7689 unsigned int table_enc = *readp++;
7691 printf (" version: %u\n"
7692 " eh_frame_ptr_enc: %#x ",
7693 version, eh_frame_ptr_enc);
7694 print_encoding_base ("", eh_frame_ptr_enc);
7695 printf (" fde_count_enc: %#x ", fde_count_enc);
7696 print_encoding_base ("", fde_count_enc);
7697 printf (" table_enc: %#x ", table_enc);
7698 print_encoding_base ("", table_enc);
7700 uint64_t eh_frame_ptr = 0;
7701 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7703 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7705 if (unlikely (readp == NULL))
7708 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7709 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7710 printf (" (offset: %#" PRIx64 ")",
7711 /* +4 because of the 4 byte header of the section. */
7712 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7714 putchar_unlocked ('\n');
7717 uint64_t fde_count = 0;
7718 if (fde_count_enc != DW_EH_PE_omit)
7720 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7721 if (unlikely (readp == NULL))
7724 printf (" fde_count: %" PRIu64 "\n", fde_count);
7727 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7732 /* Optimize for the most common case. */
7733 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7734 while (fde_count > 0 && readp + 8 <= dataend)
7736 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7737 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7738 + (int64_t) initial_location);
7739 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7740 // XXX Possibly print symbol name or section offset for initial_offset
7741 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7742 " fde=[%6" PRIx64 "]\n",
7743 initial_location, initial_offset,
7744 address, address - (eh_frame_ptr + 4));
7747 while (0 && readp < dataend)
7754 /* Print the content of the exception handling table section
7757 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7758 Ebl *ebl __attribute__ ((unused)),
7759 GElf_Ehdr *ehdr __attribute__ ((unused)),
7761 GElf_Shdr *shdr __attribute__ ((unused)),
7762 Dwarf *dbg __attribute__ ((unused)))
7765 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7768 Elf_Data *data = elf_rawdata (scn, NULL);
7770 if (unlikely (data == NULL))
7772 error (0, 0, gettext ("cannot get %s content: %s"),
7773 ".gcc_except_table", elf_errmsg (-1));
7777 const unsigned char *readp = data->d_buf;
7778 const unsigned char *const dataend = readp + data->d_size;
7780 if (unlikely (readp + 1 > dataend))
7783 error (0, 0, gettext ("invalid data"));
7786 unsigned int lpstart_encoding = *readp++;
7787 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7788 print_encoding_base ("", lpstart_encoding);
7789 if (lpstart_encoding != DW_EH_PE_omit)
7792 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7793 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7796 if (unlikely (readp + 1 > dataend))
7798 unsigned int ttype_encoding = *readp++;
7799 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7800 print_encoding_base ("", ttype_encoding);
7801 const unsigned char *ttype_base = NULL;
7802 if (ttype_encoding != DW_EH_PE_omit)
7804 unsigned int ttype_base_offset;
7805 get_uleb128 (ttype_base_offset, readp, dataend);
7806 printf (" TType base offset: %#x\n", ttype_base_offset);
7807 if ((size_t) (dataend - readp) > ttype_base_offset)
7808 ttype_base = readp + ttype_base_offset;
7811 if (unlikely (readp + 1 > dataend))
7813 unsigned int call_site_encoding = *readp++;
7814 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7815 print_encoding_base ("", call_site_encoding);
7816 unsigned int call_site_table_len;
7817 get_uleb128 (call_site_table_len, readp, dataend);
7819 const unsigned char *const action_table = readp + call_site_table_len;
7820 if (unlikely (action_table > dataend))
7823 unsigned int max_action = 0;
7824 while (readp < action_table)
7827 puts (gettext ("\n Call site table:"));
7829 uint64_t call_site_start;
7830 readp = read_encoded (call_site_encoding, readp, dataend,
7831 &call_site_start, dbg);
7832 uint64_t call_site_length;
7833 readp = read_encoded (call_site_encoding, readp, dataend,
7834 &call_site_length, dbg);
7835 uint64_t landing_pad;
7836 readp = read_encoded (call_site_encoding, readp, dataend,
7838 unsigned int action;
7839 get_uleb128 (action, readp, dataend);
7840 max_action = MAX (action, max_action);
7841 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7842 " Call site length: %" PRIu64 "\n"
7843 " Landing pad: %#" PRIx64 "\n"
7845 u++, call_site_start, call_site_length, landing_pad, action);
7847 if (readp != action_table)
7850 unsigned int max_ar_filter = 0;
7853 puts ("\n Action table:");
7855 size_t maxdata = (size_t) (dataend - action_table);
7856 if (max_action > maxdata || maxdata - max_action < 1)
7858 invalid_action_table:
7859 fputs (gettext (" <INVALID DATA>\n"), stdout);
7863 const unsigned char *const action_table_end
7864 = action_table + max_action + 1;
7870 get_sleb128 (ar_filter, readp, action_table_end);
7871 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7872 max_ar_filter = ar_filter;
7874 if (readp >= action_table_end)
7875 goto invalid_action_table;
7876 get_sleb128 (ar_disp, readp, action_table_end);
7878 printf (" [%4u] ar_filter: % d\n"
7880 u, ar_filter, ar_disp);
7881 if (abs (ar_disp) & 1)
7882 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7883 else if (ar_disp != 0)
7886 putchar_unlocked ('\n');
7889 while (readp < action_table_end);
7892 if (max_ar_filter > 0 && ttype_base != NULL)
7894 unsigned char dsize;
7895 puts ("\n TType table:");
7897 // XXX Not *4, size of encoding;
7898 switch (ttype_encoding & 7)
7900 case DW_EH_PE_udata2:
7901 case DW_EH_PE_sdata2:
7904 case DW_EH_PE_udata4:
7905 case DW_EH_PE_sdata4:
7908 case DW_EH_PE_udata8:
7909 case DW_EH_PE_sdata8:
7913 error (1, 0, gettext ("invalid TType encoding"));
7917 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
7920 readp = ttype_base - max_ar_filter * dsize;
7924 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7926 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7928 while (readp < ttype_base);
7932 /* Print the content of the '.gdb_index' section.
7933 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7936 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7937 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7939 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7940 " contains %" PRId64 " bytes :\n"),
7941 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7942 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7944 Elf_Data *data = elf_rawdata (scn, NULL);
7946 if (unlikely (data == NULL))
7948 error (0, 0, gettext ("cannot get %s content: %s"),
7949 ".gdb_index", elf_errmsg (-1));
7953 // .gdb_index is always in little endian.
7954 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7957 const unsigned char *readp = data->d_buf;
7958 const unsigned char *const dataend = readp + data->d_size;
7960 if (unlikely (readp + 4 > dataend))
7963 error (0, 0, gettext ("invalid data"));
7967 int32_t vers = read_4ubyte_unaligned (dbg, readp);
7968 printf (gettext (" Version: %" PRId32 "\n"), vers);
7970 // The only difference between version 4 and version 5 is the
7971 // hash used for generating the table. Version 6 contains symbols
7972 // for inlined functions, older versions didn't. Version 7 adds
7973 // symbol kinds. Version 8 just indicates that it correctly includes
7975 if (vers < 4 || vers > 8)
7977 printf (gettext (" unknown version, cannot parse section\n"));
7982 if (unlikely (readp + 4 > dataend))
7985 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7986 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
7989 if (unlikely (readp + 4 > dataend))
7992 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7993 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
7996 if (unlikely (readp + 4 > dataend))
7999 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
8000 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
8003 if (unlikely (readp + 4 > dataend))
8006 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8007 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
8010 if (unlikely (readp + 4 > dataend))
8013 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8014 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8016 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
8020 readp = data->d_buf + cu_off;
8022 const unsigned char *nextp = data->d_buf + tu_off;
8023 if (tu_off >= data->d_size)
8026 size_t cu_nr = (nextp - readp) / 16;
8028 printf (gettext ("\n CU list at offset %#" PRIx32
8029 " contains %zu entries:\n"),
8033 while (dataend - readp >= 16 && n < cu_nr)
8035 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8038 uint64_t len = read_8ubyte_unaligned (dbg, readp);
8041 printf (" [%4zu] start: %0#8" PRIx64
8042 ", length: %5" PRIu64 "\n", n, off, len);
8046 readp = data->d_buf + tu_off;
8047 nextp = data->d_buf + addr_off;
8048 if (addr_off >= data->d_size)
8051 size_t tu_nr = (nextp - readp) / 24;
8053 printf (gettext ("\n TU list at offset %#" PRIx32
8054 " contains %zu entries:\n"),
8058 while (dataend - readp >= 24 && n < tu_nr)
8060 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8063 uint64_t type = read_8ubyte_unaligned (dbg, readp);
8066 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8069 printf (" [%4zu] CU offset: %5" PRId64
8070 ", type offset: %5" PRId64
8071 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8075 readp = data->d_buf + addr_off;
8076 nextp = data->d_buf + sym_off;
8077 if (sym_off >= data->d_size)
8080 size_t addr_nr = (nextp - readp) / 20;
8082 printf (gettext ("\n Address list at offset %#" PRIx32
8083 " contains %zu entries:\n"),
8087 while (dataend - readp >= 20 && n < addr_nr)
8089 uint64_t low = read_8ubyte_unaligned (dbg, readp);
8092 uint64_t high = read_8ubyte_unaligned (dbg, readp);
8095 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8098 char *l = format_dwarf_addr (dwflmod, 8, low, low);
8099 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8100 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8107 const unsigned char *const_start = data->d_buf + const_off;
8108 if (const_off >= data->d_size)
8111 readp = data->d_buf + sym_off;
8112 nextp = const_start;
8113 size_t sym_nr = (nextp - readp) / 8;
8115 printf (gettext ("\n Symbol table at offset %#" PRIx32
8116 " contains %zu slots:\n"),
8120 while (dataend - readp >= 8 && n < sym_nr)
8122 uint32_t name = read_4ubyte_unaligned (dbg, readp);
8125 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8128 if (name != 0 || vector != 0)
8130 const unsigned char *sym = const_start + name;
8131 if (unlikely ((size_t) (dataend - const_start) < name
8132 || memchr (sym, '\0', dataend - sym) == NULL))
8135 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8137 const unsigned char *readcus = const_start + vector;
8138 if (unlikely ((size_t) (dataend - const_start) < vector))
8140 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8143 uint32_t cu_kind, cu, kind;
8146 if (unlikely (readcus + 4 > dataend))
8148 cu_kind = read_4ubyte_unaligned (dbg, readcus);
8149 cu = cu_kind & ((1 << 24) - 1);
8150 kind = (cu_kind >> 28) & 7;
8151 is_static = cu_kind & (1U << 31);
8153 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8155 printf ("%" PRId32, cu);
8174 printf ("unknown-0x%" PRIx32, kind);
8177 printf (":%c)", (is_static ? 'S' : 'G'));
8189 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8191 /* Before we start the real work get a debug context descriptor. */
8193 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8197 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8201 if ((print_debug_sections & ~section_exception) != 0)
8202 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8207 /* Get the section header string table index. */
8209 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8210 error (EXIT_FAILURE, 0,
8211 gettext ("cannot get section header string table index"));
8213 /* Look through all the sections for the debugging sections to print. */
8214 Elf_Scn *scn = NULL;
8215 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8218 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8220 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8225 enum section_e bitmask;
8226 void (*fp) (Dwfl_Module *, Ebl *,
8227 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8228 } debug_sections[] =
8230 #define NEW_SECTION(name) \
8231 { ".debug_" #name, section_##name, print_debug_##name##_section }
8232 NEW_SECTION (abbrev),
8233 NEW_SECTION (aranges),
8234 NEW_SECTION (frame),
8236 NEW_SECTION (types),
8239 NEW_SECTION (pubnames),
8241 NEW_SECTION (macinfo),
8242 NEW_SECTION (macro),
8243 NEW_SECTION (ranges),
8244 { ".eh_frame", section_frame | section_exception,
8245 print_debug_frame_section },
8246 { ".eh_frame_hdr", section_frame | section_exception,
8247 print_debug_frame_hdr_section },
8248 { ".gcc_except_table", section_frame | section_exception,
8249 print_debug_exception_table },
8250 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8252 const int ndebug_sections = (sizeof (debug_sections)
8253 / sizeof (debug_sections[0]));
8254 const char *name = elf_strptr (ebl->elf, shstrndx,
8260 for (n = 0; n < ndebug_sections; ++n)
8261 if (strcmp (name, debug_sections[n].name) == 0
8263 || (name[0] == '.' && name[1] == 'z'
8264 && debug_sections[n].name[1] == 'd'
8265 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8269 if ((print_debug_sections | implicit_debug_sections)
8270 & debug_sections[n].bitmask)
8271 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8277 reset_listptr (&known_loclistptr);
8278 reset_listptr (&known_rangelistptr);
8282 #define ITEM_INDENT 4
8283 #define WRAP_COLUMN 75
8285 /* Print "NAME: FORMAT", wrapping when output text would make the line
8286 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8287 but this function is also used for registers which should be printed
8288 aligned. Fortunately registers output uses fixed fields width (such
8289 as %11d) for the alignment.
8291 Line breaks should not depend on the particular values although that
8292 may happen in some cases of the core items. */
8295 __attribute__ ((format (printf, 6, 7)))
8296 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8297 size_t name_width, const char *name, const char *format, ...)
8299 size_t len = strlen (name);
8300 if (name_width < len)
8305 va_start (ap, format);
8306 int out_len = vasprintf (&out, format, ap);
8309 error (EXIT_FAILURE, 0, _("memory exhausted"));
8311 size_t n = name_width + sizeof ": " - 1 + out_len;
8315 printf ("%*s", ITEM_INDENT, "");
8316 colno = ITEM_INDENT + n;
8318 else if (colno + 2 + n < wrap)
8320 printf ("%c ", sep);
8325 printf ("\n%*s", ITEM_INDENT, "");
8326 colno = ITEM_INDENT + n;
8329 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8337 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8338 void *value, const void *data, size_t size)
8340 Elf_Data valuedata =
8344 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8345 .d_version = EV_CURRENT,
8350 .d_buf = (void *) data,
8351 .d_size = valuedata.d_size,
8352 .d_version = EV_CURRENT,
8355 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8356 ? elf32_xlatetom : elf64_xlatetom)
8357 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8359 error (EXIT_FAILURE, 0,
8360 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8362 return data + indata.d_size;
8365 typedef uint8_t GElf_Byte;
8368 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8369 unsigned int colno, size_t *repeated_size)
8371 uint_fast16_t count = item->count ?: 1;
8374 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8375 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8376 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8377 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8378 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8379 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8381 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8382 union { TYPES; } value;
8385 void *data = &value;
8386 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8387 size_t convsize = size;
8388 if (repeated_size != NULL)
8390 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8392 data = alloca (*repeated_size);
8393 count *= *repeated_size / size;
8394 convsize = count * size;
8395 *repeated_size -= convsize;
8397 else if (item->count != 0 || item->format != '\n')
8398 *repeated_size -= size;
8401 convert (core, item->type, count, data, desc + item->offset, convsize);
8403 Elf_Type type = item->type;
8404 if (type == ELF_T_ADDR)
8405 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8407 switch (item->format)
8410 assert (count == 1);
8413 #define DO_TYPE(NAME, Name, hex, dec) \
8414 case ELF_T_##NAME: \
8415 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8416 0, item->name, dec, value.Name[0]); \
8426 assert (count == 1);
8429 #define DO_TYPE(NAME, Name, hex, dec) \
8430 case ELF_T_##NAME: \
8431 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8432 0, item->name, hex, value.Name[0]); \
8443 assert (size % sizeof (unsigned int) == 0);
8444 unsigned int nbits = count * size * 8;
8445 unsigned int pop = 0;
8446 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8447 pop += __builtin_popcount (*i);
8448 bool negate = pop > nbits / 2;
8449 const unsigned int bias = item->format == 'b';
8452 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8456 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8458 assert (size == sizeof (unsigned int) * 2);
8459 for (unsigned int *i = data;
8460 (void *) i < data + count * size; i += 2)
8462 unsigned int w = i[1];
8468 unsigned int lastbit = 0;
8469 unsigned int run = 0;
8470 for (const unsigned int *i = data;
8471 (void *) i < data + count * size; ++i)
8473 unsigned int bit = ((void *) i - data) * 8;
8474 unsigned int w = negate ? ~*i : *i;
8477 /* Note that a right shift equal to (or greater than)
8478 the number of bits of w is undefined behaviour. In
8479 particular when the least significant bit is bit 32
8480 (w = 0x8000000) then w >>= n is undefined. So
8481 explicitly handle that case separately. */
8482 unsigned int n = ffs (w);
8483 if (n < sizeof (w) * 8)
8489 if (lastbit != 0 && lastbit + 1 == bit)
8494 p += sprintf (p, "%u", bit - bias);
8496 p += sprintf (p, ",%u", bit - bias);
8498 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8505 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8506 p += sprintf (p, "-%u", lastbit - bias);
8508 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8509 negate ? "~<%s>" : "<%s>", printed);
8514 case (char) ('T'|0x80):
8515 assert (count == 2);
8520 #define DO_TYPE(NAME, Name, hex, dec) \
8521 case ELF_T_##NAME: \
8522 sec = value.Name[0]; \
8523 usec = value.Name[1]; \
8530 if (unlikely (item->format == (char) ('T'|0x80)))
8532 /* This is a hack for an ill-considered 64-bit ABI where
8533 tv_usec is actually a 32-bit field with 32 bits of padding
8534 rounding out struct timeval. We've already converted it as
8535 a 64-bit field. For little-endian, this just means the
8536 high half is the padding; it's presumably zero, but should
8537 be ignored anyway. For big-endian, it means the 32-bit
8538 field went into the high half of USEC. */
8540 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8541 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8546 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8547 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8551 assert (count == 1);
8552 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8553 "%c", value.Byte[0]);
8557 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8558 "%.*s", (int) count, value.Byte);
8562 /* This is a list of strings separated by '\n'. */
8563 assert (item->count == 0);
8564 assert (repeated_size != NULL);
8565 assert (item->name == NULL);
8566 if (unlikely (item->offset >= *repeated_size))
8569 const char *s = desc + item->offset;
8570 size = *repeated_size - item->offset;
8574 const char *eol = memchr (s, '\n', size);
8578 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8581 size -= eol + 1 - s;
8585 colno = WRAP_COLUMN;
8592 error (0, 0, "XXX not handling format '%c' for %s",
8593 item->format, item->name);
8603 /* Sort items by group, and by layout offset within each group. */
8605 compare_core_items (const void *a, const void *b)
8607 const Ebl_Core_Item *const *p1 = a;
8608 const Ebl_Core_Item *const *p2 = b;
8609 const Ebl_Core_Item *item1 = *p1;
8610 const Ebl_Core_Item *item2 = *p2;
8612 return ((item1->group == item2->group ? 0
8613 : strcmp (item1->group, item2->group))
8614 ?: (int) item1->offset - (int) item2->offset);
8617 /* Sort item groups by layout offset of the first item in the group. */
8619 compare_core_item_groups (const void *a, const void *b)
8621 const Ebl_Core_Item *const *const *p1 = a;
8622 const Ebl_Core_Item *const *const *p2 = b;
8623 const Ebl_Core_Item *const *group1 = *p1;
8624 const Ebl_Core_Item *const *group2 = *p2;
8625 const Ebl_Core_Item *item1 = *group1;
8626 const Ebl_Core_Item *item2 = *group2;
8628 return (int) item1->offset - (int) item2->offset;
8632 handle_core_items (Elf *core, const void *desc, size_t descsz,
8633 const Ebl_Core_Item *items, size_t nitems)
8637 unsigned int colno = 0;
8639 /* FORMAT '\n' makes sense to be present only as a single item as it
8640 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8641 if present as a single item but they can be also processed with other
8643 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8644 || items[0].format == 'B'))
8646 assert (items[0].offset == 0);
8647 size_t size = descsz;
8648 colno = handle_core_item (core, items, desc, colno, &size);
8649 /* If SIZE is not zero here there is some remaining data. But we do not
8650 know how to process it anyway. */
8653 for (size_t i = 0; i < nitems; ++i)
8654 assert (items[i].format != '\n');
8656 /* Sort to collect the groups together. */
8657 const Ebl_Core_Item *sorted_items[nitems];
8658 for (size_t i = 0; i < nitems; ++i)
8659 sorted_items[i] = &items[i];
8660 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8662 /* Collect the unique groups and sort them. */
8663 const Ebl_Core_Item **groups[nitems];
8664 groups[0] = &sorted_items[0];
8666 for (size_t i = 1; i < nitems; ++i)
8667 if (sorted_items[i]->group != sorted_items[i - 1]->group
8668 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8669 groups[ngroups++] = &sorted_items[i];
8670 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8672 /* Write out all the groups. */
8673 const void *last = desc;
8676 for (size_t i = 0; i < ngroups; ++i)
8678 for (const Ebl_Core_Item **item = groups[i];
8679 (item < &sorted_items[nitems]
8680 && ((*item)->group == groups[i][0]->group
8681 || !strcmp ((*item)->group, groups[i][0]->group)));
8683 colno = handle_core_item (core, *item, desc, colno, NULL);
8685 /* Force a line break at the end of the group. */
8686 colno = WRAP_COLUMN;
8692 /* This set of items consumed a certain amount of the note's data.
8693 If there is more data there, we have another unit of the same size.
8694 Loop to print that out too. */
8695 const Ebl_Core_Item *item = &items[nitems - 1];
8696 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8697 item->count ?: 1, EV_CURRENT);
8706 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8710 /* For just one repeat, print it unabridged twice. */
8715 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8716 ITEM_INDENT, "", reps);
8726 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8729 desc += regloc->offset;
8737 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8738 const Ebl_Register_Location *regloc, const void *desc,
8741 if (regloc->bits % 8 != 0)
8742 return handle_bit_registers (regloc, desc, colno);
8744 desc += regloc->offset;
8746 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8748 char name[REGNAMESZ];
8751 register_info (ebl, reg, regloc, name, &bits, &type);
8754 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8755 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8756 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8757 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8759 #define BITS(bits, xtype, sfmt, ufmt) \
8760 uint##bits##_t b##bits; int##bits##_t b##bits##s
8761 union { TYPES; uint64_t b128[2]; } value;
8766 case DW_ATE_unsigned:
8768 case DW_ATE_address:
8771 #define BITS(bits, xtype, sfmt, ufmt) \
8773 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8774 if (type == DW_ATE_signed) \
8775 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8777 sfmt, value.b##bits##s); \
8779 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8781 ufmt, value.b##bits); \
8787 assert (type == DW_ATE_unsigned);
8788 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8789 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8790 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8792 "0x%.16" PRIx64 "%.16" PRIx64,
8793 value.b128[!be], value.b128[be]);
8803 /* Print each byte in hex, the whole thing in native byte order. */
8804 assert (bits % 8 == 0);
8805 const uint8_t *bytes = desc;
8807 char hex[bits / 4 + 1];
8808 hex[bits / 4] = '\0';
8810 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8812 bytes += bits / 8 - 1;
8816 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8818 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8819 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8821 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8822 maxregname, name, "0x%s", hex);
8825 desc += regloc->pad;
8834 struct register_info
8836 const Ebl_Register_Location *regloc;
8838 char name[REGNAMESZ];
8845 register_bitpos (const struct register_info *r)
8847 return (r->regloc->offset * 8
8848 + ((r->regno - r->regloc->regno)
8849 * (r->regloc->bits + r->regloc->pad * 8)));
8853 compare_sets_by_info (const struct register_info *r1,
8854 const struct register_info *r2)
8856 return ((int) r2->bits - (int) r1->bits
8857 ?: register_bitpos (r1) - register_bitpos (r2));
8860 /* Sort registers by set, and by size and layout offset within each set. */
8862 compare_registers (const void *a, const void *b)
8864 const struct register_info *r1 = a;
8865 const struct register_info *r2 = b;
8867 /* Unused elements sort last. */
8868 if (r1->regloc == NULL)
8869 return r2->regloc == NULL ? 0 : 1;
8870 if (r2->regloc == NULL)
8873 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8874 ?: compare_sets_by_info (r1, r2));
8877 /* Sort register sets by layout offset of the first register in the set. */
8879 compare_register_sets (const void *a, const void *b)
8881 const struct register_info *const *p1 = a;
8882 const struct register_info *const *p2 = b;
8883 return compare_sets_by_info (*p1, *p2);
8887 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8888 const Ebl_Register_Location *reglocs, size_t nregloc)
8893 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8896 for (size_t i = 0; i < nregloc; ++i)
8897 if (maxnreg < reglocs[i].regno + reglocs[i].count)
8898 maxnreg = reglocs[i].regno + reglocs[i].count;
8899 assert (maxnreg > 0);
8902 struct register_info regs[maxnreg];
8903 memset (regs, 0, sizeof regs);
8905 /* Sort to collect the sets together. */
8907 for (size_t i = 0; i < nregloc; ++i)
8908 for (int reg = reglocs[i].regno;
8909 reg < reglocs[i].regno + reglocs[i].count;
8912 assert (reg < maxnreg);
8915 struct register_info *info = ®s[reg];
8916 info->regloc = ®locs[i];
8918 info->set = register_info (ebl, reg, ®locs[i],
8919 info->name, &info->bits, &info->type);
8921 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8923 /* Collect the unique sets and sort them. */
8924 inline bool same_set (const struct register_info *a,
8925 const struct register_info *b)
8927 return (a < ®s[maxnreg] && a->regloc != NULL
8928 && b < ®s[maxnreg] && b->regloc != NULL
8929 && a->bits == b->bits
8930 && (a->set == b->set || !strcmp (a->set, b->set)));
8932 struct register_info *sets[maxreg + 1];
8935 for (int i = 1; i <= maxreg; ++i)
8936 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
8937 sets[nsets++] = ®s[i];
8938 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8940 /* Write out all the sets. */
8941 unsigned int colno = 0;
8942 for (size_t i = 0; i < nsets; ++i)
8944 /* Find the longest name of a register in this set. */
8946 const struct register_info *end;
8947 for (end = sets[i]; same_set (sets[i], end); ++end)
8949 size_t len = strlen (end->name);
8954 for (const struct register_info *reg = sets[i];
8956 reg += reg->regloc->count ?: 1)
8957 colno = handle_core_register (ebl, core, maxname,
8958 reg->regloc, desc, colno);
8960 /* Force a line break at the end of the group. */
8961 colno = WRAP_COLUMN;
8968 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8970 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8973 error (EXIT_FAILURE, 0,
8974 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8976 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8977 for (size_t i = 0; i < nauxv; ++i)
8980 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8986 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8989 if (av->a_un.a_val == 0)
8990 printf (" %" PRIu64 "\n", av->a_type);
8992 printf (" %" PRIu64 ": %#" PRIx64 "\n",
8993 av->a_type, av->a_un.a_val);
8998 case '\0': /* Normally zero. */
8999 if (av->a_un.a_val == 0)
9001 printf (" %s\n", name);
9006 case 'p': /* address */
9007 case 's': /* address of string */
9008 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
9011 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
9014 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
9018 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
9020 const char *pfx = "<";
9021 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9023 if (av->a_un.a_val & bit)
9025 printf ("%s%s", pfx, p);
9040 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9042 return ptr < end && (size_t) (end - ptr) >= sz;
9046 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9049 if (! buf_has_data (*ptrp, end, 4))
9052 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9057 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9060 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9061 if (! buf_has_data (*ptrp, end, sz))
9070 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9080 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9082 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9084 error (EXIT_FAILURE, 0,
9085 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9087 unsigned char const *ptr = data->d_buf;
9088 unsigned char const *const end = data->d_buf + data->d_size;
9090 /* Siginfo head is three ints: signal number, error number, origin
9092 int si_signo, si_errno, si_code;
9093 if (! buf_read_int (core, &ptr, end, &si_signo)
9094 || ! buf_read_int (core, &ptr, end, &si_errno)
9095 || ! buf_read_int (core, &ptr, end, &si_code))
9098 printf (" Not enough data in NT_SIGINFO note.\n");
9102 /* Next is a pointer-aligned union of structures. On 64-bit
9103 machines, that implies a word of padding. */
9104 if (gelf_getclass (core) == ELFCLASS64)
9107 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
9108 si_signo, si_errno, si_code);
9119 if (! buf_read_ulong (core, &ptr, end, &addr))
9121 printf (" fault address: %#" PRIx64 "\n", addr);
9127 else if (si_code == SI_USER)
9130 if (! buf_read_int (core, &ptr, end, &pid)
9131 || ! buf_read_int (core, &ptr, end, &uid))
9133 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
9138 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9140 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9142 error (EXIT_FAILURE, 0,
9143 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9145 unsigned char const *ptr = data->d_buf;
9146 unsigned char const *const end = data->d_buf + data->d_size;
9148 uint64_t count, page_size;
9149 if (! buf_read_ulong (core, &ptr, end, &count)
9150 || ! buf_read_ulong (core, &ptr, end, &page_size))
9153 printf (" Not enough data in NT_FILE note.\n");
9157 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9158 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9159 if (count > maxcount)
9162 /* Where file names are stored. */
9163 unsigned char const *const fstart = ptr + 3 * count * addrsize;
9164 char const *fptr = (char *) fstart;
9166 printf (" %" PRId64 " files:\n", count);
9167 for (uint64_t i = 0; i < count; ++i)
9169 uint64_t mstart, mend, moffset;
9170 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9171 || ! buf_read_ulong (core, &ptr, fstart, &mend)
9172 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9175 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9179 int ct = printf (" %08" PRIx64 "-%08" PRIx64
9180 " %08" PRIx64 " %" PRId64,
9181 mstart, mend, moffset * page_size, mend - mstart);
9182 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9189 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9190 const char *name, const void *desc)
9192 GElf_Word regs_offset;
9194 const Ebl_Register_Location *reglocs;
9196 const Ebl_Core_Item *items;
9198 if (! ebl_core_note (ebl, nhdr, name,
9199 ®s_offset, &nregloc, ®locs, &nitems, &items))
9202 /* Pass 0 for DESCSZ when there are registers in the note,
9203 so that the ITEMS array does not describe the whole thing.
9204 For non-register notes, the actual descsz might be a multiple
9205 of the unit size, not just exactly the unit size. */
9206 unsigned int colno = handle_core_items (ebl->elf, desc,
9207 nregloc == 0 ? nhdr->n_descsz : 0,
9210 putchar_unlocked ('\n');
9212 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9215 putchar_unlocked ('\n');
9219 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9220 GElf_Off start, Elf_Data *data)
9222 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
9231 while (offset < data->d_size
9232 && (offset = gelf_getnote (data, offset,
9233 &nhdr, &name_offset, &desc_offset)) > 0)
9235 const char *name = data->d_buf + name_offset;
9236 const char *desc = data->d_buf + desc_offset;
9240 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
9241 (int) nhdr.n_namesz, name, nhdr.n_descsz,
9242 ehdr->e_type == ET_CORE
9243 ? ebl_core_note_type_name (ebl, nhdr.n_type,
9245 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9246 buf2, sizeof (buf2)));
9248 /* Filter out invalid entries. */
9249 if (memchr (name, '\0', nhdr.n_namesz) != NULL
9250 /* XXX For now help broken Linux kernels. */
9253 if (ehdr->e_type == ET_CORE)
9255 if (nhdr.n_type == NT_AUXV
9256 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9257 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9258 && !memcmp (name, "CORE", 4))
9259 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9260 start + desc_offset);
9261 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9262 switch (nhdr.n_type)
9265 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9266 start + desc_offset);
9270 handle_file_note (ebl->elf, nhdr.n_descsz,
9271 start + desc_offset);
9275 handle_core_note (ebl, &nhdr, name, desc);
9278 handle_core_note (ebl, &nhdr, name, desc);
9281 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9285 if (offset == data->d_size)
9289 error (EXIT_FAILURE, 0,
9290 gettext ("cannot get content of note section: %s"),
9295 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9297 /* If we have section headers, just look for SHT_NOTE sections.
9298 In a debuginfo file, the program headers are not reliable. */
9301 /* Get the section header string table index. */
9303 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9304 error (EXIT_FAILURE, 0,
9305 gettext ("cannot get section header string table index"));
9307 Elf_Scn *scn = NULL;
9308 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9311 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9313 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9314 /* Not what we are looking for. */
9318 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9320 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9321 shdr->sh_size, shdr->sh_offset);
9323 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9324 elf_getdata (scn, NULL));
9329 /* We have to look through the program header to find the note
9330 sections. There can be more than one. */
9331 for (size_t cnt = 0; cnt < phnum; ++cnt)
9334 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9336 if (phdr == NULL || phdr->p_type != PT_NOTE)
9337 /* Not what we are looking for. */
9341 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9342 phdr->p_filesz, phdr->p_offset);
9344 handle_notes_data (ebl, ehdr, phdr->p_offset,
9345 elf_getdata_rawchunk (ebl->elf,
9346 phdr->p_offset, phdr->p_filesz,
9353 hex_dump (const uint8_t *data, size_t len)
9358 printf (" 0x%08zx ", pos);
9360 const size_t chunk = MIN (len - pos, 16);
9362 for (size_t i = 0; i < chunk; ++i)
9364 printf ("%02x ", data[pos + i]);
9366 printf ("%02x", data[pos + i]);
9369 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9371 for (size_t i = 0; i < chunk; ++i)
9373 unsigned char b = data[pos + i];
9374 printf ("%c", isprint (b) ? b : '.');
9383 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9385 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9386 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
9387 elf_ndxscn (scn), name);
9390 Elf_Data *data = elf_rawdata (scn, NULL);
9392 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9393 elf_ndxscn (scn), name, elf_errmsg (-1));
9396 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9397 " bytes at offset %#0" PRIx64 ":\n"),
9398 elf_ndxscn (scn), name,
9399 shdr->sh_size, shdr->sh_offset);
9400 hex_dump (data->d_buf, data->d_size);
9406 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9408 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9409 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
9410 elf_ndxscn (scn), name);
9413 Elf_Data *data = elf_rawdata (scn, NULL);
9415 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9416 elf_ndxscn (scn), name, elf_errmsg (-1));
9419 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9420 " bytes at offset %#0" PRIx64 ":\n"),
9421 elf_ndxscn (scn), name,
9422 shdr->sh_size, shdr->sh_offset);
9424 const char *start = data->d_buf;
9425 const char *const limit = start + data->d_size;
9428 const char *end = memchr (start, '\0', limit - start);
9429 const size_t pos = start - (const char *) data->d_buf;
9430 if (unlikely (end == NULL))
9432 printf (" [%6zx]- %.*s\n",
9433 pos, (int) (limit - start), start);
9436 printf (" [%6zx] %s\n", pos, start);
9438 } while (start < limit);
9444 for_each_section_argument (Elf *elf, const struct section_argument *list,
9445 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9448 /* Get the section header string table index. */
9450 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9451 error (EXIT_FAILURE, 0,
9452 gettext ("cannot get section header string table index"));
9454 for (const struct section_argument *a = list; a != NULL; a = a->next)
9458 const char *name = NULL;
9461 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9462 if (endp != a->arg && *endp == '\0')
9464 scn = elf_getscn (elf, shndx);
9467 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9471 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9472 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9474 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9478 /* Need to look up the section by name. */
9481 while ((scn = elf_nextscn (elf, scn)) != NULL)
9483 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9485 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9488 if (!strcmp (name, a->arg))
9491 (*dump) (scn, &shdr_mem, name);
9495 if (unlikely (!found) && !a->implicit)
9496 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9502 dump_data (Ebl *ebl)
9504 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9508 dump_strings (Ebl *ebl)
9510 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9514 print_strings (Ebl *ebl)
9516 /* Get the section header string table index. */
9518 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9519 error (EXIT_FAILURE, 0,
9520 gettext ("cannot get section header string table index"));
9526 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9528 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9531 if (shdr_mem.sh_type != SHT_PROGBITS
9532 || !(shdr_mem.sh_flags & SHF_STRINGS))
9535 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9539 print_string_section (scn, &shdr_mem, name);
9544 dump_archive_index (Elf *elf, const char *fname)
9547 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9550 int result = elf_errno ();
9551 if (unlikely (result != ELF_E_NO_INDEX))
9552 error (EXIT_FAILURE, 0,
9553 gettext ("cannot get symbol index of archive '%s': %s"),
9554 fname, elf_errmsg (result));
9556 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9560 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
9564 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9566 if (s->as_off != as_off)
9571 if (unlikely (elf_rand (elf, as_off) == 0)
9572 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9574 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9577 error (EXIT_FAILURE, 0,
9578 gettext ("cannot extract member at offset %zu in '%s': %s"),
9579 as_off, fname, elf_errmsg (-1));
9581 const Elf_Arhdr *h = elf_getarhdr (subelf);
9583 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9588 printf ("\t%s\n", s->as_name);
9592 #include "debugpred.h"