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