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