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