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