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