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