readelf: Robustify print_phdr program interpreter printing.
[platform/upstream/elfutils.git] / src / readelf.c
1 /* Print information from ELF file in human-readable form.
2    Copyright (C) 1999-2014 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
5
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.
10
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.
15
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/>.  */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <argp.h>
24 #include <assert.h>
25 #include <ctype.h>
26 #include <dwarf.h>
27 #include <errno.h>
28 #include <error.h>
29 #include <fcntl.h>
30 #include <gelf.h>
31 #include <inttypes.h>
32 #include <langinfo.h>
33 #include <libdw.h>
34 #include <libdwfl.h>
35 #include <libintl.h>
36 #include <locale.h>
37 #include <stdarg.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42 #include <unistd.h>
43 #include <sys/param.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46
47 #include <system.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"
54
55 #include "../libdw/known-dwarf.h"
56
57
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;
61
62 /* Bug report address.  */
63 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
64
65 /* argp key value for --elf-section, non-ascii.  */
66 #define ELF_INPUT_SECTION 256
67
68 /* Definitions of arguments for argp functions.  */
69 static const struct argp_option options[] =
70 {
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 "
74        "input data"), 0 },
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 },
94
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 },
107
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 }
116 };
117
118 /* Short description of program.  */
119 static const char doc[] = N_("\
120 Print information from ELF file in human-readable form.");
121
122 /* Strings for arguments in help texts.  */
123 static const char args_doc[] = N_("FILE...");
124
125 /* Prototype for option handler.  */
126 static error_t parse_opt (int key, char *arg, struct argp_state *state);
127
128 /* Data structure to communicate with argp functions.  */
129 static struct argp argp =
130 {
131   options, parse_opt, args_doc, doc, NULL, NULL, NULL
132 };
133
134 /* If non-null, the section from which we should read to (compressed) ELF.  */
135 static const char *elf_input_section = NULL;
136
137 /* Flags set by the option controlling the output.  */
138
139 /* True if dynamic segment should be printed.  */
140 static bool print_dynamic_table;
141
142 /* True if the file header should be printed.  */
143 static bool print_file_header;
144
145 /* True if the program headers should be printed.  */
146 static bool print_program_header;
147
148 /* True if relocations should be printed.  */
149 static bool print_relocations;
150
151 /* True if the section headers should be printed.  */
152 static bool print_section_header;
153
154 /* True if the symbol table should be printed.  */
155 static bool print_symbol_table;
156
157 /* True if the version information should be printed.  */
158 static bool print_version_info;
159
160 /* True if section groups should be printed.  */
161 static bool print_section_groups;
162
163 /* True if bucket list length histogram should be printed.  */
164 static bool print_histogram;
165
166 /* True if the architecture specific data should be printed.  */
167 static bool print_arch;
168
169 /* True if note section content should be printed.  */
170 static bool print_notes;
171
172 /* True if SHF_STRINGS section content should be printed.  */
173 static bool print_string_sections;
174
175 /* True if archive index should be printed.  */
176 static bool print_archive_index;
177
178 /* True if any of the control options except print_archive_index is set.  */
179 static bool any_control_option;
180
181 /* True if we should print addresses from DWARF in symbolic form.  */
182 static bool print_address_names = true;
183
184 /* True if we should print raw values instead of relativized addresses.  */
185 static bool print_unresolved_addresses = false;
186
187 /* True if we should print the .debug_aranges section using libdw.  */
188 static bool decodedaranges = false;
189
190 /* True if we should print the .debug_aranges section using libdw.  */
191 static bool decodedline = false;
192
193 /* Select printing of debugging sections.  */
194 static enum section_e
195 {
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
214                  | section_macro)
215 } print_debug_sections, implicit_debug_sections;
216
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;
220
221 /* Select string dumping of sections.  */
222 static struct section_argument *string_sections;
223 static struct section_argument **string_sections_tail = &string_sections;
224
225 struct section_argument
226 {
227   struct section_argument *next;
228   const char *arg;
229   bool implicit;
230 };
231
232 /* Numbers of sections and program headers in the file.  */
233 static size_t shnum;
234 static size_t phnum;
235
236
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,
247                                GElf_Shdr *shdr);
248 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
249                                 GElf_Shdr *shdr);
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,
256                            GElf_Shdr *shdr);
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 *);
266
267
268 int
269 main (int argc, char *argv[])
270 {
271   /* Set locale.  */
272   setlocale (LC_ALL, "");
273
274   /* Initialize the message catalog.  */
275   textdomain (PACKAGE_TARNAME);
276
277   /* Parse and process arguments.  */
278   int remaining;
279   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
280
281   /* Before we start tell the ELF library which version we are using.  */
282   elf_version (EV_CURRENT);
283
284   /* Now process all the files given at the command line.  */
285   bool only_one = remaining + 1 == argc;
286   do
287     {
288       /* Open the file.  */
289       int fd = open (argv[remaining], O_RDONLY);
290       if (fd == -1)
291         {
292           error (0, errno, gettext ("cannot open input file"));
293           continue;
294         }
295
296       process_file (fd, argv[remaining], only_one);
297
298       close (fd);
299     }
300   while (++remaining < argc);
301
302   return error_message_count != 0;
303 }
304
305
306 /* Handle program arguments.  */
307 static error_t
308 parse_opt (int key, char *arg,
309            struct argp_state *state __attribute__ ((unused)))
310 {
311   void add_dump_section (const char *name, bool implicit)
312   {
313     struct section_argument *a = xmalloc (sizeof *a);
314     a->arg = name;
315     a->next = NULL;
316     a->implicit = implicit;
317     struct section_argument ***tailp
318       = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
319     **tailp = a;
320     *tailp = &a->next;
321   }
322
323   switch (key)
324     {
325     case 'a':
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;
335       print_arch = true;
336       print_notes = 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;
342       break;
343     case 'A':
344       print_arch = true;
345       any_control_option = true;
346       break;
347     case 'd':
348       print_dynamic_table = true;
349       any_control_option = true;
350       break;
351     case 'e':
352       print_debug_sections |= section_exception;
353       any_control_option = true;
354       break;
355     case 'g':
356       print_section_groups = true;
357       any_control_option = true;
358       break;
359     case 'h':
360       print_file_header = true;
361       any_control_option = true;
362       break;
363     case 'I':
364       print_histogram = true;
365       any_control_option = true;
366       break;
367     case 'l':
368       print_program_header = true;
369       any_control_option = true;
370       break;
371     case 'n':
372       print_notes = true;
373       any_control_option = true;
374       break;
375     case 'r':
376       print_relocations = true;
377       any_control_option = true;
378      break;
379     case 'S':
380       print_section_header = true;
381       any_control_option = true;
382       break;
383     case 's':
384       print_symbol_table = true;
385       any_control_option = true;
386       break;
387     case 'V':
388       print_version_info = true;
389       any_control_option = true;
390       break;
391     case 'c':
392       print_archive_index = true;
393       break;
394     case 'w':
395       if (arg == NULL)
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)
402         {
403           print_debug_sections |= section_aranges;
404           decodedaranges = true;
405         }
406       else if (strcmp (arg, "ranges") == 0)
407         {
408           print_debug_sections |= section_ranges;
409           implicit_debug_sections |= section_info;
410         }
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)
416         {
417           print_debug_sections |= section_loc;
418           implicit_debug_sections |= section_info;
419         }
420       else if (strcmp (arg, "line") == 0)
421         print_debug_sections |= section_line;
422       else if (strcmp (arg, "decodedline") == 0)
423         {
424           print_debug_sections |= section_line;
425           decodedline = true;
426         }
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;
439       else
440         {
441           fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
442                    arg);
443           argp_help (&argp, stderr, ARGP_HELP_SEE,
444                      program_invocation_short_name);
445           exit (1);
446         }
447       any_control_option = true;
448       break;
449     case 'p':
450       any_control_option = true;
451       if (arg == NULL)
452         {
453           print_string_sections = true;
454           break;
455         }
456       /* Fall through.  */
457     case 'x':
458       add_dump_section (arg, false);
459       any_control_option = true;
460       break;
461     case 'N':
462       print_address_names = false;
463       break;
464     case 'U':
465       print_unresolved_addresses = true;
466       break;
467     case ARGP_KEY_NO_ARGS:
468       fputs (gettext ("Missing file name.\n"), stderr);
469       goto do_argp_help;
470     case ARGP_KEY_FINI:
471       if (! any_control_option && ! print_archive_index)
472         {
473           fputs (gettext ("No operation specified.\n"), stderr);
474         do_argp_help:
475           argp_help (&argp, stderr, ARGP_HELP_SEE,
476                      program_invocation_short_name);
477           exit (EXIT_FAILURE);
478         }
479       break;
480     case 'W':                   /* Ignored.  */
481       break;
482     case ELF_INPUT_SECTION:
483       if (arg == NULL)
484         elf_input_section = ".gnu_debugdata";
485       else
486         elf_input_section = arg;
487       break;
488     default:
489       return ARGP_ERR_UNKNOWN;
490     }
491   return 0;
492 }
493
494
495 /* Print the version information.  */
496 static void
497 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
498 {
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\
504 "), "2012");
505   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
506 }
507
508
509 /* Create a file descriptor to read the data from the
510    elf_input_section given a file descriptor to an ELF file.  */
511 static int
512 open_input_section (int fd)
513 {
514   size_t shnums;
515   size_t cnt;
516   size_t shstrndx;
517   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
518   if (elf == NULL)
519     {
520       error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
521              elf_errmsg (-1));
522       return -1;
523     }
524
525   if (elf_getshdrnum (elf, &shnums) < 0)
526     {
527       error (0, 0, gettext ("cannot determine number of sections: %s"),
528              elf_errmsg (-1));
529     open_error:
530       elf_end (elf);
531       return -1;
532     }
533
534   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
535     {
536       error (0, 0, gettext ("cannot get section header string table index"));
537       goto open_error;
538     }
539
540   for (cnt = 0; cnt < shnums; ++cnt)
541     {
542       Elf_Scn *scn = elf_getscn (elf, cnt);
543       if (scn == NULL)
544         {
545           error (0, 0, gettext ("cannot get section: %s"),
546                  elf_errmsg (-1));
547           goto open_error;
548         }
549
550       GElf_Shdr shdr_mem;
551       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
552       if (unlikely (shdr == NULL))
553         {
554           error (0, 0, gettext ("cannot get section header: %s"),
555                  elf_errmsg (-1));
556           goto open_error;
557         }
558
559       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
560       if (sname == NULL)
561         {
562           error (0, 0, gettext ("cannot get section name"));
563           goto open_error;
564         }
565
566       if (strcmp (sname, elf_input_section) == 0)
567         {
568           Elf_Data *data = elf_rawdata (scn, NULL);
569           if (data == NULL)
570             {
571               error (0, 0, gettext ("cannot get %s content: %s"),
572                      sname, elf_errmsg (-1));
573               goto open_error;
574             }
575
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);
583
584           int sfd = mkstemp (tempname);
585           if (sfd == -1)
586             {
587               error (0, 0, gettext ("cannot create temp file '%s'"),
588                      tempname);
589               goto open_error;
590             }
591           unlink (tempname);
592
593           ssize_t size = data->d_size;
594           if (write_retry (sfd, data->d_buf, size) != size)
595             {
596               error (0, 0, gettext ("cannot write section data"));
597               goto open_error;
598             }
599
600           if (elf_end (elf) != 0)
601             {
602               error (0, 0, gettext ("error while closing Elf descriptor: %s"),
603                      elf_errmsg (-1));
604               return -1;
605             }
606
607           if (lseek (sfd, 0, SEEK_SET) == -1)
608             {
609               error (0, 0, gettext ("error while rewinding file descriptor"));
610               return -1;
611             }
612
613           return sfd;
614         }
615     }
616
617   /* Named section not found.  */
618   if (elf_end (elf) != 0)
619     error (0, 0, gettext ("error while closing Elf descriptor: %s"),
620            elf_errmsg (-1));
621   return -1;
622 }
623
624 /* Check if the file is an archive, and if so dump its index.  */
625 static void
626 check_archive_index (int fd, const char *fname, bool only_one)
627 {
628   /* Create an `Elf' descriptor.  */
629   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
630   if (elf == NULL)
631     error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
632            elf_errmsg (-1));
633   else
634     {
635       if (elf_kind (elf) == ELF_K_AR)
636         {
637           if (!only_one)
638             printf ("\n%s:\n\n", fname);
639           dump_archive_index (elf, fname);
640         }
641       else
642         error (0, 0,
643                gettext ("'%s' is not an archive, cannot print archive index"),
644                fname);
645
646       /* Now we can close the descriptor.  */
647       if (elf_end (elf) != 0)
648         error (0, 0, gettext ("error while closing Elf descriptor: %s"),
649                elf_errmsg (-1));
650     }
651 }
652
653 /* Trivial callback used for checking if we opened an archive.  */
654 static int
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)),
659                void *arg)
660 {
661   if (*(bool *) arg)
662     return DWARF_CB_ABORT;
663   *(bool *) arg = true;
664   return DWARF_CB_OK;
665 }
666
667 struct process_dwflmod_args
668 {
669   int fd;
670   bool only_one;
671 };
672
673 static int
674 process_dwflmod (Dwfl_Module *dwflmod,
675                  void **userdata __attribute__ ((unused)),
676                  const char *name __attribute__ ((unused)),
677                  Dwarf_Addr base __attribute__ ((unused)),
678                  void *arg)
679 {
680   const struct process_dwflmod_args *a = arg;
681
682   /* Print the file name.  */
683   if (!a->only_one)
684     {
685       const char *fname;
686       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
687
688       printf ("\n%s:\n\n", fname);
689     }
690
691   process_elf_file (dwflmod, a->fd);
692
693   return DWARF_CB_OK;
694 }
695
696 /* Stub libdwfl callback, only the ELF handle already open is ever used.  */
697 static int
698 find_no_debuginfo (Dwfl_Module *mod __attribute__ ((unused)),
699                    void **userdata __attribute__ ((unused)),
700                    const char *modname __attribute__ ((unused)),
701                    Dwarf_Addr base __attribute__ ((unused)),
702                    const char *file_name __attribute__ ((unused)),
703                    const char *debuglink_file __attribute__ ((unused)),
704                    GElf_Word debuglink_crc __attribute__ ((unused)),
705                    char **debuginfo_file_name __attribute__ ((unused)))
706 {
707   return -1;
708 }
709
710 /* Process one input file.  */
711 static void
712 process_file (int fd, const char *fname, bool only_one)
713 {
714   if (print_archive_index)
715     check_archive_index (fd, fname, only_one);
716
717   if (!any_control_option)
718     return;
719
720   if (elf_input_section != NULL)
721     {
722       /* Replace fname and fd with section content. */
723       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
724       sprintf (fnname, "%s:%s", fname, elf_input_section);
725       fd = open_input_section (fd);
726       if (fd == -1)
727         {
728           error (0, 0, gettext ("No such section '%s' in '%s'"),
729                  elf_input_section, fname);
730           return;
731         }
732       fname = fnname;
733     }
734
735   /* Duplicate an fd for dwfl_report_offline to swallow.  */
736   int dwfl_fd = dup (fd);
737   if (unlikely (dwfl_fd < 0))
738     error (EXIT_FAILURE, errno, "dup");
739
740   /* Use libdwfl in a trivial way to open the libdw handle for us.
741      This takes care of applying relocations to DWARF data in ET_REL files.  */
742   static const Dwfl_Callbacks callbacks =
743     {
744       .section_address = dwfl_offline_section_address,
745       .find_debuginfo = find_no_debuginfo
746     };
747   Dwfl *dwfl = dwfl_begin (&callbacks);
748   if (likely (dwfl != NULL))
749     /* Let 0 be the logical address of the file (or first in archive).  */
750     dwfl->offline_next_address = 0;
751   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
752     {
753       struct stat64 st;
754       if (fstat64 (dwfl_fd, &st) != 0)
755         error (0, errno, gettext ("cannot stat input file"));
756       else if (unlikely (st.st_size == 0))
757         error (0, 0, gettext ("input file is empty"));
758       else
759         error (0, 0, gettext ("failed reading '%s': %s"),
760                fname, dwfl_errmsg (-1));
761       close (dwfl_fd);          /* Consumed on success, not on failure.  */
762     }
763   else
764     {
765       dwfl_report_end (dwfl, NULL, NULL);
766
767       if (only_one)
768         {
769           /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
770           bool seen = false;
771           only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
772         }
773
774       /* Process the one or more modules gleaned from this file.  */
775       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
776       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
777     }
778   dwfl_end (dwfl);
779
780   /* Need to close the replaced fd if we created it.  Caller takes
781      care of original.  */
782   if (elf_input_section != NULL)
783     close (fd);
784 }
785
786
787 /* Process one ELF file.  */
788 static void
789 process_elf_file (Dwfl_Module *dwflmod, int fd)
790 {
791   GElf_Addr dwflbias;
792   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
793
794   GElf_Ehdr ehdr_mem;
795   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
796
797   if (ehdr == NULL)
798     {
799     elf_error:
800       error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
801       return;
802     }
803
804   Ebl *ebl = ebl_openbackend (elf);
805   if (unlikely (ebl == NULL))
806     {
807     ebl_error:
808       error (0, errno, gettext ("cannot create EBL handle"));
809       return;
810     }
811
812   /* Determine the number of sections.  */
813   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
814     error (EXIT_FAILURE, 0,
815            gettext ("cannot determine number of sections: %s"),
816            elf_errmsg (-1));
817
818   /* Determine the number of phdrs.  */
819   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
820     error (EXIT_FAILURE, 0,
821            gettext ("cannot determine number of program headers: %s"),
822            elf_errmsg (-1));
823
824   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs
825      and may have applied relocation to some sections.
826      So we need to get a fresh Elf handle on the file to display those.  */
827   bool print_unrelocated = (print_section_header
828                             || print_relocations
829                             || dump_data_sections != NULL
830                             || print_notes);
831
832   Elf *pure_elf = NULL;
833   Ebl *pure_ebl = ebl;
834   if (ehdr->e_type == ET_REL && print_unrelocated)
835     {
836       /* Read the file afresh.  */
837       off64_t aroff = elf_getaroff (elf);
838       pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
839       if (aroff > 0)
840         {
841           /* Archive member.  */
842           (void) elf_rand (pure_elf, aroff);
843           Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
844           elf_end (pure_elf);
845           pure_elf = armem;
846         }
847       if (pure_elf == NULL)
848         goto elf_error;
849       pure_ebl = ebl_openbackend (pure_elf);
850       if (pure_ebl == NULL)
851         goto ebl_error;
852     }
853
854   if (print_file_header)
855     print_ehdr (ebl, ehdr);
856   if (print_section_header)
857     print_shdr (pure_ebl, ehdr);
858   if (print_program_header)
859     print_phdr (ebl, ehdr);
860   if (print_section_groups)
861     print_scngrp (ebl);
862   if (print_dynamic_table)
863     print_dynamic (ebl);
864   if (print_relocations)
865     print_relocs (pure_ebl, ehdr);
866   if (print_histogram)
867     handle_hash (ebl);
868   if (print_symbol_table)
869     print_symtab (ebl, SHT_DYNSYM);
870   if (print_version_info)
871     print_verinfo (ebl);
872   if (print_symbol_table)
873     print_symtab (ebl, SHT_SYMTAB);
874   if (print_arch)
875     print_liblist (ebl);
876   if (print_arch)
877     print_attributes (ebl, ehdr);
878   if (dump_data_sections != NULL)
879     dump_data (pure_ebl);
880   if (string_sections != NULL)
881     dump_strings (ebl);
882   if ((print_debug_sections | implicit_debug_sections) != 0)
883     print_debug (dwflmod, ebl, ehdr);
884   if (print_notes)
885     handle_notes (pure_ebl, ehdr);
886   if (print_string_sections)
887     print_strings (ebl);
888
889   ebl_closebackend (ebl);
890
891   if (pure_ebl != ebl)
892     {
893       ebl_closebackend (pure_ebl);
894       elf_end (pure_elf);
895     }
896 }
897
898
899 /* Print file type.  */
900 static void
901 print_file_type (unsigned short int e_type)
902 {
903   if (likely (e_type <= ET_CORE))
904     {
905       static const char *const knowntypes[] =
906       {
907         N_("NONE (None)"),
908         N_("REL (Relocatable file)"),
909         N_("EXEC (Executable file)"),
910         N_("DYN (Shared object file)"),
911         N_("CORE (Core file)")
912       };
913       puts (gettext (knowntypes[e_type]));
914     }
915   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
916     printf (gettext ("OS Specific: (%x)\n"),  e_type);
917   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
918     printf (gettext ("Processor Specific: (%x)\n"),  e_type);
919   else
920     puts ("???");
921 }
922
923
924 /* Print ELF header.  */
925 static void
926 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
927 {
928   fputs_unlocked (gettext ("ELF Header:\n  Magic:  "), stdout);
929   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
930     printf (" %02hhx", ehdr->e_ident[cnt]);
931
932   printf (gettext ("\n  Class:                             %s\n"),
933           ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
934           : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
935           : "\?\?\?");
936
937   printf (gettext ("  Data:                              %s\n"),
938           ehdr->e_ident[EI_DATA] == ELFDATA2LSB
939           ? "2's complement, little endian"
940           : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
941           ? "2's complement, big endian" : "\?\?\?");
942
943   printf (gettext ("  Ident Version:                     %hhd %s\n"),
944           ehdr->e_ident[EI_VERSION],
945           ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
946           : "(\?\?\?)");
947
948   char buf[512];
949   printf (gettext ("  OS/ABI:                            %s\n"),
950           ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
951
952   printf (gettext ("  ABI Version:                       %hhd\n"),
953           ehdr->e_ident[EI_ABIVERSION]);
954
955   fputs_unlocked (gettext ("  Type:                              "), stdout);
956   print_file_type (ehdr->e_type);
957
958   printf (gettext ("  Machine:                           %s\n"), ebl->name);
959
960   printf (gettext ("  Version:                           %d %s\n"),
961           ehdr->e_version,
962           ehdr->e_version  == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
963
964   printf (gettext ("  Entry point address:               %#" PRIx64 "\n"),
965           ehdr->e_entry);
966
967   printf (gettext ("  Start of program headers:          %" PRId64 " %s\n"),
968           ehdr->e_phoff, gettext ("(bytes into file)"));
969
970   printf (gettext ("  Start of section headers:          %" PRId64 " %s\n"),
971           ehdr->e_shoff, gettext ("(bytes into file)"));
972
973   printf (gettext ("  Flags:                             %s\n"),
974           ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
975
976   printf (gettext ("  Size of this header:               %" PRId16 " %s\n"),
977           ehdr->e_ehsize, gettext ("(bytes)"));
978
979   printf (gettext ("  Size of program header entries:    %" PRId16 " %s\n"),
980           ehdr->e_phentsize, gettext ("(bytes)"));
981
982   printf (gettext ("  Number of program headers entries: %" PRId16),
983           ehdr->e_phnum);
984   if (ehdr->e_phnum == PN_XNUM)
985     {
986       GElf_Shdr shdr_mem;
987       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
988       if (shdr != NULL)
989         printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
990                 (uint32_t) shdr->sh_info);
991       else
992         fputs_unlocked (gettext (" ([0] not available)"), stdout);
993     }
994   fputc_unlocked ('\n', stdout);
995
996   printf (gettext ("  Size of section header entries:    %" PRId16 " %s\n"),
997           ehdr->e_shentsize, gettext ("(bytes)"));
998
999   printf (gettext ("  Number of section headers entries: %" PRId16),
1000           ehdr->e_shnum);
1001   if (ehdr->e_shnum == 0)
1002     {
1003       GElf_Shdr shdr_mem;
1004       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1005       if (shdr != NULL)
1006         printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1007                 (uint32_t) shdr->sh_size);
1008       else
1009         fputs_unlocked (gettext (" ([0] not available)"), stdout);
1010     }
1011   fputc_unlocked ('\n', stdout);
1012
1013   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1014     {
1015       GElf_Shdr shdr_mem;
1016       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1017       if (shdr != NULL)
1018         /* We managed to get the zeroth section.  */
1019         snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1020                   (uint32_t) shdr->sh_link);
1021       else
1022         {
1023           strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1024           buf[sizeof (buf) - 1] = '\0';
1025         }
1026
1027       printf (gettext ("  Section header string table index: XINDEX%s\n\n"),
1028               buf);
1029     }
1030   else
1031     printf (gettext ("  Section header string table index: %" PRId16 "\n\n"),
1032             ehdr->e_shstrndx);
1033 }
1034
1035
1036 static const char *
1037 get_visibility_type (int value)
1038 {
1039   switch (value)
1040     {
1041     case STV_DEFAULT:
1042       return "DEFAULT";
1043     case STV_INTERNAL:
1044       return "INTERNAL";
1045     case STV_HIDDEN:
1046       return "HIDDEN";
1047     case STV_PROTECTED:
1048       return "PROTECTED";
1049     default:
1050       return "???";
1051     }
1052 }
1053
1054
1055 /* Print the section headers.  */
1056 static void
1057 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1058 {
1059   size_t cnt;
1060   size_t shstrndx;
1061
1062   if (! print_file_header)
1063     printf (gettext ("\
1064 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1065 \n"),
1066             ehdr->e_shnum, ehdr->e_shoff);
1067
1068   /* Get the section header string table index.  */
1069   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1070     error (EXIT_FAILURE, 0,
1071            gettext ("cannot get section header string table index"));
1072
1073   puts (gettext ("Section Headers:"));
1074
1075   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1076     puts (gettext ("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
1077   else
1078     puts (gettext ("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
1079
1080   for (cnt = 0; cnt < shnum; ++cnt)
1081     {
1082       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1083
1084       if (unlikely (scn == NULL))
1085         error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1086                elf_errmsg (-1));
1087
1088       /* Get the section header.  */
1089       GElf_Shdr shdr_mem;
1090       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1091       if (unlikely (shdr == NULL))
1092         error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1093                elf_errmsg (-1));
1094
1095       char flagbuf[20];
1096       char *cp = flagbuf;
1097       if (shdr->sh_flags & SHF_WRITE)
1098         *cp++ = 'W';
1099       if (shdr->sh_flags & SHF_ALLOC)
1100         *cp++ = 'A';
1101       if (shdr->sh_flags & SHF_EXECINSTR)
1102         *cp++ = 'X';
1103       if (shdr->sh_flags & SHF_MERGE)
1104         *cp++ = 'M';
1105       if (shdr->sh_flags & SHF_STRINGS)
1106         *cp++ = 'S';
1107       if (shdr->sh_flags & SHF_INFO_LINK)
1108         *cp++ = 'I';
1109       if (shdr->sh_flags & SHF_LINK_ORDER)
1110         *cp++ = 'L';
1111       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1112         *cp++ = 'N';
1113       if (shdr->sh_flags & SHF_GROUP)
1114         *cp++ = 'G';
1115       if (shdr->sh_flags & SHF_TLS)
1116         *cp++ = 'T';
1117       if (shdr->sh_flags & SHF_ORDERED)
1118         *cp++ = 'O';
1119       if (shdr->sh_flags & SHF_EXCLUDE)
1120         *cp++ = 'E';
1121       *cp = '\0';
1122
1123       char buf[128];
1124       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1125               " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1126               " %2" PRId64 "\n",
1127               cnt,
1128               elf_strptr (ebl->elf, shstrndx, shdr->sh_name)
1129               ?: "<corrupt>",
1130               ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1131               ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1132               ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1133               ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1134               shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1135               shdr->sh_addralign);
1136     }
1137
1138   fputc_unlocked ('\n', stdout);
1139 }
1140
1141
1142 /* Print the program header.  */
1143 static void
1144 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1145 {
1146   if (ehdr->e_phnum == 0)
1147     /* No program header, this is OK in relocatable objects.  */
1148     return;
1149
1150   puts (gettext ("Program Headers:"));
1151   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1152     puts (gettext ("\
1153   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
1154   else
1155     puts (gettext ("\
1156   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
1157
1158   /* Process all program headers.  */
1159   bool has_relro = false;
1160   GElf_Addr relro_from = 0;
1161   GElf_Addr relro_to = 0;
1162   for (size_t cnt = 0; cnt < phnum; ++cnt)
1163     {
1164       char buf[128];
1165       GElf_Phdr mem;
1166       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1167
1168       /* If for some reason the header cannot be returned show this.  */
1169       if (unlikely (phdr == NULL))
1170         {
1171           puts ("  ???");
1172           continue;
1173         }
1174
1175       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1176               " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1177               ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1178               phdr->p_offset,
1179               ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1180               ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1181               phdr->p_filesz,
1182               phdr->p_memsz,
1183               phdr->p_flags & PF_R ? 'R' : ' ',
1184               phdr->p_flags & PF_W ? 'W' : ' ',
1185               phdr->p_flags & PF_X ? 'E' : ' ',
1186               phdr->p_align);
1187
1188       if (phdr->p_type == PT_INTERP)
1189         {
1190           /* We can show the user the name of the interpreter.  */
1191           size_t maxsize;
1192           char *filedata = elf_rawfile (ebl->elf, &maxsize);
1193
1194           if (filedata != NULL && phdr->p_offset < maxsize
1195               && phdr->p_filesz <= maxsize - phdr->p_offset
1196               && memchr (filedata + phdr->p_offset, '\0',
1197                          phdr->p_filesz) != NULL)
1198             printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1199                     filedata + phdr->p_offset);
1200         }
1201       else if (phdr->p_type == PT_GNU_RELRO)
1202         {
1203           has_relro = true;
1204           relro_from = phdr->p_vaddr;
1205           relro_to = relro_from + phdr->p_memsz;
1206         }
1207     }
1208
1209   if (ehdr->e_shnum == 0)
1210     /* No sections in the file.  Punt.  */
1211     return;
1212
1213   /* Get the section header string table index.  */
1214   size_t shstrndx;
1215   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1216     error (EXIT_FAILURE, 0,
1217            gettext ("cannot get section header string table index"));
1218
1219   puts (gettext ("\n Section to Segment mapping:\n  Segment Sections..."));
1220
1221   for (size_t cnt = 0; cnt < phnum; ++cnt)
1222     {
1223       /* Print the segment number.  */
1224       printf ("   %2.2zu     ", cnt);
1225
1226       GElf_Phdr phdr_mem;
1227       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1228       /* This must not happen.  */
1229       if (unlikely (phdr == NULL))
1230         error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1231                elf_errmsg (-1));
1232
1233       /* Iterate over the sections.  */
1234       bool in_relro = false;
1235       bool in_ro = false;
1236       for (size_t inner = 1; inner < shnum; ++inner)
1237         {
1238           Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1239           /* This should not happen.  */
1240           if (unlikely (scn == NULL))
1241             error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1242                    elf_errmsg (-1));
1243
1244           /* Get the section header.  */
1245           GElf_Shdr shdr_mem;
1246           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1247           if (unlikely (shdr == NULL))
1248             error (EXIT_FAILURE, 0,
1249                    gettext ("cannot get section header: %s"),
1250                    elf_errmsg (-1));
1251
1252           if (shdr->sh_size > 0
1253               /* Compare allocated sections by VMA, unallocated
1254                  sections by file offset.  */
1255               && (shdr->sh_flags & SHF_ALLOC
1256                   ? (shdr->sh_addr >= phdr->p_vaddr
1257                      && (shdr->sh_addr + shdr->sh_size
1258                          <= phdr->p_vaddr + phdr->p_memsz))
1259                   : (shdr->sh_offset >= phdr->p_offset
1260                      && (shdr->sh_offset + shdr->sh_size
1261                          <= phdr->p_offset + phdr->p_filesz))))
1262             {
1263               if (has_relro && !in_relro
1264                   && shdr->sh_addr >= relro_from
1265                   && shdr->sh_addr + shdr->sh_size <= relro_to)
1266                 {
1267                   fputs_unlocked (" [RELRO:", stdout);
1268                   in_relro = true;
1269                 }
1270               else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1271                 {
1272                   fputs_unlocked ("]", stdout);
1273                   in_relro =  false;
1274                 }
1275               else if (has_relro && in_relro
1276                        && shdr->sh_addr + shdr->sh_size > relro_to)
1277                 fputs_unlocked ("] <RELRO:", stdout);
1278               else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1279                 {
1280                   if (!in_ro)
1281                     {
1282                       fputs_unlocked (" [RO:", stdout);
1283                       in_ro = true;
1284                     }
1285                 }
1286               else
1287                 {
1288                   /* Determine the segment this section is part of.  */
1289                   size_t cnt2;
1290                   GElf_Phdr *phdr2 = NULL;
1291                   for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1292                     {
1293                       GElf_Phdr phdr2_mem;
1294                       phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1295
1296                       if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1297                           && shdr->sh_addr >= phdr2->p_vaddr
1298                           && (shdr->sh_addr + shdr->sh_size
1299                               <= phdr2->p_vaddr + phdr2->p_memsz))
1300                         break;
1301                     }
1302
1303                   if (cnt2 < phnum)
1304                     {
1305                       if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1306                         {
1307                           fputs_unlocked (" [RO:", stdout);
1308                           in_ro = true;
1309                         }
1310                       else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1311                         {
1312                           fputs_unlocked ("]", stdout);
1313                           in_ro = false;
1314                         }
1315                     }
1316                 }
1317
1318               printf (" %s",
1319                       elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1320
1321               /* Signal that this sectin is only partially covered.  */
1322               if (has_relro && in_relro
1323                        && shdr->sh_addr + shdr->sh_size > relro_to)
1324                 {
1325                   fputs_unlocked (">", stdout);
1326                   in_relro =  false;
1327                 }
1328             }
1329         }
1330       if (in_relro || in_ro)
1331         fputs_unlocked ("]", stdout);
1332
1333       /* Finish the line.  */
1334       fputc_unlocked ('\n', stdout);
1335     }
1336 }
1337
1338
1339 static const char *
1340 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1341 {
1342   return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1343 }
1344
1345
1346 static void
1347 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1348 {
1349   /* Get the data of the section.  */
1350   Elf_Data *data = elf_getdata (scn, NULL);
1351
1352   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1353   GElf_Shdr symshdr_mem;
1354   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1355   Elf_Data *symdata = elf_getdata (symscn, NULL);
1356
1357   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1358       || symdata == NULL)
1359     return;
1360
1361   /* Get the section header string table index.  */
1362   size_t shstrndx;
1363   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1364     error (EXIT_FAILURE, 0,
1365            gettext ("cannot get section header string table index"));
1366
1367   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1368
1369   GElf_Sym sym_mem;
1370   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1371
1372   printf ((grpref[0] & GRP_COMDAT)
1373           ? ngettext ("\
1374 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1375                       "\
1376 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1377                       data->d_size / sizeof (Elf32_Word) - 1)
1378           : ngettext ("\
1379 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1380 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1381                       data->d_size / sizeof (Elf32_Word) - 1),
1382           elf_ndxscn (scn),
1383           elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1384           (sym == NULL ? NULL
1385            : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1386           ?: gettext ("<INVALID SYMBOL>"),
1387           data->d_size / sizeof (Elf32_Word) - 1);
1388
1389   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1390     {
1391       GElf_Shdr grpshdr_mem;
1392       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1393                                          &grpshdr_mem);
1394
1395       const char *str;
1396       printf ("  [%2u] %s\n",
1397               grpref[cnt],
1398               grpshdr != NULL
1399               && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1400               ? str : gettext ("<INVALID SECTION>"));
1401     }
1402 }
1403
1404
1405 static void
1406 print_scngrp (Ebl *ebl)
1407 {
1408   /* Find all relocation sections and handle them.  */
1409   Elf_Scn *scn = NULL;
1410
1411   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1412     {
1413        /* Handle the section if it is a symbol table.  */
1414       GElf_Shdr shdr_mem;
1415       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1416
1417       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1418         handle_scngrp (ebl, scn, shdr);
1419     }
1420 }
1421
1422
1423 static const struct flags
1424 {
1425   int mask;
1426   const char *str;
1427 } dt_flags[] =
1428   {
1429     { DF_ORIGIN, "ORIGIN" },
1430     { DF_SYMBOLIC, "SYMBOLIC" },
1431     { DF_TEXTREL, "TEXTREL" },
1432     { DF_BIND_NOW, "BIND_NOW" },
1433     { DF_STATIC_TLS, "STATIC_TLS" }
1434   };
1435 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1436
1437 static const struct flags dt_flags_1[] =
1438   {
1439     { DF_1_NOW, "NOW" },
1440     { DF_1_GLOBAL, "GLOBAL" },
1441     { DF_1_GROUP, "GROUP" },
1442     { DF_1_NODELETE, "NODELETE" },
1443     { DF_1_LOADFLTR, "LOADFLTR" },
1444     { DF_1_INITFIRST, "INITFIRST" },
1445     { DF_1_NOOPEN, "NOOPEN" },
1446     { DF_1_ORIGIN, "ORIGIN" },
1447     { DF_1_DIRECT, "DIRECT" },
1448     { DF_1_TRANS, "TRANS" },
1449     { DF_1_INTERPOSE, "INTERPOSE" },
1450     { DF_1_NODEFLIB, "NODEFLIB" },
1451     { DF_1_NODUMP, "NODUMP" },
1452     { DF_1_CONFALT, "CONFALT" },
1453     { DF_1_ENDFILTEE, "ENDFILTEE" },
1454     { DF_1_DISPRELDNE, "DISPRELDNE" },
1455     { DF_1_DISPRELPND, "DISPRELPND" },
1456   };
1457 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1458
1459 static const struct flags dt_feature_1[] =
1460   {
1461     { DTF_1_PARINIT, "PARINIT" },
1462     { DTF_1_CONFEXP, "CONFEXP" }
1463   };
1464 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1465                                   / sizeof (dt_feature_1[0]));
1466
1467 static const struct flags dt_posflag_1[] =
1468   {
1469     { DF_P1_LAZYLOAD, "LAZYLOAD" },
1470     { DF_P1_GROUPPERM, "GROUPPERM" }
1471   };
1472 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1473                                   / sizeof (dt_posflag_1[0]));
1474
1475
1476 static void
1477 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1478                 int nflags)
1479 {
1480   bool first = true;
1481   int cnt;
1482
1483   for (cnt = 0; cnt < nflags; ++cnt)
1484     if (d_val & flags[cnt].mask)
1485       {
1486         if (!first)
1487           putchar_unlocked (' ');
1488         fputs_unlocked (flags[cnt].str, stdout);
1489         d_val &= ~flags[cnt].mask;
1490         first = false;
1491       }
1492
1493   if (d_val != 0)
1494     {
1495       if (!first)
1496         putchar_unlocked (' ');
1497       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1498     }
1499
1500   putchar_unlocked ('\n');
1501 }
1502
1503
1504 static void
1505 print_dt_flags (int class, GElf_Xword d_val)
1506 {
1507   print_flags (class, d_val, dt_flags, ndt_flags);
1508 }
1509
1510
1511 static void
1512 print_dt_flags_1 (int class, GElf_Xword d_val)
1513 {
1514   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1515 }
1516
1517
1518 static void
1519 print_dt_feature_1 (int class, GElf_Xword d_val)
1520 {
1521   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1522 }
1523
1524
1525 static void
1526 print_dt_posflag_1 (int class, GElf_Xword d_val)
1527 {
1528   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1529 }
1530
1531
1532 static void
1533 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1534 {
1535   int class = gelf_getclass (ebl->elf);
1536   GElf_Shdr glink_mem;
1537   GElf_Shdr *glink;
1538   Elf_Data *data;
1539   size_t cnt;
1540   size_t shstrndx;
1541   size_t sh_entsize;
1542
1543   /* Get the data of the section.  */
1544   data = elf_getdata (scn, NULL);
1545   if (data == NULL)
1546     return;
1547
1548   /* Get the section header string table index.  */
1549   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1550     error (EXIT_FAILURE, 0,
1551            gettext ("cannot get section header string table index"));
1552
1553   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1554
1555   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1556   if (glink == NULL)
1557     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1558            elf_ndxscn (scn));
1559
1560   printf (ngettext ("\
1561 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1562                     "\
1563 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1564                     shdr->sh_size / sh_entsize),
1565           (unsigned long int) (shdr->sh_size / sh_entsize),
1566           class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1567           shdr->sh_offset,
1568           (int) shdr->sh_link,
1569           elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1570   fputs_unlocked (gettext ("  Type              Value\n"), stdout);
1571
1572   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1573     {
1574       GElf_Dyn dynmem;
1575       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1576       if (dyn == NULL)
1577         break;
1578
1579       char buf[64];
1580       printf ("  %-17s ",
1581               ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1582
1583       switch (dyn->d_tag)
1584         {
1585         case DT_NULL:
1586         case DT_DEBUG:
1587         case DT_BIND_NOW:
1588         case DT_TEXTREL:
1589           /* No further output.  */
1590           fputc_unlocked ('\n', stdout);
1591           break;
1592
1593         case DT_NEEDED:
1594           printf (gettext ("Shared library: [%s]\n"),
1595                   elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1596           break;
1597
1598         case DT_SONAME:
1599           printf (gettext ("Library soname: [%s]\n"),
1600                   elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1601           break;
1602
1603         case DT_RPATH:
1604           printf (gettext ("Library rpath: [%s]\n"),
1605                   elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1606           break;
1607
1608         case DT_RUNPATH:
1609           printf (gettext ("Library runpath: [%s]\n"),
1610                   elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1611           break;
1612
1613         case DT_PLTRELSZ:
1614         case DT_RELASZ:
1615         case DT_STRSZ:
1616         case DT_RELSZ:
1617         case DT_RELAENT:
1618         case DT_SYMENT:
1619         case DT_RELENT:
1620         case DT_PLTPADSZ:
1621         case DT_MOVEENT:
1622         case DT_MOVESZ:
1623         case DT_INIT_ARRAYSZ:
1624         case DT_FINI_ARRAYSZ:
1625         case DT_SYMINSZ:
1626         case DT_SYMINENT:
1627         case DT_GNU_CONFLICTSZ:
1628         case DT_GNU_LIBLISTSZ:
1629           printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1630           break;
1631
1632         case DT_VERDEFNUM:
1633         case DT_VERNEEDNUM:
1634         case DT_RELACOUNT:
1635         case DT_RELCOUNT:
1636           printf ("%" PRId64 "\n", dyn->d_un.d_val);
1637           break;
1638
1639         case DT_PLTREL:;
1640           const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1641                                                       NULL, 0);
1642           puts (tagname ?: "???");
1643           break;
1644
1645         case DT_FLAGS:
1646           print_dt_flags (class, dyn->d_un.d_val);
1647           break;
1648
1649         case DT_FLAGS_1:
1650           print_dt_flags_1 (class, dyn->d_un.d_val);
1651           break;
1652
1653         case DT_FEATURE_1:
1654           print_dt_feature_1 (class, dyn->d_un.d_val);
1655           break;
1656
1657         case DT_POSFLAG_1:
1658           print_dt_posflag_1 (class, dyn->d_un.d_val);
1659           break;
1660
1661         default:
1662           printf ("%#0*" PRIx64 "\n",
1663                   class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1664           break;
1665         }
1666     }
1667 }
1668
1669
1670 /* Print the dynamic segment.  */
1671 static void
1672 print_dynamic (Ebl *ebl)
1673 {
1674   for (size_t i = 0; i < phnum; ++i)
1675     {
1676       GElf_Phdr phdr_mem;
1677       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1678
1679       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1680         {
1681           Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1682           GElf_Shdr shdr_mem;
1683           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1684           if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1685             handle_dynamic (ebl, scn, shdr);
1686           break;
1687         }
1688     }
1689 }
1690
1691
1692 /* Print relocations.  */
1693 static void
1694 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1695 {
1696   /* Find all relocation sections and handle them.  */
1697   Elf_Scn *scn = NULL;
1698
1699   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1700     {
1701        /* Handle the section if it is a symbol table.  */
1702       GElf_Shdr shdr_mem;
1703       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1704
1705       if (likely (shdr != NULL))
1706         {
1707           if (shdr->sh_type == SHT_REL)
1708             handle_relocs_rel (ebl, ehdr, scn, shdr);
1709           else if (shdr->sh_type == SHT_RELA)
1710             handle_relocs_rela (ebl, ehdr, scn, shdr);
1711         }
1712     }
1713 }
1714
1715
1716 /* Handle a relocation section.  */
1717 static void
1718 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1719 {
1720   int class = gelf_getclass (ebl->elf);
1721   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1722   int nentries = shdr->sh_size / sh_entsize;
1723
1724   /* Get the data of the section.  */
1725   Elf_Data *data = elf_getdata (scn, NULL);
1726   if (data == NULL)
1727     return;
1728
1729   /* Get the symbol table information.  */
1730   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1731   GElf_Shdr symshdr_mem;
1732   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1733   Elf_Data *symdata = elf_getdata (symscn, NULL);
1734
1735   /* Get the section header of the section the relocations are for.  */
1736   GElf_Shdr destshdr_mem;
1737   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1738                                       &destshdr_mem);
1739
1740   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1741     {
1742       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1743               shdr->sh_offset);
1744       return;
1745     }
1746
1747   /* Search for the optional extended section index table.  */
1748   Elf_Data *xndxdata = NULL;
1749   int xndxscnidx = elf_scnshndx (scn);
1750   if (unlikely (xndxscnidx > 0))
1751     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1752
1753   /* Get the section header string table index.  */
1754   size_t shstrndx;
1755   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1756     error (EXIT_FAILURE, 0,
1757            gettext ("cannot get section header string table index"));
1758
1759   if (shdr->sh_info != 0)
1760     printf (ngettext ("\
1761 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1762                     "\
1763 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1764                       nentries),
1765             elf_ndxscn (scn),
1766             elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1767             (unsigned int) shdr->sh_info,
1768             elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1769             shdr->sh_offset,
1770             nentries);
1771   else
1772     /* The .rel.dyn section does not refer to a specific section but
1773        instead of section index zero.  Do not try to print a section
1774        name.  */
1775     printf (ngettext ("\
1776 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1777                     "\
1778 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1779                       nentries),
1780             (unsigned int) elf_ndxscn (scn),
1781             elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1782             shdr->sh_offset,
1783             nentries);
1784   fputs_unlocked (class == ELFCLASS32
1785                   ? gettext ("\
1786   Offset      Type                 Value       Name\n")
1787                   : gettext ("\
1788   Offset              Type                 Value               Name\n"),
1789          stdout);
1790
1791   int is_statically_linked = 0;
1792   for (int cnt = 0; cnt < nentries; ++cnt)
1793     {
1794       GElf_Rel relmem;
1795       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1796       if (likely (rel != NULL))
1797         {
1798           char buf[128];
1799           GElf_Sym symmem;
1800           Elf32_Word xndx;
1801           GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1802                                             GELF_R_SYM (rel->r_info),
1803                                             &symmem, &xndx);
1804           if (unlikely (sym == NULL))
1805             {
1806               /* As a special case we have to handle relocations in static
1807                  executables.  This only happens for IRELATIVE relocations
1808                  (so far).  There is no symbol table.  */
1809               if (is_statically_linked == 0)
1810                 {
1811                   /* Find the program header and look for a PT_INTERP entry. */
1812                   is_statically_linked = -1;
1813                   if (ehdr->e_type == ET_EXEC)
1814                     {
1815                       is_statically_linked = 1;
1816
1817                       for (size_t inner = 0; inner < phnum; ++inner)
1818                         {
1819                           GElf_Phdr phdr_mem;
1820                           GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1821                                                           &phdr_mem);
1822                           if (phdr != NULL && phdr->p_type == PT_INTERP)
1823                             {
1824                               is_statically_linked = -1;
1825                               break;
1826                             }
1827                         }
1828                     }
1829                 }
1830
1831               if (is_statically_linked > 0 && shdr->sh_link == 0)
1832                 printf ("\
1833   %#0*" PRIx64 "  %-20s %*s  %s\n",
1834                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1835                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1836                         /* Avoid the leading R_ which isn't carrying any
1837                            information.  */
1838                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1839                                                buf, sizeof (buf)) + 2
1840                         : gettext ("<INVALID RELOC>"),
1841                         class == ELFCLASS32 ? 10 : 18, "",
1842                         elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1843               else
1844                 printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
1845                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1846                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1847                         /* Avoid the leading R_ which isn't carrying any
1848                            information.  */
1849                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1850                                                buf, sizeof (buf)) + 2
1851                         : gettext ("<INVALID RELOC>"),
1852                         gettext ("INVALID SYMBOL"),
1853                         (long int) GELF_R_SYM (rel->r_info));
1854             }
1855           else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1856             printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
1857                     class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1858                     likely (ebl_reloc_type_check (ebl,
1859                                                   GELF_R_TYPE (rel->r_info)))
1860                     /* Avoid the leading R_ which isn't carrying any
1861                        information.  */
1862                     ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1863                                            buf, sizeof (buf)) + 2
1864                     : gettext ("<INVALID RELOC>"),
1865                     class == ELFCLASS32 ? 10 : 18, sym->st_value,
1866                     elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1867           else
1868             {
1869               destshdr = gelf_getshdr (elf_getscn (ebl->elf,
1870                                                    sym->st_shndx == SHN_XINDEX
1871                                                    ? xndx : sym->st_shndx),
1872                                        &destshdr_mem);
1873
1874               if (unlikely (destshdr == NULL))
1875                 printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
1876                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1877                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1878                         /* Avoid the leading R_ which isn't carrying any
1879                            information.  */
1880                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1881                                                buf, sizeof (buf)) + 2
1882                         : gettext ("<INVALID RELOC>"),
1883                         gettext ("INVALID SECTION"),
1884                         (long int) (sym->st_shndx == SHN_XINDEX
1885                                     ? xndx : sym->st_shndx));
1886               else
1887                 printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
1888                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1889                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1890                         /* Avoid the leading R_ which isn't carrying any
1891                            information.  */
1892                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1893                                                buf, sizeof (buf)) + 2
1894                         : gettext ("<INVALID RELOC>"),
1895                         class == ELFCLASS32 ? 10 : 18, sym->st_value,
1896                         elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1897             }
1898         }
1899     }
1900 }
1901
1902
1903 /* Handle a relocation section.  */
1904 static void
1905 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1906 {
1907   int class = gelf_getclass (ebl->elf);
1908   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1909   int nentries = shdr->sh_size / sh_entsize;
1910
1911   /* Get the data of the section.  */
1912   Elf_Data *data = elf_getdata (scn, NULL);
1913   if (data == NULL)
1914     return;
1915
1916   /* Get the symbol table information.  */
1917   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1918   GElf_Shdr symshdr_mem;
1919   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1920   Elf_Data *symdata = elf_getdata (symscn, NULL);
1921
1922   /* Get the section header of the section the relocations are for.  */
1923   GElf_Shdr destshdr_mem;
1924   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1925                                       &destshdr_mem);
1926
1927   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1928     {
1929       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1930               shdr->sh_offset);
1931       return;
1932     }
1933
1934   /* Search for the optional extended section index table.  */
1935   Elf_Data *xndxdata = NULL;
1936   int xndxscnidx = elf_scnshndx (scn);
1937   if (unlikely (xndxscnidx > 0))
1938     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1939
1940   /* Get the section header string table index.  */
1941   size_t shstrndx;
1942   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1943     error (EXIT_FAILURE, 0,
1944            gettext ("cannot get section header string table index"));
1945
1946   printf (ngettext ("\
1947 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1948                     "\
1949 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1950                     nentries),
1951           elf_ndxscn (scn),
1952           elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1953           (unsigned int) shdr->sh_info,
1954           elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1955           shdr->sh_offset,
1956           nentries);
1957   fputs_unlocked (class == ELFCLASS32
1958                   ? gettext ("\
1959   Offset      Type            Value       Addend Name\n")
1960                   : gettext ("\
1961   Offset              Type            Value               Addend Name\n"),
1962                   stdout);
1963
1964   int is_statically_linked = 0;
1965   for (int cnt = 0; cnt < nentries; ++cnt)
1966     {
1967       GElf_Rela relmem;
1968       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
1969       if (likely (rel != NULL))
1970         {
1971           char buf[64];
1972           GElf_Sym symmem;
1973           Elf32_Word xndx;
1974           GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1975                                             GELF_R_SYM (rel->r_info),
1976                                             &symmem, &xndx);
1977
1978           if (unlikely (sym == NULL))
1979             {
1980               /* As a special case we have to handle relocations in static
1981                  executables.  This only happens for IRELATIVE relocations
1982                  (so far).  There is no symbol table.  */
1983               if (is_statically_linked == 0)
1984                 {
1985                   /* Find the program header and look for a PT_INTERP entry. */
1986                   is_statically_linked = -1;
1987                   if (ehdr->e_type == ET_EXEC)
1988                     {
1989                       is_statically_linked = 1;
1990
1991                       for (size_t inner = 0; inner < phnum; ++inner)
1992                         {
1993                           GElf_Phdr phdr_mem;
1994                           GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1995                                                           &phdr_mem);
1996                           if (phdr != NULL && phdr->p_type == PT_INTERP)
1997                             {
1998                               is_statically_linked = -1;
1999                               break;
2000                             }
2001                         }
2002                     }
2003                 }
2004
2005               if (is_statically_linked > 0 && shdr->sh_link == 0)
2006                 printf ("\
2007   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
2008                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2009                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2010                         /* Avoid the leading R_ which isn't carrying any
2011                            information.  */
2012                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2013                                                buf, sizeof (buf)) + 2
2014                         : gettext ("<INVALID RELOC>"),
2015                         class == ELFCLASS32 ? 10 : 18, "",
2016                         rel->r_addend,
2017                         elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2018               else
2019                 printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2020                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2021                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2022                         /* Avoid the leading R_ which isn't carrying any
2023                            information.  */
2024                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2025                                                buf, sizeof (buf)) + 2
2026                         : gettext ("<INVALID RELOC>"),
2027                         gettext ("INVALID SYMBOL"),
2028                         (long int) GELF_R_SYM (rel->r_info));
2029             }
2030           else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2031             printf ("\
2032   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2033                     class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2034                     likely (ebl_reloc_type_check (ebl,
2035                                                   GELF_R_TYPE (rel->r_info)))
2036                     /* Avoid the leading R_ which isn't carrying any
2037                        information.  */
2038                     ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2039                                            buf, sizeof (buf)) + 2
2040                     : gettext ("<INVALID RELOC>"),
2041                     class == ELFCLASS32 ? 10 : 18, sym->st_value,
2042                     rel->r_addend,
2043                     elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2044           else
2045             {
2046               destshdr = gelf_getshdr (elf_getscn (ebl->elf,
2047                                                    sym->st_shndx == SHN_XINDEX
2048                                                    ? xndx : sym->st_shndx),
2049                                        &destshdr_mem);
2050
2051               if (unlikely (shdr == NULL))
2052                 printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2053                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2054                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2055                         /* Avoid the leading R_ which isn't carrying any
2056                            information.  */
2057                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2058                                                buf, sizeof (buf)) + 2
2059                         : gettext ("<INVALID RELOC>"),
2060                         gettext ("INVALID SECTION"),
2061                         (long int) (sym->st_shndx == SHN_XINDEX
2062                                     ? xndx : sym->st_shndx));
2063               else
2064                 printf ("\
2065   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2066                         class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2067                         ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2068                         /* Avoid the leading R_ which isn't carrying any
2069                            information.  */
2070                         ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2071                                                buf, sizeof (buf)) + 2
2072                         : gettext ("<INVALID RELOC>"),
2073                         class == ELFCLASS32 ? 10 : 18, sym->st_value,
2074                         rel->r_addend,
2075                         elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2076             }
2077         }
2078     }
2079 }
2080
2081
2082 /* Print the program header.  */
2083 static void
2084 print_symtab (Ebl *ebl, int type)
2085 {
2086   /* Find the symbol table(s).  For this we have to search through the
2087      section table.  */
2088   Elf_Scn *scn = NULL;
2089
2090   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2091     {
2092       /* Handle the section if it is a symbol table.  */
2093       GElf_Shdr shdr_mem;
2094       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2095
2096       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2097         handle_symtab (ebl, scn, shdr);
2098     }
2099 }
2100
2101
2102 static void
2103 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2104 {
2105   Elf_Data *versym_data = NULL;
2106   Elf_Data *verneed_data = NULL;
2107   Elf_Data *verdef_data = NULL;
2108   Elf_Data *xndx_data = NULL;
2109   int class = gelf_getclass (ebl->elf);
2110   Elf32_Word verneed_stridx = 0;
2111   Elf32_Word verdef_stridx = 0;
2112
2113   /* Get the data of the section.  */
2114   Elf_Data *data = elf_getdata (scn, NULL);
2115   if (data == NULL)
2116     return;
2117
2118   /* Find out whether we have other sections we might need.  */
2119   Elf_Scn *runscn = NULL;
2120   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2121     {
2122       GElf_Shdr runshdr_mem;
2123       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2124
2125       if (likely (runshdr != NULL))
2126         {
2127           if (runshdr->sh_type == SHT_GNU_versym
2128               && runshdr->sh_link == elf_ndxscn (scn))
2129             /* Bingo, found the version information.  Now get the data.  */
2130             versym_data = elf_getdata (runscn, NULL);
2131           else if (runshdr->sh_type == SHT_GNU_verneed)
2132             {
2133               /* This is the information about the needed versions.  */
2134               verneed_data = elf_getdata (runscn, NULL);
2135               verneed_stridx = runshdr->sh_link;
2136             }
2137           else if (runshdr->sh_type == SHT_GNU_verdef)
2138             {
2139               /* This is the information about the defined versions.  */
2140               verdef_data = elf_getdata (runscn, NULL);
2141               verdef_stridx = runshdr->sh_link;
2142             }
2143           else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2144               && runshdr->sh_link == elf_ndxscn (scn))
2145             /* Extended section index.  */
2146             xndx_data = elf_getdata (runscn, NULL);
2147         }
2148     }
2149
2150   /* Get the section header string table index.  */
2151   size_t shstrndx;
2152   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2153     error (EXIT_FAILURE, 0,
2154            gettext ("cannot get section header string table index"));
2155
2156   GElf_Shdr glink_mem;
2157   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2158                                    &glink_mem);
2159   if (glink == NULL)
2160     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2161            elf_ndxscn (scn));
2162
2163   /* Now we can compute the number of entries in the section.  */
2164   unsigned int nsyms = data->d_size / (class == ELFCLASS32
2165                                        ? sizeof (Elf32_Sym)
2166                                        : sizeof (Elf64_Sym));
2167
2168   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2169                     "\nSymbol table [%2u] '%s' contains %u entries:\n",
2170                     nsyms),
2171           (unsigned int) elf_ndxscn (scn),
2172           elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2173   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
2174                     " %lu local symbols  String table: [%2u] '%s'\n",
2175                     shdr->sh_info),
2176           (unsigned long int) shdr->sh_info,
2177           (unsigned int) shdr->sh_link,
2178           elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2179
2180   fputs_unlocked (class == ELFCLASS32
2181                   ? gettext ("\
2182   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
2183                   : gettext ("\
2184   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
2185                   stdout);
2186
2187   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2188     {
2189       char typebuf[64];
2190       char bindbuf[64];
2191       char scnbuf[64];
2192       Elf32_Word xndx;
2193       GElf_Sym sym_mem;
2194       GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2195
2196       if (unlikely (sym == NULL))
2197         continue;
2198
2199       /* Determine the real section index.  */
2200       if (likely (sym->st_shndx != SHN_XINDEX))
2201         xndx = sym->st_shndx;
2202
2203       printf (gettext ("\
2204 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2205               cnt,
2206               class == ELFCLASS32 ? 8 : 16,
2207               sym->st_value,
2208               sym->st_size,
2209               ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2210                                     typebuf, sizeof (typebuf)),
2211               ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2212                                        bindbuf, sizeof (bindbuf)),
2213               get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2214               ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2215                                 sizeof (scnbuf), NULL, shnum),
2216               elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2217
2218       if (versym_data != NULL)
2219         {
2220           /* Get the version information.  */
2221           GElf_Versym versym_mem;
2222           GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2223
2224           if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2225             {
2226               bool is_nobits = false;
2227               bool check_def = xndx != SHN_UNDEF;
2228
2229               if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2230                 {
2231                   GElf_Shdr symshdr_mem;
2232                   GElf_Shdr *symshdr =
2233                     gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2234
2235                   is_nobits = (symshdr != NULL
2236                                && symshdr->sh_type == SHT_NOBITS);
2237                 }
2238
2239               if (is_nobits || ! check_def)
2240                 {
2241                   /* We must test both.  */
2242                   GElf_Vernaux vernaux_mem;
2243                   GElf_Vernaux *vernaux = NULL;
2244                   size_t vn_offset = 0;
2245
2246                   GElf_Verneed verneed_mem;
2247                   GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2248                                                            &verneed_mem);
2249                   while (verneed != NULL)
2250                     {
2251                       size_t vna_offset = vn_offset;
2252
2253                       vernaux = gelf_getvernaux (verneed_data,
2254                                                  vna_offset += verneed->vn_aux,
2255                                                  &vernaux_mem);
2256                       while (vernaux != NULL
2257                              && vernaux->vna_other != *versym
2258                              && vernaux->vna_next != 0)
2259                         {
2260                           /* Update the offset.  */
2261                           vna_offset += vernaux->vna_next;
2262
2263                           vernaux = (vernaux->vna_next == 0
2264                                      ? NULL
2265                                      : gelf_getvernaux (verneed_data,
2266                                                         vna_offset,
2267                                                         &vernaux_mem));
2268                         }
2269
2270                       /* Check whether we found the version.  */
2271                       if (vernaux != NULL && vernaux->vna_other == *versym)
2272                         /* Found it.  */
2273                         break;
2274
2275                       vn_offset += verneed->vn_next;
2276                       verneed = (verneed->vn_next == 0
2277                                  ? NULL
2278                                  : gelf_getverneed (verneed_data, vn_offset,
2279                                                     &verneed_mem));
2280                     }
2281
2282                   if (vernaux != NULL && vernaux->vna_other == *versym)
2283                     {
2284                       printf ("@%s (%u)",
2285                               elf_strptr (ebl->elf, verneed_stridx,
2286                                           vernaux->vna_name),
2287                               (unsigned int) vernaux->vna_other);
2288                       check_def = 0;
2289                     }
2290                   else if (unlikely (! is_nobits))
2291                     error (0, 0, gettext ("bad dynamic symbol"));
2292                   else
2293                     check_def = 1;
2294                 }
2295
2296               if (check_def && *versym != 0x8001)
2297                 {
2298                   /* We must test both.  */
2299                   size_t vd_offset = 0;
2300
2301                   GElf_Verdef verdef_mem;
2302                   GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2303                                                         &verdef_mem);
2304                   while (verdef != NULL)
2305                     {
2306                       if (verdef->vd_ndx == (*versym & 0x7fff))
2307                         /* Found the definition.  */
2308                         break;
2309
2310                       vd_offset += verdef->vd_next;
2311                       verdef = (verdef->vd_next == 0
2312                                 ? NULL
2313                                 : gelf_getverdef (verdef_data, vd_offset,
2314                                                   &verdef_mem));
2315                     }
2316
2317                   if (verdef != NULL)
2318                     {
2319                       GElf_Verdaux verdaux_mem;
2320                       GElf_Verdaux *verdaux
2321                         = gelf_getverdaux (verdef_data,
2322                                            vd_offset + verdef->vd_aux,
2323                                            &verdaux_mem);
2324
2325                       if (verdaux != NULL)
2326                         printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2327                                 elf_strptr (ebl->elf, verdef_stridx,
2328                                             verdaux->vda_name));
2329                     }
2330                 }
2331             }
2332         }
2333
2334       putchar_unlocked ('\n');
2335     }
2336 }
2337
2338
2339 /* Print version information.  */
2340 static void
2341 print_verinfo (Ebl *ebl)
2342 {
2343   /* Find the version information sections.  For this we have to
2344      search through the section table.  */
2345   Elf_Scn *scn = NULL;
2346
2347   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2348     {
2349       /* Handle the section if it is part of the versioning handling.  */
2350       GElf_Shdr shdr_mem;
2351       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2352
2353       if (likely (shdr != NULL))
2354         {
2355           if (shdr->sh_type == SHT_GNU_verneed)
2356             handle_verneed (ebl, scn, shdr);
2357           else if (shdr->sh_type == SHT_GNU_verdef)
2358             handle_verdef (ebl, scn, shdr);
2359           else if (shdr->sh_type == SHT_GNU_versym)
2360             handle_versym (ebl, scn, shdr);
2361         }
2362     }
2363 }
2364
2365
2366 static const char *
2367 get_ver_flags (unsigned int flags)
2368 {
2369   static char buf[32];
2370   char *endp;
2371
2372   if (flags == 0)
2373     return gettext ("none");
2374
2375   if (flags & VER_FLG_BASE)
2376     endp = stpcpy (buf, "BASE ");
2377   else
2378     endp = buf;
2379
2380   if (flags & VER_FLG_WEAK)
2381     {
2382       if (endp != buf)
2383         endp = stpcpy (endp, "| ");
2384
2385       endp = stpcpy (endp, "WEAK ");
2386     }
2387
2388   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2389     {
2390       strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2391       buf[sizeof (buf) - 1] = '\0';
2392     }
2393
2394   return buf;
2395 }
2396
2397
2398 static void
2399 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2400 {
2401   int class = gelf_getclass (ebl->elf);
2402
2403   /* Get the data of the section.  */
2404   Elf_Data *data = elf_getdata (scn, NULL);
2405   if (data == NULL)
2406     return;
2407
2408   /* Get the section header string table index.  */
2409   size_t shstrndx;
2410   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2411     error (EXIT_FAILURE, 0,
2412            gettext ("cannot get section header string table index"));
2413
2414   GElf_Shdr glink_mem;
2415   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2416                                    &glink_mem);
2417   if (glink == NULL)
2418     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2419            elf_ndxscn (scn));
2420
2421   printf (ngettext ("\
2422 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2423                     "\
2424 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2425                     shdr->sh_info),
2426           (unsigned int) elf_ndxscn (scn),
2427           elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2428           class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2429           shdr->sh_offset,
2430           (unsigned int) shdr->sh_link,
2431           elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2432
2433   unsigned int offset = 0;
2434   for (int cnt = shdr->sh_info; --cnt >= 0; )
2435     {
2436       /* Get the data at the next offset.  */
2437       GElf_Verneed needmem;
2438       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2439       if (unlikely (need == NULL))
2440         break;
2441
2442       printf (gettext ("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
2443               offset, (unsigned short int) need->vn_version,
2444               elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2445               (unsigned short int) need->vn_cnt);
2446
2447       unsigned int auxoffset = offset + need->vn_aux;
2448       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2449         {
2450           GElf_Vernaux auxmem;
2451           GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2452           if (unlikely (aux == NULL))
2453             break;
2454
2455           printf (gettext ("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
2456                   auxoffset,
2457                   elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2458                   get_ver_flags (aux->vna_flags),
2459                   (unsigned short int) aux->vna_other);
2460
2461           auxoffset += aux->vna_next;
2462         }
2463
2464       /* Find the next offset.  */
2465       offset += need->vn_next;
2466     }
2467 }
2468
2469
2470 static void
2471 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2472 {
2473   /* Get the data of the section.  */
2474   Elf_Data *data = elf_getdata (scn, NULL);
2475   if (data == NULL)
2476     return;
2477
2478   /* Get the section header string table index.  */
2479   size_t shstrndx;
2480   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2481     error (EXIT_FAILURE, 0,
2482            gettext ("cannot get section header string table index"));
2483
2484   GElf_Shdr glink_mem;
2485   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2486                                    &glink_mem);
2487   if (glink == NULL)
2488     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2489            elf_ndxscn (scn));
2490
2491   int class = gelf_getclass (ebl->elf);
2492   printf (ngettext ("\
2493 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2494                     "\
2495 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2496                     shdr->sh_info),
2497           (unsigned int) elf_ndxscn (scn),
2498           elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2499           shdr->sh_info,
2500           class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2501           shdr->sh_offset,
2502           (unsigned int) shdr->sh_link,
2503           elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2504
2505   unsigned int offset = 0;
2506   for (int cnt = shdr->sh_info; --cnt >= 0; )
2507     {
2508       /* Get the data at the next offset.  */
2509       GElf_Verdef defmem;
2510       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2511       if (unlikely (def == NULL))
2512         break;
2513
2514       unsigned int auxoffset = offset + def->vd_aux;
2515       GElf_Verdaux auxmem;
2516       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2517       if (unlikely (aux == NULL))
2518         break;
2519
2520       printf (gettext ("\
2521   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
2522               offset, def->vd_version,
2523               get_ver_flags (def->vd_flags),
2524               def->vd_ndx,
2525               def->vd_cnt,
2526               elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2527
2528       auxoffset += aux->vda_next;
2529       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2530         {
2531           aux = gelf_getverdaux (data, auxoffset, &auxmem);
2532           if (unlikely (aux == NULL))
2533             break;
2534
2535           printf (gettext ("  %#06x: Parent %d: %s\n"),
2536                   auxoffset, cnt2,
2537                   elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2538
2539           auxoffset += aux->vda_next;
2540         }
2541
2542       /* Find the next offset.  */
2543       offset += def->vd_next;
2544     }
2545 }
2546
2547
2548 static void
2549 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2550 {
2551   int class = gelf_getclass (ebl->elf);
2552   const char **vername;
2553   const char **filename;
2554
2555   /* Get the data of the section.  */
2556   Elf_Data *data = elf_getdata (scn, NULL);
2557   if (data == NULL)
2558     return;
2559
2560   /* Get the section header string table index.  */
2561   size_t shstrndx;
2562   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2563     error (EXIT_FAILURE, 0,
2564            gettext ("cannot get section header string table index"));
2565
2566   /* We have to find the version definition section and extract the
2567      version names.  */
2568   Elf_Scn *defscn = NULL;
2569   Elf_Scn *needscn = NULL;
2570
2571   Elf_Scn *verscn = NULL;
2572   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2573     {
2574       GElf_Shdr vershdr_mem;
2575       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2576
2577       if (likely (vershdr != NULL))
2578         {
2579           if (vershdr->sh_type == SHT_GNU_verdef)
2580             defscn = verscn;
2581           else if (vershdr->sh_type == SHT_GNU_verneed)
2582             needscn = verscn;
2583         }
2584     }
2585
2586   size_t nvername;
2587   if (defscn != NULL || needscn != NULL)
2588     {
2589       /* We have a version information (better should have).  Now get
2590          the version names.  First find the maximum version number.  */
2591       nvername = 0;
2592       if (defscn != NULL)
2593         {
2594           /* Run through the version definitions and find the highest
2595              index.  */
2596           unsigned int offset = 0;
2597           Elf_Data *defdata;
2598           GElf_Shdr defshdrmem;
2599           GElf_Shdr *defshdr;
2600
2601           defdata = elf_getdata (defscn, NULL);
2602           if (unlikely (defdata == NULL))
2603             return;
2604
2605           defshdr = gelf_getshdr (defscn, &defshdrmem);
2606           if (unlikely (defshdr == NULL))
2607             return;
2608
2609           for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2610             {
2611               GElf_Verdef defmem;
2612               GElf_Verdef *def;
2613
2614               /* Get the data at the next offset.  */
2615               def = gelf_getverdef (defdata, offset, &defmem);
2616               if (unlikely (def == NULL))
2617                 break;
2618
2619               nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2620
2621               offset += def->vd_next;
2622             }
2623         }
2624       if (needscn != NULL)
2625         {
2626           unsigned int offset = 0;
2627           Elf_Data *needdata;
2628           GElf_Shdr needshdrmem;
2629           GElf_Shdr *needshdr;
2630
2631           needdata = elf_getdata (needscn, NULL);
2632           if (unlikely (needdata == NULL))
2633             return;
2634
2635           needshdr = gelf_getshdr (needscn, &needshdrmem);
2636           if (unlikely (needshdr == NULL))
2637             return;
2638
2639           for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2640             {
2641               GElf_Verneed needmem;
2642               GElf_Verneed *need;
2643               unsigned int auxoffset;
2644               int cnt2;
2645
2646               /* Get the data at the next offset.  */
2647               need = gelf_getverneed (needdata, offset, &needmem);
2648               if (unlikely (need == NULL))
2649                 break;
2650
2651               /* Run through the auxiliary entries.  */
2652               auxoffset = offset + need->vn_aux;
2653               for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2654                 {
2655                   GElf_Vernaux auxmem;
2656                   GElf_Vernaux *aux;
2657
2658                   aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2659                   if (unlikely (aux == NULL))
2660                     break;
2661
2662                   nvername = MAX (nvername,
2663                                   (size_t) (aux->vna_other & 0x7fff));
2664
2665                   auxoffset += aux->vna_next;
2666                 }
2667
2668               offset += need->vn_next;
2669             }
2670         }
2671
2672       /* This is the number of versions we know about.  */
2673       ++nvername;
2674
2675       /* Allocate the array.  */
2676       vername = (const char **) alloca (nvername * sizeof (const char *));
2677       filename = (const char **) alloca (nvername * sizeof (const char *));
2678
2679       /* Run through the data structures again and collect the strings.  */
2680       if (defscn != NULL)
2681         {
2682           /* Run through the version definitions and find the highest
2683              index.  */
2684           unsigned int offset = 0;
2685           Elf_Data *defdata;
2686           GElf_Shdr defshdrmem;
2687           GElf_Shdr *defshdr;
2688
2689           defdata = elf_getdata (defscn, NULL);
2690           if (unlikely (defdata == NULL))
2691             return;
2692
2693           defshdr = gelf_getshdr (defscn, &defshdrmem);
2694           if (unlikely (defshdr == NULL))
2695             return;
2696
2697           for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2698             {
2699
2700               /* Get the data at the next offset.  */
2701               GElf_Verdef defmem;
2702               GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2703               GElf_Verdaux auxmem;
2704               GElf_Verdaux *aux = gelf_getverdaux (defdata,
2705                                                    offset + def->vd_aux,
2706                                                    &auxmem);
2707               if (unlikely (def == NULL || aux == NULL))
2708                 break;
2709
2710               vername[def->vd_ndx & 0x7fff]
2711                 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2712               filename[def->vd_ndx & 0x7fff] = NULL;
2713
2714               offset += def->vd_next;
2715             }
2716         }
2717       if (needscn != NULL)
2718         {
2719           unsigned int offset = 0;
2720
2721           Elf_Data *needdata = elf_getdata (needscn, NULL);
2722           GElf_Shdr needshdrmem;
2723           GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2724           if (unlikely (needdata == NULL || needshdr == NULL))
2725             return;
2726
2727           for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2728             {
2729               /* Get the data at the next offset.  */
2730               GElf_Verneed needmem;
2731               GElf_Verneed *need = gelf_getverneed (needdata, offset,
2732                                                     &needmem);
2733               if (unlikely (need == NULL))
2734                 break;
2735
2736               /* Run through the auxiliary entries.  */
2737               unsigned int auxoffset = offset + need->vn_aux;
2738               for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2739                 {
2740                   GElf_Vernaux auxmem;
2741                   GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2742                                                        &auxmem);
2743                   if (unlikely (aux == NULL))
2744                     break;
2745
2746                   vername[aux->vna_other & 0x7fff]
2747                     = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2748                   filename[aux->vna_other & 0x7fff]
2749                     = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2750
2751                   auxoffset += aux->vna_next;
2752                 }
2753
2754               offset += need->vn_next;
2755             }
2756         }
2757     }
2758   else
2759     {
2760       vername = NULL;
2761       nvername = 1;
2762       filename = NULL;
2763     }
2764
2765   GElf_Shdr glink_mem;
2766   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2767                                    &glink_mem);
2768   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2769   if (glink == NULL)
2770     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
2771            elf_ndxscn (scn));
2772
2773   /* Print the header.  */
2774   printf (ngettext ("\
2775 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
2776                     "\
2777 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
2778                     shdr->sh_size / sh_entsize),
2779           (unsigned int) elf_ndxscn (scn),
2780           elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2781           (int) (shdr->sh_size / sh_entsize),
2782           class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2783           shdr->sh_offset,
2784           (unsigned int) shdr->sh_link,
2785           elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2786
2787   /* Now we can finally look at the actual contents of this section.  */
2788   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2789     {
2790       if (cnt % 2 == 0)
2791         printf ("\n %4d:", cnt);
2792
2793       GElf_Versym symmem;
2794       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2795       if (sym == NULL)
2796         break;
2797
2798       switch (*sym)
2799         {
2800           ssize_t n;
2801         case 0:
2802           fputs_unlocked (gettext ("   0 *local*                     "),
2803                           stdout);
2804           break;
2805
2806         case 1:
2807           fputs_unlocked (gettext ("   1 *global*                    "),
2808                           stdout);
2809           break;
2810
2811         default:
2812           n = printf ("%4d%c%s",
2813                       *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2814                       (unsigned int) (*sym & 0x7fff) < nvername
2815                       ? vername[*sym & 0x7fff] : "???");
2816           if ((unsigned int) (*sym & 0x7fff) < nvername
2817               && filename[*sym & 0x7fff] != NULL)
2818             n += printf ("(%s)", filename[*sym & 0x7fff]);
2819           printf ("%*s", MAX (0, 33 - (int) n), " ");
2820           break;
2821         }
2822     }
2823   putchar_unlocked ('\n');
2824 }
2825
2826
2827 static void
2828 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
2829                  uint_fast32_t maxlength, Elf32_Word nbucket,
2830                  uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
2831 {
2832   uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
2833
2834   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2835     ++counts[lengths[cnt]];
2836
2837   GElf_Shdr glink_mem;
2838   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
2839                                                shdr->sh_link),
2840                                    &glink_mem);
2841   if (glink == NULL)
2842     {
2843       error (0, 0, gettext ("invalid sh_link value in section %Zu"),
2844              elf_ndxscn (scn));
2845       return;
2846     }
2847
2848   printf (ngettext ("\
2849 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2850                     "\
2851 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2852                     nbucket),
2853           (unsigned int) elf_ndxscn (scn),
2854           elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2855           (int) nbucket,
2856           gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
2857           shdr->sh_addr,
2858           shdr->sh_offset,
2859           (unsigned int) shdr->sh_link,
2860           elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2861
2862   if (extrastr != NULL)
2863     fputs (extrastr, stdout);
2864
2865   if (likely (nbucket > 0))
2866     {
2867       uint64_t success = 0;
2868
2869       /* xgettext:no-c-format */
2870       fputs_unlocked (gettext ("\
2871  Length  Number  % of total  Coverage\n"), stdout);
2872       printf (gettext ("      0  %6" PRIu32 "      %5.1f%%\n"),
2873               counts[0], (counts[0] * 100.0) / nbucket);
2874
2875       uint64_t nzero_counts = 0;
2876       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2877         {
2878           nzero_counts += counts[cnt] * cnt;
2879           printf (gettext ("\
2880 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
2881                   (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
2882                   (nzero_counts * 100.0) / nsyms);
2883         }
2884
2885       Elf32_Word acc = 0;
2886       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
2887         {
2888           acc += cnt;
2889           success += counts[cnt] * acc;
2890         }
2891
2892       printf (gettext ("\
2893  Average number of tests:   successful lookup: %f\n\
2894                           unsuccessful lookup: %f\n"),
2895               (double) success / (double) nzero_counts,
2896               (double) nzero_counts / (double) nbucket);
2897     }
2898
2899   free (counts);
2900 }
2901
2902
2903 /* This function handles the traditional System V-style hash table format.  */
2904 static void
2905 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2906 {
2907   Elf_Data *data = elf_getdata (scn, NULL);
2908   if (unlikely (data == NULL))
2909     {
2910       error (0, 0, gettext ("cannot get data for section %d: %s"),
2911              (int) elf_ndxscn (scn), elf_errmsg (-1));
2912       return;
2913     }
2914
2915   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2916   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
2917   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
2918   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
2919
2920   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2921
2922   uint_fast32_t maxlength = 0;
2923   uint_fast32_t nsyms = 0;
2924   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
2925     {
2926       Elf32_Word inner = bucket[cnt];
2927       while (inner > 0 && inner < nchain)
2928         {
2929           ++nsyms;
2930           if (maxlength < ++lengths[cnt])
2931             ++maxlength;
2932
2933           inner = chain[inner];
2934         }
2935     }
2936
2937   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2938                    lengths, NULL);
2939
2940   free (lengths);
2941 }
2942
2943
2944 /* This function handles the incorrect, System V-style hash table
2945    format some 64-bit architectures use.  */
2946 static void
2947 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2948 {
2949   Elf_Data *data = elf_getdata (scn, NULL);
2950   if (unlikely (data == NULL))
2951     {
2952       error (0, 0, gettext ("cannot get data for section %d: %s"),
2953              (int) elf_ndxscn (scn), elf_errmsg (-1));
2954       return;
2955     }
2956
2957   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
2958   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
2959   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
2960   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
2961
2962   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
2963
2964   uint_fast32_t maxlength = 0;
2965   uint_fast32_t nsyms = 0;
2966   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
2967     {
2968       Elf64_Xword inner = bucket[cnt];
2969       while (inner > 0 && inner < nchain)
2970         {
2971           ++nsyms;
2972           if (maxlength < ++lengths[cnt])
2973             ++maxlength;
2974
2975           inner = chain[inner];
2976         }
2977     }
2978
2979   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
2980                    lengths, NULL);
2981
2982   free (lengths);
2983 }
2984
2985
2986 /* This function handles the GNU-style hash table format.  */
2987 static void
2988 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
2989 {
2990   Elf_Data *data = elf_getdata (scn, NULL);
2991   if (unlikely (data == NULL))
2992     {
2993       error (0, 0, gettext ("cannot get data for section %d: %s"),
2994              (int) elf_ndxscn (scn), elf_errmsg (-1));
2995       return;
2996     }
2997
2998   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
2999   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3000
3001   /* Next comes the size of the bitmap.  It's measured in words for
3002      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
3003      64 bit archs.  */
3004   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3005   if (gelf_getclass (ebl->elf) == ELFCLASS64)
3006     bitmask_words *= 2;
3007
3008   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3009
3010   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3011
3012   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3013   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3014   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3015                                                     + nbucket];
3016
3017   /* Compute distribution of chain lengths.  */
3018   uint_fast32_t maxlength = 0;
3019   uint_fast32_t nsyms = 0;
3020   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3021     if (bucket[cnt] != 0)
3022       {
3023         Elf32_Word inner = bucket[cnt] - symbias;
3024         do
3025           {
3026             ++nsyms;
3027             if (maxlength < ++lengths[cnt])
3028               ++maxlength;
3029           }
3030         while ((chain[inner++] & 1) == 0);
3031       }
3032
3033   /* Count bits in bitmask.  */
3034   uint_fast32_t nbits = 0;
3035   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3036     {
3037       uint_fast32_t word = bitmask[cnt];
3038
3039       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3040       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3041       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3042       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3043       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3044     }
3045
3046   char *str;
3047   if (unlikely (asprintf (&str, gettext ("\
3048  Symbol Bias: %u\n\
3049  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
3050                           (unsigned int) symbias,
3051                           bitmask_words * sizeof (Elf32_Word),
3052                           ((nbits * 100 + 50)
3053                            / (uint_fast32_t) (bitmask_words
3054                                               * sizeof (Elf32_Word) * 8)),
3055                           (unsigned int) shift) == -1))
3056     error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3057
3058   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3059                    lengths, str);
3060
3061   free (str);
3062   free (lengths);
3063 }
3064
3065
3066 /* Find the symbol table(s).  For this we have to search through the
3067    section table.  */
3068 static void
3069 handle_hash (Ebl *ebl)
3070 {
3071   /* Get the section header string table index.  */
3072   size_t shstrndx;
3073   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3074     error (EXIT_FAILURE, 0,
3075            gettext ("cannot get section header string table index"));
3076
3077   Elf_Scn *scn = NULL;
3078   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3079     {
3080       /* Handle the section if it is a symbol table.  */
3081       GElf_Shdr shdr_mem;
3082       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3083
3084       if (likely (shdr != NULL))
3085         {
3086           if (shdr->sh_type == SHT_HASH)
3087             {
3088               if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3089                 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3090               else
3091                 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3092             }
3093           else if (shdr->sh_type == SHT_GNU_HASH)
3094             handle_gnu_hash (ebl, scn, shdr, shstrndx);
3095         }
3096     }
3097 }
3098
3099
3100 static void
3101 print_liblist (Ebl *ebl)
3102 {
3103   /* Find the library list sections.  For this we have to search
3104      through the section table.  */
3105   Elf_Scn *scn = NULL;
3106
3107   /* Get the section header string table index.  */
3108   size_t shstrndx;
3109   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3110     error (EXIT_FAILURE, 0,
3111            gettext ("cannot get section header string table index"));
3112
3113   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3114     {
3115       GElf_Shdr shdr_mem;
3116       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3117
3118       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3119         {
3120           size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3121           int nentries = shdr->sh_size / sh_entsize;
3122           printf (ngettext ("\
3123 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3124                             "\
3125 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3126                             nentries),
3127                   elf_ndxscn (scn),
3128                   elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3129                   shdr->sh_offset,
3130                   nentries);
3131
3132           Elf_Data *data = elf_getdata (scn, NULL);
3133           if (data == NULL)
3134             return;
3135
3136           puts (gettext ("\
3137        Library                       Time Stamp          Checksum Version Flags"));
3138
3139           for (int cnt = 0; cnt < nentries; ++cnt)
3140             {
3141               GElf_Lib lib_mem;
3142               GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3143               if (unlikely (lib == NULL))
3144                 continue;
3145
3146               time_t t = (time_t) lib->l_time_stamp;
3147               struct tm *tm = gmtime (&t);
3148               if (unlikely (tm == NULL))
3149                 continue;
3150
3151               printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3152                       cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3153                       tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3154                       tm->tm_hour, tm->tm_min, tm->tm_sec,
3155                       (unsigned int) lib->l_checksum,
3156                       (unsigned int) lib->l_version,
3157                       (unsigned int) lib->l_flags);
3158             }
3159         }
3160     }
3161 }
3162
3163 static void
3164 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3165 {
3166   /* Find the object attributes sections.  For this we have to search
3167      through the section table.  */
3168   Elf_Scn *scn = NULL;
3169
3170   /* Get the section header string table index.  */
3171   size_t shstrndx;
3172   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3173     error (EXIT_FAILURE, 0,
3174            gettext ("cannot get section header string table index"));
3175
3176   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3177     {
3178       GElf_Shdr shdr_mem;
3179       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3180
3181       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3182                            && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3183                                || ehdr->e_machine != EM_ARM)))
3184         continue;
3185
3186       printf (gettext ("\
3187 \nObject attributes section [%2zu] '%s' of %" PRIu64
3188                        " bytes at offset %#0" PRIx64 ":\n"),
3189               elf_ndxscn (scn),
3190               elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3191               shdr->sh_size, shdr->sh_offset);
3192
3193       Elf_Data *data = elf_rawdata (scn, NULL);
3194       if (data == NULL)
3195         return;
3196
3197       const unsigned char *p = data->d_buf;
3198
3199       if (unlikely (*p++ != 'A'))
3200         return;
3201
3202       fputs_unlocked (gettext ("  Owner          Size\n"), stdout);
3203
3204       inline size_t left (void)
3205       {
3206         return (const unsigned char *) data->d_buf + data->d_size - p;
3207       }
3208
3209       while (left () >= 4)
3210         {
3211           uint32_t len;
3212           memcpy (&len, p, sizeof len);
3213
3214           if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3215             CONVERT (len);
3216
3217           if (unlikely (len > left ()))
3218             break;
3219
3220           const unsigned char *name = p + sizeof len;
3221           p += len;
3222
3223           unsigned const char *q = memchr (name, '\0', len);
3224           if (unlikely (q == NULL))
3225             continue;
3226           ++q;
3227
3228           printf (gettext ("  %-13s  %4" PRIu32 "\n"), name, len);
3229
3230           if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3231               || (q - name == sizeof "gnu"
3232                   && !memcmp (name, "gnu", sizeof "gnu")))
3233             while (q < p)
3234               {
3235                 const unsigned char *const sub = q;
3236
3237                 unsigned int subsection_tag;
3238                 get_uleb128 (subsection_tag, q);
3239                 if (unlikely (q >= p))
3240                   break;
3241
3242                 uint32_t subsection_len;
3243                 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3244                   break;
3245
3246                 memcpy (&subsection_len, q, sizeof subsection_len);
3247
3248                 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3249                   CONVERT (subsection_len);
3250
3251                 if (unlikely (p - sub < (ptrdiff_t) subsection_len))
3252                   break;
3253
3254                 const unsigned char *r = q + sizeof subsection_len;
3255                 q = sub + subsection_len;
3256
3257                 switch (subsection_tag)
3258                   {
3259                   default:
3260                     printf (gettext ("    %-4u %12" PRIu32 "\n"),
3261                             subsection_tag, subsection_len);
3262                     break;
3263
3264                   case 1:       /* Tag_File */
3265                     printf (gettext ("    File: %11" PRIu32 "\n"),
3266                             subsection_len);
3267
3268                     while (r < q)
3269                       {
3270                         unsigned int tag;
3271                         get_uleb128 (tag, r);
3272                         if (unlikely (r >= q))
3273                           break;
3274
3275                         uint64_t value = 0;
3276                         const char *string = NULL;
3277                         if (tag == 32 || (tag & 1) == 0)
3278                           {
3279                             get_uleb128 (value, r);
3280                             if (r > q)
3281                               break;
3282                           }
3283                         if (tag == 32 || (tag & 1) != 0)
3284                           {
3285                             r = memchr (r, '\0', q - r);
3286                             if (r == NULL)
3287                               break;
3288                             ++r;
3289                           }
3290
3291                         const char *tag_name = NULL;
3292                         const char *value_name = NULL;
3293                         ebl_check_object_attribute (ebl, (const char *) name,
3294                                                     tag, value,
3295                                                     &tag_name, &value_name);
3296
3297                         if (tag_name != NULL)
3298                           {
3299                             if (tag == 32)
3300                               printf (gettext ("      %s: %" PRId64 ", %s\n"),
3301                                       tag_name, value, string);
3302                             else if (string == NULL && value_name == NULL)
3303                               printf (gettext ("      %s: %" PRId64 "\n"),
3304                                       tag_name, value);
3305                             else
3306                               printf (gettext ("      %s: %s\n"),
3307                                       tag_name, string ?: value_name);
3308                           }
3309                         else
3310                           {
3311                             assert (tag != 32);
3312                             if (string == NULL)
3313                               printf (gettext ("      %u: %" PRId64 "\n"),
3314                                       tag, value);
3315                             else
3316                               printf (gettext ("      %u: %s\n"),
3317                                       tag, string);
3318                           }
3319                       }
3320                   }
3321               }
3322         }
3323     }
3324 }
3325
3326
3327 static char *
3328 format_dwarf_addr (Dwfl_Module *dwflmod,
3329                    int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3330 {
3331   /* See if there is a name we can give for this address.  */
3332   GElf_Sym sym;
3333   GElf_Off off = 0;
3334   const char *name = (print_address_names && ! print_unresolved_addresses)
3335     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3336     : NULL;
3337
3338   const char *scn;
3339   if (print_unresolved_addresses)
3340     {
3341       address = raw;
3342       scn = NULL;
3343     }
3344   else
3345     {
3346       /* Relativize the address.  */
3347       int n = dwfl_module_relocations (dwflmod);
3348       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3349
3350       /* In an ET_REL file there is a section name to refer to.  */
3351       scn = (i < 0 ? NULL
3352              : dwfl_module_relocation_info (dwflmod, i, NULL));
3353     }
3354
3355   char *result;
3356   if ((name != NULL
3357        ? (off != 0
3358           ? (scn != NULL
3359              ? (address_size == 0
3360                 ? asprintf (&result,
3361                             gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3362                             scn, address, name, off)
3363                 : asprintf (&result,
3364                             gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3365                             scn, 2 + address_size * 2, address,
3366                             name, off))
3367              : (address_size == 0
3368                 ? asprintf (&result,
3369                             gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3370                             address, name, off)
3371                 : asprintf (&result,
3372                             gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3373                             2 + address_size * 2, address,
3374                             name, off)))
3375           : (scn != NULL
3376              ? (address_size == 0
3377                 ? asprintf (&result,
3378                             gettext ("%s+%#" PRIx64 " <%s>"),
3379                             scn, address, name)
3380                 : asprintf (&result,
3381                             gettext ("%s+%#0*" PRIx64 " <%s>"),
3382                             scn, 2 + address_size * 2, address, name))
3383              : (address_size == 0
3384                 ? asprintf (&result,
3385                             gettext ("%#" PRIx64 " <%s>"),
3386                             address, name)
3387                 : asprintf (&result,
3388                             gettext ("%#0*" PRIx64 " <%s>"),
3389                             2 + address_size * 2, address, name))))
3390        : (scn != NULL
3391           ? (address_size == 0
3392              ? asprintf (&result,
3393                          gettext ("%s+%#" PRIx64),
3394                          scn, address)
3395              : asprintf (&result,
3396                          gettext ("%s+%#0*" PRIx64),
3397                          scn, 2 + address_size * 2, address))
3398           : (address_size == 0
3399              ? asprintf (&result,
3400                          "%#" PRIx64,
3401                          address)
3402              : asprintf (&result,
3403                          "%#0*" PRIx64,
3404                          2 + address_size * 2, address)))) < 0)
3405     error (EXIT_FAILURE, 0, _("memory exhausted"));
3406
3407   return result;
3408 }
3409
3410 static const char *
3411 dwarf_tag_string (unsigned int tag)
3412 {
3413   switch (tag)
3414     {
3415 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3416       ALL_KNOWN_DW_TAG
3417 #undef ONE_KNOWN_DW_TAG
3418     default:
3419       return NULL;
3420     }
3421 }
3422
3423
3424 static const char *
3425 dwarf_attr_string (unsigned int attrnum)
3426 {
3427   switch (attrnum)
3428     {
3429 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3430       ALL_KNOWN_DW_AT
3431 #undef ONE_KNOWN_DW_AT
3432     default:
3433       return NULL;
3434     }
3435 }
3436
3437
3438 static const char *
3439 dwarf_form_string (unsigned int form)
3440 {
3441   switch (form)
3442     {
3443 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
3444 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3445       ALL_KNOWN_DW_FORM
3446 #undef ONE_KNOWN_DW_FORM
3447 #undef ONE_KNOWN_DW_FORM_DESC
3448     default:
3449       return NULL;
3450     }
3451 }
3452
3453
3454 static const char *
3455 dwarf_lang_string (unsigned int lang)
3456 {
3457   switch (lang)
3458     {
3459 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
3460       ALL_KNOWN_DW_LANG
3461 #undef ONE_KNOWN_DW_LANG_DESC
3462     default:
3463       return NULL;
3464     }
3465 }
3466
3467
3468 static const char *
3469 dwarf_inline_string (unsigned int code)
3470 {
3471   static const char *const known[] =
3472     {
3473 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3474       ALL_KNOWN_DW_INL
3475 #undef ONE_KNOWN_DW_INL
3476     };
3477
3478   if (likely (code < sizeof (known) / sizeof (known[0])))
3479     return known[code];
3480
3481   return NULL;
3482 }
3483
3484
3485 static const char *
3486 dwarf_encoding_string (unsigned int code)
3487 {
3488   static const char *const known[] =
3489     {
3490 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3491       ALL_KNOWN_DW_ATE
3492 #undef ONE_KNOWN_DW_ATE
3493     };
3494
3495   if (likely (code < sizeof (known) / sizeof (known[0])))
3496     return known[code];
3497
3498   return NULL;
3499 }
3500
3501
3502 static const char *
3503 dwarf_access_string (unsigned int code)
3504 {
3505   static const char *const known[] =
3506     {
3507 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3508       ALL_KNOWN_DW_ACCESS
3509 #undef ONE_KNOWN_DW_ACCESS
3510     };
3511
3512   if (likely (code < sizeof (known) / sizeof (known[0])))
3513     return known[code];
3514
3515   return NULL;
3516 }
3517
3518
3519 static const char *
3520 dwarf_visibility_string (unsigned int code)
3521 {
3522   static const char *const known[] =
3523     {
3524 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3525       ALL_KNOWN_DW_VIS
3526 #undef ONE_KNOWN_DW_VIS
3527     };
3528
3529   if (likely (code < sizeof (known) / sizeof (known[0])))
3530     return known[code];
3531
3532   return NULL;
3533 }
3534
3535
3536 static const char *
3537 dwarf_virtuality_string (unsigned int code)
3538 {
3539   static const char *const known[] =
3540     {
3541 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3542       ALL_KNOWN_DW_VIRTUALITY
3543 #undef ONE_KNOWN_DW_VIRTUALITY
3544     };
3545
3546   if (likely (code < sizeof (known) / sizeof (known[0])))
3547     return known[code];
3548
3549   return NULL;
3550 }
3551
3552
3553 static const char *
3554 dwarf_identifier_case_string (unsigned int code)
3555 {
3556   static const char *const known[] =
3557     {
3558 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3559       ALL_KNOWN_DW_ID
3560 #undef ONE_KNOWN_DW_ID
3561     };
3562
3563   if (likely (code < sizeof (known) / sizeof (known[0])))
3564     return known[code];
3565
3566   return NULL;
3567 }
3568
3569
3570 static const char *
3571 dwarf_calling_convention_string (unsigned int code)
3572 {
3573   static const char *const known[] =
3574     {
3575 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3576       ALL_KNOWN_DW_CC
3577 #undef ONE_KNOWN_DW_CC
3578     };
3579
3580   if (likely (code < sizeof (known) / sizeof (known[0])))
3581     return known[code];
3582
3583   return NULL;
3584 }
3585
3586
3587 static const char *
3588 dwarf_ordering_string (unsigned int code)
3589 {
3590   static const char *const known[] =
3591     {
3592 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3593       ALL_KNOWN_DW_ORD
3594 #undef ONE_KNOWN_DW_ORD
3595     };
3596
3597   if (likely (code < sizeof (known) / sizeof (known[0])))
3598     return known[code];
3599
3600   return NULL;
3601 }
3602
3603
3604 static const char *
3605 dwarf_discr_list_string (unsigned int code)
3606 {
3607   static const char *const known[] =
3608     {
3609 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3610       ALL_KNOWN_DW_DSC
3611 #undef ONE_KNOWN_DW_DSC
3612     };
3613
3614   if (likely (code < sizeof (known) / sizeof (known[0])))
3615     return known[code];
3616
3617   return NULL;
3618 }
3619
3620
3621 static const char *
3622 dwarf_locexpr_opcode_string (unsigned int code)
3623 {
3624   static const char *const known[] =
3625     {
3626       /* Normally we can't affort building huge table of 64K entries,
3627          most of them zero, just because there are a couple defined
3628          values at the far end.  In case of opcodes, it's OK.  */
3629 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
3630 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3631       ALL_KNOWN_DW_OP
3632 #undef ONE_KNOWN_DW_OP
3633 #undef ONE_KNOWN_DW_OP_DESC
3634     };
3635
3636   if (likely (code < sizeof (known) / sizeof (known[0])))
3637     return known[code];
3638
3639   return NULL;
3640 }
3641
3642
3643 /* Used by all dwarf_foo_name functions.  */
3644 static const char *
3645 string_or_unknown (const char *known, unsigned int code,
3646                    unsigned int lo_user, unsigned int hi_user,
3647                    bool print_unknown_num)
3648 {
3649   static char unknown_buf[20];
3650
3651   if (likely (known != NULL))
3652     return known;
3653
3654   if (lo_user != 0 && code >= lo_user && code <= hi_user)
3655     {
3656       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3657                 code - lo_user);
3658       return unknown_buf;
3659     }
3660
3661   if (print_unknown_num)
3662     {
3663       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3664       return unknown_buf;
3665     }
3666
3667   return "???";
3668 }
3669
3670
3671 static const char *
3672 dwarf_tag_name (unsigned int tag)
3673 {
3674   const char *ret = dwarf_tag_string (tag);
3675   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3676 }
3677
3678 static const char *
3679 dwarf_attr_name (unsigned int attr)
3680 {
3681   const char *ret = dwarf_attr_string (attr);
3682   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3683 }
3684
3685
3686 static const char *
3687 dwarf_form_name (unsigned int form)
3688 {
3689   const char *ret = dwarf_form_string (form);
3690   return string_or_unknown (ret, form, 0, 0, true);
3691 }
3692
3693
3694 static const char *
3695 dwarf_lang_name (unsigned int lang)
3696 {
3697   const char *ret = dwarf_lang_string (lang);
3698   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3699 }
3700
3701
3702 static const char *
3703 dwarf_inline_name (unsigned int code)
3704 {
3705   const char *ret = dwarf_inline_string (code);
3706   return string_or_unknown (ret, code, 0, 0, false);
3707 }
3708
3709
3710 static const char *
3711 dwarf_encoding_name (unsigned int code)
3712 {
3713   const char *ret = dwarf_encoding_string (code);
3714   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3715 }
3716
3717
3718 static const char *
3719 dwarf_access_name (unsigned int code)
3720 {
3721   const char *ret = dwarf_access_string (code);
3722   return string_or_unknown (ret, code, 0, 0, false);
3723 }
3724
3725
3726 static const char *
3727 dwarf_visibility_name (unsigned int code)
3728 {
3729   const char *ret = dwarf_visibility_string (code);
3730   return string_or_unknown (ret, code, 0, 0, false);
3731 }
3732
3733
3734 static const char *
3735 dwarf_virtuality_name (unsigned int code)
3736 {
3737   const char *ret = dwarf_virtuality_string (code);
3738   return string_or_unknown (ret, code, 0, 0, false);
3739 }
3740
3741
3742 static const char *
3743 dwarf_identifier_case_name (unsigned int code)
3744 {
3745   const char *ret = dwarf_identifier_case_string (code);
3746   return string_or_unknown (ret, code, 0, 0, false);
3747 }
3748
3749
3750 static const char *
3751 dwarf_calling_convention_name (unsigned int code)
3752 {
3753   const char *ret = dwarf_calling_convention_string (code);
3754   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
3755 }
3756
3757
3758 static const char *
3759 dwarf_ordering_name (unsigned int code)
3760 {
3761   const char *ret = dwarf_ordering_string (code);
3762   return string_or_unknown (ret, code, 0, 0, false);
3763 }
3764
3765
3766 static const char *
3767 dwarf_discr_list_name (unsigned int code)
3768 {
3769   const char *ret = dwarf_discr_list_string (code);
3770   return string_or_unknown (ret, code, 0, 0, false);
3771 }
3772
3773
3774 static void
3775 print_block (size_t n, const void *block)
3776 {
3777   if (n == 0)
3778     puts (_("empty block"));
3779   else
3780     {
3781       printf (_("%zu byte block:"), n);
3782       const unsigned char *data = block;
3783       do
3784         printf (" %02x", *data++);
3785       while (--n > 0);
3786       putchar ('\n');
3787     }
3788 }
3789
3790 static void
3791 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
3792            unsigned int vers, unsigned int addrsize, unsigned int offset_size,
3793            struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
3794 {
3795   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
3796
3797   if (len == 0)
3798     {
3799       printf ("%*s(empty)\n", indent, "");
3800       return;
3801     }
3802
3803 #define NEED(n)         if (len < (Dwarf_Word) (n)) goto invalid
3804 #define CONSUME(n)      NEED (n); else len -= (n)
3805
3806   Dwarf_Word offset = 0;
3807   while (len-- > 0)
3808     {
3809       uint_fast8_t op = *data++;
3810
3811       const char *op_name = dwarf_locexpr_opcode_string (op);
3812       if (unlikely (op_name == NULL))
3813         {
3814           static char buf[20];
3815           if (op >= DW_OP_lo_user)
3816             snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
3817           else
3818             snprintf (buf, sizeof buf, "??? (%#x)", op);
3819           op_name = buf;
3820         }
3821
3822       switch (op)
3823         {
3824         case DW_OP_addr:;
3825           /* Address operand.  */
3826           Dwarf_Word addr;
3827           NEED (addrsize);
3828           if (addrsize == 4)
3829             addr = read_4ubyte_unaligned (dbg, data);
3830           else
3831             {
3832               assert (addrsize == 8);
3833               addr = read_8ubyte_unaligned (dbg, data);
3834             }
3835           data += addrsize;
3836           CONSUME (addrsize);
3837
3838           char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
3839           printf ("%*s[%4" PRIuMAX "] %s %s\n",
3840                   indent, "", (uintmax_t) offset, op_name, a);
3841           free (a);
3842
3843           offset += 1 + addrsize;
3844           break;
3845
3846         case DW_OP_call_ref:
3847           /* Offset operand.  */
3848           NEED (ref_size);
3849           if (ref_size == 4)
3850             addr = read_4ubyte_unaligned (dbg, data);
3851           else
3852             {
3853               assert (ref_size == 8);
3854               addr = read_8ubyte_unaligned (dbg, data);
3855             }
3856           data += ref_size;
3857           CONSUME (ref_size);
3858
3859           printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
3860                   indent, "", (uintmax_t) offset,
3861                   op_name, (uintmax_t) addr);
3862           offset += 1 + ref_size;
3863           break;
3864
3865         case DW_OP_deref_size:
3866         case DW_OP_xderef_size:
3867         case DW_OP_pick:
3868         case DW_OP_const1u:
3869           // XXX value might be modified by relocation
3870           NEED (1);
3871           printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
3872                   indent, "", (uintmax_t) offset,
3873                   op_name, *((uint8_t *) data));
3874           ++data;
3875           --len;
3876           offset += 2;
3877           break;
3878
3879         case DW_OP_const2u:
3880           NEED (2);
3881           // XXX value might be modified by relocation
3882           printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
3883                   indent, "", (uintmax_t) offset,
3884                   op_name, read_2ubyte_unaligned (dbg, data));
3885           CONSUME (2);
3886           data += 2;
3887           offset += 3;
3888           break;
3889
3890         case DW_OP_const4u:
3891           NEED (4);
3892           // XXX value might be modified by relocation
3893           printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
3894                   indent, "", (uintmax_t) offset,
3895                   op_name, read_4ubyte_unaligned (dbg, data));
3896           CONSUME (4);
3897           data += 4;
3898           offset += 5;
3899           break;
3900
3901         case DW_OP_const8u:
3902           NEED (8);
3903           // XXX value might be modified by relocation
3904           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3905                   indent, "", (uintmax_t) offset,
3906                   op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
3907           CONSUME (8);
3908           data += 8;
3909           offset += 9;
3910           break;
3911
3912         case DW_OP_const1s:
3913           NEED (1);
3914           // XXX value might be modified by relocation
3915           printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
3916                   indent, "", (uintmax_t) offset,
3917                   op_name, *((int8_t *) data));
3918           ++data;
3919           --len;
3920           offset += 2;
3921           break;
3922
3923         case DW_OP_const2s:
3924           NEED (2);
3925           // XXX value might be modified by relocation
3926           printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
3927                   indent, "", (uintmax_t) offset,
3928                   op_name, read_2sbyte_unaligned (dbg, data));
3929           CONSUME (2);
3930           data += 2;
3931           offset += 3;
3932           break;
3933
3934         case DW_OP_const4s:
3935           NEED (4);
3936           // XXX value might be modified by relocation
3937           printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
3938                   indent, "", (uintmax_t) offset,
3939                   op_name, read_4sbyte_unaligned (dbg, data));
3940           CONSUME (4);
3941           data += 4;
3942           offset += 5;
3943           break;
3944
3945         case DW_OP_const8s:
3946           NEED (8);
3947           // XXX value might be modified by relocation
3948           printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3949                   indent, "", (uintmax_t) offset,
3950                   op_name, read_8sbyte_unaligned (dbg, data));
3951           CONSUME (8);
3952           data += 8;
3953           offset += 9;
3954           break;
3955
3956         case DW_OP_piece:
3957         case DW_OP_regx:
3958         case DW_OP_plus_uconst:
3959         case DW_OP_constu:;
3960           const unsigned char *start = data;
3961           uint64_t uleb;
3962           NEED (1);
3963           get_uleb128 (uleb, data); /* XXX check overrun */
3964           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
3965                   indent, "", (uintmax_t) offset, op_name, uleb);
3966           CONSUME (data - start);
3967           offset += 1 + (data - start);
3968           break;
3969
3970         case DW_OP_bit_piece:
3971           start = data;
3972           uint64_t uleb2;
3973           NEED (2);
3974           get_uleb128 (uleb, data); /* XXX check overrun */
3975           get_uleb128 (uleb2, data); /* XXX check overrun */
3976           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
3977                   indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
3978           CONSUME (data - start);
3979           offset += 1 + (data - start);
3980           break;
3981
3982         case DW_OP_fbreg:
3983         case DW_OP_breg0 ... DW_OP_breg31:
3984         case DW_OP_consts:
3985           start = data;
3986           int64_t sleb;
3987           NEED (1);
3988           get_sleb128 (sleb, data); /* XXX check overrun */
3989           printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
3990                   indent, "", (uintmax_t) offset, op_name, sleb);
3991           CONSUME (data - start);
3992           offset += 1 + (data - start);
3993           break;
3994
3995         case DW_OP_bregx:
3996           start = data;
3997           NEED (2);
3998           get_uleb128 (uleb, data); /* XXX check overrun */
3999           get_sleb128 (sleb, data); /* XXX check overrun */
4000           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4001                   indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4002           CONSUME (data - start);
4003           offset += 1 + (data - start);
4004           break;
4005
4006         case DW_OP_call2:
4007           NEED (2);
4008           printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4009                   indent, "", (uintmax_t) offset, op_name,
4010                   read_2ubyte_unaligned (dbg, data));
4011           CONSUME (2);
4012           offset += 3;
4013           break;
4014
4015         case DW_OP_call4:
4016           NEED (4);
4017           printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4018                   indent, "", (uintmax_t) offset, op_name,
4019                   read_4ubyte_unaligned (dbg, data));
4020           CONSUME (4);
4021           offset += 5;
4022           break;
4023
4024         case DW_OP_skip:
4025         case DW_OP_bra:
4026           NEED (2);
4027           printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4028                   indent, "", (uintmax_t) offset, op_name,
4029                   (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4030           CONSUME (2);
4031           data += 2;
4032           offset += 3;
4033           break;
4034
4035         case DW_OP_implicit_value:
4036           start = data;
4037           NEED (1);
4038           get_uleb128 (uleb, data); /* XXX check overrun */
4039           printf ("%*s[%4" PRIuMAX "] %s: ",
4040                   indent, "", (uintmax_t) offset, op_name);
4041           NEED (uleb);
4042           print_block (uleb, data);
4043           data += uleb;
4044           CONSUME (data - start);
4045           offset += 1 + (data - start);
4046           break;
4047
4048         case DW_OP_GNU_implicit_pointer:
4049           /* DIE offset operand.  */
4050           start = data;
4051           NEED (ref_size + 1);
4052           if (ref_size == 4)
4053             addr = read_4ubyte_unaligned (dbg, data);
4054           else
4055             {
4056               assert (ref_size == 8);
4057               addr = read_8ubyte_unaligned (dbg, data);
4058             }
4059           data += ref_size;
4060           /* Byte offset operand.  */
4061           get_sleb128 (sleb, data); /* XXX check overrun */
4062
4063           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4064                   indent, "", (intmax_t) offset,
4065                   op_name, (uintmax_t) addr, sleb);
4066           CONSUME (data - start);
4067           offset += 1 + (data - start);
4068           break;
4069
4070         case DW_OP_GNU_entry_value:
4071           /* Size plus expression block.  */
4072           start = data;
4073           NEED (1);
4074           get_uleb128 (uleb, data); /* XXX check overrun */
4075           printf ("%*s[%4" PRIuMAX "] %s:\n",
4076                   indent, "", (uintmax_t) offset, op_name);
4077           NEED (uleb);
4078           print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4079                      addrsize, offset_size, cu, uleb, data);
4080           data += uleb;
4081           CONSUME (data - start);
4082           offset += 1 + (data - start);
4083           break;
4084
4085         case DW_OP_GNU_const_type:
4086           /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4087              unsigned size plus block.  */
4088           start = data;
4089           NEED (2);
4090           get_uleb128 (uleb, data); /* XXX check overrun */
4091           if (! print_unresolved_addresses && cu != NULL)
4092             uleb += cu->start;
4093           uint8_t usize = *(uint8_t *) data++;
4094           NEED (usize);
4095           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4096                   indent, "", (uintmax_t) offset, op_name, uleb);
4097           print_block (usize, data);
4098           data += usize;
4099           CONSUME (data - start);
4100           offset += 1 + (data - start);
4101           break;
4102
4103         case DW_OP_GNU_regval_type:
4104           /* uleb128 register number, uleb128 CU relative
4105              DW_TAG_base_type DIE offset.  */
4106           start = data;
4107           NEED (2);
4108           get_uleb128 (uleb, data); /* XXX check overrun */
4109           get_uleb128 (uleb2, data); /* XXX check overrun */
4110           if (! print_unresolved_addresses && cu != NULL)
4111             uleb2 += cu->start;
4112           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4113                   indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4114           CONSUME (data - start);
4115           offset += 1 + (data - start);
4116           break;
4117
4118         case DW_OP_GNU_deref_type:
4119           /* 1-byte unsigned size of value, uleb128 CU relative
4120              DW_TAG_base_type DIE offset.  */
4121           start = data;
4122           NEED (2);
4123           usize = *(uint8_t *) data++;
4124           get_uleb128 (uleb, data); /* XXX check overrun */
4125           if (! print_unresolved_addresses && cu != NULL)
4126             uleb += cu->start;
4127           printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4128                   indent, "", (uintmax_t) offset,
4129                   op_name, usize, uleb);
4130           CONSUME (data - start);
4131           offset += 1 + (data - start);
4132           break;
4133
4134         case DW_OP_GNU_convert:
4135         case DW_OP_GNU_reinterpret:
4136           /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4137              for conversion to untyped.  */
4138           start = data;
4139           NEED (1);
4140           get_uleb128 (uleb, data); /* XXX check overrun */
4141           if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4142             uleb += cu->start;
4143           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4144                   indent, "", (uintmax_t) offset, op_name, uleb);
4145           CONSUME (data - start);
4146           offset += 1 + (data - start);
4147           break;
4148
4149         case DW_OP_GNU_parameter_ref:
4150           /* 4 byte CU relative reference to the abstract optimized away
4151              DW_TAG_formal_parameter.  */
4152           NEED (4);
4153           uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4154           if (! print_unresolved_addresses && cu != NULL)
4155             param_off += cu->start;
4156           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4157                   indent, "", (uintmax_t) offset, op_name, param_off);
4158           CONSUME (4);
4159           data += 4;
4160           offset += 5;
4161           break;
4162
4163         default:
4164           /* No Operand.  */
4165           printf ("%*s[%4" PRIuMAX "] %s\n",
4166                   indent, "", (uintmax_t) offset, op_name);
4167           ++offset;
4168           break;
4169         }
4170
4171       indent = indentrest;
4172       continue;
4173
4174     invalid:
4175       printf (gettext ("%*s[%4" PRIuMAX "] %s  <TRUNCATED>\n"),
4176               indent, "", (uintmax_t) offset, op_name);
4177       break;
4178     }
4179 }
4180
4181
4182 struct listptr
4183 {
4184   Dwarf_Off offset:(64 - 3);
4185   bool addr64:1;
4186   bool dwarf64:1;
4187   bool warned:1;
4188   struct Dwarf_CU *cu;
4189 };
4190
4191 #define listptr_offset_size(p)  ((p)->dwarf64 ? 8 : 4)
4192 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4193
4194 static Dwarf_Addr
4195 listptr_base (struct listptr *p)
4196 {
4197   Dwarf_Addr base;
4198   Dwarf_Die cu = CUDIE (p->cu);
4199   /* Find the base address of the compilation unit.  It will normally
4200      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
4201      address could be overridden by DW_AT_entry_pc.  It's been
4202      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4203      compilation units with discontinuous ranges.  */
4204   if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4205     {
4206       Dwarf_Attribute attr_mem;
4207       if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4208                           &base) != 0)
4209         base = 0;
4210     }
4211   return base;
4212 }
4213
4214 static int
4215 compare_listptr (const void *a, const void *b, void *arg)
4216 {
4217   const char *name = arg;
4218   struct listptr *p1 = (void *) a;
4219   struct listptr *p2 = (void *) b;
4220
4221   if (p1->offset < p2->offset)
4222     return -1;
4223   if (p1->offset > p2->offset)
4224     return 1;
4225
4226   if (!p1->warned && !p2->warned)
4227     {
4228       if (p1->addr64 != p2->addr64)
4229         {
4230           p1->warned = p2->warned = true;
4231           error (0, 0,
4232                  gettext ("%s %#" PRIx64 " used with different address sizes"),
4233                  name, (uint64_t) p1->offset);
4234         }
4235       if (p1->dwarf64 != p2->dwarf64)
4236         {
4237           p1->warned = p2->warned = true;
4238           error (0, 0,
4239                  gettext ("%s %#" PRIx64 " used with different offset sizes"),
4240                  name, (uint64_t) p1->offset);
4241         }
4242       if (listptr_base (p1) != listptr_base (p2))
4243         {
4244           p1->warned = p2->warned = true;
4245           error (0, 0,
4246                  gettext ("%s %#" PRIx64 " used with different base addresses"),
4247                  name, (uint64_t) p1->offset);
4248         }
4249     }
4250
4251   return 0;
4252 }
4253
4254 struct listptr_table
4255 {
4256   size_t n;
4257   size_t alloc;
4258   struct listptr *table;
4259 };
4260
4261 static struct listptr_table known_loclistptr;
4262 static struct listptr_table known_rangelistptr;
4263
4264 static void
4265 reset_listptr (struct listptr_table *table)
4266 {
4267   free (table->table);
4268   table->table = NULL;
4269   table->n = table->alloc = 0;
4270 }
4271
4272 static void
4273 notice_listptr (enum section_e section, struct listptr_table *table,
4274                 uint_fast8_t address_size, uint_fast8_t offset_size,
4275                 struct Dwarf_CU *cu, Dwarf_Off offset)
4276 {
4277   if (print_debug_sections & section)
4278     {
4279       if (table->n == table->alloc)
4280         {
4281           if (table->alloc == 0)
4282             table->alloc = 128;
4283           else
4284             table->alloc *= 2;
4285           table->table = xrealloc (table->table,
4286                                    table->alloc * sizeof table->table[0]);
4287         }
4288
4289       struct listptr *p = &table->table[table->n++];
4290
4291       *p = (struct listptr)
4292         {
4293           .addr64 = address_size == 8,
4294           .dwarf64 = offset_size == 8,
4295           .offset = offset,
4296           .cu = cu
4297         };
4298       assert (p->offset == offset);
4299     }
4300 }
4301
4302 static void
4303 sort_listptr (struct listptr_table *table, const char *name)
4304 {
4305   if (table->n > 0)
4306     qsort_r (table->table, table->n, sizeof table->table[0],
4307              &compare_listptr, (void *) name);
4308 }
4309
4310 static bool
4311 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4312                    uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4313                    Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4314                    unsigned char **readp, unsigned char *endp)
4315 {
4316   if (table->n == 0)
4317     return false;
4318
4319   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4320     ++*idxp;
4321
4322   struct listptr *p = &table->table[*idxp];
4323
4324   if (*idxp == table->n
4325       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4326     {
4327       *readp = endp;
4328       printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
4329               offset);
4330       return true;
4331     }
4332
4333   if (p->offset != (Dwarf_Off) offset)
4334     {
4335       *readp += p->offset - offset;
4336       printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4337               offset, (Dwarf_Off) p->offset - offset);
4338       return true;
4339     }
4340
4341   if (address_sizep != NULL)
4342     *address_sizep = listptr_address_size (p);
4343   if (offset_sizep != NULL)
4344     *offset_sizep = listptr_offset_size (p);
4345   if (base != NULL)
4346     *base = listptr_base (p);
4347   if (cu != NULL)
4348     *cu = p->cu;
4349
4350   return false;
4351 }
4352
4353
4354 static void
4355 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4356                             Ebl *ebl, GElf_Ehdr *ehdr,
4357                             Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4358 {
4359   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4360                           dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4361
4362   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4363                    " [ Code]\n"),
4364           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4365           (uint64_t) shdr->sh_offset);
4366
4367   Dwarf_Off offset = 0;
4368   while (offset < sh_size)
4369     {
4370       printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4371               offset);
4372
4373       while (1)
4374         {
4375           size_t length;
4376           Dwarf_Abbrev abbrev;
4377
4378           int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4379           if (res != 0)
4380             {
4381               if (unlikely (res < 0))
4382                 {
4383                   printf (gettext ("\
4384  *** error while reading abbreviation: %s\n"),
4385                           dwarf_errmsg (-1));
4386                   return;
4387                 }
4388
4389               /* This is the NUL byte at the end of the section.  */
4390               ++offset;
4391               break;
4392             }
4393
4394           /* We know these calls can never fail.  */
4395           unsigned int code = dwarf_getabbrevcode (&abbrev);
4396           unsigned int tag = dwarf_getabbrevtag (&abbrev);
4397           int has_children = dwarf_abbrevhaschildren (&abbrev);
4398
4399           printf (gettext (" [%5u] offset: %" PRId64
4400                            ", children: %s, tag: %s\n"),
4401                   code, (int64_t) offset,
4402                   has_children ? gettext ("yes") : gettext ("no"),
4403                   dwarf_tag_name (tag));
4404
4405           size_t cnt = 0;
4406           unsigned int name;
4407           unsigned int form;
4408           Dwarf_Off enoffset;
4409           while (dwarf_getabbrevattr (&abbrev, cnt,
4410                                       &name, &form, &enoffset) == 0)
4411             {
4412               printf ("          attr: %s, form: %s, offset: %#" PRIx64 "\n",
4413                       dwarf_attr_name (name), dwarf_form_name (form),
4414                       (uint64_t) enoffset);
4415
4416               ++cnt;
4417             }
4418
4419           offset += length;
4420         }
4421     }
4422 }
4423
4424
4425 /* Print content of DWARF .debug_aranges section.  We fortunately do
4426    not have to know a bit about the structure of the section, libdwarf
4427    takes care of it.  */
4428 static void
4429 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4430                                GElf_Shdr *shdr, Dwarf *dbg)
4431 {
4432   Dwarf_Aranges *aranges;
4433   size_t cnt;
4434   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4435     {
4436       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4437              dwarf_errmsg (-1));
4438       return;
4439     }
4440
4441   GElf_Shdr glink_mem;
4442   GElf_Shdr *glink;
4443   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4444   if (glink == NULL)
4445     {
4446       error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4447              elf_ndxscn (scn));
4448       return;
4449     }
4450
4451   printf (ngettext ("\
4452 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4453                     "\
4454 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4455                     cnt),
4456           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4457           (uint64_t) shdr->sh_offset, cnt);
4458
4459   /* Compute floor(log16(cnt)).  */
4460   size_t tmp = cnt;
4461   int digits = 1;
4462   while (tmp >= 16)
4463     {
4464       ++digits;
4465       tmp >>= 4;
4466     }
4467
4468   for (size_t n = 0; n < cnt; ++n)
4469     {
4470       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4471       if (unlikely (runp == NULL))
4472         {
4473           printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4474           return;
4475         }
4476
4477       Dwarf_Addr start;
4478       Dwarf_Word length;
4479       Dwarf_Off offset;
4480
4481       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4482         printf (gettext (" [%*zu] ???\n"), digits, n);
4483       else
4484         printf (gettext (" [%*zu] start: %0#*" PRIx64
4485                          ", length: %5" PRIu64 ", CU DIE offset: %6"
4486                          PRId64 "\n"),
4487                 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4488                 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4489     }
4490 }
4491
4492
4493 /* Print content of DWARF .debug_aranges section.  */
4494 static void
4495 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4496                              Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4497                              GElf_Shdr *shdr, Dwarf *dbg)
4498 {
4499   if (decodedaranges)
4500     {
4501       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4502       return;
4503     }
4504
4505   Elf_Data *data = elf_rawdata (scn, NULL);
4506
4507   if (unlikely (data == NULL))
4508     {
4509       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4510              elf_errmsg (-1));
4511       return;
4512     }
4513
4514   printf (gettext ("\
4515 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4516           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4517           (uint64_t) shdr->sh_offset);
4518
4519   const unsigned char *readp = data->d_buf;
4520   const unsigned char *readendp = readp + data->d_size;
4521
4522   while (readp < readendp)
4523     {
4524       const unsigned char *hdrstart = readp;
4525       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4526
4527       printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4528       if (readp + 4 > readendp)
4529         {
4530         invalid_data:
4531           error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4532                  elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4533           return;
4534         }
4535
4536       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4537       unsigned int length_bytes = 4;
4538       if (length == DWARF3_LENGTH_64_BIT)
4539         {
4540           if (readp + 8 > readendp)
4541             goto invalid_data;
4542           length = read_8ubyte_unaligned_inc (dbg, readp);
4543           length_bytes = 8;
4544         }
4545
4546       const unsigned char *nexthdr = readp + length;
4547       printf (gettext ("\n Length:        %6" PRIu64 "\n"),
4548               (uint64_t) length);
4549
4550       if (nexthdr > readendp)
4551         goto invalid_data;
4552
4553       if (length == 0)
4554         continue;
4555
4556       if (readp + 2 > readendp)
4557         goto invalid_data;
4558       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4559       printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4560               version);
4561       if (version != 2)
4562         {
4563           error (0, 0, gettext ("unsupported aranges version"));
4564           goto next_table;
4565         }
4566
4567       Dwarf_Word offset;
4568       if (readp + length_bytes > readendp)
4569         goto invalid_data;
4570       if (length_bytes == 8)
4571         offset = read_8ubyte_unaligned_inc (dbg, readp);
4572       else
4573         offset = read_4ubyte_unaligned_inc (dbg, readp);
4574       printf (gettext (" CU offset:     %6" PRIx64 "\n"),
4575               (uint64_t) offset);
4576
4577       if (readp + 1 > readendp)
4578         goto invalid_data;
4579       unsigned int address_size = *readp++;
4580       printf (gettext (" Address size:  %6" PRIu64 "\n"),
4581               (uint64_t) address_size);
4582       if (address_size != 4 && address_size != 8)
4583         {
4584           error (0, 0, gettext ("unsupported address size"));
4585           goto next_table;
4586         }
4587
4588       unsigned int segment_size = *readp++;
4589       printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
4590               (uint64_t) segment_size);
4591       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4592         {
4593           error (0, 0, gettext ("unsupported segment size"));
4594           goto next_table;
4595         }
4596
4597       /* Round the address to the next multiple of 2*address_size.  */
4598       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4599                 % (2 * address_size));
4600
4601       while (readp < nexthdr)
4602         {
4603           Dwarf_Word range_address;
4604           Dwarf_Word range_length;
4605           Dwarf_Word segment = 0;
4606           if (readp + 2 * address_size + segment_size > readendp)
4607             goto invalid_data;
4608           if (address_size == 4)
4609             {
4610               range_address = read_4ubyte_unaligned_inc (dbg, readp);
4611               range_length = read_4ubyte_unaligned_inc (dbg, readp);
4612             }
4613           else
4614             {
4615               range_address = read_8ubyte_unaligned_inc (dbg, readp);
4616               range_length = read_8ubyte_unaligned_inc (dbg, readp);
4617             }
4618
4619           if (segment_size == 4)
4620             segment = read_4ubyte_unaligned_inc (dbg, readp);
4621           else if (segment_size == 8)
4622             segment = read_8ubyte_unaligned_inc (dbg, readp);
4623
4624           if (range_address == 0 && range_length == 0 && segment == 0)
4625             break;
4626
4627           char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4628                                        range_address);
4629           char *e = format_dwarf_addr (dwflmod, address_size,
4630                                        range_address + range_length - 1,
4631                                        range_length);
4632           if (segment_size != 0)
4633             printf (gettext ("   %s..%s (%" PRIx64 ")\n"), b, e,
4634                     (uint64_t) segment);
4635           else
4636             printf (gettext ("   %s..%s\n"), b, e);
4637           free (b);
4638           free (e);
4639         }
4640
4641     next_table:
4642       if (readp != nexthdr)
4643         {
4644           size_t padding = nexthdr - readp;
4645           printf (gettext ("   %Zu padding bytes\n"), padding);
4646           readp = nexthdr;
4647         }
4648     }
4649 }
4650
4651
4652 /* Print content of DWARF .debug_ranges section.  */
4653 static void
4654 print_debug_ranges_section (Dwfl_Module *dwflmod,
4655                             Ebl *ebl, GElf_Ehdr *ehdr,
4656                             Elf_Scn *scn, GElf_Shdr *shdr,
4657                             Dwarf *dbg)
4658 {
4659   Elf_Data *data = elf_rawdata (scn, NULL);
4660
4661   if (unlikely (data == NULL))
4662     {
4663       error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4664              elf_errmsg (-1));
4665       return;
4666     }
4667
4668   printf (gettext ("\
4669 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4670           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4671           (uint64_t) shdr->sh_offset);
4672
4673   sort_listptr (&known_rangelistptr, "rangelistptr");
4674   size_t listptr_idx = 0;
4675
4676   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4677
4678   bool first = true;
4679   Dwarf_Addr base = 0;
4680   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4681   unsigned char *readp = data->d_buf;
4682   while (readp < endp)
4683     {
4684       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4685
4686       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4687                                       &address_size, NULL, &base, NULL,
4688                                       offset, &readp, endp))
4689         continue;
4690
4691       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4692         {
4693           printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
4694           break;
4695         }
4696
4697       Dwarf_Addr begin;
4698       Dwarf_Addr end;
4699       if (address_size == 8)
4700         {
4701           begin = read_8ubyte_unaligned_inc (dbg, readp);
4702           end = read_8ubyte_unaligned_inc (dbg, readp);
4703         }
4704       else
4705         {
4706           begin = read_4ubyte_unaligned_inc (dbg, readp);
4707           end = read_4ubyte_unaligned_inc (dbg, readp);
4708           if (begin == (Dwarf_Addr) (uint32_t) -1)
4709             begin = (Dwarf_Addr) -1l;
4710         }
4711
4712       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
4713         {
4714           char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4715           printf (gettext (" [%6tx]  base address %s\n"), offset, b);
4716           free (b);
4717           base = end;
4718         }
4719       else if (begin == 0 && end == 0) /* End of list entry.  */
4720         {
4721           if (first)
4722             printf (gettext (" [%6tx]  empty list\n"), offset);
4723           first = true;
4724         }
4725       else
4726         {
4727           char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4728                                        begin);
4729           char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4730                                        end);
4731           /* We have an address range entry.  */
4732           if (first)            /* First address range entry in a list.  */
4733             printf (gettext (" [%6tx]  %s..%s\n"), offset, b, e);
4734           else
4735             printf (gettext ("           %s..%s\n"), b, e);
4736           free (b);
4737           free (e);
4738
4739           first = false;
4740         }
4741     }
4742 }
4743
4744 #define REGNAMESZ 16
4745 static const char *
4746 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4747                char name[REGNAMESZ], int *bits, int *type)
4748 {
4749   const char *set;
4750   const char *pfx;
4751   int ignore;
4752   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4753                                  bits ?: &ignore, type ?: &ignore);
4754   if (n <= 0)
4755     {
4756       if (loc != NULL)
4757         snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4758       else
4759         snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4760       if (bits != NULL)
4761         *bits = loc != NULL ? loc->bits : 0;
4762       if (type != NULL)
4763         *type = DW_ATE_unsigned;
4764       set = "??? unrecognized";
4765     }
4766   else
4767     {
4768       if (bits != NULL && *bits <= 0)
4769         *bits = loc != NULL ? loc->bits : 0;
4770       if (type != NULL && *type == DW_ATE_void)
4771         *type = DW_ATE_unsigned;
4772
4773     }
4774   return set;
4775 }
4776
4777 static void
4778 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4779                    Dwarf_Word vma_base, unsigned int code_align,
4780                    int data_align,
4781                    unsigned int version, unsigned int ptr_size,
4782                    Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4783 {
4784   char regnamebuf[REGNAMESZ];
4785   const char *regname (unsigned int regno)
4786   {
4787     register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4788     return regnamebuf;
4789   }
4790
4791   puts ("\n   Program:");
4792   Dwarf_Word pc = vma_base;
4793   while (readp < endp)
4794     {
4795       unsigned int opcode = *readp++;
4796
4797       if (opcode < DW_CFA_advance_loc)
4798         /* Extended opcode.  */
4799         switch (opcode)
4800           {
4801             uint64_t op1;
4802             int64_t sop1;
4803             uint64_t op2;
4804             int64_t sop2;
4805
4806           case DW_CFA_nop:
4807             puts ("     nop");
4808             break;
4809           case DW_CFA_set_loc:
4810             // XXX overflow check
4811             get_uleb128 (op1, readp);
4812             op1 += vma_base;
4813             printf ("     set_loc %" PRIu64 "\n", op1 * code_align);
4814             break;
4815           case DW_CFA_advance_loc1:
4816             printf ("     advance_loc1 %u to %#" PRIx64 "\n",
4817                     *readp, pc += *readp * code_align);
4818             ++readp;
4819             break;
4820           case DW_CFA_advance_loc2:
4821             op1 = read_2ubyte_unaligned_inc (dbg, readp);
4822             printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4823                     op1, pc += op1 * code_align);
4824             break;
4825           case DW_CFA_advance_loc4:
4826             op1 = read_4ubyte_unaligned_inc (dbg, readp);
4827             printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4828                     op1, pc += op1 * code_align);
4829             break;
4830           case DW_CFA_offset_extended:
4831             // XXX overflow check
4832             get_uleb128 (op1, readp);
4833             get_uleb128 (op2, readp);
4834             printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4835                     "\n",
4836                     op1, regname (op1), op2 * data_align);
4837             break;
4838           case DW_CFA_restore_extended:
4839             // XXX overflow check
4840             get_uleb128 (op1, readp);
4841             printf ("     restore_extended r%" PRIu64 " (%s)\n",
4842                     op1, regname (op1));
4843             break;
4844           case DW_CFA_undefined:
4845             // XXX overflow check
4846             get_uleb128 (op1, readp);
4847             printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
4848             break;
4849           case DW_CFA_same_value:
4850             // XXX overflow check
4851             get_uleb128 (op1, readp);
4852             printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
4853             break;
4854           case DW_CFA_register:
4855             // XXX overflow check
4856             get_uleb128 (op1, readp);
4857             get_uleb128 (op2, readp);
4858             printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
4859                     op1, regname (op1), op2, regname (op2));
4860             break;
4861           case DW_CFA_remember_state:
4862             puts ("     remember_state");
4863             break;
4864           case DW_CFA_restore_state:
4865             puts ("     restore_state");
4866             break;
4867           case DW_CFA_def_cfa:
4868             // XXX overflow check
4869             get_uleb128 (op1, readp);
4870             get_uleb128 (op2, readp);
4871             printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
4872                     op1, regname (op1), op2);
4873             break;
4874           case DW_CFA_def_cfa_register:
4875             // XXX overflow check
4876             get_uleb128 (op1, readp);
4877             printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
4878                     op1, regname (op1));
4879             break;
4880           case DW_CFA_def_cfa_offset:
4881             // XXX overflow check
4882             get_uleb128 (op1, readp);
4883             printf ("     def_cfa_offset %" PRIu64 "\n", op1);
4884             break;
4885           case DW_CFA_def_cfa_expression:
4886             // XXX overflow check
4887             get_uleb128 (op1, readp);   /* Length of DW_FORM_block.  */
4888             printf ("     def_cfa_expression %" PRIu64 "\n", op1);
4889             print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4890                        op1, readp);
4891             readp += op1;
4892             break;
4893           case DW_CFA_expression:
4894             // XXX overflow check
4895             get_uleb128 (op1, readp);
4896             get_uleb128 (op2, readp);   /* Length of DW_FORM_block.  */
4897             printf ("     expression r%" PRIu64 " (%s) \n",
4898                     op1, regname (op1));
4899             print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
4900                        op2, readp);
4901             readp += op2;
4902             break;
4903           case DW_CFA_offset_extended_sf:
4904             // XXX overflow check
4905             get_uleb128 (op1, readp);
4906             get_sleb128 (sop2, readp);
4907             printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
4908                     PRId64 "\n",
4909                     op1, regname (op1), sop2 * data_align);
4910             break;
4911           case DW_CFA_def_cfa_sf:
4912             // XXX overflow check
4913             get_uleb128 (op1, readp);
4914             get_sleb128 (sop2, readp);
4915             printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
4916                     op1, regname (op1), sop2 * data_align);
4917             break;
4918           case DW_CFA_def_cfa_offset_sf:
4919             // XXX overflow check
4920             get_sleb128 (sop1, readp);
4921             printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
4922             break;
4923           case DW_CFA_val_offset:
4924             // XXX overflow check
4925             get_uleb128 (op1, readp);
4926             get_uleb128 (op2, readp);
4927             printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
4928                     op1, op2 * data_align);
4929             break;
4930           case DW_CFA_val_offset_sf:
4931             // XXX overflow check
4932             get_uleb128 (op1, readp);
4933             get_sleb128 (sop2, readp);
4934             printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
4935                     op1, sop2 * data_align);
4936             break;
4937           case DW_CFA_val_expression:
4938             // XXX overflow check
4939             get_uleb128 (op1, readp);
4940             get_uleb128 (op2, readp);   /* Length of DW_FORM_block.  */
4941             printf ("     val_expression r%" PRIu64 " (%s)\n",
4942                     op1, regname (op1));
4943             print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
4944                        NULL, op2, readp);
4945             readp += op2;
4946             break;
4947           case DW_CFA_MIPS_advance_loc8:
4948             op1 = read_8ubyte_unaligned_inc (dbg, readp);
4949             printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
4950                     op1, pc += op1 * code_align);
4951             break;
4952           case DW_CFA_GNU_window_save:
4953             puts ("     GNU_window_save");
4954             break;
4955           case DW_CFA_GNU_args_size:
4956             // XXX overflow check
4957             get_uleb128 (op1, readp);
4958             printf ("     args_size %" PRIu64 "\n", op1);
4959             break;
4960           default:
4961             printf ("     ??? (%u)\n", opcode);
4962             break;
4963           }
4964       else if (opcode < DW_CFA_offset)
4965         printf ("     advance_loc %u to %#" PRIx64 "\n",
4966                 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
4967       else if (opcode < DW_CFA_restore)
4968         {
4969           uint64_t offset;
4970           // XXX overflow check
4971           get_uleb128 (offset, readp);
4972           printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
4973                   opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
4974         }
4975       else
4976         printf ("     restore r%u (%s)\n",
4977                 opcode & 0x3f, regname (opcode & 0x3f));
4978     }
4979 }
4980
4981
4982 static unsigned int
4983 encoded_ptr_size (int encoding, unsigned int ptr_size)
4984 {
4985   switch (encoding & 7)
4986     {
4987     case 2:
4988       return 2;
4989     case 3:
4990       return 4;
4991     case 4:
4992       return 8;
4993     default:
4994       return ptr_size;
4995     }
4996 }
4997
4998
4999 static unsigned int
5000 print_encoding (unsigned int val)
5001 {
5002   switch (val & 0xf)
5003     {
5004     case DW_EH_PE_absptr:
5005       fputs ("absptr", stdout);
5006       break;
5007     case DW_EH_PE_uleb128:
5008       fputs ("uleb128", stdout);
5009       break;
5010     case DW_EH_PE_udata2:
5011       fputs ("udata2", stdout);
5012       break;
5013     case DW_EH_PE_udata4:
5014       fputs ("udata4", stdout);
5015       break;
5016     case DW_EH_PE_udata8:
5017       fputs ("udata8", stdout);
5018       break;
5019     case DW_EH_PE_sleb128:
5020       fputs ("sleb128", stdout);
5021       break;
5022     case DW_EH_PE_sdata2:
5023       fputs ("sdata2", stdout);
5024       break;
5025     case DW_EH_PE_sdata4:
5026       fputs ("sdata4", stdout);
5027       break;
5028     case DW_EH_PE_sdata8:
5029       fputs ("sdata8", stdout);
5030       break;
5031     default:
5032       /* We did not use any of the bits after all.  */
5033       return val;
5034     }
5035
5036   return val & ~0xf;
5037 }
5038
5039
5040 static unsigned int
5041 print_relinfo (unsigned int val)
5042 {
5043   switch (val & 0x70)
5044     {
5045     case DW_EH_PE_pcrel:
5046       fputs ("pcrel", stdout);
5047       break;
5048     case DW_EH_PE_textrel:
5049       fputs ("textrel", stdout);
5050       break;
5051     case DW_EH_PE_datarel:
5052       fputs ("datarel", stdout);
5053       break;
5054     case DW_EH_PE_funcrel:
5055       fputs ("funcrel", stdout);
5056       break;
5057     case DW_EH_PE_aligned:
5058       fputs ("aligned", stdout);
5059       break;
5060     default:
5061       return val;
5062     }
5063
5064   return val & ~0x70;
5065 }
5066
5067
5068 static void
5069 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5070 {
5071   printf ("(%s", pfx);
5072
5073   if (fde_encoding == DW_EH_PE_omit)
5074     puts ("omit)");
5075   else
5076     {
5077       unsigned int w = fde_encoding;
5078
5079       w = print_encoding (w);
5080
5081       if (w & 0x70)
5082         {
5083           if (w != fde_encoding)
5084             fputc_unlocked (' ', stdout);
5085
5086           w = print_relinfo (w);
5087         }
5088
5089       if (w != 0)
5090         printf ("%s%x", w != fde_encoding ? " " : "", w);
5091
5092       puts (")");
5093     }
5094 }
5095
5096
5097 static const unsigned char *
5098 read_encoded (unsigned int encoding, const unsigned char *readp,
5099               const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5100 {
5101   if ((encoding & 0xf) == DW_EH_PE_absptr)
5102     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5103       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5104
5105   switch (encoding & 0xf)
5106     {
5107     case DW_EH_PE_uleb128:
5108       // XXX buffer overrun check
5109       get_uleb128 (*res, readp);
5110       break;
5111     case DW_EH_PE_sleb128:
5112       // XXX buffer overrun check
5113       get_sleb128 (*res, readp);
5114       break;
5115     case DW_EH_PE_udata2:
5116       if (readp + 2 > endp)
5117         goto invalid;
5118       *res = read_2ubyte_unaligned_inc (dbg, readp);
5119       break;
5120     case DW_EH_PE_udata4:
5121       if (readp + 4 > endp)
5122         goto invalid;
5123       *res = read_4ubyte_unaligned_inc (dbg, readp);
5124       break;
5125     case DW_EH_PE_udata8:
5126       if (readp + 8 > endp)
5127         goto invalid;
5128       *res = read_8ubyte_unaligned_inc (dbg, readp);
5129       break;
5130     case DW_EH_PE_sdata2:
5131       if (readp + 2 > endp)
5132         goto invalid;
5133       *res = read_2sbyte_unaligned_inc (dbg, readp);
5134       break;
5135     case DW_EH_PE_sdata4:
5136       if (readp + 4 > endp)
5137         goto invalid;
5138       *res = read_4sbyte_unaligned_inc (dbg, readp);
5139       break;
5140     case DW_EH_PE_sdata8:
5141       if (readp + 8 > endp)
5142         goto invalid;
5143       *res = read_8sbyte_unaligned_inc (dbg, readp);
5144       break;
5145     default:
5146     invalid:
5147       error (1, 0,
5148              gettext ("invalid encoding"));
5149     }
5150
5151   return readp;
5152 }
5153
5154
5155 static void
5156 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5157                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5158 {
5159   size_t shstrndx;
5160   /* We know this call will succeed since it did in the caller.  */
5161   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5162   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5163
5164   /* Needed if we find PC-relative addresses.  */
5165   GElf_Addr bias;
5166   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5167     {
5168       error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5169       return;
5170     }
5171
5172   Elf_Data *data = elf_rawdata (scn, NULL);
5173
5174   if (unlikely (data == NULL))
5175     {
5176       error (0, 0, gettext ("cannot get %s content: %s"),
5177              scnname, elf_errmsg (-1));
5178       return;
5179     }
5180   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5181
5182   if (is_eh_frame)
5183     printf (gettext ("\
5184 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5185             elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5186   else
5187     printf (gettext ("\
5188 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5189             elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5190
5191   struct cieinfo
5192   {
5193     ptrdiff_t cie_offset;
5194     const char *augmentation;
5195     unsigned int code_alignment_factor;
5196     unsigned int data_alignment_factor;
5197     uint8_t address_size;
5198     uint8_t fde_encoding;
5199     uint8_t lsda_encoding;
5200     struct cieinfo *next;
5201   } *cies = NULL;
5202
5203   const unsigned char *readp = data->d_buf;
5204   const unsigned char *const dataend = ((unsigned char *) data->d_buf
5205                                         + data->d_size);
5206   while (readp < dataend)
5207     {
5208       if (unlikely (readp + 4 > dataend))
5209         {
5210         invalid_data:
5211           error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5212                      elf_ndxscn (scn), scnname);
5213               return;
5214         }
5215
5216       /* At the beginning there must be a CIE.  There can be multiple,
5217          hence we test tis in a loop.  */
5218       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5219
5220       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5221       unsigned int length = 4;
5222       if (unlikely (unit_length == 0xffffffff))
5223         {
5224           if (unlikely (readp + 8 > dataend))
5225             goto invalid_data;
5226
5227           unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5228           length = 8;
5229         }
5230
5231       if (unlikely (unit_length == 0))
5232         {
5233           printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5234           continue;
5235         }
5236
5237       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5238
5239       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5240       const unsigned char *const cieend = readp + unit_length;
5241       if (unlikely (cieend > dataend || readp + 8 > dataend))
5242         goto invalid_data;
5243
5244       Dwarf_Off cie_id;
5245       if (length == 4)
5246         {
5247           cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5248           if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5249             cie_id = DW_CIE_ID_64;
5250         }
5251       else
5252         cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5253
5254       uint_fast8_t version = 2;
5255       unsigned int code_alignment_factor;
5256       int data_alignment_factor;
5257       unsigned int fde_encoding = 0;
5258       unsigned int lsda_encoding = 0;
5259       Dwarf_Word initial_location = 0;
5260       Dwarf_Word vma_base = 0;
5261
5262       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5263         {
5264           version = *readp++;
5265           const char *const augmentation = (const char *) readp;
5266           readp = memchr (readp, '\0', cieend - readp);
5267           if (unlikely (readp == NULL))
5268             goto invalid_data;
5269           ++readp;
5270
5271           uint_fast8_t segment_size = 0;
5272           if (version >= 4)
5273             {
5274               if (cieend - readp < 5)
5275                 goto invalid_data;
5276               ptr_size = *readp++;
5277               segment_size = *readp++;
5278             }
5279
5280           // XXX Check overflow
5281           get_uleb128 (code_alignment_factor, readp);
5282           // XXX Check overflow
5283           get_sleb128 (data_alignment_factor, readp);
5284
5285           /* In some variant for unwind data there is another field.  */
5286           if (strcmp (augmentation, "eh") == 0)
5287             readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5288
5289           unsigned int return_address_register;
5290           if (unlikely (version == 1))
5291             return_address_register = *readp++;
5292           else
5293             // XXX Check overflow
5294             get_uleb128 (return_address_register, readp);
5295
5296           printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5297                   "   CIE_id:                   %" PRIu64 "\n"
5298                   "   version:                  %u\n"
5299                   "   augmentation:             \"%s\"\n",
5300                   offset, (uint64_t) unit_length, (uint64_t) cie_id,
5301                   version, augmentation);
5302           if (version >= 4)
5303             printf ("   address_size:             %u\n"
5304                     "   segment_size:             %u\n",
5305                     ptr_size, segment_size);
5306           printf ("   code_alignment_factor:    %u\n"
5307                   "   data_alignment_factor:    %d\n"
5308                   "   return_address_register:  %u\n",
5309                   code_alignment_factor,
5310                   data_alignment_factor, return_address_register);
5311
5312           if (augmentation[0] == 'z')
5313             {
5314               unsigned int augmentationlen;
5315               get_uleb128 (augmentationlen, readp);
5316
5317               if (augmentationlen > (size_t) (dataend - readp))
5318                 error (1, 0, gettext ("invalid augmentation length"));
5319
5320               const char *hdr = "Augmentation data:";
5321               const char *cp = augmentation + 1;
5322               while (*cp != '\0')
5323                 {
5324                   printf ("   %-26s%#x ", hdr, *readp);
5325                   hdr = "";
5326
5327                   if (*cp == 'R')
5328                     {
5329                       fde_encoding = *readp++;
5330                       print_encoding_base (gettext ("FDE address encoding: "),
5331                                            fde_encoding);
5332                     }
5333                   else if (*cp == 'L')
5334                     {
5335                       lsda_encoding = *readp++;
5336                       print_encoding_base (gettext ("LSDA pointer encoding: "),
5337                                            lsda_encoding);
5338                     }
5339                   else if (*cp == 'P')
5340                     {
5341                       /* Personality.  This field usually has a relocation
5342                          attached pointing to __gcc_personality_v0.  */
5343                       const unsigned char *startp = readp;
5344                       unsigned int encoding = *readp++;
5345                       uint64_t val = 0;
5346                       readp = read_encoded (encoding, readp,
5347                                             readp - 1 + augmentationlen,
5348                                             &val, dbg);
5349
5350                       while (++startp < readp)
5351                         printf ("%#x ", *startp);
5352
5353                       putchar ('(');
5354                       print_encoding (encoding);
5355                       putchar (' ');
5356                       switch (encoding & 0xf)
5357                         {
5358                         case DW_EH_PE_sleb128:
5359                         case DW_EH_PE_sdata2:
5360                         case DW_EH_PE_sdata4:
5361                           printf ("%" PRId64 ")\n", val);
5362                           break;
5363                         default:
5364                           printf ("%#" PRIx64 ")\n", val);
5365                           break;
5366                         }
5367                     }
5368                   else
5369                     printf ("(%x)\n", *readp++);
5370
5371                   ++cp;
5372                 }
5373             }
5374
5375           if (likely (ptr_size == 4 || ptr_size == 8))
5376             {
5377               struct cieinfo *newp = alloca (sizeof (*newp));
5378               newp->cie_offset = offset;
5379               newp->augmentation = augmentation;
5380               newp->fde_encoding = fde_encoding;
5381               newp->lsda_encoding = lsda_encoding;
5382               newp->address_size = ptr_size;
5383               newp->code_alignment_factor = code_alignment_factor;
5384               newp->data_alignment_factor = data_alignment_factor;
5385               newp->next = cies;
5386               cies = newp;
5387             }
5388         }
5389       else
5390         {
5391           struct cieinfo *cie = cies;
5392           while (cie != NULL)
5393             if (is_eh_frame
5394                 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5395                 : (ptrdiff_t) cie_id == cie->cie_offset)
5396               break;
5397             else
5398               cie = cie->next;
5399           if (unlikely (cie == NULL))
5400             {
5401               puts ("invalid CIE reference in FDE");
5402               return;
5403             }
5404
5405           /* Initialize from CIE data.  */
5406           fde_encoding = cie->fde_encoding;
5407           lsda_encoding = cie->lsda_encoding;
5408           ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5409           code_alignment_factor = cie->code_alignment_factor;
5410           data_alignment_factor = cie->data_alignment_factor;
5411
5412           const unsigned char *base = readp;
5413           // XXX There are sometimes relocations for this value
5414           initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5415           Dwarf_Word address_range
5416             = read_ubyte_unaligned_inc (ptr_size, dbg, readp);
5417
5418           /* pcrel for an FDE address is relative to the runtime
5419              address of the start_address field itself.  Sign extend
5420              if necessary to make sure the calculation is done on the
5421              full 64 bit address even when initial_location only holds
5422              the lower 32 bits.  */
5423           Dwarf_Addr pc_start = initial_location;
5424           if (ptr_size == 4)
5425             pc_start = (uint64_t) (int32_t) pc_start;
5426           if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5427             pc_start += ((uint64_t) shdr->sh_addr
5428                          + (base - (const unsigned char *) data->d_buf)
5429                          - bias);
5430
5431           char *a = format_dwarf_addr (dwflmod, cie->address_size,
5432                                        pc_start, initial_location);
5433           printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5434                   "   CIE_pointer:              %" PRIu64 "\n"
5435                   "   initial_location:         %s",
5436                   offset, (uint64_t) unit_length,
5437                   cie->cie_offset, (uint64_t) cie_id, a);
5438           free (a);
5439           if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5440             {
5441               vma_base = (((uint64_t) shdr->sh_offset
5442                            + (base - (const unsigned char *) data->d_buf)
5443                            + (uint64_t) initial_location)
5444                           & (ptr_size == 4
5445                              ? UINT64_C (0xffffffff)
5446                              : UINT64_C (0xffffffffffffffff)));
5447               printf (gettext (" (offset: %#" PRIx64 ")"),
5448                       (uint64_t) vma_base);
5449             }
5450
5451           printf ("\n   address_range:            %#" PRIx64,
5452                   (uint64_t) address_range);
5453           if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5454             printf (gettext (" (end offset: %#" PRIx64 ")"),
5455                     ((uint64_t) vma_base + (uint64_t) address_range)
5456                     & (ptr_size == 4
5457                        ? UINT64_C (0xffffffff)
5458                        : UINT64_C (0xffffffffffffffff)));
5459           putchar ('\n');
5460
5461           if (cie->augmentation[0] == 'z')
5462             {
5463               unsigned int augmentationlen;
5464               get_uleb128 (augmentationlen, readp);
5465
5466               if (augmentationlen > 0)
5467                 {
5468                   const char *hdr = "Augmentation data:";
5469                   const char *cp = cie->augmentation + 1;
5470                   unsigned int u = 0;
5471                   while (*cp != '\0')
5472                     {
5473                       if (*cp == 'L')
5474                         {
5475                           uint64_t lsda_pointer;
5476                           const unsigned char *p
5477                             = read_encoded (lsda_encoding, &readp[u],
5478                                             &readp[augmentationlen],
5479                                             &lsda_pointer, dbg);
5480                           u = p - readp;
5481                           printf (gettext ("\
5482    %-26sLSDA pointer: %#" PRIx64 "\n"),
5483                                   hdr, lsda_pointer);
5484                           hdr = "";
5485                         }
5486                       ++cp;
5487                     }
5488
5489                   while (u < augmentationlen)
5490                     {
5491                       printf ("   %-26s%#x\n", hdr, readp[u++]);
5492                       hdr = "";
5493                     }
5494                 }
5495
5496               readp += augmentationlen;
5497             }
5498         }
5499
5500       /* Handle the initialization instructions.  */
5501       print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5502                          data_alignment_factor, version, ptr_size,
5503                          dwflmod, ebl, dbg);
5504       readp = cieend;
5505     }
5506 }
5507
5508
5509 struct attrcb_args
5510 {
5511   Dwfl_Module *dwflmod;
5512   Dwarf *dbg;
5513   Dwarf_Die *die;
5514   int level;
5515   bool silent;
5516   unsigned int version;
5517   unsigned int addrsize;
5518   unsigned int offset_size;
5519   struct Dwarf_CU *cu;
5520 };
5521
5522
5523 static int
5524 attr_callback (Dwarf_Attribute *attrp, void *arg)
5525 {
5526   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5527   const int level = cbargs->level;
5528
5529   unsigned int attr = dwarf_whatattr (attrp);
5530   if (unlikely (attr == 0))
5531     {
5532       if (!cbargs->silent)
5533         error (0, 0, gettext ("cannot get attribute code: %s"),
5534                dwarf_errmsg (-1));
5535       return DWARF_CB_ABORT;
5536     }
5537
5538   unsigned int form = dwarf_whatform (attrp);
5539   if (unlikely (form == 0))
5540     {
5541       if (!cbargs->silent)
5542         error (0, 0, gettext ("cannot get attribute form: %s"),
5543                dwarf_errmsg (-1));
5544       return DWARF_CB_ABORT;
5545     }
5546
5547   switch (form)
5548     {
5549     case DW_FORM_addr:
5550       if (!cbargs->silent)
5551         {
5552           Dwarf_Addr addr;
5553           if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5554             {
5555             attrval_out:
5556               if (!cbargs->silent)
5557                 error (0, 0, gettext ("cannot get attribute value: %s"),
5558                        dwarf_errmsg (-1));
5559               return DWARF_CB_ABORT;
5560             }
5561           char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5562                                        addr, addr);
5563           printf ("           %*s%-20s (%s) %s\n",
5564                   (int) (level * 2), "", dwarf_attr_name (attr),
5565                   dwarf_form_name (form), a);
5566           free (a);
5567         }
5568       break;
5569
5570     case DW_FORM_indirect:
5571     case DW_FORM_strp:
5572     case DW_FORM_string:
5573     case DW_FORM_GNU_strp_alt:
5574       if (cbargs->silent)
5575         break;
5576       const char *str = dwarf_formstring (attrp);
5577       if (unlikely (str == NULL))
5578         goto attrval_out;
5579       printf ("           %*s%-20s (%s) \"%s\"\n",
5580               (int) (level * 2), "", dwarf_attr_name (attr),
5581               dwarf_form_name (form), str);
5582       break;
5583
5584     case DW_FORM_ref_addr:
5585     case DW_FORM_ref_udata:
5586     case DW_FORM_ref8:
5587     case DW_FORM_ref4:
5588     case DW_FORM_ref2:
5589     case DW_FORM_ref1:
5590     case DW_FORM_GNU_ref_alt:
5591       if (cbargs->silent)
5592         break;
5593       Dwarf_Die ref;
5594       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5595         goto attrval_out;
5596
5597       printf ("           %*s%-20s (%s) [%6" PRIxMAX "]\n",
5598               (int) (level * 2), "", dwarf_attr_name (attr),
5599               dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5600       break;
5601
5602     case DW_FORM_ref_sig8:
5603       if (cbargs->silent)
5604         break;
5605       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
5606               (int) (level * 2), "", dwarf_attr_name (attr),
5607               dwarf_form_name (form),
5608               (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5609       break;
5610
5611     case DW_FORM_sec_offset:
5612     case DW_FORM_udata:
5613     case DW_FORM_sdata:
5614     case DW_FORM_data8:
5615     case DW_FORM_data4:
5616     case DW_FORM_data2:
5617     case DW_FORM_data1:;
5618       Dwarf_Word num;
5619       if (unlikely (dwarf_formudata (attrp, &num) != 0))
5620         goto attrval_out;
5621
5622       const char *valuestr = NULL;
5623       switch (attr)
5624         {
5625           /* This case can take either a constant or a loclistptr.  */
5626         case DW_AT_data_member_location:
5627           if (form != DW_FORM_sec_offset
5628               && (cbargs->version >= 4
5629                   || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5630             {
5631               if (!cbargs->silent)
5632                 printf ("           %*s%-20s (%s) %" PRIxMAX "\n",
5633                         (int) (level * 2), "", dwarf_attr_name (attr),
5634                         dwarf_form_name (form), (uintmax_t) num);
5635               return DWARF_CB_OK;
5636             }
5637           /* else fallthrough */
5638
5639         /* These cases always take a loclistptr and no constant. */
5640         case DW_AT_location:
5641         case DW_AT_data_location:
5642         case DW_AT_vtable_elem_location:
5643         case DW_AT_string_length:
5644         case DW_AT_use_location:
5645         case DW_AT_frame_base:
5646         case DW_AT_return_addr:
5647         case DW_AT_static_link:
5648         case DW_AT_GNU_call_site_value:
5649         case DW_AT_GNU_call_site_data_value:
5650         case DW_AT_GNU_call_site_target:
5651         case DW_AT_GNU_call_site_target_clobbered:
5652           notice_listptr (section_loc, &known_loclistptr,
5653                           cbargs->addrsize, cbargs->offset_size,
5654                           cbargs->cu, num);
5655           if (!cbargs->silent)
5656             printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5657                     (int) (level * 2), "", dwarf_attr_name (attr),
5658                     dwarf_form_name (form), (uintmax_t) num);
5659           return DWARF_CB_OK;
5660
5661         case DW_AT_ranges:
5662           notice_listptr (section_ranges, &known_rangelistptr,
5663                           cbargs->addrsize, cbargs->offset_size,
5664                           cbargs->cu, num);
5665           if (!cbargs->silent)
5666             printf ("           %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5667                     (int) (level * 2), "", dwarf_attr_name (attr),
5668                     dwarf_form_name (form), (uintmax_t) num);
5669           return DWARF_CB_OK;
5670
5671         case DW_AT_language:
5672           valuestr = dwarf_lang_name (num);
5673           break;
5674         case DW_AT_encoding:
5675           valuestr = dwarf_encoding_name (num);
5676           break;
5677         case DW_AT_accessibility:
5678           valuestr = dwarf_access_name (num);
5679           break;
5680         case DW_AT_visibility:
5681           valuestr = dwarf_visibility_name (num);
5682           break;
5683         case DW_AT_virtuality:
5684           valuestr = dwarf_virtuality_name (num);
5685           break;
5686         case DW_AT_identifier_case:
5687           valuestr = dwarf_identifier_case_name (num);
5688           break;
5689         case DW_AT_calling_convention:
5690           valuestr = dwarf_calling_convention_name (num);
5691           break;
5692         case DW_AT_inline:
5693           valuestr = dwarf_inline_name (num);
5694           break;
5695         case DW_AT_ordering:
5696           valuestr = dwarf_ordering_name (num);
5697           break;
5698         case DW_AT_discr_list:
5699           valuestr = dwarf_discr_list_name (num);
5700           break;
5701         default:
5702           /* Nothing.  */
5703           break;
5704         }
5705
5706       if (cbargs->silent)
5707         break;
5708
5709       /* When highpc is in constant form it is relative to lowpc.
5710          In that case also show the address.  */
5711       Dwarf_Addr highpc;
5712       if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5713         {
5714           char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5715                                        highpc, highpc);
5716           printf ("           %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5717                   (int) (level * 2), "", dwarf_attr_name (attr),
5718                   dwarf_form_name (form), (uintmax_t) num, a);
5719           free (a);
5720         }
5721       else if (valuestr == NULL)
5722         printf ("           %*s%-20s (%s) %" PRIuMAX "\n",
5723                 (int) (level * 2), "", dwarf_attr_name (attr),
5724                 dwarf_form_name (form), (uintmax_t) num);
5725       else
5726         printf ("           %*s%-20s (%s) %s (%" PRIuMAX ")\n",
5727                 (int) (level * 2), "", dwarf_attr_name (attr),
5728                 dwarf_form_name (form), valuestr, (uintmax_t) num);
5729       break;
5730
5731     case DW_FORM_flag:
5732       if (cbargs->silent)
5733         break;
5734       bool flag;
5735       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5736         goto attrval_out;
5737
5738       printf ("           %*s%-20s (%s) %s\n",
5739               (int) (level * 2), "", dwarf_attr_name (attr),
5740               dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5741       break;
5742
5743     case DW_FORM_flag_present:
5744       if (cbargs->silent)
5745         break;
5746       printf ("           %*s%-20s (%s) %s\n",
5747               (int) (level * 2), "", dwarf_attr_name (attr),
5748               dwarf_form_name (form), nl_langinfo (YESSTR));
5749       break;
5750
5751     case DW_FORM_exprloc:
5752     case DW_FORM_block4:
5753     case DW_FORM_block2:
5754     case DW_FORM_block1:
5755     case DW_FORM_block:
5756       if (cbargs->silent)
5757         break;
5758       Dwarf_Block block;
5759       if (unlikely (dwarf_formblock (attrp, &block) != 0))
5760         goto attrval_out;
5761
5762       printf ("           %*s%-20s (%s) ",
5763               (int) (level * 2), "", dwarf_attr_name (attr),
5764               dwarf_form_name (form));
5765
5766       switch (attr)
5767         {
5768         default:
5769           if (form != DW_FORM_exprloc)
5770             {
5771               print_block (block.length, block.data);
5772               break;
5773             }
5774           /* Fall through.  */
5775
5776         case DW_AT_location:
5777         case DW_AT_data_location:
5778         case DW_AT_data_member_location:
5779         case DW_AT_vtable_elem_location:
5780         case DW_AT_string_length:
5781         case DW_AT_use_location:
5782         case DW_AT_frame_base:
5783         case DW_AT_return_addr:
5784         case DW_AT_static_link:
5785         case DW_AT_allocated:
5786         case DW_AT_associated:
5787         case DW_AT_bit_size:
5788         case DW_AT_bit_offset:
5789         case DW_AT_bit_stride:
5790         case DW_AT_byte_size:
5791         case DW_AT_byte_stride:
5792         case DW_AT_count:
5793         case DW_AT_lower_bound:
5794         case DW_AT_upper_bound:
5795         case DW_AT_GNU_call_site_value:
5796         case DW_AT_GNU_call_site_data_value:
5797         case DW_AT_GNU_call_site_target:
5798         case DW_AT_GNU_call_site_target_clobbered:
5799           putchar ('\n');
5800           print_ops (cbargs->dwflmod, cbargs->dbg,
5801                      12 + level * 2, 12 + level * 2,
5802                      cbargs->version, cbargs->addrsize, cbargs->offset_size,
5803                      attrp->cu, block.length, block.data);
5804           break;
5805         }
5806       break;
5807
5808     default:
5809       if (cbargs->silent)
5810         break;
5811       printf ("           %*s%-20s (form: %#x) ???\n",
5812               (int) (level * 2), "", dwarf_attr_name (attr),
5813               (int) form);
5814       break;
5815     }
5816
5817   return DWARF_CB_OK;
5818 }
5819
5820 static void
5821 print_debug_units (Dwfl_Module *dwflmod,
5822                    Ebl *ebl, GElf_Ehdr *ehdr,
5823                    Elf_Scn *scn, GElf_Shdr *shdr,
5824                    Dwarf *dbg, bool debug_types)
5825 {
5826   const bool silent = !(print_debug_sections & section_info);
5827   const char *secname = section_name (ebl, ehdr, shdr);
5828
5829   if (!silent)
5830     printf (gettext ("\
5831 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
5832             elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
5833
5834   /* If the section is empty we don't have to do anything.  */
5835   if (!silent && shdr->sh_size == 0)
5836     return;
5837
5838   int maxdies = 20;
5839   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
5840
5841   Dwarf_Off offset = 0;
5842
5843   /* New compilation unit.  */
5844   size_t cuhl;
5845   Dwarf_Half version;
5846   Dwarf_Off abbroffset;
5847   uint8_t addrsize;
5848   uint8_t offsize;
5849   Dwarf_Off nextcu;
5850   uint64_t typesig;
5851   Dwarf_Off typeoff;
5852  next_cu:
5853   if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
5854                        &abbroffset, &addrsize, &offsize,
5855                        debug_types ? &typesig : NULL,
5856                        debug_types ? &typeoff : NULL) != 0)
5857     goto do_return;
5858
5859   if (!silent)
5860     {
5861       if (debug_types)
5862         printf (gettext (" Type unit at offset %" PRIu64 ":\n"
5863                          " Version: %" PRIu16 ", Abbreviation section offset: %"
5864                          PRIu64 ", Address size: %" PRIu8
5865                          ", Offset size: %" PRIu8
5866                          "\n Type signature: %#" PRIx64
5867                          ", Type offset: %#" PRIx64 "\n"),
5868                 (uint64_t) offset, version, abbroffset, addrsize, offsize,
5869                 typesig, (uint64_t) typeoff);
5870       else
5871         printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
5872                          " Version: %" PRIu16 ", Abbreviation section offset: %"
5873                          PRIu64 ", Address size: %" PRIu8
5874                          ", Offset size: %" PRIu8 "\n"),
5875                 (uint64_t) offset, version, abbroffset, addrsize, offsize);
5876     }
5877
5878   struct attrcb_args args =
5879     {
5880       .dwflmod = dwflmod,
5881       .dbg = dbg,
5882       .silent = silent,
5883       .version = version,
5884       .addrsize = addrsize,
5885       .offset_size = offsize
5886     };
5887
5888   offset += cuhl;
5889
5890   int level = 0;
5891
5892   if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
5893                 (dbg, offset, &dies[level]) == NULL))
5894     {
5895       if (!silent)
5896         error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
5897                               " in section '%s': %s"),
5898                (uint64_t) offset, secname, dwarf_errmsg (-1));
5899       goto do_return;
5900     }
5901
5902   args.cu = dies[0].cu;
5903
5904   do
5905     {
5906       offset = dwarf_dieoffset (&dies[level]);
5907       if (unlikely (offset == ~0ul))
5908         {
5909           if (!silent)
5910             error (0, 0, gettext ("cannot get DIE offset: %s"),
5911                    dwarf_errmsg (-1));
5912           goto do_return;
5913         }
5914
5915       int tag = dwarf_tag (&dies[level]);
5916       if (unlikely (tag == DW_TAG_invalid))
5917         {
5918           if (!silent)
5919             error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
5920                                   " in section '%s': %s"),
5921                    (uint64_t) offset, secname, dwarf_errmsg (-1));
5922           goto do_return;
5923         }
5924
5925       if (!silent)
5926         printf (" [%6" PRIx64 "]  %*s%s\n",
5927                 (uint64_t) offset, (int) (level * 2), "",
5928                 dwarf_tag_name (tag));
5929
5930       /* Print the attribute values.  */
5931       args.level = level;
5932       args.die = &dies[level];
5933       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
5934
5935       /* Make room for the next level's DIE.  */
5936       if (level + 1 == maxdies)
5937         dies = (Dwarf_Die *) xrealloc (dies,
5938                                        (maxdies += 10)
5939                                        * sizeof (Dwarf_Die));
5940
5941       int res = dwarf_child (&dies[level], &dies[level + 1]);
5942       if (res > 0)
5943         {
5944           while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
5945             if (level-- == 0)
5946               break;
5947
5948           if (unlikely (res == -1))
5949             {
5950               if (!silent)
5951                 error (0, 0, gettext ("cannot get next DIE: %s\n"),
5952                        dwarf_errmsg (-1));
5953               goto do_return;
5954             }
5955         }
5956       else if (unlikely (res < 0))
5957         {
5958           if (!silent)
5959             error (0, 0, gettext ("cannot get next DIE: %s"),
5960                    dwarf_errmsg (-1));
5961           goto do_return;
5962         }
5963       else
5964         ++level;
5965     }
5966   while (level >= 0);
5967
5968   offset = nextcu;
5969   if (offset != 0)
5970      goto next_cu;
5971
5972  do_return:
5973   free (dies);
5974 }
5975
5976 static void
5977 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5978                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5979 {
5980   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
5981 }
5982
5983 static void
5984 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5985                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5986 {
5987   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
5988 }
5989
5990
5991 static void
5992 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5993                             Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5994 {
5995   printf (gettext ("\
5996 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
5997           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
5998           (uint64_t) shdr->sh_offset);
5999
6000   size_t address_size
6001     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6002
6003   Dwarf_Off cuoffset;
6004   Dwarf_Off ncuoffset = 0;
6005   size_t hsize;
6006   while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6007                        NULL, NULL, NULL) == 0)
6008     {
6009       Dwarf_Die cudie;
6010       if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6011         continue;
6012
6013       size_t nlines;
6014       Dwarf_Lines *lines;
6015       if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6016         continue;
6017
6018       printf (" CU [%" PRIx64 "] %s\n",
6019               dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6020       printf ("  line:col SBPE* disc isa op address"
6021               " (Statement Block Prologue Epilogue *End)\n");
6022       const char *last_file = "";
6023       for (size_t n = 0; n < nlines; n++)
6024         {
6025           Dwarf_Line *line = dwarf_onesrcline (lines, n);
6026           Dwarf_Word mtime, length;
6027           const char *file = dwarf_linesrc (line, &mtime, &length);
6028           if (strcmp (last_file, file) != 0)
6029             {
6030               printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6031                       file, mtime, length);
6032               last_file = file;
6033             }
6034
6035           int lineno, colno;
6036           bool statement, endseq, block, prologue_end, epilogue_begin;
6037           unsigned int lineop, isa, disc;
6038           Dwarf_Addr address;
6039           dwarf_lineaddr (line, &address);
6040           dwarf_lineno (line, &lineno);
6041           dwarf_linecol (line, &colno);
6042           dwarf_lineop_index (line, &lineop);
6043           dwarf_linebeginstatement (line, &statement);
6044           dwarf_lineendsequence (line, &endseq);
6045           dwarf_lineblock (line, &block);
6046           dwarf_lineprologueend (line, &prologue_end);
6047           dwarf_lineepiloguebegin (line, &epilogue_begin);
6048           dwarf_lineisa (line, &isa);
6049           dwarf_linediscriminator (line, &disc);
6050
6051           /* End sequence is special, it is one byte past.  */
6052           char *a = format_dwarf_addr (dwflmod, address_size,
6053                                        address - (endseq ? 1 : 0), address);
6054           printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6055                   lineno, colno,
6056                   (statement ? 'S' : ' '),
6057                   (block ? 'B' : ' '),
6058                   (prologue_end ? 'P' : ' '),
6059                   (epilogue_begin ? 'E' : ' '),
6060                   (endseq ? '*' : ' '),
6061                   disc, isa, lineop, a);
6062           free (a);
6063
6064           if (endseq)
6065             printf("\n");
6066         }
6067     }
6068 }
6069
6070
6071 static void
6072 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6073                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6074 {
6075   if (decodedline)
6076     {
6077       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6078       return;
6079     }
6080
6081   printf (gettext ("\
6082 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6083           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6084           (uint64_t) shdr->sh_offset);
6085
6086   if (shdr->sh_size == 0)
6087     return;
6088
6089   /* There is no functionality in libdw to read the information in the
6090      way it is represented here.  Hardcode the decoder.  */
6091   Elf_Data *data = elf_getdata (scn, NULL);
6092   if (unlikely (data == NULL || data->d_buf == NULL))
6093     {
6094       error (0, 0, gettext ("cannot get line data section data: %s"),
6095              elf_errmsg (-1));
6096       return;
6097     }
6098
6099   const unsigned char *linep = (const unsigned char *) data->d_buf;
6100   const unsigned char *lineendp;
6101
6102   while (linep
6103          < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6104     {
6105       size_t start_offset = linep - (const unsigned char *) data->d_buf;
6106
6107       printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6108
6109       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6110       unsigned int length = 4;
6111       if (unlikely (unit_length == 0xffffffff))
6112         {
6113           if (unlikely (linep + 8 > lineendp))
6114             {
6115             invalid_data:
6116               error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6117                      elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6118               return;
6119             }
6120           unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6121           length = 8;
6122         }
6123
6124       /* Check whether we have enough room in the section.  */
6125       if (unit_length < 2 + length + 5 * 1
6126           || unlikely (linep + unit_length > lineendp))
6127         goto invalid_data;
6128       lineendp = linep + unit_length;
6129
6130       /* The next element of the header is the version identifier.  */
6131       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6132
6133       /* Next comes the header length.  */
6134       Dwarf_Word header_length;
6135       if (length == 4)
6136         header_length = read_4ubyte_unaligned_inc (dbg, linep);
6137       else
6138         header_length = read_8ubyte_unaligned_inc (dbg, linep);
6139       //const unsigned char *header_start = linep;
6140
6141       /* Next the minimum instruction length.  */
6142       uint_fast8_t minimum_instr_len = *linep++;
6143
6144       /* Next the maximum operations per instruction, in version 4 format.  */
6145       uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6146
6147         /* Then the flag determining the default value of the is_stmt
6148            register.  */
6149       uint_fast8_t default_is_stmt = *linep++;
6150
6151       /* Now the line base.  */
6152       int_fast8_t line_base = *((const int_fast8_t *) linep);
6153       ++linep;
6154
6155       /* And the line range.  */
6156       uint_fast8_t line_range = *linep++;
6157
6158       /* The opcode base.  */
6159       uint_fast8_t opcode_base = *linep++;
6160
6161       /* Print what we got so far.  */
6162       printf (gettext ("\n"
6163                        " Length:                     %" PRIu64 "\n"
6164                        " DWARF version:              %" PRIuFAST16 "\n"
6165                        " Prologue length:            %" PRIu64 "\n"
6166                        " Minimum instruction length: %" PRIuFAST8 "\n"
6167                        " Maximum operations per instruction: %" PRIuFAST8 "\n"
6168                        " Initial value if '%s': %" PRIuFAST8 "\n"
6169                        " Line base:                  %" PRIdFAST8 "\n"
6170                        " Line range:                 %" PRIuFAST8 "\n"
6171                        " Opcode base:                %" PRIuFAST8 "\n"
6172                        "\n"
6173                        "Opcodes:\n"),
6174               (uint64_t) unit_length, version, (uint64_t) header_length,
6175               minimum_instr_len, max_ops_per_instr,
6176               "is_stmt", default_is_stmt, line_base,
6177               line_range, opcode_base);
6178
6179       if (unlikely (linep + opcode_base - 1 >= lineendp))
6180         {
6181         invalid_unit:
6182           error (0, 0,
6183                  gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6184                  linep - (const unsigned char *) data->d_buf,
6185                  elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6186           linep = lineendp;
6187           continue;
6188         }
6189       int opcode_base_l10 = 1;
6190       unsigned int tmp = opcode_base;
6191       while (tmp > 10)
6192         {
6193           tmp /= 10;
6194           ++opcode_base_l10;
6195         }
6196       const uint8_t *standard_opcode_lengths = linep - 1;
6197       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6198         printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
6199                           "  [%*" PRIuFAST8 "]  %hhu arguments\n",
6200                           (int) linep[cnt - 1]),
6201                 opcode_base_l10, cnt, linep[cnt - 1]);
6202       linep += opcode_base - 1;
6203       if (unlikely (linep >= lineendp))
6204         goto invalid_unit;
6205
6206       puts (gettext ("\nDirectory table:"));
6207       while (*linep != 0)
6208         {
6209           unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6210           if (unlikely (endp == NULL))
6211             goto invalid_unit;
6212
6213           printf (" %s\n", (char *) linep);
6214
6215           linep = endp + 1;
6216         }
6217       /* Skip the final NUL byte.  */
6218       ++linep;
6219
6220       if (unlikely (linep >= lineendp))
6221         goto invalid_unit;
6222       puts (gettext ("\nFile name table:\n"
6223                      " Entry Dir   Time      Size      Name"));
6224       for (unsigned int cnt = 1; *linep != 0; ++cnt)
6225         {
6226           /* First comes the file name.  */
6227           char *fname = (char *) linep;
6228           unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6229           if (unlikely (endp == NULL))
6230             goto invalid_unit;
6231           linep = endp + 1;
6232
6233           /* Then the index.  */
6234           unsigned int diridx;
6235           get_uleb128 (diridx, linep);
6236
6237           /* Next comes the modification time.  */
6238           unsigned int mtime;
6239           get_uleb128 (mtime, linep);
6240
6241           /* Finally the length of the file.  */
6242           unsigned int fsize;
6243           get_uleb128 (fsize, linep);
6244
6245           printf (" %-5u %-5u %-9u %-9u %s\n",
6246                   cnt, diridx, mtime, fsize, fname);
6247         }
6248       /* Skip the final NUL byte.  */
6249       ++linep;
6250
6251       puts (gettext ("\nLine number statements:"));
6252       Dwarf_Word address = 0;
6253       unsigned int op_index = 0;
6254       size_t line = 1;
6255       uint_fast8_t is_stmt = default_is_stmt;
6256
6257       /* Default address value, in case we do not find the CU.  */
6258       size_t address_size
6259         = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6260
6261       /* Determine the CU this block is for.  */
6262       Dwarf_Off cuoffset;
6263       Dwarf_Off ncuoffset = 0;
6264       size_t hsize;
6265       while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6266                            NULL, NULL, NULL) == 0)
6267         {
6268           Dwarf_Die cudie;
6269           if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6270             continue;
6271           Dwarf_Attribute stmt_list;
6272           if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6273             continue;
6274           Dwarf_Word lineoff;
6275           if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6276             continue;
6277           if (lineoff == start_offset)
6278             {
6279               /* Found the CU.  */
6280               address_size = cudie.cu->address_size;
6281               break;
6282             }
6283         }
6284
6285       /* Apply the "operation advance" from a special opcode
6286          or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
6287       unsigned int op_addr_advance;
6288       bool show_op_index;
6289       inline void advance_pc (unsigned int op_advance)
6290       {
6291         op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6292                                                / max_ops_per_instr);
6293         address += op_advance;
6294         show_op_index = (op_index > 0 ||
6295                          (op_index + op_advance) % max_ops_per_instr > 0);
6296         op_index = (op_index + op_advance) % max_ops_per_instr;
6297       }
6298
6299       while (linep < lineendp)
6300         {
6301           size_t offset = linep - (const unsigned char *) data->d_buf;
6302           unsigned int u128;
6303           int s128;
6304
6305           /* Read the opcode.  */
6306           unsigned int opcode = *linep++;
6307
6308           printf (" [%6" PRIx64 "]", (uint64_t)offset);
6309           /* Is this a special opcode?  */
6310           if (likely (opcode >= opcode_base))
6311             {
6312               /* Yes.  Handling this is quite easy since the opcode value
6313                  is computed with
6314
6315                  opcode = (desired line increment - line_base)
6316                            + (line_range * address advance) + opcode_base
6317               */
6318               int line_increment = (line_base
6319                                     + (opcode - opcode_base) % line_range);
6320
6321               /* Perform the increments.  */
6322               line += line_increment;
6323               advance_pc ((opcode - opcode_base) / line_range);
6324
6325               char *a = format_dwarf_addr (dwflmod, 0, address, address);
6326               if (show_op_index)
6327                 printf (gettext ("\
6328  special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6329                         opcode, op_addr_advance, a, op_index,
6330                         line_increment, line);
6331               else
6332                 printf (gettext ("\
6333  special opcode %u: address+%u = %s, line%+d = %zu\n"),
6334                         opcode, op_addr_advance, a, line_increment, line);
6335               free (a);
6336             }
6337           else if (opcode == 0)
6338             {
6339               /* This an extended opcode.  */
6340               if (unlikely (linep + 2 > lineendp))
6341                 goto invalid_unit;
6342
6343               /* The length.  */
6344               unsigned int len = *linep++;
6345
6346               if (unlikely (linep + len > lineendp))
6347                 goto invalid_unit;
6348
6349               /* The sub-opcode.  */
6350               opcode = *linep++;
6351
6352               printf (gettext (" extended opcode %u: "), opcode);
6353
6354               switch (opcode)
6355                 {
6356                 case DW_LNE_end_sequence:
6357                   puts (gettext (" end of sequence"));
6358
6359                   /* Reset the registers we care about.  */
6360                   address = 0;
6361                   op_index = 0;
6362                   line = 1;
6363                   is_stmt = default_is_stmt;
6364                   break;
6365
6366                 case DW_LNE_set_address:
6367                   op_index = 0;
6368                   if (address_size == 4)
6369                     address = read_4ubyte_unaligned_inc (dbg, linep);
6370                   else
6371                     address = read_8ubyte_unaligned_inc (dbg, linep);
6372                   {
6373                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6374                     printf (gettext (" set address to %s\n"), a);
6375                     free (a);
6376                   }
6377                   break;
6378
6379                 case DW_LNE_define_file:
6380                   {
6381                     char *fname = (char *) linep;
6382                     unsigned char *endp = memchr (linep, '\0',
6383                                                   lineendp - linep);
6384                     if (unlikely (endp == NULL))
6385                       goto invalid_unit;
6386                     linep = endp + 1;
6387
6388                     unsigned int diridx;
6389                     get_uleb128 (diridx, linep);
6390                     Dwarf_Word mtime;
6391                     get_uleb128 (mtime, linep);
6392                     Dwarf_Word filelength;
6393                     get_uleb128 (filelength, linep);
6394
6395                     printf (gettext ("\
6396  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6397                             diridx, (uint64_t) mtime, (uint64_t) filelength,
6398                             fname);
6399                   }
6400                   break;
6401
6402                 case DW_LNE_set_discriminator:
6403                   /* Takes one ULEB128 parameter, the discriminator.  */
6404                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6405                     goto invalid_unit;
6406
6407                   get_uleb128 (u128, linep);
6408                   printf (gettext (" set discriminator to %u\n"), u128);
6409                   break;
6410
6411                 default:
6412                   /* Unknown, ignore it.  */
6413                   puts (gettext (" unknown opcode"));
6414                   linep += len - 1;
6415                   break;
6416                 }
6417             }
6418           else if (opcode <= DW_LNS_set_isa)
6419             {
6420               /* This is a known standard opcode.  */
6421               switch (opcode)
6422                 {
6423                 case DW_LNS_copy:
6424                   /* Takes no argument.  */
6425                   puts (gettext (" copy"));
6426                   break;
6427
6428                 case DW_LNS_advance_pc:
6429                   /* Takes one uleb128 parameter which is added to the
6430                      address.  */
6431                   get_uleb128 (u128, linep);
6432                   advance_pc (u128);
6433                   {
6434                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6435                     if (show_op_index)
6436                       printf (gettext ("\
6437  advance address by %u to %s, op_index to %u\n"),
6438                               op_addr_advance, a, op_index);
6439                     else
6440                       printf (gettext (" advance address by %u to %s\n"),
6441                               op_addr_advance, a);
6442                     free (a);
6443                   }
6444                   break;
6445
6446                 case DW_LNS_advance_line:
6447                   /* Takes one sleb128 parameter which is added to the
6448                      line.  */
6449                   get_sleb128 (s128, linep);
6450                   line += s128;
6451                   printf (gettext ("\
6452  advance line by constant %d to %" PRId64 "\n"),
6453                           s128, (int64_t) line);
6454                   break;
6455
6456                 case DW_LNS_set_file:
6457                   /* Takes one uleb128 parameter which is stored in file.  */
6458                   get_uleb128 (u128, linep);
6459                   printf (gettext (" set file to %" PRIu64 "\n"),
6460                           (uint64_t) u128);
6461                   break;
6462
6463                 case DW_LNS_set_column:
6464                   /* Takes one uleb128 parameter which is stored in column.  */
6465                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6466                     goto invalid_unit;
6467
6468                   get_uleb128 (u128, linep);
6469                   printf (gettext (" set column to %" PRIu64 "\n"),
6470                           (uint64_t) u128);
6471                   break;
6472
6473                 case DW_LNS_negate_stmt:
6474                   /* Takes no argument.  */
6475                   is_stmt = 1 - is_stmt;
6476                   printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6477                           "is_stmt", is_stmt);
6478                   break;
6479
6480                 case DW_LNS_set_basic_block:
6481                   /* Takes no argument.  */
6482                   puts (gettext (" set basic block flag"));
6483                   break;
6484
6485                 case DW_LNS_const_add_pc:
6486                   /* Takes no argument.  */
6487                   advance_pc ((255 - opcode_base) / line_range);
6488                   {
6489                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6490                     if (show_op_index)
6491                       printf (gettext ("\
6492  advance address by constant %u to %s, op_index to %u\n"),
6493                               op_addr_advance, a, op_index);
6494                     else
6495                       printf (gettext ("\
6496  advance address by constant %u to %s\n"),
6497                               op_addr_advance, a);
6498                     free (a);
6499                   }
6500                   break;
6501
6502                 case DW_LNS_fixed_advance_pc:
6503                   /* Takes one 16 bit parameter which is added to the
6504                      address.  */
6505                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6506                     goto invalid_unit;
6507
6508                   u128 = read_2ubyte_unaligned_inc (dbg, linep);
6509                   address += u128;
6510                   op_index = 0;
6511                   {
6512                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6513                     printf (gettext ("\
6514  advance address by fixed value %u to %s\n"),
6515                             u128, a);
6516                     free (a);
6517                   }
6518                   break;
6519
6520                 case DW_LNS_set_prologue_end:
6521                   /* Takes no argument.  */
6522                   puts (gettext (" set prologue end flag"));
6523                   break;
6524
6525                 case DW_LNS_set_epilogue_begin:
6526                   /* Takes no argument.  */
6527                   puts (gettext (" set epilogue begin flag"));
6528                   break;
6529
6530                 case DW_LNS_set_isa:
6531                   /* Takes one uleb128 parameter which is stored in isa.  */
6532                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6533                     goto invalid_unit;
6534
6535                   get_uleb128 (u128, linep);
6536                   printf (gettext (" set isa to %u\n"), u128);
6537                   break;
6538                 }
6539             }
6540           else
6541             {
6542               /* This is a new opcode the generator but not we know about.
6543                  Read the parameters associated with it but then discard
6544                  everything.  Read all the parameters for this opcode.  */
6545               printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6546                                 " unknown opcode with %" PRIu8 " parameters:",
6547                                 standard_opcode_lengths[opcode]),
6548                       standard_opcode_lengths[opcode]);
6549               for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6550                 {
6551                   get_uleb128 (u128, linep);
6552                   if (n != standard_opcode_lengths[opcode])
6553                     putc_unlocked (',', stdout);
6554                   printf (" %u", u128);
6555                 }
6556
6557               /* Next round, ignore this opcode.  */
6558               continue;
6559             }
6560         }
6561     }
6562
6563   /* There must only be one data block.  */
6564   assert (elf_getdata (scn, data) == NULL);
6565 }
6566
6567
6568 static void
6569 print_debug_loc_section (Dwfl_Module *dwflmod,
6570                          Ebl *ebl, GElf_Ehdr *ehdr,
6571                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6572 {
6573   Elf_Data *data = elf_rawdata (scn, NULL);
6574
6575   if (unlikely (data == NULL))
6576     {
6577       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6578              elf_errmsg (-1));
6579       return;
6580     }
6581
6582   printf (gettext ("\
6583 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6584           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6585           (uint64_t) shdr->sh_offset);
6586
6587   sort_listptr (&known_loclistptr, "loclistptr");
6588   size_t listptr_idx = 0;
6589
6590   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6591   uint_fast8_t offset_size = 4;
6592
6593   bool first = true;
6594   struct Dwarf_CU *cu = NULL;
6595   Dwarf_Addr base = 0;
6596   unsigned char *readp = data->d_buf;
6597   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6598   while (readp < endp)
6599     {
6600       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6601
6602       if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6603                                       &address_size, &offset_size, &base,
6604                                       &cu, offset, &readp, endp))
6605         continue;
6606
6607       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6608         {
6609           printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
6610           break;
6611         }
6612
6613       Dwarf_Addr begin;
6614       Dwarf_Addr end;
6615       if (address_size == 8)
6616         {
6617           begin = read_8ubyte_unaligned_inc (dbg, readp);
6618           end = read_8ubyte_unaligned_inc (dbg, readp);
6619         }
6620       else
6621         {
6622           begin = read_4ubyte_unaligned_inc (dbg, readp);
6623           end = read_4ubyte_unaligned_inc (dbg, readp);
6624           if (begin == (Dwarf_Addr) (uint32_t) -1)
6625             begin = (Dwarf_Addr) -1l;
6626         }
6627
6628       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
6629         {
6630           char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6631           printf (gettext (" [%6tx]  base address %s\n"), offset, b);
6632           free (b);
6633           base = end;
6634         }
6635       else if (begin == 0 && end == 0) /* End of list entry.  */
6636         {
6637           if (first)
6638             printf (gettext (" [%6tx]  empty list\n"), offset);
6639           first = true;
6640         }
6641       else
6642         {
6643           /* We have a location expression entry.  */
6644           uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6645
6646           char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6647                                        begin);
6648           char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6649                                        end);
6650
6651           if (first)            /* First entry in a list.  */
6652             printf (gettext (" [%6tx]  %s..%s"), offset, b, e);
6653           else
6654             printf (gettext ("           %s..%s"), b, e);
6655
6656           free (b);
6657           free (e);
6658
6659           if (endp - readp <= (ptrdiff_t) len)
6660             {
6661               fputs (gettext ("   <INVALID DATA>\n"), stdout);
6662               break;
6663             }
6664
6665           print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6666                      3 /*XXX*/, address_size, offset_size, cu, len, readp);
6667
6668           first = false;
6669           readp += len;
6670         }
6671     }
6672 }
6673
6674 struct mac_culist
6675 {
6676   Dwarf_Die die;
6677   Dwarf_Off offset;
6678   Dwarf_Files *files;
6679   struct mac_culist *next;
6680 };
6681
6682
6683 static int
6684 mac_compare (const void *p1, const void *p2)
6685 {
6686   struct mac_culist *m1 = (struct mac_culist *) p1;
6687   struct mac_culist *m2 = (struct mac_culist *) p2;
6688
6689   if (m1->offset < m2->offset)
6690     return -1;
6691   if (m1->offset > m2->offset)
6692     return 1;
6693   return 0;
6694 }
6695
6696
6697 static void
6698 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6699                              Ebl *ebl, GElf_Ehdr *ehdr,
6700                              Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6701 {
6702   printf (gettext ("\
6703 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6704           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6705           (uint64_t) shdr->sh_offset);
6706   putc_unlocked ('\n', stdout);
6707
6708   /* There is no function in libdw to iterate over the raw content of
6709      the section but it is easy enough to do.  */
6710   Elf_Data *data = elf_getdata (scn, NULL);
6711   if (unlikely (data == NULL || data->d_buf == NULL))
6712     {
6713       error (0, 0, gettext ("cannot get macro information section data: %s"),
6714              elf_errmsg (-1));
6715       return;
6716     }
6717
6718   /* Get the source file information for all CUs.  */
6719   Dwarf_Off offset;
6720   Dwarf_Off ncu = 0;
6721   size_t hsize;
6722   struct mac_culist *culist = NULL;
6723   size_t nculist = 0;
6724   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6725     {
6726       Dwarf_Die cudie;
6727       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6728         continue;
6729
6730       Dwarf_Attribute attr;
6731       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6732         continue;
6733
6734       Dwarf_Word macoff;
6735       if (dwarf_formudata (&attr, &macoff) != 0)
6736         continue;
6737
6738       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6739       newp->die = cudie;
6740       newp->offset = macoff;
6741       newp->files = NULL;
6742       newp->next = culist;
6743       culist = newp;
6744       ++nculist;
6745     }
6746
6747   /* Convert the list into an array for easier consumption.  */
6748   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6749                                                          * sizeof (*cus));
6750   /* Add sentinel.  */
6751   cus[nculist].offset = data->d_size;
6752   if (nculist > 0)
6753     {
6754       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6755         {
6756           assert (cnt < nculist);
6757           cus[cnt] = *culist;
6758           culist = culist->next;
6759         }
6760
6761       /* Sort the array according to the offset in the .debug_macinfo
6762          section.  Note we keep the sentinel at the end.  */
6763       qsort (cus, nculist, sizeof (*cus), mac_compare);
6764     }
6765
6766   const unsigned char *readp = (const unsigned char *) data->d_buf;
6767   const unsigned char *readendp = readp + data->d_size;
6768   int level = 1;
6769
6770   while (readp < readendp)
6771     {
6772       unsigned int opcode = *readp++;
6773       unsigned int u128;
6774       unsigned int u128_2;
6775       const unsigned char *endp;
6776
6777       switch (opcode)
6778         {
6779         case DW_MACINFO_define:
6780         case DW_MACINFO_undef:
6781         case DW_MACINFO_vendor_ext:
6782           /*  For the first two opcodes the parameters are
6783                 line, string
6784               For the latter
6785                 number, string.
6786               We can treat these cases together.  */
6787           get_uleb128 (u128, readp);
6788
6789           endp = memchr (readp, '\0', readendp - readp);
6790           if (unlikely (endp == NULL))
6791             {
6792               printf (gettext ("\
6793 %*s*** non-terminated string at end of section"),
6794                       level, "");
6795               return;
6796             }
6797
6798           if (opcode == DW_MACINFO_define)
6799             printf ("%*s#define %s, line %u\n",
6800                     level, "", (char *) readp, u128);
6801           else if (opcode == DW_MACINFO_undef)
6802             printf ("%*s#undef %s, line %u\n",
6803                     level, "", (char *) readp, u128);
6804           else
6805             printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
6806
6807           readp = endp + 1;
6808           break;
6809
6810         case DW_MACINFO_start_file:
6811           /* The two parameters are line and file index, in this order.  */
6812           get_uleb128 (u128, readp);
6813           get_uleb128 (u128_2, readp);
6814
6815           /* Find the CU DIE for this file.  */
6816           size_t macoff = readp - (const unsigned char *) data->d_buf;
6817           const char *fname = "???";
6818           if (macoff >= cus[0].offset)
6819             {
6820               while (macoff >= cus[1].offset)
6821                 ++cus;
6822
6823               if (cus[0].files == NULL
6824                 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
6825                 cus[0].files = (Dwarf_Files *) -1l;
6826
6827               if (cus[0].files != (Dwarf_Files *) -1l)
6828                 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
6829                          ?: "???");
6830             }
6831
6832           printf ("%*sstart_file %u, [%u] %s\n",
6833                   level, "", u128, u128_2, fname);
6834           ++level;
6835           break;
6836
6837         case DW_MACINFO_end_file:
6838           --level;
6839           printf ("%*send_file\n", level, "");
6840           /* Nothing more to do.  */
6841           break;
6842
6843         default:
6844           // XXX gcc seems to generate files with a trailing zero.
6845           if (unlikely (opcode != 0 || readp != readendp))
6846             printf ("%*s*** invalid opcode %u\n", level, "", opcode);
6847           break;
6848         }
6849     }
6850 }
6851
6852
6853 static void
6854 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6855                            Ebl *ebl, GElf_Ehdr *ehdr,
6856                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6857 {
6858   printf (gettext ("\
6859 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6860           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6861           (uint64_t) shdr->sh_offset);
6862   putc_unlocked ('\n', stdout);
6863
6864   Elf_Data *data = elf_getdata (scn, NULL);
6865   if (unlikely (data == NULL || data->d_buf == NULL))
6866     {
6867       error (0, 0, gettext ("cannot get macro information section data: %s"),
6868              elf_errmsg (-1));
6869       return;
6870     }
6871
6872   /* Get the source file information for all CUs.  Uses same
6873      datastructure as macinfo.  But uses offset field to directly
6874      match .debug_line offset.  And just stored in a list.  */
6875   Dwarf_Off offset;
6876   Dwarf_Off ncu = 0;
6877   size_t hsize;
6878   struct mac_culist *culist = NULL;
6879   size_t nculist = 0;
6880   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6881     {
6882       Dwarf_Die cudie;
6883       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6884         continue;
6885
6886       Dwarf_Attribute attr;
6887       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
6888         continue;
6889
6890       Dwarf_Word lineoff;
6891       if (dwarf_formudata (&attr, &lineoff) != 0)
6892         continue;
6893
6894       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6895       newp->die = cudie;
6896       newp->offset = lineoff;
6897       newp->files = NULL;
6898       newp->next = culist;
6899       culist = newp;
6900       ++nculist;
6901     }
6902
6903   const unsigned char *readp = (const unsigned char *) data->d_buf;
6904   const unsigned char *readendp = readp + data->d_size;
6905
6906   while (readp < readendp)
6907     {
6908       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
6909               (uint64_t) (readp - (const unsigned char *) data->d_buf));
6910
6911       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
6912       // optional vendor extension macro entry table.
6913       if (readp + 2 > readendp)
6914         {
6915         invalid_data:
6916           error (0, 0, gettext ("invalid data"));
6917           return;
6918         }
6919       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
6920       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
6921
6922       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
6923       // 5 when it gets standardized.
6924       if (vers != 4)
6925         {
6926           printf (gettext ("  unknown version, cannot parse section\n"));
6927           return;
6928         }
6929
6930       if (readp + 1 > readendp)
6931         goto invalid_data;
6932       const unsigned char flag = *readp++;
6933       printf (gettext (" Flag:               0x%" PRIx8 "\n"), flag);
6934
6935       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
6936       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
6937       Dwarf_Off line_offset = -1;
6938       if (flag & 0x02)
6939         {
6940           if (offset_len == 8)
6941             line_offset = read_8ubyte_unaligned_inc (dbg, readp);
6942           else
6943             line_offset = read_4ubyte_unaligned_inc (dbg, readp);
6944           printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
6945                   line_offset);
6946         }
6947
6948       const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
6949       memset (vendor, 0, sizeof vendor);
6950       if (flag & 0x04)
6951         {
6952           // 1 byte length, for each item, 1 byte opcode, uleb128 number
6953           // of arguments, for each argument 1 byte form code.
6954           if (readp + 1 > readendp)
6955             goto invalid_data;
6956           unsigned int tlen = *readp++;
6957           printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
6958                   tlen);
6959           for (unsigned int i = 0; i < tlen; i++)
6960             {
6961               if (readp + 1 > readendp)
6962                 goto invalid_data;
6963               unsigned int opcode = *readp++;
6964               printf (gettext ("    [%" PRIx8 "]"), opcode);
6965               if (opcode < DW_MACRO_GNU_lo_user
6966                   || opcode > DW_MACRO_GNU_hi_user)
6967                 goto invalid_data;
6968               // Record the start of description for this vendor opcode.
6969               // uleb128 nr args, 1 byte per arg form.
6970               vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
6971               if (readp + 1 > readendp)
6972                 goto invalid_data;
6973               unsigned int args = *readp++;
6974               if (args > 0)
6975                 {
6976                   printf (gettext (" %" PRIu8 " arguments:"), args);
6977                   while (args > 0)
6978                     {
6979                       if (readp + 1 > readendp)
6980                         goto invalid_data;
6981                       unsigned int form = *readp++;
6982                       printf (" %s", dwarf_form_string (form));
6983                       if (form != DW_FORM_data1
6984                           && form != DW_FORM_data2
6985                           && form != DW_FORM_data4
6986                           && form != DW_FORM_data8
6987                           && form != DW_FORM_sdata
6988                           && form != DW_FORM_udata
6989                           && form != DW_FORM_block
6990                           && form != DW_FORM_block1
6991                           && form != DW_FORM_block2
6992                           && form != DW_FORM_block4
6993                           && form != DW_FORM_flag
6994                           && form != DW_FORM_string
6995                           && form != DW_FORM_strp
6996                           && form != DW_FORM_sec_offset)
6997                         goto invalid_data;
6998                       args--;
6999                       if (args > 0)
7000                         putchar_unlocked (',');
7001                     }
7002                 }
7003               else
7004                 printf (gettext (" no arguments."));
7005               putchar_unlocked ('\n');
7006             }
7007         }
7008       putchar_unlocked ('\n');
7009
7010       int level = 1;
7011       if (readp + 1 > readendp)
7012         goto invalid_data;
7013       unsigned int opcode = *readp++;
7014       while (opcode != 0)
7015         {
7016           unsigned int u128;
7017           unsigned int u128_2;
7018           const unsigned char *endp;
7019           uint64_t off;
7020
7021           switch (opcode)
7022             {
7023             case DW_MACRO_GNU_start_file:
7024               get_uleb128 (u128, readp);
7025               get_uleb128 (u128_2, readp);
7026
7027               /* Find the CU DIE that matches this line offset.  */
7028               const char *fname = "???";
7029               if (line_offset != (Dwarf_Off) -1)
7030                 {
7031                   struct mac_culist *cu = culist;
7032                   while (cu != NULL && line_offset != cu->offset)
7033                     cu = cu->next;
7034                   if (cu != NULL)
7035                     {
7036                       if (cu->files == NULL
7037                           && dwarf_getsrcfiles (&cu->die, &cu->files,
7038                                                 NULL) != 0)
7039                         cu->files = (Dwarf_Files *) -1l;
7040
7041                       if (cu->files != (Dwarf_Files *) -1l)
7042                         fname = (dwarf_filesrc (cu->files, u128_2,
7043                                                 NULL, NULL) ?: "???");
7044                     }
7045                 }
7046               printf ("%*sstart_file %u, [%u] %s\n",
7047                       level, "", u128, u128_2, fname);
7048               ++level;
7049               break;
7050
7051             case DW_MACRO_GNU_end_file:
7052               --level;
7053               printf ("%*send_file\n", level, "");
7054               break;
7055
7056             case DW_MACRO_GNU_define:
7057               get_uleb128 (u128, readp);
7058               endp = memchr (readp, '\0', readendp - readp);
7059               if (endp == NULL)
7060                 goto invalid_data;
7061               printf ("%*s#define %s, line %u\n",
7062                       level, "", readp, u128);
7063               readp = endp + 1;
7064               break;
7065
7066             case DW_MACRO_GNU_undef:
7067               get_uleb128 (u128, readp);
7068               endp = memchr (readp, '\0', readendp - readp);
7069               if (endp == NULL)
7070                 goto invalid_data;
7071               printf ("%*s#undef %s, line %u\n",
7072                       level, "", readp, u128);
7073               readp = endp + 1;
7074               break;
7075
7076             case DW_MACRO_GNU_define_indirect:
7077               get_uleb128 (u128, readp);
7078               if (readp + offset_len > readendp)
7079                 goto invalid_data;
7080               if (offset_len == 8)
7081                 off = read_8ubyte_unaligned_inc (dbg, readp);
7082               else
7083                 off = read_4ubyte_unaligned_inc (dbg, readp);
7084               printf ("%*s#define %s, line %u (indirect)\n",
7085                       level, "", dwarf_getstring (dbg, off, NULL), u128);
7086               break;
7087
7088             case DW_MACRO_GNU_undef_indirect:
7089               get_uleb128 (u128, readp);
7090               if (readp + offset_len > readendp)
7091                 goto invalid_data;
7092               if (offset_len == 8)
7093                 off = read_8ubyte_unaligned_inc (dbg, readp);
7094               else
7095                 off = read_4ubyte_unaligned_inc (dbg, readp);
7096               printf ("%*s#undef %s, line %u (indirect)\n",
7097                       level, "", dwarf_getstring (dbg, off, NULL), u128);
7098               break;
7099
7100             case DW_MACRO_GNU_transparent_include:
7101               if (readp + offset_len > readendp)
7102                 goto invalid_data;
7103               if (offset_len == 8)
7104                 off = read_8ubyte_unaligned_inc (dbg, readp);
7105               else
7106                 off = read_4ubyte_unaligned_inc (dbg, readp);
7107               printf ("%*s#include offset 0x%" PRIx64 "\n",
7108                       level, "", off);
7109               break;
7110
7111             default:
7112               printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7113               if (opcode < DW_MACRO_GNU_lo_user
7114                   || opcode > DW_MACRO_GNU_lo_user
7115                   || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7116                 goto invalid_data;
7117
7118               const unsigned char *op_desc;
7119               op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7120
7121               // Just skip the arguments, we cannot really interpret them,
7122               // but print as much as we can.
7123               unsigned int args = *op_desc++;
7124               while (args > 0)
7125                 {
7126                   unsigned int form = *op_desc++;
7127                   Dwarf_Word val;
7128                   switch (form)
7129                     {
7130                     case DW_FORM_data1:
7131                       if (readp + 1 > readendp)
7132                         goto invalid_data;
7133                       val = *readp++;
7134                       printf (" %" PRIx8, (unsigned int) val);
7135                       break;
7136
7137                     case DW_FORM_data2:
7138                       if (readp + 2 > readendp)
7139                         goto invalid_data;
7140                       val = read_2ubyte_unaligned_inc (dbg, readp);
7141                       printf(" %" PRIx16, (unsigned int) val);
7142                       break;
7143
7144                     case DW_FORM_data4:
7145                       if (readp + 4 > readendp)
7146                         goto invalid_data;
7147                       val = read_4ubyte_unaligned_inc (dbg, readp);
7148                       printf (" %" PRIx32, (unsigned int) val);
7149                       break;
7150
7151                     case DW_FORM_data8:
7152                       if (readp + 8 > readendp)
7153                         goto invalid_data;
7154                       val = read_8ubyte_unaligned_inc (dbg, readp);
7155                       printf (" %" PRIx64, val);
7156                       break;
7157
7158                     case DW_FORM_sdata:
7159                       get_sleb128 (val, readp);
7160                       printf (" %" PRIx64, val);
7161                       break;
7162
7163                     case DW_FORM_udata:
7164                       get_uleb128 (val, readp);
7165                       printf (" %" PRIx64, val);
7166                       break;
7167
7168                     case DW_FORM_block:
7169                       get_uleb128 (val, readp);
7170                       printf (" block[%" PRIu64 "]", val);
7171                       if (readp + val > readendp)
7172                         goto invalid_data;
7173                       readp += val;
7174                       break;
7175
7176                     case DW_FORM_block1:
7177                       if (readp + 1 > readendp)
7178                         goto invalid_data;
7179                       val = *readp++;
7180                       printf (" block[%" PRIu64 "]", val);
7181                       if (readp + val > readendp)
7182                         goto invalid_data;
7183                       break;
7184
7185                     case DW_FORM_block2:
7186                       if (readp + 2 > readendp)
7187                         goto invalid_data;
7188                       val = read_2ubyte_unaligned_inc (dbg, readp);
7189                       printf (" block[%" PRIu64 "]", val);
7190                       if (readp + val > readendp)
7191                         goto invalid_data;
7192                       break;
7193
7194                     case DW_FORM_block4:
7195                       if (readp + 2 > readendp)
7196                         goto invalid_data;
7197                       val =read_4ubyte_unaligned_inc (dbg, readp);
7198                       printf (" block[%" PRIu64 "]", val);
7199                       if (readp + val > readendp)
7200                         goto invalid_data;
7201                       break;
7202
7203                     case DW_FORM_flag:
7204                       if (readp + 1 > readendp)
7205                         goto invalid_data;
7206                       val = *readp++;
7207                       printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7208                       break;
7209
7210                     case DW_FORM_string:
7211                       endp = memchr (readp, '\0', readendp - readp);
7212                       if (endp == NULL)
7213                         goto invalid_data;
7214                       printf (" %s", readp);
7215                       readp = endp + 1;
7216                       break;
7217
7218                     case DW_FORM_strp:
7219                       if (readp + offset_len > readendp)
7220                         goto invalid_data;
7221                       if (offset_len == 8)
7222                         val = read_8ubyte_unaligned_inc (dbg, readp);
7223                       else
7224                         val = read_4ubyte_unaligned_inc (dbg, readp);
7225                       printf (" %s", dwarf_getstring (dbg, val, NULL));
7226                       break;
7227
7228                     case DW_FORM_sec_offset:
7229                       if (readp + offset_len > readendp)
7230                         goto invalid_data;
7231                       if (offset_len == 8)
7232                         val = read_8ubyte_unaligned_inc (dbg, readp);
7233                       else
7234                         val = read_4ubyte_unaligned_inc (dbg, readp);
7235                       printf (" %" PRIx64, val);
7236                       break;
7237
7238                       default:
7239                         error (0, 0, gettext ("vendor opcode not verified?"));
7240                         return;
7241                     }
7242
7243                   args--;
7244                   if (args > 0)
7245                     putchar_unlocked (',');
7246                 }
7247               putchar_unlocked ('\n');
7248             }
7249
7250           if (readp + 1 > readendp)
7251             goto invalid_data;
7252           opcode = *readp++;
7253           if (opcode == 0)
7254             putchar_unlocked ('\n');
7255         }
7256     }
7257 }
7258
7259
7260 /* Callback for printing global names.  */
7261 static int
7262 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7263                 void *arg)
7264 {
7265   int *np = (int *) arg;
7266
7267   printf (gettext (" [%5d] DIE offset: %6" PRId64
7268                    ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7269           (*np)++, global->die_offset, global->cu_offset, global->name);
7270
7271   return 0;
7272 }
7273
7274
7275 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
7276 static void
7277 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7278                               Ebl *ebl, GElf_Ehdr *ehdr,
7279                               Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7280 {
7281   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7282           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7283           (uint64_t) shdr->sh_offset);
7284
7285   int n = 0;
7286   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7287 }
7288
7289 /* Print the content of the DWARF string section '.debug_str'.  */
7290 static void
7291 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7292                          Ebl *ebl, GElf_Ehdr *ehdr,
7293                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7294 {
7295   const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7296                           dbg->sectiondata[IDX_debug_str]->d_size : 0);
7297
7298   /* Compute floor(log16(shdr->sh_size)).  */
7299   GElf_Addr tmp = sh_size;
7300   int digits = 1;
7301   while (tmp >= 16)
7302     {
7303       ++digits;
7304       tmp >>= 4;
7305     }
7306   digits = MAX (4, digits);
7307
7308   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7309                    " %*s  String\n"),
7310           elf_ndxscn (scn),
7311           section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7312           /* TRANS: the debugstr| prefix makes the string unique.  */
7313           digits + 2, sgettext ("debugstr|Offset"));
7314
7315   Dwarf_Off offset = 0;
7316   while (offset < sh_size)
7317     {
7318       size_t len;
7319       const char *str = dwarf_getstring (dbg, offset, &len);
7320       if (unlikely (str == NULL))
7321         {
7322           printf (gettext (" *** error while reading strings: %s\n"),
7323                   dwarf_errmsg (-1));
7324           break;
7325         }
7326
7327       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
7328
7329       offset += len + 1;
7330     }
7331 }
7332
7333
7334 /* Print the content of the call frame search table section
7335    '.eh_frame_hdr'.  */
7336 static void
7337 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7338                                Ebl *ebl __attribute__ ((unused)),
7339                                GElf_Ehdr *ehdr __attribute__ ((unused)),
7340                                Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7341 {
7342   printf (gettext ("\
7343 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7344           elf_ndxscn (scn));
7345
7346   Elf_Data *data = elf_rawdata (scn, NULL);
7347
7348   if (unlikely (data == NULL))
7349     {
7350       error (0, 0, gettext ("cannot get %s content: %s"),
7351              ".eh_frame_hdr", elf_errmsg (-1));
7352       return;
7353     }
7354
7355   const unsigned char *readp = data->d_buf;
7356   const unsigned char *const dataend = ((unsigned char *) data->d_buf
7357                                         + data->d_size);
7358
7359   if (unlikely (readp + 4 > dataend))
7360     {
7361     invalid_data:
7362       error (0, 0, gettext ("invalid data"));
7363       return;
7364     }
7365
7366   unsigned int version = *readp++;
7367   unsigned int eh_frame_ptr_enc = *readp++;
7368   unsigned int fde_count_enc = *readp++;
7369   unsigned int table_enc = *readp++;
7370
7371   printf (" version:          %u\n"
7372           " eh_frame_ptr_enc: %#x ",
7373           version, eh_frame_ptr_enc);
7374   print_encoding_base ("", eh_frame_ptr_enc);
7375   printf (" fde_count_enc:    %#x ", fde_count_enc);
7376   print_encoding_base ("", fde_count_enc);
7377   printf (" table_enc:        %#x ", table_enc);
7378   print_encoding_base ("", table_enc);
7379
7380   uint64_t eh_frame_ptr = 0;
7381   if (eh_frame_ptr_enc != DW_EH_PE_omit)
7382     {
7383       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7384                             dbg);
7385       if (unlikely (readp == NULL))
7386         goto invalid_data;
7387
7388       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
7389       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7390         printf (" (offset: %#" PRIx64 ")",
7391                 /* +4 because of the 4 byte header of the section.  */
7392                 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7393
7394       putchar_unlocked ('\n');
7395     }
7396
7397   uint64_t fde_count = 0;
7398   if (fde_count_enc != DW_EH_PE_omit)
7399     {
7400       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7401       if (unlikely (readp == NULL))
7402         goto invalid_data;
7403
7404       printf (" fde_count:        %" PRIu64 "\n", fde_count);
7405     }
7406
7407   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7408     return;
7409
7410   puts (" Table:");
7411
7412   /* Optimize for the most common case.  */
7413   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7414     while (fde_count > 0 && readp + 8 <= dataend)
7415       {
7416         int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7417         uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7418                                    + (int64_t) initial_location);
7419         int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7420         // XXX Possibly print symbol name or section offset for initial_offset
7421         printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7422                 " fde=[%6" PRIx64 "]\n",
7423                 initial_location, initial_offset,
7424                 address, address - (eh_frame_ptr + 4));
7425       }
7426   else
7427     while (0 && readp < dataend)
7428       {
7429
7430       }
7431 }
7432
7433
7434 /* Print the content of the exception handling table section
7435    '.eh_frame_hdr'.  */
7436 static void
7437 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7438                              Ebl *ebl __attribute__ ((unused)),
7439                              GElf_Ehdr *ehdr __attribute__ ((unused)),
7440                              Elf_Scn *scn,
7441                              GElf_Shdr *shdr __attribute__ ((unused)),
7442                              Dwarf *dbg __attribute__ ((unused)))
7443 {
7444   printf (gettext ("\
7445 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7446           elf_ndxscn (scn));
7447
7448   Elf_Data *data = elf_rawdata (scn, NULL);
7449
7450   if (unlikely (data == NULL))
7451     {
7452       error (0, 0, gettext ("cannot get %s content: %s"),
7453              ".gcc_except_table", elf_errmsg (-1));
7454       return;
7455     }
7456
7457   const unsigned char *readp = data->d_buf;
7458   const unsigned char *const dataend = readp + data->d_size;
7459
7460   if (unlikely (readp + 1 > dataend))
7461     {
7462     invalid_data:
7463       error (0, 0, gettext ("invalid data"));
7464       return;
7465     }
7466   unsigned int lpstart_encoding = *readp++;
7467   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
7468   print_encoding_base ("", lpstart_encoding);
7469   if (lpstart_encoding != DW_EH_PE_omit)
7470     {
7471       uint64_t lpstart;
7472       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7473       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
7474     }
7475
7476   if (unlikely (readp + 1 > dataend))
7477     goto invalid_data;
7478   unsigned int ttype_encoding = *readp++;
7479   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
7480   print_encoding_base ("", ttype_encoding);
7481   const unsigned char *ttype_base = NULL;
7482   if (ttype_encoding != DW_EH_PE_omit)
7483     {
7484       unsigned int ttype_base_offset;
7485       get_uleb128 (ttype_base_offset, readp);
7486       printf (" TType base offset:   %#x\n", ttype_base_offset);
7487       ttype_base = readp + ttype_base_offset;
7488     }
7489
7490   if (unlikely (readp + 1 > dataend))
7491     goto invalid_data;
7492   unsigned int call_site_encoding = *readp++;
7493   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
7494   print_encoding_base ("", call_site_encoding);
7495   unsigned int call_site_table_len;
7496   get_uleb128 (call_site_table_len, readp);
7497
7498   const unsigned char *const action_table = readp + call_site_table_len;
7499   if (unlikely (action_table > dataend))
7500     goto invalid_data;
7501   unsigned int u = 0;
7502   unsigned int max_action = 0;
7503   while (readp < action_table)
7504     {
7505       if (u == 0)
7506         puts (gettext ("\n Call site table:"));
7507
7508       uint64_t call_site_start;
7509       readp = read_encoded (call_site_encoding, readp, dataend,
7510                             &call_site_start, dbg);
7511       uint64_t call_site_length;
7512       readp = read_encoded (call_site_encoding, readp, dataend,
7513                             &call_site_length, dbg);
7514       uint64_t landing_pad;
7515       readp = read_encoded (call_site_encoding, readp, dataend,
7516                             &landing_pad, dbg);
7517       unsigned int action;
7518       get_uleb128 (action, readp);
7519       max_action = MAX (action, max_action);
7520       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
7521                        "        Call site length:  %" PRIu64 "\n"
7522                        "        Landing pad:       %#" PRIx64 "\n"
7523                        "        Action:            %u\n"),
7524               u++, call_site_start, call_site_length, landing_pad, action);
7525     }
7526   assert (readp == action_table);
7527
7528   unsigned int max_ar_filter = 0;
7529   if (max_action > 0)
7530     {
7531       puts ("\n Action table:");
7532
7533       const unsigned char *const action_table_end
7534         = action_table + max_action + 1;
7535
7536       u = 0;
7537       do
7538         {
7539           int ar_filter;
7540           get_sleb128 (ar_filter, readp);
7541           if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7542             max_ar_filter = ar_filter;
7543           int ar_disp;
7544           get_sleb128 (ar_disp, readp);
7545
7546           printf (" [%4u] ar_filter:  % d\n"
7547                   "        ar_disp:    % -5d",
7548                   u, ar_filter, ar_disp);
7549           if (abs (ar_disp) & 1)
7550             printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7551           else if (ar_disp != 0)
7552             puts (" -> ???");
7553           else
7554             putchar_unlocked ('\n');
7555           ++u;
7556         }
7557       while (readp < action_table_end);
7558     }
7559
7560   if (max_ar_filter > 0)
7561     {
7562       puts ("\n TType table:");
7563
7564       // XXX Not *4, size of encoding;
7565       switch (ttype_encoding & 7)
7566         {
7567         case DW_EH_PE_udata2:
7568         case DW_EH_PE_sdata2:
7569           readp = ttype_base - max_ar_filter * 2;
7570           break;
7571         case DW_EH_PE_udata4:
7572         case DW_EH_PE_sdata4:
7573           readp = ttype_base - max_ar_filter * 4;
7574           break;
7575         case DW_EH_PE_udata8:
7576         case DW_EH_PE_sdata8:
7577           readp = ttype_base - max_ar_filter * 8;
7578           break;
7579         default:
7580           error (1, 0, gettext ("invalid TType encoding"));
7581         }
7582
7583       do
7584         {
7585           uint64_t ttype;
7586           readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7587                                 dbg);
7588           printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7589         }
7590       while (readp < ttype_base);
7591     }
7592 }
7593
7594 /* Print the content of the '.gdb_index' section.
7595    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7596 */
7597 static void
7598 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7599                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7600 {
7601   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7602                    " contains %" PRId64 " bytes :\n"),
7603           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7604           (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7605
7606   Elf_Data *data = elf_rawdata (scn, NULL);
7607
7608   if (unlikely (data == NULL))
7609     {
7610       error (0, 0, gettext ("cannot get %s content: %s"),
7611              ".gdb_index", elf_errmsg (-1));
7612       return;
7613     }
7614
7615   // .gdb_index is always in little endian.
7616   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7617   dbg = &dummy_dbg;
7618
7619   const unsigned char *readp = data->d_buf;
7620   const unsigned char *const dataend = readp + data->d_size;
7621
7622   if (unlikely (readp + 4 > dataend))
7623     {
7624     invalid_data:
7625       error (0, 0, gettext ("invalid data"));
7626       return;
7627     }
7628
7629   int32_t vers = read_4ubyte_unaligned (dbg, readp);
7630   printf (gettext (" Version:         %" PRId32 "\n"), vers);
7631
7632   // The only difference between version 4 and version 5 is the
7633   // hash used for generating the table.  Version 6 contains symbols
7634   // for inlined functions, older versions didn't.  Version 7 adds
7635   // symbol kinds.  Version 8 just indicates that it correctly includes
7636   // TUs for symbols.
7637   if (vers < 4 || vers > 8)
7638     {
7639       printf (gettext ("  unknown version, cannot parse section\n"));
7640       return;
7641     }
7642
7643   readp += 4;
7644   if (unlikely (readp + 4 > dataend))
7645     goto invalid_data;
7646
7647   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7648   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
7649
7650   readp += 4;
7651   if (unlikely (readp + 4 > dataend))
7652     goto invalid_data;
7653
7654   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7655   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
7656
7657   readp += 4;
7658   if (unlikely (readp + 4 > dataend))
7659     goto invalid_data;
7660
7661   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7662   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
7663
7664   readp += 4;
7665   if (unlikely (readp + 4 > dataend))
7666     goto invalid_data;
7667
7668   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7669   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
7670
7671   readp += 4;
7672   if (unlikely (readp + 4 > dataend))
7673     goto invalid_data;
7674
7675   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7676   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7677
7678   readp = data->d_buf + cu_off;
7679
7680   const unsigned char *nextp = data->d_buf + tu_off;
7681   size_t cu_nr = (nextp - readp) / 16;
7682
7683   printf (gettext ("\n CU list at offset %#" PRIx32
7684                    " contains %zu entries:\n"),
7685           cu_off, cu_nr);
7686
7687   size_t n = 0;
7688   while (readp + 16 <= dataend && n < cu_nr)
7689     {
7690       uint64_t off = read_8ubyte_unaligned (dbg, readp);
7691       readp += 8;
7692
7693       uint64_t len = read_8ubyte_unaligned (dbg, readp);
7694       readp += 8;
7695
7696       printf (" [%4zu] start: %0#8" PRIx64
7697               ", length: %5" PRIu64 "\n", n, off, len);
7698       n++;
7699     }
7700
7701   readp = data->d_buf + tu_off;
7702   nextp = data->d_buf + addr_off;
7703   size_t tu_nr = (nextp - readp) / 24;
7704
7705   printf (gettext ("\n TU list at offset %#" PRIx32
7706                    " contains %zu entries:\n"),
7707           tu_off, tu_nr);
7708
7709   n = 0;
7710   while (readp + 24 <= dataend && n < tu_nr)
7711     {
7712       uint64_t off = read_8ubyte_unaligned (dbg, readp);
7713       readp += 8;
7714
7715       uint64_t type = read_8ubyte_unaligned (dbg, readp);
7716       readp += 8;
7717
7718       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7719       readp += 8;
7720
7721       printf (" [%4zu] CU offset: %5" PRId64
7722               ", type offset: %5" PRId64
7723               ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7724       n++;
7725     }
7726
7727   readp = data->d_buf + addr_off;
7728   nextp = data->d_buf + sym_off;
7729   size_t addr_nr = (nextp - readp) / 20;
7730
7731   printf (gettext ("\n Address list at offset %#" PRIx32
7732                    " contains %zu entries:\n"),
7733           addr_off, addr_nr);
7734
7735   n = 0;
7736   while (readp + 20 <= dataend && n < addr_nr)
7737     {
7738       uint64_t low = read_8ubyte_unaligned (dbg, readp);
7739       readp += 8;
7740
7741       uint64_t high = read_8ubyte_unaligned (dbg, readp);
7742       readp += 8;
7743
7744       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7745       readp += 4;
7746
7747       char *l = format_dwarf_addr (dwflmod, 8, low, low);
7748       char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7749       printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7750               n, l, h, idx);
7751       free (l);
7752       free (h);
7753       n++;
7754     }
7755
7756   readp = data->d_buf + sym_off;
7757   nextp = data->d_buf + const_off;
7758   size_t sym_nr = (nextp - readp) / 8;
7759
7760   printf (gettext ("\n Symbol table at offset %#" PRIx32
7761                    " contains %zu slots:\n"),
7762           addr_off, sym_nr);
7763
7764   n = 0;
7765   while (readp + 8 <= dataend && n < sym_nr)
7766     {
7767       uint32_t name = read_4ubyte_unaligned (dbg, readp);
7768       readp += 4;
7769
7770       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7771       readp += 4;
7772
7773       if (name != 0 || vector != 0)
7774         {
7775           const unsigned char *sym = data->d_buf + const_off + name;
7776           if (unlikely (sym > dataend))
7777             goto invalid_data;
7778
7779           printf (" [%4zu] symbol: %s, CUs: ", n, sym);
7780
7781           const unsigned char *readcus = data->d_buf + const_off + vector;
7782           if (unlikely (readcus + 8 > dataend))
7783             goto invalid_data;
7784
7785           uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
7786           while (cus--)
7787             {
7788               uint32_t cu_kind, cu, kind;
7789               bool is_static;
7790               readcus += 4;
7791               cu_kind = read_4ubyte_unaligned (dbg, readcus);
7792               cu = cu_kind & ((1 << 24) - 1);
7793               kind = (cu_kind >> 28) & 7;
7794               is_static = cu_kind & (1 << 31);
7795               if (cu > cu_nr - 1)
7796                 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
7797               else
7798                 printf ("%" PRId32, cu);
7799               if (kind != 0)
7800                 {
7801                   printf (" (");
7802                   switch (kind)
7803                     {
7804                     case 1:
7805                       printf ("type");
7806                       break;
7807                     case 2:
7808                       printf ("var");
7809                       break;
7810                     case 3:
7811                       printf ("func");
7812                       break;
7813                     case 4:
7814                       printf ("other");
7815                       break;
7816                     default:
7817                       printf ("unknown-0x%" PRIx32, kind);
7818                       break;
7819                     }
7820                   printf (":%c)", (is_static ? 'S' : 'G'));
7821                 }
7822               if (cus > 0)
7823                 printf (", ");
7824             }
7825           printf ("\n");
7826         }
7827       n++;
7828     }
7829 }
7830
7831 static void
7832 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
7833 {
7834   /* Before we start the real work get a debug context descriptor.  */
7835   Dwarf_Addr dwbias;
7836   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
7837   Dwarf dummy_dbg =
7838     {
7839       .elf = ebl->elf,
7840       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
7841     };
7842   if (dbg == NULL)
7843     {
7844       if ((print_debug_sections & ~section_exception) != 0)
7845         error (0, 0, gettext ("cannot get debug context descriptor: %s"),
7846                dwfl_errmsg (-1));
7847       if ((print_debug_sections & section_exception) == 0)
7848         return;
7849       dbg = &dummy_dbg;
7850     }
7851
7852   /* Get the section header string table index.  */
7853   size_t shstrndx;
7854   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
7855     error (EXIT_FAILURE, 0,
7856            gettext ("cannot get section header string table index"));
7857
7858   /* Look through all the sections for the debugging sections to print.  */
7859   Elf_Scn *scn = NULL;
7860   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
7861     {
7862       GElf_Shdr shdr_mem;
7863       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
7864
7865       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
7866         {
7867           static const struct
7868           {
7869             const char *name;
7870             enum section_e bitmask;
7871             void (*fp) (Dwfl_Module *, Ebl *,
7872                         GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
7873           } debug_sections[] =
7874             {
7875 #define NEW_SECTION(name) \
7876               { ".debug_" #name, section_##name, print_debug_##name##_section }
7877               NEW_SECTION (abbrev),
7878               NEW_SECTION (aranges),
7879               NEW_SECTION (frame),
7880               NEW_SECTION (info),
7881               NEW_SECTION (types),
7882               NEW_SECTION (line),
7883               NEW_SECTION (loc),
7884               NEW_SECTION (pubnames),
7885               NEW_SECTION (str),
7886               NEW_SECTION (macinfo),
7887               NEW_SECTION (macro),
7888               NEW_SECTION (ranges),
7889               { ".eh_frame", section_frame | section_exception,
7890                 print_debug_frame_section },
7891               { ".eh_frame_hdr", section_frame | section_exception,
7892                 print_debug_frame_hdr_section },
7893               { ".gcc_except_table", section_frame | section_exception,
7894                 print_debug_exception_table },
7895               { ".gdb_index", section_gdb_index, print_gdb_index_section }
7896             };
7897           const int ndebug_sections = (sizeof (debug_sections)
7898                                        / sizeof (debug_sections[0]));
7899           const char *name = elf_strptr (ebl->elf, shstrndx,
7900                                          shdr->sh_name);
7901           int n;
7902
7903           for (n = 0; n < ndebug_sections; ++n)
7904             if (strcmp (name, debug_sections[n].name) == 0
7905 #if USE_ZLIB
7906                 || (name[0] == '.' && name[1] == 'z'
7907                     && debug_sections[n].name[1] == 'd'
7908                     && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
7909 #endif
7910                 )
7911               {
7912                 if ((print_debug_sections | implicit_debug_sections)
7913                     & debug_sections[n].bitmask)
7914                   debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
7915                 break;
7916               }
7917         }
7918     }
7919
7920   reset_listptr (&known_loclistptr);
7921   reset_listptr (&known_rangelistptr);
7922 }
7923
7924
7925 #define ITEM_INDENT             4
7926 #define WRAP_COLUMN             75
7927
7928 /* Print "NAME: FORMAT", wrapping when output text would make the line
7929    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
7930    but this function is also used for registers which should be printed
7931    aligned.  Fortunately registers output uses fixed fields width (such
7932    as %11d) for the alignment.
7933
7934    Line breaks should not depend on the particular values although that
7935    may happen in some cases of the core items.  */
7936
7937 static unsigned int
7938 __attribute__ ((format (printf, 6, 7)))
7939 print_core_item (unsigned int colno, char sep, unsigned int wrap,
7940                  size_t name_width, const char *name, const char *format, ...)
7941 {
7942   size_t len = strlen (name);
7943   if (name_width < len)
7944     name_width = len;
7945
7946   char *out;
7947   va_list ap;
7948   va_start (ap, format);
7949   int out_len = vasprintf (&out, format, ap);
7950   va_end (ap);
7951   if (out_len == -1)
7952     error (EXIT_FAILURE, 0, _("memory exhausted"));
7953
7954   size_t n = name_width + sizeof ": " - 1 + out_len;
7955
7956   if (colno == 0)
7957     {
7958       printf ("%*s", ITEM_INDENT, "");
7959       colno = ITEM_INDENT + n;
7960     }
7961   else if (colno + 2 + n < wrap)
7962     {
7963       printf ("%c ", sep);
7964       colno += 2 + n;
7965     }
7966   else
7967     {
7968       printf ("\n%*s", ITEM_INDENT, "");
7969       colno = ITEM_INDENT + n;
7970     }
7971
7972   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
7973
7974   free (out);
7975
7976   return colno;
7977 }
7978
7979 static const void *
7980 convert (Elf *core, Elf_Type type, uint_fast16_t count,
7981          void *value, const void *data, size_t size)
7982 {
7983   Elf_Data valuedata =
7984     {
7985       .d_type = type,
7986       .d_buf = value,
7987       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
7988       .d_version = EV_CURRENT,
7989     };
7990   Elf_Data indata =
7991     {
7992       .d_type = type,
7993       .d_buf = (void *) data,
7994       .d_size = valuedata.d_size,
7995       .d_version = EV_CURRENT,
7996     };
7997
7998   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
7999                  ? elf32_xlatetom : elf64_xlatetom)
8000     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8001   if (d == NULL)
8002     error (EXIT_FAILURE, 0,
8003            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8004
8005   return data + indata.d_size;
8006 }
8007
8008 typedef uint8_t GElf_Byte;
8009
8010 static unsigned int
8011 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8012                   unsigned int colno, size_t *repeated_size)
8013 {
8014   uint_fast16_t count = item->count ?: 1;
8015
8016 #define TYPES                                                                 \
8017   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);                             \
8018   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);                           \
8019   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);                           \
8020   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);                             \
8021   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);                        \
8022   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8023
8024 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8025   union { TYPES; } value;
8026 #undef DO_TYPE
8027
8028   void *data = &value;
8029   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8030   size_t convsize = size;
8031   if (repeated_size != NULL)
8032     {
8033       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8034         {
8035           data = alloca (*repeated_size);
8036           count *= *repeated_size / size;
8037           convsize = count * size;
8038           *repeated_size -= convsize;
8039         }
8040       else if (item->count != 0 || item->format != '\n')
8041         *repeated_size -= size;
8042     }
8043
8044   convert (core, item->type, count, data, desc + item->offset, convsize);
8045
8046   Elf_Type type = item->type;
8047   if (type == ELF_T_ADDR)
8048     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8049
8050   switch (item->format)
8051     {
8052     case 'd':
8053       assert (count == 1);
8054       switch (type)
8055         {
8056 #define DO_TYPE(NAME, Name, hex, dec)                                         \
8057           case ELF_T_##NAME:                                                  \
8058             colno = print_core_item (colno, ',', WRAP_COLUMN,                 \
8059                                      0, item->name, dec, value.Name[0]); \
8060             break
8061           TYPES;
8062 #undef DO_TYPE
8063         default:
8064           abort ();
8065         }
8066       break;
8067
8068     case 'x':
8069       assert (count == 1);
8070       switch (type)
8071         {
8072 #define DO_TYPE(NAME, Name, hex, dec)                                         \
8073           case ELF_T_##NAME:                                                  \
8074             colno = print_core_item (colno, ',', WRAP_COLUMN,                 \
8075                                      0, item->name, hex, value.Name[0]);      \
8076             break
8077           TYPES;
8078 #undef DO_TYPE
8079         default:
8080           abort ();
8081         }
8082       break;
8083
8084     case 'b':
8085     case 'B':
8086       assert (size % sizeof (unsigned int) == 0);
8087       unsigned int nbits = count * size * 8;
8088       unsigned int pop = 0;
8089       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8090         pop += __builtin_popcount (*i);
8091       bool negate = pop > nbits / 2;
8092       const unsigned int bias = item->format == 'b';
8093
8094       {
8095         char printed[(negate ? nbits - pop : pop) * 16];
8096         char *p = printed;
8097         *p = '\0';
8098
8099         if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8100           {
8101             assert (size == sizeof (unsigned int) * 2);
8102             for (unsigned int *i = data;
8103                  (void *) i < data + count * size; i += 2)
8104               {
8105                 unsigned int w = i[1];
8106                 i[1] = i[0];
8107                 i[0] = w;
8108               }
8109           }
8110
8111         unsigned int lastbit = 0;
8112         unsigned int run = 0;
8113         for (const unsigned int *i = data;
8114              (void *) i < data + count * size; ++i)
8115           {
8116             unsigned int bit = ((void *) i - data) * 8;
8117             unsigned int w = negate ? ~*i : *i;
8118             while (w != 0)
8119               {
8120                 int n = ffs (w);
8121                 w >>= n;
8122                 bit += n;
8123
8124                 if (lastbit != 0 && lastbit + 1 == bit)
8125                   ++run;
8126                 else
8127                   {
8128                     if (lastbit == 0)
8129                       p += sprintf (p, "%u", bit - bias);
8130                     else if (run == 0)
8131                       p += sprintf (p, ",%u", bit - bias);
8132                     else
8133                       p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8134                     run = 0;
8135                   }
8136
8137                 lastbit = bit;
8138               }
8139           }
8140         if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8141           p += sprintf (p, "-%u", lastbit - bias);
8142
8143         colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8144                                  negate ? "~<%s>" : "<%s>", printed);
8145       }
8146       break;
8147
8148     case 'T':
8149     case (char) ('T'|0x80):
8150       assert (count == 2);
8151       Dwarf_Word sec;
8152       Dwarf_Word usec;
8153       switch (type)
8154         {
8155 #define DO_TYPE(NAME, Name, hex, dec)                                         \
8156           case ELF_T_##NAME:                                                  \
8157             sec = value.Name[0];                                              \
8158             usec = value.Name[1];                                             \
8159             break
8160           TYPES;
8161 #undef DO_TYPE
8162         default:
8163           abort ();
8164         }
8165       if (unlikely (item->format == (char) ('T'|0x80)))
8166         {
8167           /* This is a hack for an ill-considered 64-bit ABI where
8168              tv_usec is actually a 32-bit field with 32 bits of padding
8169              rounding out struct timeval.  We've already converted it as
8170              a 64-bit field.  For little-endian, this just means the
8171              high half is the padding; it's presumably zero, but should
8172              be ignored anyway.  For big-endian, it means the 32-bit
8173              field went into the high half of USEC.  */
8174           GElf_Ehdr ehdr_mem;
8175           GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8176           if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8177             usec >>= 32;
8178           else
8179             usec &= UINT32_MAX;
8180         }
8181       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8182                                "%" PRIu64 ".%.6" PRIu64, sec, usec);
8183       break;
8184
8185     case 'c':
8186       assert (count == 1);
8187       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8188                                "%c", value.Byte[0]);
8189       break;
8190
8191     case 's':
8192       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8193                                "%.*s", (int) count, value.Byte);
8194       break;
8195
8196     case '\n':
8197       /* This is a list of strings separated by '\n'.  */
8198       assert (item->count == 0);
8199       assert (repeated_size != NULL);
8200       assert (item->name == NULL);
8201       if (unlikely (item->offset >= *repeated_size))
8202         break;
8203
8204       const char *s = desc + item->offset;
8205       size = *repeated_size - item->offset;
8206       *repeated_size = 0;
8207       while (size > 0)
8208         {
8209           const char *eol = memchr (s, '\n', size);
8210           int len = size;
8211           if (eol != NULL)
8212             len = eol - s;
8213           printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8214           if (eol == NULL)
8215             break;
8216           size -= eol + 1 - s;
8217           s = eol + 1;
8218         }
8219
8220       colno = WRAP_COLUMN;
8221       break;
8222
8223     case 'h':
8224       break;
8225
8226     default:
8227       error (0, 0, "XXX not handling format '%c' for %s",
8228              item->format, item->name);
8229       break;
8230     }
8231
8232 #undef TYPES
8233
8234   return colno;
8235 }
8236
8237
8238 /* Sort items by group, and by layout offset within each group.  */
8239 static int
8240 compare_core_items (const void *a, const void *b)
8241 {
8242   const Ebl_Core_Item *const *p1 = a;
8243   const Ebl_Core_Item *const *p2 = b;
8244   const Ebl_Core_Item *item1 = *p1;
8245   const Ebl_Core_Item *item2 = *p2;
8246
8247   return ((item1->group == item2->group ? 0
8248            : strcmp (item1->group, item2->group))
8249           ?: (int) item1->offset - (int) item2->offset);
8250 }
8251
8252 /* Sort item groups by layout offset of the first item in the group.  */
8253 static int
8254 compare_core_item_groups (const void *a, const void *b)
8255 {
8256   const Ebl_Core_Item *const *const *p1 = a;
8257   const Ebl_Core_Item *const *const *p2 = b;
8258   const Ebl_Core_Item *const *group1 = *p1;
8259   const Ebl_Core_Item *const *group2 = *p2;
8260   const Ebl_Core_Item *item1 = *group1;
8261   const Ebl_Core_Item *item2 = *group2;
8262
8263   return (int) item1->offset - (int) item2->offset;
8264 }
8265
8266 static unsigned int
8267 handle_core_items (Elf *core, const void *desc, size_t descsz,
8268                    const Ebl_Core_Item *items, size_t nitems)
8269 {
8270   if (nitems == 0)
8271     return 0;
8272   unsigned int colno = 0;
8273
8274   /* FORMAT '\n' makes sense to be present only as a single item as it
8275      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
8276      if present as a single item but they can be also processed with other
8277      items below.  */
8278   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8279                       || items[0].format == 'B'))
8280     {
8281       assert (items[0].offset == 0);
8282       size_t size = descsz;
8283       colno = handle_core_item (core, items, desc, colno, &size);
8284       /* If SIZE is not zero here there is some remaining data.  But we do not
8285          know how to process it anyway.  */
8286       return colno;
8287     }
8288   for (size_t i = 0; i < nitems; ++i)
8289     assert (items[i].format != '\n');
8290
8291   /* Sort to collect the groups together.  */
8292   const Ebl_Core_Item *sorted_items[nitems];
8293   for (size_t i = 0; i < nitems; ++i)
8294     sorted_items[i] = &items[i];
8295   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8296
8297   /* Collect the unique groups and sort them.  */
8298   const Ebl_Core_Item **groups[nitems];
8299   groups[0] = &sorted_items[0];
8300   size_t ngroups = 1;
8301   for (size_t i = 1; i < nitems; ++i)
8302     if (sorted_items[i]->group != sorted_items[i - 1]->group
8303         && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8304       groups[ngroups++] = &sorted_items[i];
8305   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8306
8307   /* Write out all the groups.  */
8308   const void *last = desc;
8309   do
8310     {
8311       for (size_t i = 0; i < ngroups; ++i)
8312         {
8313           for (const Ebl_Core_Item **item = groups[i];
8314                (item < &sorted_items[nitems]
8315                 && ((*item)->group == groups[i][0]->group
8316                     || !strcmp ((*item)->group, groups[i][0]->group)));
8317                ++item)
8318             colno = handle_core_item (core, *item, desc, colno, NULL);
8319
8320           /* Force a line break at the end of the group.  */
8321           colno = WRAP_COLUMN;
8322         }
8323
8324       if (descsz == 0)
8325         break;
8326
8327       /* This set of items consumed a certain amount of the note's data.
8328          If there is more data there, we have another unit of the same size.
8329          Loop to print that out too.  */
8330       const Ebl_Core_Item *item = &items[nitems - 1];
8331       size_t eltsz = item->offset + gelf_fsize (core, item->type,
8332                                                 item->count ?: 1, EV_CURRENT);
8333
8334       int reps = -1;
8335       do
8336         {
8337           ++reps;
8338           desc += eltsz;
8339           descsz -= eltsz;
8340         }
8341       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8342
8343       if (reps == 1)
8344         {
8345           /* For just one repeat, print it unabridged twice.  */
8346           desc -= eltsz;
8347           descsz += eltsz;
8348         }
8349       else if (reps > 1)
8350         printf (gettext ("\n%*s... <repeats %u more times> ..."),
8351                 ITEM_INDENT, "", reps);
8352
8353       last = desc;
8354     }
8355   while (descsz > 0);
8356
8357   return colno;
8358 }
8359
8360 static unsigned int
8361 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8362                       unsigned int colno)
8363 {
8364   desc += regloc->offset;
8365
8366   abort ();                     /* XXX */
8367   return colno;
8368 }
8369
8370
8371 static unsigned int
8372 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8373                       const Ebl_Register_Location *regloc, const void *desc,
8374                       unsigned int colno)
8375 {
8376   if (regloc->bits % 8 != 0)
8377     return handle_bit_registers (regloc, desc, colno);
8378
8379   desc += regloc->offset;
8380
8381   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8382     {
8383       char name[REGNAMESZ];
8384       int bits;
8385       int type;
8386       register_info (ebl, reg, regloc, name, &bits, &type);
8387
8388 #define TYPES                                                                 \
8389       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);                              \
8390       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);                           \
8391       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);                         \
8392       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
8393
8394 #define BITS(bits, xtype, sfmt, ufmt)                           \
8395       uint##bits##_t b##bits; int##bits##_t b##bits##s
8396       union { TYPES; uint64_t b128[2]; } value;
8397 #undef  BITS
8398
8399       switch (type)
8400         {
8401         case DW_ATE_unsigned:
8402         case DW_ATE_signed:
8403         case DW_ATE_address:
8404           switch (bits)
8405             {
8406 #define BITS(bits, xtype, sfmt, ufmt)                                         \
8407             case bits:                                                        \
8408               desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);       \
8409               if (type == DW_ATE_signed)                                      \
8410                 colno = print_core_item (colno, ' ', WRAP_COLUMN,             \
8411                                          maxregname, name,                    \
8412                                          sfmt, value.b##bits##s);             \
8413               else                                                            \
8414                 colno = print_core_item (colno, ' ', WRAP_COLUMN,             \
8415                                          maxregname, name,                    \
8416                                          ufmt, value.b##bits);                \
8417               break
8418
8419             TYPES;
8420
8421             case 128:
8422               assert (type == DW_ATE_unsigned);
8423               desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8424               int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8425               colno = print_core_item (colno, ' ', WRAP_COLUMN,
8426                                        maxregname, name,
8427                                        "0x%.16" PRIx64 "%.16" PRIx64,
8428                                        value.b128[!be], value.b128[be]);
8429               break;
8430
8431             default:
8432               abort ();
8433 #undef  BITS
8434             }
8435           break;
8436
8437         default:
8438           /* Print each byte in hex, the whole thing in native byte order.  */
8439           assert (bits % 8 == 0);
8440           const uint8_t *bytes = desc;
8441           desc += bits / 8;
8442           char hex[bits / 4 + 1];
8443           hex[bits / 4] = '\0';
8444           int incr = 1;
8445           if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8446             {
8447               bytes += bits / 8 - 1;
8448               incr = -1;
8449             }
8450           size_t idx = 0;
8451           for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8452             {
8453               *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8454               *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8455             }
8456           colno = print_core_item (colno, ' ', WRAP_COLUMN,
8457                                    maxregname, name, "0x%s", hex);
8458           break;
8459         }
8460       desc += regloc->pad;
8461
8462 #undef TYPES
8463     }
8464
8465   return colno;
8466 }
8467
8468
8469 struct register_info
8470 {
8471   const Ebl_Register_Location *regloc;
8472   const char *set;
8473   char name[REGNAMESZ];
8474   int regno;
8475   int bits;
8476   int type;
8477 };
8478
8479 static int
8480 register_bitpos (const struct register_info *r)
8481 {
8482   return (r->regloc->offset * 8
8483           + ((r->regno - r->regloc->regno)
8484              * (r->regloc->bits + r->regloc->pad * 8)));
8485 }
8486
8487 static int
8488 compare_sets_by_info (const struct register_info *r1,
8489                       const struct register_info *r2)
8490 {
8491   return ((int) r2->bits - (int) r1->bits
8492           ?: register_bitpos (r1) - register_bitpos (r2));
8493 }
8494
8495 /* Sort registers by set, and by size and layout offset within each set.  */
8496 static int
8497 compare_registers (const void *a, const void *b)
8498 {
8499   const struct register_info *r1 = a;
8500   const struct register_info *r2 = b;
8501
8502   /* Unused elements sort last.  */
8503   if (r1->regloc == NULL)
8504     return r2->regloc == NULL ? 0 : 1;
8505   if (r2->regloc == NULL)
8506     return -1;
8507
8508   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8509           ?: compare_sets_by_info (r1, r2));
8510 }
8511
8512 /* Sort register sets by layout offset of the first register in the set.  */
8513 static int
8514 compare_register_sets (const void *a, const void *b)
8515 {
8516   const struct register_info *const *p1 = a;
8517   const struct register_info *const *p2 = b;
8518   return compare_sets_by_info (*p1, *p2);
8519 }
8520
8521 static unsigned int
8522 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8523                        const Ebl_Register_Location *reglocs, size_t nregloc)
8524 {
8525   if (nregloc == 0)
8526     return 0;
8527
8528   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8529   if (maxnreg <= 0)
8530     {
8531       for (size_t i = 0; i < nregloc; ++i)
8532         if (maxnreg < reglocs[i].regno + reglocs[i].count)
8533           maxnreg = reglocs[i].regno + reglocs[i].count;
8534       assert (maxnreg > 0);
8535     }
8536
8537   struct register_info regs[maxnreg];
8538   memset (regs, 0, sizeof regs);
8539
8540   /* Sort to collect the sets together.  */
8541   int maxreg = 0;
8542   for (size_t i = 0; i < nregloc; ++i)
8543     for (int reg = reglocs[i].regno;
8544          reg < reglocs[i].regno + reglocs[i].count;
8545          ++reg)
8546       {
8547         assert (reg < maxnreg);
8548         if (reg > maxreg)
8549           maxreg = reg;
8550         struct register_info *info = &regs[reg];
8551         info->regloc = &reglocs[i];
8552         info->regno = reg;
8553         info->set = register_info (ebl, reg, &reglocs[i],
8554                                    info->name, &info->bits, &info->type);
8555       }
8556   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8557
8558   /* Collect the unique sets and sort them.  */
8559   inline bool same_set (const struct register_info *a,
8560                         const struct register_info *b)
8561   {
8562     return (a < &regs[maxnreg] && a->regloc != NULL
8563             && b < &regs[maxnreg] && b->regloc != NULL
8564             && a->bits == b->bits
8565             && (a->set == b->set || !strcmp (a->set, b->set)));
8566   }
8567   struct register_info *sets[maxreg + 1];
8568   sets[0] = &regs[0];
8569   size_t nsets = 1;
8570   for (int i = 1; i <= maxreg; ++i)
8571     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
8572       sets[nsets++] = &regs[i];
8573   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8574
8575   /* Write out all the sets.  */
8576   unsigned int colno = 0;
8577   for (size_t i = 0; i < nsets; ++i)
8578     {
8579       /* Find the longest name of a register in this set.  */
8580       size_t maxname = 0;
8581       const struct register_info *end;
8582       for (end = sets[i]; same_set (sets[i], end); ++end)
8583         {
8584           size_t len = strlen (end->name);
8585           if (len > maxname)
8586             maxname = len;
8587         }
8588
8589       for (const struct register_info *reg = sets[i];
8590            reg < end;
8591            reg += reg->regloc->count ?: 1)
8592         colno = handle_core_register (ebl, core, maxname,
8593                                       reg->regloc, desc, colno);
8594
8595       /* Force a line break at the end of the group.  */
8596       colno = WRAP_COLUMN;
8597     }
8598
8599   return colno;
8600 }
8601
8602 static void
8603 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8604 {
8605   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8606   if (data == NULL)
8607   elf_error:
8608     error (EXIT_FAILURE, 0,
8609            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8610
8611   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8612   for (size_t i = 0; i < nauxv; ++i)
8613     {
8614       GElf_auxv_t av_mem;
8615       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8616       if (av == NULL)
8617         goto elf_error;
8618
8619       const char *name;
8620       const char *fmt;
8621       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8622         {
8623           /* Unknown type.  */
8624           if (av->a_un.a_val == 0)
8625             printf ("    %" PRIu64 "\n", av->a_type);
8626           else
8627             printf ("    %" PRIu64 ": %#" PRIx64 "\n",
8628                     av->a_type, av->a_un.a_val);
8629         }
8630       else
8631         switch (fmt[0])
8632           {
8633           case '\0':            /* Normally zero.  */
8634             if (av->a_un.a_val == 0)
8635               {
8636                 printf ("    %s\n", name);
8637                 break;
8638               }
8639             /* Fall through */
8640           case 'x':             /* hex */
8641           case 'p':             /* address */
8642           case 's':             /* address of string */
8643             printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8644             break;
8645           case 'u':
8646             printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
8647             break;
8648           case 'd':
8649             printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
8650             break;
8651
8652           case 'b':
8653             printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
8654             GElf_Xword bit = 1;
8655             const char *pfx = "<";
8656             for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8657               {
8658                 if (av->a_un.a_val & bit)
8659                   {
8660                     printf ("%s%s", pfx, p);
8661                     pfx = " ";
8662                   }
8663                 bit <<= 1;
8664               }
8665             printf (">\n");
8666             break;
8667
8668           default:
8669             abort ();
8670           }
8671     }
8672 }
8673
8674 static bool
8675 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8676 {
8677   return ptr < end && (size_t) (end - ptr) >= sz;
8678 }
8679
8680 static bool
8681 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8682               int *retp)
8683 {
8684   if (! buf_has_data (*ptrp, end, 4))
8685     return false;
8686
8687   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8688   return true;
8689 }
8690
8691 static bool
8692 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8693                 uint64_t *retp)
8694 {
8695   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8696   if (! buf_has_data (*ptrp, end, sz))
8697     return false;
8698
8699   union
8700   {
8701     uint64_t u64;
8702     uint32_t u32;
8703   } u;
8704
8705   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sizeof u);
8706
8707   if (sz == 4)
8708     *retp = u.u32;
8709   else
8710     *retp = u.u64;
8711   return true;
8712 }
8713
8714 static void
8715 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8716 {
8717   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8718   if (data == NULL)
8719     error (EXIT_FAILURE, 0,
8720            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8721
8722   unsigned char const *ptr = data->d_buf;
8723   unsigned char const *const end = data->d_buf + data->d_size;
8724
8725   /* Siginfo head is three ints: signal number, error number, origin
8726      code.  */
8727   int si_signo, si_errno, si_code;
8728   if (! buf_read_int (core, &ptr, end, &si_signo)
8729       || ! buf_read_int (core, &ptr, end, &si_errno)
8730       || ! buf_read_int (core, &ptr, end, &si_code))
8731     {
8732     fail:
8733       printf ("    Not enough data in NT_SIGINFO note.\n");
8734       return;
8735     }
8736
8737   /* Next is a pointer-aligned union of structures.  On 64-bit
8738      machines, that implies a word of padding.  */
8739   if (gelf_getclass (core) == ELFCLASS64)
8740     ptr += 4;
8741
8742   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
8743           si_signo, si_errno, si_code);
8744
8745   if (si_code > 0)
8746     switch (si_signo)
8747       {
8748       case SIGILL:
8749       case SIGFPE:
8750       case SIGSEGV:
8751       case SIGBUS:
8752         {
8753           uint64_t addr;
8754           if (! buf_read_ulong (core, &ptr, end, &addr))
8755             goto fail;
8756           printf ("    fault address: %#" PRIx64 "\n", addr);
8757           break;
8758         }
8759       default:
8760         ;
8761       }
8762   else if (si_code == SI_USER)
8763     {
8764       int pid, uid;
8765       if (! buf_read_int (core, &ptr, end, &pid)
8766           || ! buf_read_int (core, &ptr, end, &uid))
8767         goto fail;
8768       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
8769     }
8770 }
8771
8772 static void
8773 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8774 {
8775   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8776   if (data == NULL)
8777     error (EXIT_FAILURE, 0,
8778            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8779
8780   unsigned char const *ptr = data->d_buf;
8781   unsigned char const *const end = data->d_buf + data->d_size;
8782
8783   uint64_t count, page_size;
8784   if (! buf_read_ulong (core, &ptr, end, &count)
8785       || ! buf_read_ulong (core, &ptr, end, &page_size))
8786     {
8787     fail:
8788       printf ("    Not enough data in NT_FILE note.\n");
8789       return;
8790     }
8791
8792   /* Where file names are stored.  */
8793   unsigned char const *const fstart
8794     = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8795   char const *fptr = (char *) fstart;
8796
8797   printf ("    %" PRId64 " files:\n", count);
8798   for (uint64_t i = 0; i < count; ++i)
8799     {
8800       uint64_t mstart, mend, moffset;
8801       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
8802           || ! buf_read_ulong (core, &ptr, fstart, &mend)
8803           || ! buf_read_ulong (core, &ptr, fstart, &moffset))
8804         goto fail;
8805
8806       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
8807       if (fnext == NULL)
8808         goto fail;
8809
8810       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
8811                        " %08" PRIx64 " %" PRId64,
8812                        mstart, mend, moffset * page_size, mend - mstart);
8813       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
8814
8815       fptr = fnext + 1;
8816     }
8817 }
8818
8819 static void
8820 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
8821                   const char *name, const void *desc)
8822 {
8823   GElf_Word regs_offset;
8824   size_t nregloc;
8825   const Ebl_Register_Location *reglocs;
8826   size_t nitems;
8827   const Ebl_Core_Item *items;
8828
8829   if (! ebl_core_note (ebl, nhdr, name,
8830                        &regs_offset, &nregloc, &reglocs, &nitems, &items))
8831     return;
8832
8833   /* Pass 0 for DESCSZ when there are registers in the note,
8834      so that the ITEMS array does not describe the whole thing.
8835      For non-register notes, the actual descsz might be a multiple
8836      of the unit size, not just exactly the unit size.  */
8837   unsigned int colno = handle_core_items (ebl->elf, desc,
8838                                           nregloc == 0 ? nhdr->n_descsz : 0,
8839                                           items, nitems);
8840   if (colno != 0)
8841     putchar_unlocked ('\n');
8842
8843   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
8844                                  reglocs, nregloc);
8845   if (colno != 0)
8846     putchar_unlocked ('\n');
8847 }
8848
8849 static void
8850 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
8851                    GElf_Off start, Elf_Data *data)
8852 {
8853   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
8854
8855   if (data == NULL)
8856     goto bad_note;
8857
8858   size_t offset = 0;
8859   GElf_Nhdr nhdr;
8860   size_t name_offset;
8861   size_t desc_offset;
8862   while (offset < data->d_size
8863          && (offset = gelf_getnote (data, offset,
8864                                     &nhdr, &name_offset, &desc_offset)) > 0)
8865     {
8866       const char *name = data->d_buf + name_offset;
8867       const char *desc = data->d_buf + desc_offset;
8868
8869       char buf[100];
8870       char buf2[100];
8871       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
8872               (int) nhdr.n_namesz, name, nhdr.n_descsz,
8873               ehdr->e_type == ET_CORE
8874               ? ebl_core_note_type_name (ebl, nhdr.n_type,
8875                                          buf, sizeof (buf))
8876               : ebl_object_note_type_name (ebl, name, nhdr.n_type,
8877                                            buf2, sizeof (buf2)));
8878
8879       /* Filter out invalid entries.  */
8880       if (memchr (name, '\0', nhdr.n_namesz) != NULL
8881           /* XXX For now help broken Linux kernels.  */
8882           || 1)
8883         {
8884           if (ehdr->e_type == ET_CORE)
8885             {
8886               if (nhdr.n_type == NT_AUXV
8887                   && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
8888                       || (nhdr.n_namesz == 5 && name[4] == '\0'))
8889                   && !memcmp (name, "CORE", 4))
8890                 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
8891                                   start + desc_offset);
8892               else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
8893                 switch (nhdr.n_type)
8894                   {
8895                   case NT_SIGINFO:
8896                     handle_siginfo_note (ebl->elf, nhdr.n_descsz,
8897                                          start + desc_offset);
8898                     break;
8899
8900                   case NT_FILE:
8901                     handle_file_note (ebl->elf, nhdr.n_descsz,
8902                                       start + desc_offset);
8903                     break;
8904
8905                   default:
8906                     handle_core_note (ebl, &nhdr, name, desc);
8907                   }
8908               else
8909                 handle_core_note (ebl, &nhdr, name, desc);
8910             }
8911           else
8912             ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
8913         }
8914     }
8915
8916   if (offset == data->d_size)
8917     return;
8918
8919  bad_note:
8920   error (EXIT_FAILURE, 0,
8921          gettext ("cannot get content of note section: %s"),
8922          elf_errmsg (-1));
8923 }
8924
8925 static void
8926 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
8927 {
8928   /* If we have section headers, just look for SHT_NOTE sections.
8929      In a debuginfo file, the program headers are not reliable.  */
8930   if (shnum != 0)
8931     {
8932       /* Get the section header string table index.  */
8933       size_t shstrndx;
8934       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
8935         error (EXIT_FAILURE, 0,
8936                gettext ("cannot get section header string table index"));
8937
8938       Elf_Scn *scn = NULL;
8939       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8940         {
8941           GElf_Shdr shdr_mem;
8942           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8943
8944           if (shdr == NULL || shdr->sh_type != SHT_NOTE)
8945             /* Not what we are looking for.  */
8946             continue;
8947
8948           printf (gettext ("\
8949 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8950                   elf_ndxscn (scn),
8951                   elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
8952                   shdr->sh_size, shdr->sh_offset);
8953
8954           handle_notes_data (ebl, ehdr, shdr->sh_offset,
8955                              elf_getdata (scn, NULL));
8956         }
8957       return;
8958     }
8959
8960   /* We have to look through the program header to find the note
8961      sections.  There can be more than one.  */
8962   for (size_t cnt = 0; cnt < phnum; ++cnt)
8963     {
8964       GElf_Phdr mem;
8965       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
8966
8967       if (phdr == NULL || phdr->p_type != PT_NOTE)
8968         /* Not what we are looking for.  */
8969         continue;
8970
8971       printf (gettext ("\
8972 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
8973               phdr->p_filesz, phdr->p_offset);
8974
8975       handle_notes_data (ebl, ehdr, phdr->p_offset,
8976                          elf_getdata_rawchunk (ebl->elf,
8977                                                phdr->p_offset, phdr->p_filesz,
8978                                                ELF_T_NHDR));
8979     }
8980 }
8981
8982
8983 static void
8984 hex_dump (const uint8_t *data, size_t len)
8985 {
8986   size_t pos = 0;
8987   while (pos < len)
8988     {
8989       printf ("  0x%08Zx ", pos);
8990
8991       const size_t chunk = MIN (len - pos, 16);
8992
8993       for (size_t i = 0; i < chunk; ++i)
8994         if (i % 4 == 3)
8995           printf ("%02x ", data[pos + i]);
8996         else
8997           printf ("%02x", data[pos + i]);
8998
8999       if (chunk < 16)
9000         printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9001
9002       for (size_t i = 0; i < chunk; ++i)
9003         {
9004           unsigned char b = data[pos + i];
9005           printf ("%c", isprint (b) ? b : '.');
9006         }
9007
9008       putchar ('\n');
9009       pos += chunk;
9010     }
9011 }
9012
9013 static void
9014 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9015 {
9016   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9017     printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9018             elf_ndxscn (scn), name);
9019   else
9020     {
9021       Elf_Data *data = elf_rawdata (scn, NULL);
9022       if (data == NULL)
9023         error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9024                elf_ndxscn (scn), name, elf_errmsg (-1));
9025       else
9026         {
9027           printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9028                            " bytes at offset %#0" PRIx64 ":\n"),
9029                   elf_ndxscn (scn), name,
9030                   shdr->sh_size, shdr->sh_offset);
9031           hex_dump (data->d_buf, data->d_size);
9032         }
9033     }
9034 }
9035
9036 static void
9037 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9038 {
9039   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9040     printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9041             elf_ndxscn (scn), name);
9042   else
9043     {
9044       Elf_Data *data = elf_rawdata (scn, NULL);
9045       if (data == NULL)
9046         error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9047                elf_ndxscn (scn), name, elf_errmsg (-1));
9048       else
9049         {
9050           printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9051                            " bytes at offset %#0" PRIx64 ":\n"),
9052                   elf_ndxscn (scn), name,
9053                   shdr->sh_size, shdr->sh_offset);
9054
9055           const char *start = data->d_buf;
9056           const char *const limit = start + data->d_size;
9057           do
9058             {
9059               const char *end = memchr (start, '\0', limit - start);
9060               const size_t pos = start - (const char *) data->d_buf;
9061               if (unlikely (end == NULL))
9062                 {
9063                   printf ("  [%6Zx]- %.*s\n",
9064                           pos, (int) (limit - start), start);
9065                   break;
9066                 }
9067               printf ("  [%6Zx]  %s\n", pos, start);
9068               start = end + 1;
9069             } while (start < limit);
9070         }
9071     }
9072 }
9073
9074 static void
9075 for_each_section_argument (Elf *elf, const struct section_argument *list,
9076                            void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9077                                          const char *name))
9078 {
9079   /* Get the section header string table index.  */
9080   size_t shstrndx;
9081   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9082     error (EXIT_FAILURE, 0,
9083            gettext ("cannot get section header string table index"));
9084
9085   for (const struct section_argument *a = list; a != NULL; a = a->next)
9086     {
9087       Elf_Scn *scn;
9088       GElf_Shdr shdr_mem;
9089       const char *name = NULL;
9090
9091       char *endp = NULL;
9092       unsigned long int shndx = strtoul (a->arg, &endp, 0);
9093       if (endp != a->arg && *endp == '\0')
9094         {
9095           scn = elf_getscn (elf, shndx);
9096           if (scn == NULL)
9097             {
9098               error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9099               continue;
9100             }
9101
9102           if (gelf_getshdr (scn, &shdr_mem) == NULL)
9103             error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9104                    elf_errmsg (-1));
9105           name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9106         }
9107       else
9108         {
9109           /* Need to look up the section by name.  */
9110           scn = NULL;
9111           bool found = false;
9112           while ((scn = elf_nextscn (elf, scn)) != NULL)
9113             {
9114               if (gelf_getshdr (scn, &shdr_mem) == NULL)
9115                 continue;
9116               name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9117               if (name == NULL)
9118                 continue;
9119               if (!strcmp (name, a->arg))
9120                 {
9121                   found = true;
9122                   (*dump) (scn, &shdr_mem, name);
9123                 }
9124             }
9125
9126           if (unlikely (!found) && !a->implicit)
9127             error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9128         }
9129     }
9130 }
9131
9132 static void
9133 dump_data (Ebl *ebl)
9134 {
9135   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9136 }
9137
9138 static void
9139 dump_strings (Ebl *ebl)
9140 {
9141   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9142 }
9143
9144 static void
9145 print_strings (Ebl *ebl)
9146 {
9147   /* Get the section header string table index.  */
9148   size_t shstrndx;
9149   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9150     error (EXIT_FAILURE, 0,
9151            gettext ("cannot get section header string table index"));
9152
9153   Elf_Scn *scn;
9154   GElf_Shdr shdr_mem;
9155   const char *name;
9156   scn = NULL;
9157   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9158     {
9159       if (gelf_getshdr (scn, &shdr_mem) == NULL)
9160         continue;
9161
9162       if (shdr_mem.sh_type != SHT_PROGBITS
9163           || !(shdr_mem.sh_flags & SHF_STRINGS))
9164         continue;
9165
9166       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9167       if (name == NULL)
9168         continue;
9169
9170       print_string_section (scn, &shdr_mem, name);
9171     }
9172 }
9173
9174 static void
9175 dump_archive_index (Elf *elf, const char *fname)
9176 {
9177   size_t narsym;
9178   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9179   if (arsym == NULL)
9180     {
9181       int result = elf_errno ();
9182       if (unlikely (result != ELF_E_NO_INDEX))
9183         error (EXIT_FAILURE, 0,
9184                gettext ("cannot get symbol index of archive '%s': %s"),
9185                fname, elf_errmsg (result));
9186       else
9187         printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9188       return;
9189     }
9190
9191   printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9192           fname, narsym);
9193
9194   size_t as_off = 0;
9195   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9196     {
9197       if (s->as_off != as_off)
9198         {
9199           as_off = s->as_off;
9200
9201           Elf *subelf;
9202           if (unlikely (elf_rand (elf, as_off) == 0)
9203               || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9204                            == NULL))
9205 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9206             while (1)
9207 #endif
9208               error (EXIT_FAILURE, 0,
9209                      gettext ("cannot extract member at offset %Zu in '%s': %s"),
9210                      as_off, fname, elf_errmsg (-1));
9211
9212           const Elf_Arhdr *h = elf_getarhdr (subelf);
9213
9214           printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9215
9216           elf_end (subelf);
9217         }
9218
9219       printf ("\t%s\n", s->as_name);
9220     }
9221 }
9222
9223 #include "debugpred.h"