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