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