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