readelf: maximum operations per instruction cannot be zero in .debug_line.
[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           if (ref_size == 0)
4003             goto invalid; /* Cannot be used in CFA.  */
4004           NEED (ref_size);
4005           if (ref_size == 4)
4006             addr = read_4ubyte_unaligned (dbg, data);
4007           else
4008             {
4009               assert (ref_size == 8);
4010               addr = read_8ubyte_unaligned (dbg, data);
4011             }
4012           data += ref_size;
4013           CONSUME (ref_size);
4014
4015           printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4016                   indent, "", (uintmax_t) offset,
4017                   op_name, (uintmax_t) addr);
4018           offset += 1 + ref_size;
4019           break;
4020
4021         case DW_OP_deref_size:
4022         case DW_OP_xderef_size:
4023         case DW_OP_pick:
4024         case DW_OP_const1u:
4025           // XXX value might be modified by relocation
4026           NEED (1);
4027           printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4028                   indent, "", (uintmax_t) offset,
4029                   op_name, *((uint8_t *) data));
4030           ++data;
4031           --len;
4032           offset += 2;
4033           break;
4034
4035         case DW_OP_const2u:
4036           NEED (2);
4037           // XXX value might be modified by relocation
4038           printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4039                   indent, "", (uintmax_t) offset,
4040                   op_name, read_2ubyte_unaligned (dbg, data));
4041           CONSUME (2);
4042           data += 2;
4043           offset += 3;
4044           break;
4045
4046         case DW_OP_const4u:
4047           NEED (4);
4048           // XXX value might be modified by relocation
4049           printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4050                   indent, "", (uintmax_t) offset,
4051                   op_name, read_4ubyte_unaligned (dbg, data));
4052           CONSUME (4);
4053           data += 4;
4054           offset += 5;
4055           break;
4056
4057         case DW_OP_const8u:
4058           NEED (8);
4059           // XXX value might be modified by relocation
4060           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4061                   indent, "", (uintmax_t) offset,
4062                   op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4063           CONSUME (8);
4064           data += 8;
4065           offset += 9;
4066           break;
4067
4068         case DW_OP_const1s:
4069           NEED (1);
4070           // XXX value might be modified by relocation
4071           printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4072                   indent, "", (uintmax_t) offset,
4073                   op_name, *((int8_t *) data));
4074           ++data;
4075           --len;
4076           offset += 2;
4077           break;
4078
4079         case DW_OP_const2s:
4080           NEED (2);
4081           // XXX value might be modified by relocation
4082           printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4083                   indent, "", (uintmax_t) offset,
4084                   op_name, read_2sbyte_unaligned (dbg, data));
4085           CONSUME (2);
4086           data += 2;
4087           offset += 3;
4088           break;
4089
4090         case DW_OP_const4s:
4091           NEED (4);
4092           // XXX value might be modified by relocation
4093           printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4094                   indent, "", (uintmax_t) offset,
4095                   op_name, read_4sbyte_unaligned (dbg, data));
4096           CONSUME (4);
4097           data += 4;
4098           offset += 5;
4099           break;
4100
4101         case DW_OP_const8s:
4102           NEED (8);
4103           // XXX value might be modified by relocation
4104           printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4105                   indent, "", (uintmax_t) offset,
4106                   op_name, read_8sbyte_unaligned (dbg, data));
4107           CONSUME (8);
4108           data += 8;
4109           offset += 9;
4110           break;
4111
4112         case DW_OP_piece:
4113         case DW_OP_regx:
4114         case DW_OP_plus_uconst:
4115         case DW_OP_constu:;
4116           const unsigned char *start = data;
4117           uint64_t uleb;
4118           NEED (1);
4119           get_uleb128 (uleb, data); /* XXX check overrun */
4120           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4121                   indent, "", (uintmax_t) offset, op_name, uleb);
4122           CONSUME (data - start);
4123           offset += 1 + (data - start);
4124           break;
4125
4126         case DW_OP_bit_piece:
4127           start = data;
4128           uint64_t uleb2;
4129           NEED (2);
4130           get_uleb128 (uleb, data); /* XXX check overrun */
4131           get_uleb128 (uleb2, data); /* XXX check overrun */
4132           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4133                   indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4134           CONSUME (data - start);
4135           offset += 1 + (data - start);
4136           break;
4137
4138         case DW_OP_fbreg:
4139         case DW_OP_breg0 ... DW_OP_breg31:
4140         case DW_OP_consts:
4141           start = data;
4142           int64_t sleb;
4143           NEED (1);
4144           get_sleb128 (sleb, data); /* XXX check overrun */
4145           printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4146                   indent, "", (uintmax_t) offset, op_name, sleb);
4147           CONSUME (data - start);
4148           offset += 1 + (data - start);
4149           break;
4150
4151         case DW_OP_bregx:
4152           start = data;
4153           NEED (2);
4154           get_uleb128 (uleb, data); /* XXX check overrun */
4155           get_sleb128 (sleb, data); /* XXX check overrun */
4156           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4157                   indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4158           CONSUME (data - start);
4159           offset += 1 + (data - start);
4160           break;
4161
4162         case DW_OP_call2:
4163           NEED (2);
4164           printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4165                   indent, "", (uintmax_t) offset, op_name,
4166                   read_2ubyte_unaligned (dbg, data));
4167           CONSUME (2);
4168           offset += 3;
4169           break;
4170
4171         case DW_OP_call4:
4172           NEED (4);
4173           printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4174                   indent, "", (uintmax_t) offset, op_name,
4175                   read_4ubyte_unaligned (dbg, data));
4176           CONSUME (4);
4177           offset += 5;
4178           break;
4179
4180         case DW_OP_skip:
4181         case DW_OP_bra:
4182           NEED (2);
4183           printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4184                   indent, "", (uintmax_t) offset, op_name,
4185                   (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4186           CONSUME (2);
4187           data += 2;
4188           offset += 3;
4189           break;
4190
4191         case DW_OP_implicit_value:
4192           start = data;
4193           NEED (1);
4194           get_uleb128 (uleb, data); /* XXX check overrun */
4195           printf ("%*s[%4" PRIuMAX "] %s: ",
4196                   indent, "", (uintmax_t) offset, op_name);
4197           NEED (uleb);
4198           print_block (uleb, data);
4199           data += uleb;
4200           CONSUME (data - start);
4201           offset += 1 + (data - start);
4202           break;
4203
4204         case DW_OP_GNU_implicit_pointer:
4205           /* DIE offset operand.  */
4206           start = data;
4207           NEED (ref_size + 1);
4208           if (ref_size == 0)
4209             goto invalid; /* Cannot be used in CFA.  */
4210           if (ref_size == 4)
4211             addr = read_4ubyte_unaligned (dbg, data);
4212           else
4213             {
4214               assert (ref_size == 8);
4215               addr = read_8ubyte_unaligned (dbg, data);
4216             }
4217           data += ref_size;
4218           /* Byte offset operand.  */
4219           get_sleb128 (sleb, data); /* XXX check overrun */
4220
4221           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4222                   indent, "", (intmax_t) offset,
4223                   op_name, (uintmax_t) addr, sleb);
4224           CONSUME (data - start);
4225           offset += 1 + (data - start);
4226           break;
4227
4228         case DW_OP_GNU_entry_value:
4229           /* Size plus expression block.  */
4230           start = data;
4231           NEED (1);
4232           get_uleb128 (uleb, data); /* XXX check overrun */
4233           printf ("%*s[%4" PRIuMAX "] %s:\n",
4234                   indent, "", (uintmax_t) offset, op_name);
4235           NEED (uleb);
4236           print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4237                      addrsize, offset_size, cu, uleb, data);
4238           data += uleb;
4239           CONSUME (data - start);
4240           offset += 1 + (data - start);
4241           break;
4242
4243         case DW_OP_GNU_const_type:
4244           /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4245              unsigned size plus block.  */
4246           start = data;
4247           NEED (2);
4248           get_uleb128 (uleb, data); /* XXX check overrun */
4249           if (! print_unresolved_addresses && cu != NULL)
4250             uleb += cu->start;
4251           uint8_t usize = *(uint8_t *) data++;
4252           NEED (usize);
4253           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4254                   indent, "", (uintmax_t) offset, op_name, uleb);
4255           print_block (usize, data);
4256           data += usize;
4257           CONSUME (data - start);
4258           offset += 1 + (data - start);
4259           break;
4260
4261         case DW_OP_GNU_regval_type:
4262           /* uleb128 register number, uleb128 CU relative
4263              DW_TAG_base_type DIE offset.  */
4264           start = data;
4265           NEED (2);
4266           get_uleb128 (uleb, data); /* XXX check overrun */
4267           get_uleb128 (uleb2, data); /* XXX check overrun */
4268           if (! print_unresolved_addresses && cu != NULL)
4269             uleb2 += cu->start;
4270           printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4271                   indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4272           CONSUME (data - start);
4273           offset += 1 + (data - start);
4274           break;
4275
4276         case DW_OP_GNU_deref_type:
4277           /* 1-byte unsigned size of value, uleb128 CU relative
4278              DW_TAG_base_type DIE offset.  */
4279           start = data;
4280           NEED (2);
4281           usize = *(uint8_t *) data++;
4282           get_uleb128 (uleb, data); /* XXX check overrun */
4283           if (! print_unresolved_addresses && cu != NULL)
4284             uleb += cu->start;
4285           printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4286                   indent, "", (uintmax_t) offset,
4287                   op_name, usize, uleb);
4288           CONSUME (data - start);
4289           offset += 1 + (data - start);
4290           break;
4291
4292         case DW_OP_GNU_convert:
4293         case DW_OP_GNU_reinterpret:
4294           /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4295              for conversion to untyped.  */
4296           start = data;
4297           NEED (1);
4298           get_uleb128 (uleb, data); /* XXX check overrun */
4299           if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4300             uleb += cu->start;
4301           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4302                   indent, "", (uintmax_t) offset, op_name, uleb);
4303           CONSUME (data - start);
4304           offset += 1 + (data - start);
4305           break;
4306
4307         case DW_OP_GNU_parameter_ref:
4308           /* 4 byte CU relative reference to the abstract optimized away
4309              DW_TAG_formal_parameter.  */
4310           NEED (4);
4311           uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4312           if (! print_unresolved_addresses && cu != NULL)
4313             param_off += cu->start;
4314           printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4315                   indent, "", (uintmax_t) offset, op_name, param_off);
4316           CONSUME (4);
4317           data += 4;
4318           offset += 5;
4319           break;
4320
4321         default:
4322           /* No Operand.  */
4323           printf ("%*s[%4" PRIuMAX "] %s\n",
4324                   indent, "", (uintmax_t) offset, op_name);
4325           ++offset;
4326           break;
4327         }
4328
4329       indent = indentrest;
4330       continue;
4331
4332     invalid:
4333       printf (gettext ("%*s[%4" PRIuMAX "] %s  <TRUNCATED>\n"),
4334               indent, "", (uintmax_t) offset, op_name);
4335       break;
4336     }
4337 }
4338
4339
4340 struct listptr
4341 {
4342   Dwarf_Off offset:(64 - 3);
4343   bool addr64:1;
4344   bool dwarf64:1;
4345   bool warned:1;
4346   struct Dwarf_CU *cu;
4347 };
4348
4349 #define listptr_offset_size(p)  ((p)->dwarf64 ? 8 : 4)
4350 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4351
4352 static Dwarf_Addr
4353 listptr_base (struct listptr *p)
4354 {
4355   Dwarf_Addr base;
4356   Dwarf_Die cu = CUDIE (p->cu);
4357   /* Find the base address of the compilation unit.  It will normally
4358      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
4359      address could be overridden by DW_AT_entry_pc.  It's been
4360      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4361      compilation units with discontinuous ranges.  */
4362   if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4363     {
4364       Dwarf_Attribute attr_mem;
4365       if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4366                           &base) != 0)
4367         base = 0;
4368     }
4369   return base;
4370 }
4371
4372 static int
4373 compare_listptr (const void *a, const void *b, void *arg)
4374 {
4375   const char *name = arg;
4376   struct listptr *p1 = (void *) a;
4377   struct listptr *p2 = (void *) b;
4378
4379   if (p1->offset < p2->offset)
4380     return -1;
4381   if (p1->offset > p2->offset)
4382     return 1;
4383
4384   if (!p1->warned && !p2->warned)
4385     {
4386       if (p1->addr64 != p2->addr64)
4387         {
4388           p1->warned = p2->warned = true;
4389           error (0, 0,
4390                  gettext ("%s %#" PRIx64 " used with different address sizes"),
4391                  name, (uint64_t) p1->offset);
4392         }
4393       if (p1->dwarf64 != p2->dwarf64)
4394         {
4395           p1->warned = p2->warned = true;
4396           error (0, 0,
4397                  gettext ("%s %#" PRIx64 " used with different offset sizes"),
4398                  name, (uint64_t) p1->offset);
4399         }
4400       if (listptr_base (p1) != listptr_base (p2))
4401         {
4402           p1->warned = p2->warned = true;
4403           error (0, 0,
4404                  gettext ("%s %#" PRIx64 " used with different base addresses"),
4405                  name, (uint64_t) p1->offset);
4406         }
4407     }
4408
4409   return 0;
4410 }
4411
4412 struct listptr_table
4413 {
4414   size_t n;
4415   size_t alloc;
4416   struct listptr *table;
4417 };
4418
4419 static struct listptr_table known_loclistptr;
4420 static struct listptr_table known_rangelistptr;
4421
4422 static void
4423 reset_listptr (struct listptr_table *table)
4424 {
4425   free (table->table);
4426   table->table = NULL;
4427   table->n = table->alloc = 0;
4428 }
4429
4430 static void
4431 notice_listptr (enum section_e section, struct listptr_table *table,
4432                 uint_fast8_t address_size, uint_fast8_t offset_size,
4433                 struct Dwarf_CU *cu, Dwarf_Off offset)
4434 {
4435   if (print_debug_sections & section)
4436     {
4437       if (table->n == table->alloc)
4438         {
4439           if (table->alloc == 0)
4440             table->alloc = 128;
4441           else
4442             table->alloc *= 2;
4443           table->table = xrealloc (table->table,
4444                                    table->alloc * sizeof table->table[0]);
4445         }
4446
4447       struct listptr *p = &table->table[table->n++];
4448
4449       *p = (struct listptr)
4450         {
4451           .addr64 = address_size == 8,
4452           .dwarf64 = offset_size == 8,
4453           .offset = offset,
4454           .cu = cu
4455         };
4456       assert (p->offset == offset);
4457     }
4458 }
4459
4460 static void
4461 sort_listptr (struct listptr_table *table, const char *name)
4462 {
4463   if (table->n > 0)
4464     qsort_r (table->table, table->n, sizeof table->table[0],
4465              &compare_listptr, (void *) name);
4466 }
4467
4468 static bool
4469 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4470                    uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4471                    Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4472                    unsigned char **readp, unsigned char *endp)
4473 {
4474   if (table->n == 0)
4475     return false;
4476
4477   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4478     ++*idxp;
4479
4480   struct listptr *p = &table->table[*idxp];
4481
4482   if (*idxp == table->n
4483       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4484     {
4485       *readp = endp;
4486       printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
4487               offset);
4488       return true;
4489     }
4490
4491   if (p->offset != (Dwarf_Off) offset)
4492     {
4493       *readp += p->offset - offset;
4494       printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4495               offset, (Dwarf_Off) p->offset - offset);
4496       return true;
4497     }
4498
4499   if (address_sizep != NULL)
4500     *address_sizep = listptr_address_size (p);
4501   if (offset_sizep != NULL)
4502     *offset_sizep = listptr_offset_size (p);
4503   if (base != NULL)
4504     *base = listptr_base (p);
4505   if (cu != NULL)
4506     *cu = p->cu;
4507
4508   return false;
4509 }
4510
4511
4512 static void
4513 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4514                             Ebl *ebl, GElf_Ehdr *ehdr,
4515                             Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4516 {
4517   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4518                           dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4519
4520   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4521                    " [ Code]\n"),
4522           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4523           (uint64_t) shdr->sh_offset);
4524
4525   Dwarf_Off offset = 0;
4526   while (offset < sh_size)
4527     {
4528       printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4529               offset);
4530
4531       while (1)
4532         {
4533           size_t length;
4534           Dwarf_Abbrev abbrev;
4535
4536           int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4537           if (res != 0)
4538             {
4539               if (unlikely (res < 0))
4540                 {
4541                   printf (gettext ("\
4542  *** error while reading abbreviation: %s\n"),
4543                           dwarf_errmsg (-1));
4544                   return;
4545                 }
4546
4547               /* This is the NUL byte at the end of the section.  */
4548               ++offset;
4549               break;
4550             }
4551
4552           /* We know these calls can never fail.  */
4553           unsigned int code = dwarf_getabbrevcode (&abbrev);
4554           unsigned int tag = dwarf_getabbrevtag (&abbrev);
4555           int has_children = dwarf_abbrevhaschildren (&abbrev);
4556
4557           printf (gettext (" [%5u] offset: %" PRId64
4558                            ", children: %s, tag: %s\n"),
4559                   code, (int64_t) offset,
4560                   has_children ? gettext ("yes") : gettext ("no"),
4561                   dwarf_tag_name (tag));
4562
4563           size_t cnt = 0;
4564           unsigned int name;
4565           unsigned int form;
4566           Dwarf_Off enoffset;
4567           while (dwarf_getabbrevattr (&abbrev, cnt,
4568                                       &name, &form, &enoffset) == 0)
4569             {
4570               printf ("          attr: %s, form: %s, offset: %#" PRIx64 "\n",
4571                       dwarf_attr_name (name), dwarf_form_name (form),
4572                       (uint64_t) enoffset);
4573
4574               ++cnt;
4575             }
4576
4577           offset += length;
4578         }
4579     }
4580 }
4581
4582
4583 /* Print content of DWARF .debug_aranges section.  We fortunately do
4584    not have to know a bit about the structure of the section, libdwarf
4585    takes care of it.  */
4586 static void
4587 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4588                                GElf_Shdr *shdr, Dwarf *dbg)
4589 {
4590   Dwarf_Aranges *aranges;
4591   size_t cnt;
4592   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4593     {
4594       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4595              dwarf_errmsg (-1));
4596       return;
4597     }
4598
4599   GElf_Shdr glink_mem;
4600   GElf_Shdr *glink;
4601   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4602   if (glink == NULL)
4603     {
4604       error (0, 0, gettext ("invalid sh_link value in section %Zu"),
4605              elf_ndxscn (scn));
4606       return;
4607     }
4608
4609   printf (ngettext ("\
4610 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4611                     "\
4612 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4613                     cnt),
4614           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4615           (uint64_t) shdr->sh_offset, cnt);
4616
4617   /* Compute floor(log16(cnt)).  */
4618   size_t tmp = cnt;
4619   int digits = 1;
4620   while (tmp >= 16)
4621     {
4622       ++digits;
4623       tmp >>= 4;
4624     }
4625
4626   for (size_t n = 0; n < cnt; ++n)
4627     {
4628       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4629       if (unlikely (runp == NULL))
4630         {
4631           printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4632           return;
4633         }
4634
4635       Dwarf_Addr start;
4636       Dwarf_Word length;
4637       Dwarf_Off offset;
4638
4639       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4640         printf (gettext (" [%*zu] ???\n"), digits, n);
4641       else
4642         printf (gettext (" [%*zu] start: %0#*" PRIx64
4643                          ", length: %5" PRIu64 ", CU DIE offset: %6"
4644                          PRId64 "\n"),
4645                 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4646                 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4647     }
4648 }
4649
4650
4651 /* Print content of DWARF .debug_aranges section.  */
4652 static void
4653 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4654                              Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4655                              GElf_Shdr *shdr, Dwarf *dbg)
4656 {
4657   if (decodedaranges)
4658     {
4659       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4660       return;
4661     }
4662
4663   Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4664
4665   if (unlikely (data == NULL))
4666     {
4667       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4668              elf_errmsg (-1));
4669       return;
4670     }
4671
4672   printf (gettext ("\
4673 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4674           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4675           (uint64_t) shdr->sh_offset);
4676
4677   const unsigned char *readp = data->d_buf;
4678   const unsigned char *readendp = readp + data->d_size;
4679
4680   while (readp < readendp)
4681     {
4682       const unsigned char *hdrstart = readp;
4683       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4684
4685       printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
4686       if (readp + 4 > readendp)
4687         {
4688         invalid_data:
4689           error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4690                  elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4691           return;
4692         }
4693
4694       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4695       unsigned int length_bytes = 4;
4696       if (length == DWARF3_LENGTH_64_BIT)
4697         {
4698           if (readp + 8 > readendp)
4699             goto invalid_data;
4700           length = read_8ubyte_unaligned_inc (dbg, readp);
4701           length_bytes = 8;
4702         }
4703
4704       const unsigned char *nexthdr = readp + length;
4705       printf (gettext ("\n Length:        %6" PRIu64 "\n"),
4706               (uint64_t) length);
4707
4708       if (unlikely ((ptrdiff_t) length > readendp - readp))
4709         goto invalid_data;
4710
4711       if (length == 0)
4712         continue;
4713
4714       if (readp + 2 > readendp)
4715         goto invalid_data;
4716       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4717       printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4718               version);
4719       if (version != 2)
4720         {
4721           error (0, 0, gettext ("unsupported aranges version"));
4722           goto next_table;
4723         }
4724
4725       Dwarf_Word offset;
4726       if (readp + length_bytes > readendp)
4727         goto invalid_data;
4728       if (length_bytes == 8)
4729         offset = read_8ubyte_unaligned_inc (dbg, readp);
4730       else
4731         offset = read_4ubyte_unaligned_inc (dbg, readp);
4732       printf (gettext (" CU offset:     %6" PRIx64 "\n"),
4733               (uint64_t) offset);
4734
4735       if (readp + 1 > readendp)
4736         goto invalid_data;
4737       unsigned int address_size = *readp++;
4738       printf (gettext (" Address size:  %6" PRIu64 "\n"),
4739               (uint64_t) address_size);
4740       if (address_size != 4 && address_size != 8)
4741         {
4742           error (0, 0, gettext ("unsupported address size"));
4743           goto next_table;
4744         }
4745
4746       unsigned int segment_size = *readp++;
4747       printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
4748               (uint64_t) segment_size);
4749       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4750         {
4751           error (0, 0, gettext ("unsupported segment size"));
4752           goto next_table;
4753         }
4754
4755       /* Round the address to the next multiple of 2*address_size.  */
4756       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4757                 % (2 * address_size));
4758
4759       while (readp < nexthdr)
4760         {
4761           Dwarf_Word range_address;
4762           Dwarf_Word range_length;
4763           Dwarf_Word segment = 0;
4764           if (readp + 2 * address_size + segment_size > readendp)
4765             goto invalid_data;
4766           if (address_size == 4)
4767             {
4768               range_address = read_4ubyte_unaligned_inc (dbg, readp);
4769               range_length = read_4ubyte_unaligned_inc (dbg, readp);
4770             }
4771           else
4772             {
4773               range_address = read_8ubyte_unaligned_inc (dbg, readp);
4774               range_length = read_8ubyte_unaligned_inc (dbg, readp);
4775             }
4776
4777           if (segment_size == 4)
4778             segment = read_4ubyte_unaligned_inc (dbg, readp);
4779           else if (segment_size == 8)
4780             segment = read_8ubyte_unaligned_inc (dbg, readp);
4781
4782           if (range_address == 0 && range_length == 0 && segment == 0)
4783             break;
4784
4785           char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4786                                        range_address);
4787           char *e = format_dwarf_addr (dwflmod, address_size,
4788                                        range_address + range_length - 1,
4789                                        range_length);
4790           if (segment_size != 0)
4791             printf (gettext ("   %s..%s (%" PRIx64 ")\n"), b, e,
4792                     (uint64_t) segment);
4793           else
4794             printf (gettext ("   %s..%s\n"), b, e);
4795           free (b);
4796           free (e);
4797         }
4798
4799     next_table:
4800       if (readp != nexthdr)
4801         {
4802           size_t padding = nexthdr - readp;
4803           printf (gettext ("   %Zu padding bytes\n"), padding);
4804           readp = nexthdr;
4805         }
4806     }
4807 }
4808
4809
4810 /* Print content of DWARF .debug_ranges section.  */
4811 static void
4812 print_debug_ranges_section (Dwfl_Module *dwflmod,
4813                             Ebl *ebl, GElf_Ehdr *ehdr,
4814                             Elf_Scn *scn, GElf_Shdr *shdr,
4815                             Dwarf *dbg)
4816 {
4817   Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4818
4819   if (unlikely (data == NULL))
4820     {
4821       error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4822              elf_errmsg (-1));
4823       return;
4824     }
4825
4826   printf (gettext ("\
4827 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4828           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4829           (uint64_t) shdr->sh_offset);
4830
4831   sort_listptr (&known_rangelistptr, "rangelistptr");
4832   size_t listptr_idx = 0;
4833
4834   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4835
4836   bool first = true;
4837   Dwarf_Addr base = 0;
4838   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4839   unsigned char *readp = data->d_buf;
4840   while (readp < endp)
4841     {
4842       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4843
4844       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4845                                       &address_size, NULL, &base, NULL,
4846                                       offset, &readp, endp))
4847         continue;
4848
4849       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4850         {
4851           printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
4852           break;
4853         }
4854
4855       Dwarf_Addr begin;
4856       Dwarf_Addr end;
4857       if (address_size == 8)
4858         {
4859           begin = read_8ubyte_unaligned_inc (dbg, readp);
4860           end = read_8ubyte_unaligned_inc (dbg, readp);
4861         }
4862       else
4863         {
4864           begin = read_4ubyte_unaligned_inc (dbg, readp);
4865           end = read_4ubyte_unaligned_inc (dbg, readp);
4866           if (begin == (Dwarf_Addr) (uint32_t) -1)
4867             begin = (Dwarf_Addr) -1l;
4868         }
4869
4870       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
4871         {
4872           char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4873           printf (gettext (" [%6tx]  base address %s\n"), offset, b);
4874           free (b);
4875           base = end;
4876         }
4877       else if (begin == 0 && end == 0) /* End of list entry.  */
4878         {
4879           if (first)
4880             printf (gettext (" [%6tx]  empty list\n"), offset);
4881           first = true;
4882         }
4883       else
4884         {
4885           char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4886                                        begin);
4887           char *e = format_dwarf_addr (dwflmod, address_size, base + end,
4888                                        end);
4889           /* We have an address range entry.  */
4890           if (first)            /* First address range entry in a list.  */
4891             printf (gettext (" [%6tx]  %s..%s\n"), offset, b, e);
4892           else
4893             printf (gettext ("           %s..%s\n"), b, e);
4894           free (b);
4895           free (e);
4896
4897           first = false;
4898         }
4899     }
4900 }
4901
4902 #define REGNAMESZ 16
4903 static const char *
4904 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
4905                char name[REGNAMESZ], int *bits, int *type)
4906 {
4907   const char *set;
4908   const char *pfx;
4909   int ignore;
4910   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
4911                                  bits ?: &ignore, type ?: &ignore);
4912   if (n <= 0)
4913     {
4914       if (loc != NULL)
4915         snprintf (name, REGNAMESZ, "reg%u", loc->regno);
4916       else
4917         snprintf (name, REGNAMESZ, "??? 0x%x", regno);
4918       if (bits != NULL)
4919         *bits = loc != NULL ? loc->bits : 0;
4920       if (type != NULL)
4921         *type = DW_ATE_unsigned;
4922       set = "??? unrecognized";
4923     }
4924   else
4925     {
4926       if (bits != NULL && *bits <= 0)
4927         *bits = loc != NULL ? loc->bits : 0;
4928       if (type != NULL && *type == DW_ATE_void)
4929         *type = DW_ATE_unsigned;
4930
4931     }
4932   return set;
4933 }
4934
4935 static void
4936 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
4937                    Dwarf_Word vma_base, unsigned int code_align,
4938                    int data_align,
4939                    unsigned int version, unsigned int ptr_size,
4940                    Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
4941 {
4942   char regnamebuf[REGNAMESZ];
4943   const char *regname (unsigned int regno)
4944   {
4945     register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
4946     return regnamebuf;
4947   }
4948
4949   puts ("\n   Program:");
4950   Dwarf_Word pc = vma_base;
4951   while (readp < endp)
4952     {
4953       unsigned int opcode = *readp++;
4954
4955       if (opcode < DW_CFA_advance_loc)
4956         /* Extended opcode.  */
4957         switch (opcode)
4958           {
4959             uint64_t op1;
4960             int64_t sop1;
4961             uint64_t op2;
4962             int64_t sop2;
4963
4964           case DW_CFA_nop:
4965             puts ("     nop");
4966             break;
4967           case DW_CFA_set_loc:
4968             // XXX overflow check
4969             get_uleb128 (op1, readp);
4970             op1 += vma_base;
4971             printf ("     set_loc %" PRIu64 "\n", op1 * code_align);
4972             break;
4973           case DW_CFA_advance_loc1:
4974             printf ("     advance_loc1 %u to %#" PRIx64 "\n",
4975                     *readp, pc += *readp * code_align);
4976             ++readp;
4977             break;
4978           case DW_CFA_advance_loc2:
4979             op1 = read_2ubyte_unaligned_inc (dbg, readp);
4980             printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
4981                     op1, pc += op1 * code_align);
4982             break;
4983           case DW_CFA_advance_loc4:
4984             op1 = read_4ubyte_unaligned_inc (dbg, readp);
4985             printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
4986                     op1, pc += op1 * code_align);
4987             break;
4988           case DW_CFA_offset_extended:
4989             // XXX overflow check
4990             get_uleb128 (op1, readp);
4991             get_uleb128 (op2, readp);
4992             printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
4993                     "\n",
4994                     op1, regname (op1), op2 * data_align);
4995             break;
4996           case DW_CFA_restore_extended:
4997             // XXX overflow check
4998             get_uleb128 (op1, readp);
4999             printf ("     restore_extended r%" PRIu64 " (%s)\n",
5000                     op1, regname (op1));
5001             break;
5002           case DW_CFA_undefined:
5003             // XXX overflow check
5004             get_uleb128 (op1, readp);
5005             printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5006             break;
5007           case DW_CFA_same_value:
5008             // XXX overflow check
5009             get_uleb128 (op1, readp);
5010             printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5011             break;
5012           case DW_CFA_register:
5013             // XXX overflow check
5014             get_uleb128 (op1, readp);
5015             get_uleb128 (op2, readp);
5016             printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5017                     op1, regname (op1), op2, regname (op2));
5018             break;
5019           case DW_CFA_remember_state:
5020             puts ("     remember_state");
5021             break;
5022           case DW_CFA_restore_state:
5023             puts ("     restore_state");
5024             break;
5025           case DW_CFA_def_cfa:
5026             // XXX overflow check
5027             get_uleb128 (op1, readp);
5028             get_uleb128 (op2, readp);
5029             printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5030                     op1, regname (op1), op2);
5031             break;
5032           case DW_CFA_def_cfa_register:
5033             // XXX overflow check
5034             get_uleb128 (op1, readp);
5035             printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
5036                     op1, regname (op1));
5037             break;
5038           case DW_CFA_def_cfa_offset:
5039             // XXX overflow check
5040             get_uleb128 (op1, readp);
5041             printf ("     def_cfa_offset %" PRIu64 "\n", op1);
5042             break;
5043           case DW_CFA_def_cfa_expression:
5044             // XXX overflow check
5045             get_uleb128 (op1, readp);   /* Length of DW_FORM_block.  */
5046             printf ("     def_cfa_expression %" PRIu64 "\n", op1);
5047             if ((uint64_t) (endp - readp) < op1)
5048               {
5049             invalid:
5050                 fputs (gettext ("         <INVALID DATA>\n"), stdout);
5051                 return;
5052               }
5053             print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5054                        op1, readp);
5055             readp += op1;
5056             break;
5057           case DW_CFA_expression:
5058             // XXX overflow check
5059             get_uleb128 (op1, readp);
5060             get_uleb128 (op2, readp);   /* Length of DW_FORM_block.  */
5061             printf ("     expression r%" PRIu64 " (%s) \n",
5062                     op1, regname (op1));
5063             if ((uint64_t) (endp - readp) < op2)
5064               goto invalid;
5065             print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5066                        op2, readp);
5067             readp += op2;
5068             break;
5069           case DW_CFA_offset_extended_sf:
5070             // XXX overflow check
5071             get_uleb128 (op1, readp);
5072             get_sleb128 (sop2, readp);
5073             printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5074                     PRId64 "\n",
5075                     op1, regname (op1), sop2 * data_align);
5076             break;
5077           case DW_CFA_def_cfa_sf:
5078             // XXX overflow check
5079             get_uleb128 (op1, readp);
5080             get_sleb128 (sop2, readp);
5081             printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5082                     op1, regname (op1), sop2 * data_align);
5083             break;
5084           case DW_CFA_def_cfa_offset_sf:
5085             // XXX overflow check
5086             get_sleb128 (sop1, readp);
5087             printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5088             break;
5089           case DW_CFA_val_offset:
5090             // XXX overflow check
5091             get_uleb128 (op1, readp);
5092             get_uleb128 (op2, readp);
5093             printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5094                     op1, op2 * data_align);
5095             break;
5096           case DW_CFA_val_offset_sf:
5097             // XXX overflow check
5098             get_uleb128 (op1, readp);
5099             get_sleb128 (sop2, readp);
5100             printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5101                     op1, sop2 * data_align);
5102             break;
5103           case DW_CFA_val_expression:
5104             // XXX overflow check
5105             get_uleb128 (op1, readp);
5106             get_uleb128 (op2, readp);   /* Length of DW_FORM_block.  */
5107             printf ("     val_expression r%" PRIu64 " (%s)\n",
5108                     op1, regname (op1));
5109             if ((uint64_t) (endp - readp) < op2)
5110               goto invalid;
5111             print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5112                        NULL, op2, readp);
5113             readp += op2;
5114             break;
5115           case DW_CFA_MIPS_advance_loc8:
5116             op1 = read_8ubyte_unaligned_inc (dbg, readp);
5117             printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5118                     op1, pc += op1 * code_align);
5119             break;
5120           case DW_CFA_GNU_window_save:
5121             puts ("     GNU_window_save");
5122             break;
5123           case DW_CFA_GNU_args_size:
5124             // XXX overflow check
5125             get_uleb128 (op1, readp);
5126             printf ("     args_size %" PRIu64 "\n", op1);
5127             break;
5128           default:
5129             printf ("     ??? (%u)\n", opcode);
5130             break;
5131           }
5132       else if (opcode < DW_CFA_offset)
5133         printf ("     advance_loc %u to %#" PRIx64 "\n",
5134                 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5135       else if (opcode < DW_CFA_restore)
5136         {
5137           uint64_t offset;
5138           // XXX overflow check
5139           get_uleb128 (offset, readp);
5140           printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
5141                   opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5142         }
5143       else
5144         printf ("     restore r%u (%s)\n",
5145                 opcode & 0x3f, regname (opcode & 0x3f));
5146     }
5147 }
5148
5149
5150 static unsigned int
5151 encoded_ptr_size (int encoding, unsigned int ptr_size)
5152 {
5153   switch (encoding & 7)
5154     {
5155     case DW_EH_PE_udata4:
5156       return 4;
5157     case DW_EH_PE_udata8:
5158       return 8;
5159     case 0:
5160       return ptr_size;
5161     }
5162
5163   fprintf (stderr, "Unsupported pointer encoding: %#x, "
5164            "assuming pointer size of %d.\n", encoding, ptr_size);
5165   return ptr_size;
5166 }
5167
5168
5169 static unsigned int
5170 print_encoding (unsigned int val)
5171 {
5172   switch (val & 0xf)
5173     {
5174     case DW_EH_PE_absptr:
5175       fputs ("absptr", stdout);
5176       break;
5177     case DW_EH_PE_uleb128:
5178       fputs ("uleb128", stdout);
5179       break;
5180     case DW_EH_PE_udata2:
5181       fputs ("udata2", stdout);
5182       break;
5183     case DW_EH_PE_udata4:
5184       fputs ("udata4", stdout);
5185       break;
5186     case DW_EH_PE_udata8:
5187       fputs ("udata8", stdout);
5188       break;
5189     case DW_EH_PE_sleb128:
5190       fputs ("sleb128", stdout);
5191       break;
5192     case DW_EH_PE_sdata2:
5193       fputs ("sdata2", stdout);
5194       break;
5195     case DW_EH_PE_sdata4:
5196       fputs ("sdata4", stdout);
5197       break;
5198     case DW_EH_PE_sdata8:
5199       fputs ("sdata8", stdout);
5200       break;
5201     default:
5202       /* We did not use any of the bits after all.  */
5203       return val;
5204     }
5205
5206   return val & ~0xf;
5207 }
5208
5209
5210 static unsigned int
5211 print_relinfo (unsigned int val)
5212 {
5213   switch (val & 0x70)
5214     {
5215     case DW_EH_PE_pcrel:
5216       fputs ("pcrel", stdout);
5217       break;
5218     case DW_EH_PE_textrel:
5219       fputs ("textrel", stdout);
5220       break;
5221     case DW_EH_PE_datarel:
5222       fputs ("datarel", stdout);
5223       break;
5224     case DW_EH_PE_funcrel:
5225       fputs ("funcrel", stdout);
5226       break;
5227     case DW_EH_PE_aligned:
5228       fputs ("aligned", stdout);
5229       break;
5230     default:
5231       return val;
5232     }
5233
5234   return val & ~0x70;
5235 }
5236
5237
5238 static void
5239 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5240 {
5241   printf ("(%s", pfx);
5242
5243   if (fde_encoding == DW_EH_PE_omit)
5244     puts ("omit)");
5245   else
5246     {
5247       unsigned int w = fde_encoding;
5248
5249       w = print_encoding (w);
5250
5251       if (w & 0x70)
5252         {
5253           if (w != fde_encoding)
5254             fputc_unlocked (' ', stdout);
5255
5256           w = print_relinfo (w);
5257         }
5258
5259       if (w != 0)
5260         printf ("%s%x", w != fde_encoding ? " " : "", w);
5261
5262       puts (")");
5263     }
5264 }
5265
5266
5267 static const unsigned char *
5268 read_encoded (unsigned int encoding, const unsigned char *readp,
5269               const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5270 {
5271   if ((encoding & 0xf) == DW_EH_PE_absptr)
5272     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5273       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5274
5275   switch (encoding & 0xf)
5276     {
5277     case DW_EH_PE_uleb128:
5278       // XXX buffer overrun check
5279       get_uleb128 (*res, readp);
5280       break;
5281     case DW_EH_PE_sleb128:
5282       // XXX buffer overrun check
5283       get_sleb128 (*res, readp);
5284       break;
5285     case DW_EH_PE_udata2:
5286       if (readp + 2 > endp)
5287         goto invalid;
5288       *res = read_2ubyte_unaligned_inc (dbg, readp);
5289       break;
5290     case DW_EH_PE_udata4:
5291       if (readp + 4 > endp)
5292         goto invalid;
5293       *res = read_4ubyte_unaligned_inc (dbg, readp);
5294       break;
5295     case DW_EH_PE_udata8:
5296       if (readp + 8 > endp)
5297         goto invalid;
5298       *res = read_8ubyte_unaligned_inc (dbg, readp);
5299       break;
5300     case DW_EH_PE_sdata2:
5301       if (readp + 2 > endp)
5302         goto invalid;
5303       *res = read_2sbyte_unaligned_inc (dbg, readp);
5304       break;
5305     case DW_EH_PE_sdata4:
5306       if (readp + 4 > endp)
5307         goto invalid;
5308       *res = read_4sbyte_unaligned_inc (dbg, readp);
5309       break;
5310     case DW_EH_PE_sdata8:
5311       if (readp + 8 > endp)
5312         goto invalid;
5313       *res = read_8sbyte_unaligned_inc (dbg, readp);
5314       break;
5315     default:
5316     invalid:
5317       error (1, 0,
5318              gettext ("invalid encoding"));
5319     }
5320
5321   return readp;
5322 }
5323
5324
5325 static void
5326 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5327                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5328 {
5329   size_t shstrndx;
5330   /* We know this call will succeed since it did in the caller.  */
5331   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5332   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5333
5334   /* Needed if we find PC-relative addresses.  */
5335   GElf_Addr bias;
5336   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5337     {
5338       error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5339       return;
5340     }
5341
5342   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5343   Elf_Data *data = (is_eh_frame
5344                     ? elf_rawdata (scn, NULL)
5345                     : dbg->sectiondata[IDX_debug_frame]);
5346
5347   if (unlikely (data == NULL))
5348     {
5349       error (0, 0, gettext ("cannot get %s content: %s"),
5350              scnname, elf_errmsg (-1));
5351       return;
5352     }
5353
5354   if (is_eh_frame)
5355     printf (gettext ("\
5356 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5357             elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5358   else
5359     printf (gettext ("\
5360 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5361             elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5362
5363   struct cieinfo
5364   {
5365     ptrdiff_t cie_offset;
5366     const char *augmentation;
5367     unsigned int code_alignment_factor;
5368     unsigned int data_alignment_factor;
5369     uint8_t address_size;
5370     uint8_t fde_encoding;
5371     uint8_t lsda_encoding;
5372     struct cieinfo *next;
5373   } *cies = NULL;
5374
5375   const unsigned char *readp = data->d_buf;
5376   const unsigned char *const dataend = ((unsigned char *) data->d_buf
5377                                         + data->d_size);
5378   while (readp < dataend)
5379     {
5380       if (unlikely (readp + 4 > dataend))
5381         {
5382         invalid_data:
5383           error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5384                      elf_ndxscn (scn), scnname);
5385               return;
5386         }
5387
5388       /* At the beginning there must be a CIE.  There can be multiple,
5389          hence we test tis in a loop.  */
5390       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5391
5392       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5393       unsigned int length = 4;
5394       if (unlikely (unit_length == 0xffffffff))
5395         {
5396           if (unlikely (readp + 8 > dataend))
5397             goto invalid_data;
5398
5399           unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5400           length = 8;
5401         }
5402
5403       if (unlikely (unit_length == 0))
5404         {
5405           printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5406           continue;
5407         }
5408
5409       Dwarf_Word maxsize = dataend - readp;
5410       if (unlikely (unit_length > maxsize))
5411         goto invalid_data;
5412
5413       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5414
5415       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5416       const unsigned char *const cieend = readp + unit_length;
5417       if (unlikely (cieend > dataend || readp + 8 > dataend))
5418         goto invalid_data;
5419
5420       Dwarf_Off cie_id;
5421       if (length == 4)
5422         {
5423           cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5424           if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5425             cie_id = DW_CIE_ID_64;
5426         }
5427       else
5428         cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5429
5430       uint_fast8_t version = 2;
5431       unsigned int code_alignment_factor;
5432       int data_alignment_factor;
5433       unsigned int fde_encoding = 0;
5434       unsigned int lsda_encoding = 0;
5435       Dwarf_Word initial_location = 0;
5436       Dwarf_Word vma_base = 0;
5437
5438       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5439         {
5440           version = *readp++;
5441           const char *const augmentation = (const char *) readp;
5442           readp = memchr (readp, '\0', cieend - readp);
5443           if (unlikely (readp == NULL))
5444             goto invalid_data;
5445           ++readp;
5446
5447           uint_fast8_t segment_size = 0;
5448           if (version >= 4)
5449             {
5450               if (cieend - readp < 5)
5451                 goto invalid_data;
5452               ptr_size = *readp++;
5453               segment_size = *readp++;
5454             }
5455
5456           // XXX Check overflow
5457           get_uleb128 (code_alignment_factor, readp);
5458           // XXX Check overflow
5459           get_sleb128 (data_alignment_factor, readp);
5460
5461           /* In some variant for unwind data there is another field.  */
5462           if (strcmp (augmentation, "eh") == 0)
5463             readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5464
5465           unsigned int return_address_register;
5466           if (unlikely (version == 1))
5467             return_address_register = *readp++;
5468           else
5469             // XXX Check overflow
5470             get_uleb128 (return_address_register, readp);
5471
5472           printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5473                   "   CIE_id:                   %" PRIu64 "\n"
5474                   "   version:                  %u\n"
5475                   "   augmentation:             \"%s\"\n",
5476                   offset, (uint64_t) unit_length, (uint64_t) cie_id,
5477                   version, augmentation);
5478           if (version >= 4)
5479             printf ("   address_size:             %u\n"
5480                     "   segment_size:             %u\n",
5481                     ptr_size, segment_size);
5482           printf ("   code_alignment_factor:    %u\n"
5483                   "   data_alignment_factor:    %d\n"
5484                   "   return_address_register:  %u\n",
5485                   code_alignment_factor,
5486                   data_alignment_factor, return_address_register);
5487
5488           if (augmentation[0] == 'z')
5489             {
5490               unsigned int augmentationlen;
5491               get_uleb128 (augmentationlen, readp);
5492
5493               if (augmentationlen > (size_t) (dataend - readp))
5494                 {
5495                   error (0, 0, gettext ("invalid augmentation length"));
5496                   readp = cieend;
5497                   continue;
5498                 }
5499
5500               const char *hdr = "Augmentation data:";
5501               const char *cp = augmentation + 1;
5502               while (*cp != '\0')
5503                 {
5504                   printf ("   %-26s%#x ", hdr, *readp);
5505                   hdr = "";
5506
5507                   if (*cp == 'R')
5508                     {
5509                       fde_encoding = *readp++;
5510                       print_encoding_base (gettext ("FDE address encoding: "),
5511                                            fde_encoding);
5512                     }
5513                   else if (*cp == 'L')
5514                     {
5515                       lsda_encoding = *readp++;
5516                       print_encoding_base (gettext ("LSDA pointer encoding: "),
5517                                            lsda_encoding);
5518                     }
5519                   else if (*cp == 'P')
5520                     {
5521                       /* Personality.  This field usually has a relocation
5522                          attached pointing to __gcc_personality_v0.  */
5523                       const unsigned char *startp = readp;
5524                       unsigned int encoding = *readp++;
5525                       uint64_t val = 0;
5526                       readp = read_encoded (encoding, readp,
5527                                             readp - 1 + augmentationlen,
5528                                             &val, dbg);
5529
5530                       while (++startp < readp)
5531                         printf ("%#x ", *startp);
5532
5533                       putchar ('(');
5534                       print_encoding (encoding);
5535                       putchar (' ');
5536                       switch (encoding & 0xf)
5537                         {
5538                         case DW_EH_PE_sleb128:
5539                         case DW_EH_PE_sdata2:
5540                         case DW_EH_PE_sdata4:
5541                           printf ("%" PRId64 ")\n", val);
5542                           break;
5543                         default:
5544                           printf ("%#" PRIx64 ")\n", val);
5545                           break;
5546                         }
5547                     }
5548                   else
5549                     printf ("(%x)\n", *readp++);
5550
5551                   ++cp;
5552                 }
5553             }
5554
5555           if (likely (ptr_size == 4 || ptr_size == 8))
5556             {
5557               struct cieinfo *newp = alloca (sizeof (*newp));
5558               newp->cie_offset = offset;
5559               newp->augmentation = augmentation;
5560               newp->fde_encoding = fde_encoding;
5561               newp->lsda_encoding = lsda_encoding;
5562               newp->address_size = ptr_size;
5563               newp->code_alignment_factor = code_alignment_factor;
5564               newp->data_alignment_factor = data_alignment_factor;
5565               newp->next = cies;
5566               cies = newp;
5567             }
5568         }
5569       else
5570         {
5571           struct cieinfo *cie = cies;
5572           while (cie != NULL)
5573             if (is_eh_frame
5574                 ? start - (ptrdiff_t) cie_id == cie->cie_offset
5575                 : (ptrdiff_t) cie_id == cie->cie_offset)
5576               break;
5577             else
5578               cie = cie->next;
5579           if (unlikely (cie == NULL))
5580             {
5581               puts ("invalid CIE reference in FDE");
5582               return;
5583             }
5584
5585           /* Initialize from CIE data.  */
5586           fde_encoding = cie->fde_encoding;
5587           lsda_encoding = cie->lsda_encoding;
5588           ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5589           code_alignment_factor = cie->code_alignment_factor;
5590           data_alignment_factor = cie->data_alignment_factor;
5591
5592           const unsigned char *base = readp;
5593           // XXX There are sometimes relocations for this value
5594           initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5595           Dwarf_Word address_range
5596             = read_addr_unaligned_inc (ptr_size, dbg, readp);
5597
5598           /* pcrel for an FDE address is relative to the runtime
5599              address of the start_address field itself.  Sign extend
5600              if necessary to make sure the calculation is done on the
5601              full 64 bit address even when initial_location only holds
5602              the lower 32 bits.  */
5603           Dwarf_Addr pc_start = initial_location;
5604           if (ptr_size == 4)
5605             pc_start = (uint64_t) (int32_t) pc_start;
5606           if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5607             pc_start += ((uint64_t) shdr->sh_addr
5608                          + (base - (const unsigned char *) data->d_buf)
5609                          - bias);
5610
5611           char *a = format_dwarf_addr (dwflmod, cie->address_size,
5612                                        pc_start, initial_location);
5613           printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5614                   "   CIE_pointer:              %" PRIu64 "\n"
5615                   "   initial_location:         %s",
5616                   offset, (uint64_t) unit_length,
5617                   cie->cie_offset, (uint64_t) cie_id, a);
5618           free (a);
5619           if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5620             {
5621               vma_base = (((uint64_t) shdr->sh_offset
5622                            + (base - (const unsigned char *) data->d_buf)
5623                            + (uint64_t) initial_location)
5624                           & (ptr_size == 4
5625                              ? UINT64_C (0xffffffff)
5626                              : UINT64_C (0xffffffffffffffff)));
5627               printf (gettext (" (offset: %#" PRIx64 ")"),
5628                       (uint64_t) vma_base);
5629             }
5630
5631           printf ("\n   address_range:            %#" PRIx64,
5632                   (uint64_t) address_range);
5633           if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5634             printf (gettext (" (end offset: %#" PRIx64 ")"),
5635                     ((uint64_t) vma_base + (uint64_t) address_range)
5636                     & (ptr_size == 4
5637                        ? UINT64_C (0xffffffff)
5638                        : UINT64_C (0xffffffffffffffff)));
5639           putchar ('\n');
5640
5641           if (cie->augmentation[0] == 'z')
5642             {
5643               unsigned int augmentationlen;
5644               get_uleb128 (augmentationlen, readp);
5645
5646               if (augmentationlen > (size_t) (dataend - readp))
5647                 {
5648                   error (0, 0, gettext ("invalid augmentation length"));
5649                   readp = cieend;
5650                   continue;
5651                 }
5652
5653               if (augmentationlen > 0)
5654                 {
5655                   const char *hdr = "Augmentation data:";
5656                   const char *cp = cie->augmentation + 1;
5657                   unsigned int u = 0;
5658                   while (*cp != '\0')
5659                     {
5660                       if (*cp == 'L')
5661                         {
5662                           uint64_t lsda_pointer;
5663                           const unsigned char *p
5664                             = read_encoded (lsda_encoding, &readp[u],
5665                                             &readp[augmentationlen],
5666                                             &lsda_pointer, dbg);
5667                           u = p - readp;
5668                           printf (gettext ("\
5669    %-26sLSDA pointer: %#" PRIx64 "\n"),
5670                                   hdr, lsda_pointer);
5671                           hdr = "";
5672                         }
5673                       ++cp;
5674                     }
5675
5676                   while (u < augmentationlen)
5677                     {
5678                       printf ("   %-26s%#x\n", hdr, readp[u++]);
5679                       hdr = "";
5680                     }
5681                 }
5682
5683               readp += augmentationlen;
5684             }
5685         }
5686
5687       /* Handle the initialization instructions.  */
5688       if (ptr_size != 4 && ptr_size !=8)
5689         printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5690       else
5691         print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5692                            data_alignment_factor, version, ptr_size,
5693                            dwflmod, ebl, dbg);
5694       readp = cieend;
5695     }
5696 }
5697
5698
5699 struct attrcb_args
5700 {
5701   Dwfl_Module *dwflmod;
5702   Dwarf *dbg;
5703   Dwarf_Die *die;
5704   int level;
5705   bool silent;
5706   unsigned int version;
5707   unsigned int addrsize;
5708   unsigned int offset_size;
5709   struct Dwarf_CU *cu;
5710 };
5711
5712
5713 static int
5714 attr_callback (Dwarf_Attribute *attrp, void *arg)
5715 {
5716   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5717   const int level = cbargs->level;
5718
5719   unsigned int attr = dwarf_whatattr (attrp);
5720   if (unlikely (attr == 0))
5721     {
5722       if (!cbargs->silent)
5723         error (0, 0, gettext ("cannot get attribute code: %s"),
5724                dwarf_errmsg (-1));
5725       return DWARF_CB_ABORT;
5726     }
5727
5728   unsigned int form = dwarf_whatform (attrp);
5729   if (unlikely (form == 0))
5730     {
5731       if (!cbargs->silent)
5732         error (0, 0, gettext ("cannot get attribute form: %s"),
5733                dwarf_errmsg (-1));
5734       return DWARF_CB_ABORT;
5735     }
5736
5737   switch (form)
5738     {
5739     case DW_FORM_addr:
5740       if (!cbargs->silent)
5741         {
5742           Dwarf_Addr addr;
5743           if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5744             {
5745             attrval_out:
5746               if (!cbargs->silent)
5747                 error (0, 0, gettext ("cannot get attribute value: %s"),
5748                        dwarf_errmsg (-1));
5749               return DWARF_CB_ABORT;
5750             }
5751           char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5752                                        addr, addr);
5753           printf ("           %*s%-20s (%s) %s\n",
5754                   (int) (level * 2), "", dwarf_attr_name (attr),
5755                   dwarf_form_name (form), a);
5756           free (a);
5757         }
5758       break;
5759
5760     case DW_FORM_indirect:
5761     case DW_FORM_strp:
5762     case DW_FORM_string:
5763     case DW_FORM_GNU_strp_alt:
5764       if (cbargs->silent)
5765         break;
5766       const char *str = dwarf_formstring (attrp);
5767       if (unlikely (str == NULL))
5768         goto attrval_out;
5769       printf ("           %*s%-20s (%s) \"%s\"\n",
5770               (int) (level * 2), "", dwarf_attr_name (attr),
5771               dwarf_form_name (form), str);
5772       break;
5773
5774     case DW_FORM_ref_addr:
5775     case DW_FORM_ref_udata:
5776     case DW_FORM_ref8:
5777     case DW_FORM_ref4:
5778     case DW_FORM_ref2:
5779     case DW_FORM_ref1:
5780     case DW_FORM_GNU_ref_alt:
5781       if (cbargs->silent)
5782         break;
5783       Dwarf_Die ref;
5784       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5785         goto attrval_out;
5786
5787       printf ("           %*s%-20s (%s) [%6" PRIxMAX "]\n",
5788               (int) (level * 2), "", dwarf_attr_name (attr),
5789               dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5790       break;
5791
5792     case DW_FORM_ref_sig8:
5793       if (cbargs->silent)
5794         break;
5795       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
5796               (int) (level * 2), "", dwarf_attr_name (attr),
5797               dwarf_form_name (form),
5798               (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5799       break;
5800
5801     case DW_FORM_sec_offset:
5802     case DW_FORM_udata:
5803     case DW_FORM_sdata:
5804     case DW_FORM_data8:
5805     case DW_FORM_data4:
5806     case DW_FORM_data2:
5807     case DW_FORM_data1:;
5808       Dwarf_Word num;
5809       if (unlikely (dwarf_formudata (attrp, &num) != 0))
5810         goto attrval_out;
5811
5812       const char *valuestr = NULL;
5813       switch (attr)
5814         {
5815           /* This case can take either a constant or a loclistptr.  */
5816         case DW_AT_data_member_location:
5817           if (form != DW_FORM_sec_offset
5818               && (cbargs->version >= 4
5819                   || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5820             {
5821               if (!cbargs->silent)
5822                 printf ("           %*s%-20s (%s) %" PRIxMAX "\n",
5823                         (int) (level * 2), "", dwarf_attr_name (attr),
5824                         dwarf_form_name (form), (uintmax_t) num);
5825               return DWARF_CB_OK;
5826             }
5827           /* else fallthrough */
5828
5829         /* These cases always take a loclistptr and no constant. */
5830         case DW_AT_location:
5831         case DW_AT_data_location:
5832         case DW_AT_vtable_elem_location:
5833         case DW_AT_string_length:
5834         case DW_AT_use_location:
5835         case DW_AT_frame_base:
5836         case DW_AT_return_addr:
5837         case DW_AT_static_link:
5838         case DW_AT_GNU_call_site_value:
5839         case DW_AT_GNU_call_site_data_value:
5840         case DW_AT_GNU_call_site_target:
5841         case DW_AT_GNU_call_site_target_clobbered:
5842           notice_listptr (section_loc, &known_loclistptr,
5843                           cbargs->addrsize, cbargs->offset_size,
5844                           cbargs->cu, num);
5845           if (!cbargs->silent)
5846             printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
5847                     (int) (level * 2), "", dwarf_attr_name (attr),
5848                     dwarf_form_name (form), (uintmax_t) num);
5849           return DWARF_CB_OK;
5850
5851         case DW_AT_ranges:
5852           notice_listptr (section_ranges, &known_rangelistptr,
5853                           cbargs->addrsize, cbargs->offset_size,
5854                           cbargs->cu, num);
5855           if (!cbargs->silent)
5856             printf ("           %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
5857                     (int) (level * 2), "", dwarf_attr_name (attr),
5858                     dwarf_form_name (form), (uintmax_t) num);
5859           return DWARF_CB_OK;
5860
5861         case DW_AT_language:
5862           valuestr = dwarf_lang_name (num);
5863           break;
5864         case DW_AT_encoding:
5865           valuestr = dwarf_encoding_name (num);
5866           break;
5867         case DW_AT_accessibility:
5868           valuestr = dwarf_access_name (num);
5869           break;
5870         case DW_AT_visibility:
5871           valuestr = dwarf_visibility_name (num);
5872           break;
5873         case DW_AT_virtuality:
5874           valuestr = dwarf_virtuality_name (num);
5875           break;
5876         case DW_AT_identifier_case:
5877           valuestr = dwarf_identifier_case_name (num);
5878           break;
5879         case DW_AT_calling_convention:
5880           valuestr = dwarf_calling_convention_name (num);
5881           break;
5882         case DW_AT_inline:
5883           valuestr = dwarf_inline_name (num);
5884           break;
5885         case DW_AT_ordering:
5886           valuestr = dwarf_ordering_name (num);
5887           break;
5888         case DW_AT_discr_list:
5889           valuestr = dwarf_discr_list_name (num);
5890           break;
5891         default:
5892           /* Nothing.  */
5893           break;
5894         }
5895
5896       if (cbargs->silent)
5897         break;
5898
5899       /* When highpc is in constant form it is relative to lowpc.
5900          In that case also show the address.  */
5901       Dwarf_Addr highpc;
5902       if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
5903         {
5904           char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5905                                        highpc, highpc);
5906           printf ("           %*s%-20s (%s) %" PRIuMAX " (%s)\n",
5907                   (int) (level * 2), "", dwarf_attr_name (attr),
5908                   dwarf_form_name (form), (uintmax_t) num, a);
5909           free (a);
5910         }
5911       else
5912         {
5913           Dwarf_Sword snum = 0;
5914           if (form == DW_FORM_sdata)
5915             if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
5916               goto attrval_out;
5917
5918           if (valuestr == NULL)
5919             {
5920               printf ("           %*s%-20s (%s)",
5921                       (int) (level * 2), "", dwarf_attr_name (attr),
5922                       dwarf_form_name (form));
5923               if (form == DW_FORM_sdata)
5924                 printf (" %" PRIdMAX "\n", (intmax_t) snum);
5925               else
5926                 printf (" %" PRIuMAX "\n", (uintmax_t) num);
5927             }
5928           else
5929             {
5930               printf ("           %*s%-20s (%s) %s",
5931                       (int) (level * 2), "", dwarf_attr_name (attr),
5932                       dwarf_form_name (form), valuestr);
5933               if (form == DW_FORM_sdata)
5934                 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
5935               else
5936                 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
5937             }
5938         }
5939       break;
5940
5941     case DW_FORM_flag:
5942       if (cbargs->silent)
5943         break;
5944       bool flag;
5945       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
5946         goto attrval_out;
5947
5948       printf ("           %*s%-20s (%s) %s\n",
5949               (int) (level * 2), "", dwarf_attr_name (attr),
5950               dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
5951       break;
5952
5953     case DW_FORM_flag_present:
5954       if (cbargs->silent)
5955         break;
5956       printf ("           %*s%-20s (%s) %s\n",
5957               (int) (level * 2), "", dwarf_attr_name (attr),
5958               dwarf_form_name (form), nl_langinfo (YESSTR));
5959       break;
5960
5961     case DW_FORM_exprloc:
5962     case DW_FORM_block4:
5963     case DW_FORM_block2:
5964     case DW_FORM_block1:
5965     case DW_FORM_block:
5966       if (cbargs->silent)
5967         break;
5968       Dwarf_Block block;
5969       if (unlikely (dwarf_formblock (attrp, &block) != 0))
5970         goto attrval_out;
5971
5972       printf ("           %*s%-20s (%s) ",
5973               (int) (level * 2), "", dwarf_attr_name (attr),
5974               dwarf_form_name (form));
5975
5976       switch (attr)
5977         {
5978         default:
5979           if (form != DW_FORM_exprloc)
5980             {
5981               print_block (block.length, block.data);
5982               break;
5983             }
5984           /* Fall through.  */
5985
5986         case DW_AT_location:
5987         case DW_AT_data_location:
5988         case DW_AT_data_member_location:
5989         case DW_AT_vtable_elem_location:
5990         case DW_AT_string_length:
5991         case DW_AT_use_location:
5992         case DW_AT_frame_base:
5993         case DW_AT_return_addr:
5994         case DW_AT_static_link:
5995         case DW_AT_allocated:
5996         case DW_AT_associated:
5997         case DW_AT_bit_size:
5998         case DW_AT_bit_offset:
5999         case DW_AT_bit_stride:
6000         case DW_AT_byte_size:
6001         case DW_AT_byte_stride:
6002         case DW_AT_count:
6003         case DW_AT_lower_bound:
6004         case DW_AT_upper_bound:
6005         case DW_AT_GNU_call_site_value:
6006         case DW_AT_GNU_call_site_data_value:
6007         case DW_AT_GNU_call_site_target:
6008         case DW_AT_GNU_call_site_target_clobbered:
6009           putchar ('\n');
6010           print_ops (cbargs->dwflmod, cbargs->dbg,
6011                      12 + level * 2, 12 + level * 2,
6012                      cbargs->version, cbargs->addrsize, cbargs->offset_size,
6013                      attrp->cu, block.length, block.data);
6014           break;
6015         }
6016       break;
6017
6018     default:
6019       if (cbargs->silent)
6020         break;
6021       printf ("           %*s%-20s (form: %#x) ???\n",
6022               (int) (level * 2), "", dwarf_attr_name (attr),
6023               (int) form);
6024       break;
6025     }
6026
6027   return DWARF_CB_OK;
6028 }
6029
6030 static void
6031 print_debug_units (Dwfl_Module *dwflmod,
6032                    Ebl *ebl, GElf_Ehdr *ehdr,
6033                    Elf_Scn *scn, GElf_Shdr *shdr,
6034                    Dwarf *dbg, bool debug_types)
6035 {
6036   const bool silent = !(print_debug_sections & section_info);
6037   const char *secname = section_name (ebl, ehdr, shdr);
6038
6039   if (!silent)
6040     printf (gettext ("\
6041 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6042             elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6043
6044   /* If the section is empty we don't have to do anything.  */
6045   if (!silent && shdr->sh_size == 0)
6046     return;
6047
6048   int maxdies = 20;
6049   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6050
6051   Dwarf_Off offset = 0;
6052
6053   /* New compilation unit.  */
6054   size_t cuhl;
6055   Dwarf_Half version;
6056   Dwarf_Off abbroffset;
6057   uint8_t addrsize;
6058   uint8_t offsize;
6059   Dwarf_Off nextcu;
6060   uint64_t typesig;
6061   Dwarf_Off typeoff;
6062  next_cu:
6063   if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6064                        &abbroffset, &addrsize, &offsize,
6065                        debug_types ? &typesig : NULL,
6066                        debug_types ? &typeoff : NULL) != 0)
6067     goto do_return;
6068
6069   if (!silent)
6070     {
6071       if (debug_types)
6072         printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6073                          " Version: %" PRIu16 ", Abbreviation section offset: %"
6074                          PRIu64 ", Address size: %" PRIu8
6075                          ", Offset size: %" PRIu8
6076                          "\n Type signature: %#" PRIx64
6077                          ", Type offset: %#" PRIx64 "\n"),
6078                 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6079                 typesig, (uint64_t) typeoff);
6080       else
6081         printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6082                          " Version: %" PRIu16 ", Abbreviation section offset: %"
6083                          PRIu64 ", Address size: %" PRIu8
6084                          ", Offset size: %" PRIu8 "\n"),
6085                 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6086     }
6087
6088   struct attrcb_args args =
6089     {
6090       .dwflmod = dwflmod,
6091       .dbg = dbg,
6092       .silent = silent,
6093       .version = version,
6094       .addrsize = addrsize,
6095       .offset_size = offsize
6096     };
6097
6098   offset += cuhl;
6099
6100   int level = 0;
6101
6102   if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6103                 (dbg, offset, &dies[level]) == NULL))
6104     {
6105       if (!silent)
6106         error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6107                               " in section '%s': %s"),
6108                (uint64_t) offset, secname, dwarf_errmsg (-1));
6109       goto do_return;
6110     }
6111
6112   args.cu = dies[0].cu;
6113
6114   do
6115     {
6116       offset = dwarf_dieoffset (&dies[level]);
6117       if (unlikely (offset == ~0ul))
6118         {
6119           if (!silent)
6120             error (0, 0, gettext ("cannot get DIE offset: %s"),
6121                    dwarf_errmsg (-1));
6122           goto do_return;
6123         }
6124
6125       int tag = dwarf_tag (&dies[level]);
6126       if (unlikely (tag == DW_TAG_invalid))
6127         {
6128           if (!silent)
6129             error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6130                                   " in section '%s': %s"),
6131                    (uint64_t) offset, secname, dwarf_errmsg (-1));
6132           goto do_return;
6133         }
6134
6135       if (!silent)
6136         printf (" [%6" PRIx64 "]  %*s%s\n",
6137                 (uint64_t) offset, (int) (level * 2), "",
6138                 dwarf_tag_name (tag));
6139
6140       /* Print the attribute values.  */
6141       args.level = level;
6142       args.die = &dies[level];
6143       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6144
6145       /* Make room for the next level's DIE.  */
6146       if (level + 1 == maxdies)
6147         dies = (Dwarf_Die *) xrealloc (dies,
6148                                        (maxdies += 10)
6149                                        * sizeof (Dwarf_Die));
6150
6151       int res = dwarf_child (&dies[level], &dies[level + 1]);
6152       if (res > 0)
6153         {
6154           while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6155             if (level-- == 0)
6156               break;
6157
6158           if (unlikely (res == -1))
6159             {
6160               if (!silent)
6161                 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6162                        dwarf_errmsg (-1));
6163               goto do_return;
6164             }
6165         }
6166       else if (unlikely (res < 0))
6167         {
6168           if (!silent)
6169             error (0, 0, gettext ("cannot get next DIE: %s"),
6170                    dwarf_errmsg (-1));
6171           goto do_return;
6172         }
6173       else
6174         ++level;
6175     }
6176   while (level >= 0);
6177
6178   offset = nextcu;
6179   if (offset != 0)
6180      goto next_cu;
6181
6182  do_return:
6183   free (dies);
6184 }
6185
6186 static void
6187 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6188                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6189 {
6190   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6191 }
6192
6193 static void
6194 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6195                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6196 {
6197   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6198 }
6199
6200
6201 static void
6202 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6203                             Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6204 {
6205   printf (gettext ("\
6206 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6207           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6208           (uint64_t) shdr->sh_offset);
6209
6210   size_t address_size
6211     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6212
6213   Dwarf_Off cuoffset;
6214   Dwarf_Off ncuoffset = 0;
6215   size_t hsize;
6216   while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6217                        NULL, NULL, NULL) == 0)
6218     {
6219       Dwarf_Die cudie;
6220       if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6221         continue;
6222
6223       size_t nlines;
6224       Dwarf_Lines *lines;
6225       if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6226         continue;
6227
6228       printf (" CU [%" PRIx64 "] %s\n",
6229               dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6230       printf ("  line:col SBPE* disc isa op address"
6231               " (Statement Block Prologue Epilogue *End)\n");
6232       const char *last_file = "";
6233       for (size_t n = 0; n < nlines; n++)
6234         {
6235           Dwarf_Line *line = dwarf_onesrcline (lines, n);
6236           Dwarf_Word mtime, length;
6237           const char *file = dwarf_linesrc (line, &mtime, &length);
6238           if (strcmp (last_file, file) != 0)
6239             {
6240               printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6241                       file, mtime, length);
6242               last_file = file;
6243             }
6244
6245           int lineno, colno;
6246           bool statement, endseq, block, prologue_end, epilogue_begin;
6247           unsigned int lineop, isa, disc;
6248           Dwarf_Addr address;
6249           dwarf_lineaddr (line, &address);
6250           dwarf_lineno (line, &lineno);
6251           dwarf_linecol (line, &colno);
6252           dwarf_lineop_index (line, &lineop);
6253           dwarf_linebeginstatement (line, &statement);
6254           dwarf_lineendsequence (line, &endseq);
6255           dwarf_lineblock (line, &block);
6256           dwarf_lineprologueend (line, &prologue_end);
6257           dwarf_lineepiloguebegin (line, &epilogue_begin);
6258           dwarf_lineisa (line, &isa);
6259           dwarf_linediscriminator (line, &disc);
6260
6261           /* End sequence is special, it is one byte past.  */
6262           char *a = format_dwarf_addr (dwflmod, address_size,
6263                                        address - (endseq ? 1 : 0), address);
6264           printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6265                   lineno, colno,
6266                   (statement ? 'S' : ' '),
6267                   (block ? 'B' : ' '),
6268                   (prologue_end ? 'P' : ' '),
6269                   (epilogue_begin ? 'E' : ' '),
6270                   (endseq ? '*' : ' '),
6271                   disc, isa, lineop, a);
6272           free (a);
6273
6274           if (endseq)
6275             printf("\n");
6276         }
6277     }
6278 }
6279
6280
6281 static void
6282 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6283                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6284 {
6285   if (decodedline)
6286     {
6287       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6288       return;
6289     }
6290
6291   printf (gettext ("\
6292 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6293           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6294           (uint64_t) shdr->sh_offset);
6295
6296   if (shdr->sh_size == 0)
6297     return;
6298
6299   /* There is no functionality in libdw to read the information in the
6300      way it is represented here.  Hardcode the decoder.  */
6301   Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6302   if (unlikely (data == NULL || data->d_buf == NULL))
6303     {
6304       error (0, 0, gettext ("cannot get line data section data: %s"),
6305              elf_errmsg (-1));
6306       return;
6307     }
6308
6309   const unsigned char *linep = (const unsigned char *) data->d_buf;
6310   const unsigned char *lineendp;
6311
6312   while (linep
6313          < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6314     {
6315       size_t start_offset = linep - (const unsigned char *) data->d_buf;
6316
6317       printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
6318
6319       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6320       unsigned int length = 4;
6321       if (unlikely (unit_length == 0xffffffff))
6322         {
6323           if (unlikely (linep + 8 > lineendp))
6324             {
6325             invalid_data:
6326               error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6327                      elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6328               return;
6329             }
6330           unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6331           length = 8;
6332         }
6333
6334       /* Check whether we have enough room in the section.  */
6335       if (unit_length < 2 + length + 5 * 1
6336           || unlikely (linep + unit_length > lineendp))
6337         goto invalid_data;
6338       lineendp = linep + unit_length;
6339
6340       /* The next element of the header is the version identifier.  */
6341       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6342
6343       /* Next comes the header length.  */
6344       Dwarf_Word header_length;
6345       if (length == 4)
6346         header_length = read_4ubyte_unaligned_inc (dbg, linep);
6347       else
6348         header_length = read_8ubyte_unaligned_inc (dbg, linep);
6349       //const unsigned char *header_start = linep;
6350
6351       /* Next the minimum instruction length.  */
6352       uint_fast8_t minimum_instr_len = *linep++;
6353
6354       /* Next the maximum operations per instruction, in version 4 format.  */
6355       uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6356
6357         /* Then the flag determining the default value of the is_stmt
6358            register.  */
6359       uint_fast8_t default_is_stmt = *linep++;
6360
6361       /* Now the line base.  */
6362       int_fast8_t line_base = *((const int_fast8_t *) linep);
6363       ++linep;
6364
6365       /* And the line range.  */
6366       uint_fast8_t line_range = *linep++;
6367
6368       /* The opcode base.  */
6369       uint_fast8_t opcode_base = *linep++;
6370
6371       /* Print what we got so far.  */
6372       printf (gettext ("\n"
6373                        " Length:                     %" PRIu64 "\n"
6374                        " DWARF version:              %" PRIuFAST16 "\n"
6375                        " Prologue length:            %" PRIu64 "\n"
6376                        " Minimum instruction length: %" PRIuFAST8 "\n"
6377                        " Maximum operations per instruction: %" PRIuFAST8 "\n"
6378                        " Initial value if '%s': %" PRIuFAST8 "\n"
6379                        " Line base:                  %" PRIdFAST8 "\n"
6380                        " Line range:                 %" PRIuFAST8 "\n"
6381                        " Opcode base:                %" PRIuFAST8 "\n"
6382                        "\n"
6383                        "Opcodes:\n"),
6384               (uint64_t) unit_length, version, (uint64_t) header_length,
6385               minimum_instr_len, max_ops_per_instr,
6386               "is_stmt", default_is_stmt, line_base,
6387               line_range, opcode_base);
6388
6389       if (unlikely (linep + opcode_base - 1 >= lineendp))
6390         {
6391         invalid_unit:
6392           error (0, 0,
6393                  gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6394                  linep - (const unsigned char *) data->d_buf,
6395                  elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6396           linep = lineendp;
6397           continue;
6398         }
6399       int opcode_base_l10 = 1;
6400       unsigned int tmp = opcode_base;
6401       while (tmp > 10)
6402         {
6403           tmp /= 10;
6404           ++opcode_base_l10;
6405         }
6406       const uint8_t *standard_opcode_lengths = linep - 1;
6407       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6408         printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
6409                           "  [%*" PRIuFAST8 "]  %hhu arguments\n",
6410                           (int) linep[cnt - 1]),
6411                 opcode_base_l10, cnt, linep[cnt - 1]);
6412       linep += opcode_base - 1;
6413       if (unlikely (linep >= lineendp))
6414         goto invalid_unit;
6415
6416       puts (gettext ("\nDirectory table:"));
6417       while (*linep != 0)
6418         {
6419           unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6420           if (unlikely (endp == NULL))
6421             goto invalid_unit;
6422
6423           printf (" %s\n", (char *) linep);
6424
6425           linep = endp + 1;
6426         }
6427       /* Skip the final NUL byte.  */
6428       ++linep;
6429
6430       if (unlikely (linep >= lineendp))
6431         goto invalid_unit;
6432       puts (gettext ("\nFile name table:\n"
6433                      " Entry Dir   Time      Size      Name"));
6434       for (unsigned int cnt = 1; *linep != 0; ++cnt)
6435         {
6436           /* First comes the file name.  */
6437           char *fname = (char *) linep;
6438           unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6439           if (unlikely (endp == NULL))
6440             goto invalid_unit;
6441           linep = endp + 1;
6442
6443           /* Then the index.  */
6444           unsigned int diridx;
6445           get_uleb128 (diridx, linep);
6446
6447           /* Next comes the modification time.  */
6448           unsigned int mtime;
6449           get_uleb128 (mtime, linep);
6450
6451           /* Finally the length of the file.  */
6452           unsigned int fsize;
6453           get_uleb128 (fsize, linep);
6454
6455           printf (" %-5u %-5u %-9u %-9u %s\n",
6456                   cnt, diridx, mtime, fsize, fname);
6457         }
6458       /* Skip the final NUL byte.  */
6459       ++linep;
6460
6461       puts (gettext ("\nLine number statements:"));
6462       Dwarf_Word address = 0;
6463       unsigned int op_index = 0;
6464       size_t line = 1;
6465       uint_fast8_t is_stmt = default_is_stmt;
6466
6467       /* Default address value, in case we do not find the CU.  */
6468       size_t address_size
6469         = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6470
6471       /* Determine the CU this block is for.  */
6472       Dwarf_Off cuoffset;
6473       Dwarf_Off ncuoffset = 0;
6474       size_t hsize;
6475       while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6476                            NULL, NULL, NULL) == 0)
6477         {
6478           Dwarf_Die cudie;
6479           if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6480             continue;
6481           Dwarf_Attribute stmt_list;
6482           if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6483             continue;
6484           Dwarf_Word lineoff;
6485           if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6486             continue;
6487           if (lineoff == start_offset)
6488             {
6489               /* Found the CU.  */
6490               address_size = cudie.cu->address_size;
6491               break;
6492             }
6493         }
6494
6495       /* Apply the "operation advance" from a special opcode
6496          or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
6497       unsigned int op_addr_advance;
6498       bool show_op_index;
6499       inline void advance_pc (unsigned int op_advance)
6500       {
6501         op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6502                                                / max_ops_per_instr);
6503         address += op_advance;
6504         show_op_index = (op_index > 0 ||
6505                          (op_index + op_advance) % max_ops_per_instr > 0);
6506         op_index = (op_index + op_advance) % max_ops_per_instr;
6507       }
6508
6509       if (max_ops_per_instr == 0)
6510         {
6511           error (0, 0,
6512                  gettext ("invalid maximum operations per instruction is zero"));
6513           linep = lineendp;
6514           continue;
6515         }
6516
6517       while (linep < lineendp)
6518         {
6519           size_t offset = linep - (const unsigned char *) data->d_buf;
6520           unsigned int u128;
6521           int s128;
6522
6523           /* Read the opcode.  */
6524           unsigned int opcode = *linep++;
6525
6526           printf (" [%6" PRIx64 "]", (uint64_t)offset);
6527           /* Is this a special opcode?  */
6528           if (likely (opcode >= opcode_base))
6529             {
6530               if (unlikely (line_range == 0))
6531                 goto invalid_unit;
6532
6533               /* Yes.  Handling this is quite easy since the opcode value
6534                  is computed with
6535
6536                  opcode = (desired line increment - line_base)
6537                            + (line_range * address advance) + opcode_base
6538               */
6539               int line_increment = (line_base
6540                                     + (opcode - opcode_base) % line_range);
6541
6542               /* Perform the increments.  */
6543               line += line_increment;
6544               advance_pc ((opcode - opcode_base) / line_range);
6545
6546               char *a = format_dwarf_addr (dwflmod, 0, address, address);
6547               if (show_op_index)
6548                 printf (gettext ("\
6549  special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6550                         opcode, op_addr_advance, a, op_index,
6551                         line_increment, line);
6552               else
6553                 printf (gettext ("\
6554  special opcode %u: address+%u = %s, line%+d = %zu\n"),
6555                         opcode, op_addr_advance, a, line_increment, line);
6556               free (a);
6557             }
6558           else if (opcode == 0)
6559             {
6560               /* This an extended opcode.  */
6561               if (unlikely (linep + 2 > lineendp))
6562                 goto invalid_unit;
6563
6564               /* The length.  */
6565               unsigned int len = *linep++;
6566
6567               if (unlikely (linep + len > lineendp))
6568                 goto invalid_unit;
6569
6570               /* The sub-opcode.  */
6571               opcode = *linep++;
6572
6573               printf (gettext (" extended opcode %u: "), opcode);
6574
6575               switch (opcode)
6576                 {
6577                 case DW_LNE_end_sequence:
6578                   puts (gettext (" end of sequence"));
6579
6580                   /* Reset the registers we care about.  */
6581                   address = 0;
6582                   op_index = 0;
6583                   line = 1;
6584                   is_stmt = default_is_stmt;
6585                   break;
6586
6587                 case DW_LNE_set_address:
6588                   op_index = 0;
6589                   if (address_size == 4)
6590                     address = read_4ubyte_unaligned_inc (dbg, linep);
6591                   else
6592                     address = read_8ubyte_unaligned_inc (dbg, linep);
6593                   {
6594                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6595                     printf (gettext (" set address to %s\n"), a);
6596                     free (a);
6597                   }
6598                   break;
6599
6600                 case DW_LNE_define_file:
6601                   {
6602                     char *fname = (char *) linep;
6603                     unsigned char *endp = memchr (linep, '\0',
6604                                                   lineendp - linep);
6605                     if (unlikely (endp == NULL))
6606                       goto invalid_unit;
6607                     linep = endp + 1;
6608
6609                     unsigned int diridx;
6610                     get_uleb128 (diridx, linep);
6611                     Dwarf_Word mtime;
6612                     get_uleb128 (mtime, linep);
6613                     Dwarf_Word filelength;
6614                     get_uleb128 (filelength, linep);
6615
6616                     printf (gettext ("\
6617  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6618                             diridx, (uint64_t) mtime, (uint64_t) filelength,
6619                             fname);
6620                   }
6621                   break;
6622
6623                 case DW_LNE_set_discriminator:
6624                   /* Takes one ULEB128 parameter, the discriminator.  */
6625                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6626                     goto invalid_unit;
6627
6628                   get_uleb128 (u128, linep);
6629                   printf (gettext (" set discriminator to %u\n"), u128);
6630                   break;
6631
6632                 default:
6633                   /* Unknown, ignore it.  */
6634                   puts (gettext (" unknown opcode"));
6635                   linep += len - 1;
6636                   break;
6637                 }
6638             }
6639           else if (opcode <= DW_LNS_set_isa)
6640             {
6641               /* This is a known standard opcode.  */
6642               switch (opcode)
6643                 {
6644                 case DW_LNS_copy:
6645                   /* Takes no argument.  */
6646                   puts (gettext (" copy"));
6647                   break;
6648
6649                 case DW_LNS_advance_pc:
6650                   /* Takes one uleb128 parameter which is added to the
6651                      address.  */
6652                   get_uleb128 (u128, linep);
6653                   advance_pc (u128);
6654                   {
6655                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6656                     if (show_op_index)
6657                       printf (gettext ("\
6658  advance address by %u to %s, op_index to %u\n"),
6659                               op_addr_advance, a, op_index);
6660                     else
6661                       printf (gettext (" advance address by %u to %s\n"),
6662                               op_addr_advance, a);
6663                     free (a);
6664                   }
6665                   break;
6666
6667                 case DW_LNS_advance_line:
6668                   /* Takes one sleb128 parameter which is added to the
6669                      line.  */
6670                   get_sleb128 (s128, linep);
6671                   line += s128;
6672                   printf (gettext ("\
6673  advance line by constant %d to %" PRId64 "\n"),
6674                           s128, (int64_t) line);
6675                   break;
6676
6677                 case DW_LNS_set_file:
6678                   /* Takes one uleb128 parameter which is stored in file.  */
6679                   get_uleb128 (u128, linep);
6680                   printf (gettext (" set file to %" PRIu64 "\n"),
6681                           (uint64_t) u128);
6682                   break;
6683
6684                 case DW_LNS_set_column:
6685                   /* Takes one uleb128 parameter which is stored in column.  */
6686                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6687                     goto invalid_unit;
6688
6689                   get_uleb128 (u128, linep);
6690                   printf (gettext (" set column to %" PRIu64 "\n"),
6691                           (uint64_t) u128);
6692                   break;
6693
6694                 case DW_LNS_negate_stmt:
6695                   /* Takes no argument.  */
6696                   is_stmt = 1 - is_stmt;
6697                   printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6698                           "is_stmt", is_stmt);
6699                   break;
6700
6701                 case DW_LNS_set_basic_block:
6702                   /* Takes no argument.  */
6703                   puts (gettext (" set basic block flag"));
6704                   break;
6705
6706                 case DW_LNS_const_add_pc:
6707                   /* Takes no argument.  */
6708
6709                   if (unlikely (line_range == 0))
6710                     goto invalid_unit;
6711
6712                   advance_pc ((255 - opcode_base) / line_range);
6713                   {
6714                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6715                     if (show_op_index)
6716                       printf (gettext ("\
6717  advance address by constant %u to %s, op_index to %u\n"),
6718                               op_addr_advance, a, op_index);
6719                     else
6720                       printf (gettext ("\
6721  advance address by constant %u to %s\n"),
6722                               op_addr_advance, a);
6723                     free (a);
6724                   }
6725                   break;
6726
6727                 case DW_LNS_fixed_advance_pc:
6728                   /* Takes one 16 bit parameter which is added to the
6729                      address.  */
6730                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6731                     goto invalid_unit;
6732
6733                   u128 = read_2ubyte_unaligned_inc (dbg, linep);
6734                   address += u128;
6735                   op_index = 0;
6736                   {
6737                     char *a = format_dwarf_addr (dwflmod, 0, address, address);
6738                     printf (gettext ("\
6739  advance address by fixed value %u to %s\n"),
6740                             u128, a);
6741                     free (a);
6742                   }
6743                   break;
6744
6745                 case DW_LNS_set_prologue_end:
6746                   /* Takes no argument.  */
6747                   puts (gettext (" set prologue end flag"));
6748                   break;
6749
6750                 case DW_LNS_set_epilogue_begin:
6751                   /* Takes no argument.  */
6752                   puts (gettext (" set epilogue begin flag"));
6753                   break;
6754
6755                 case DW_LNS_set_isa:
6756                   /* Takes one uleb128 parameter which is stored in isa.  */
6757                   if (unlikely (standard_opcode_lengths[opcode] != 1))
6758                     goto invalid_unit;
6759
6760                   get_uleb128 (u128, linep);
6761                   printf (gettext (" set isa to %u\n"), u128);
6762                   break;
6763                 }
6764             }
6765           else
6766             {
6767               /* This is a new opcode the generator but not we know about.
6768                  Read the parameters associated with it but then discard
6769                  everything.  Read all the parameters for this opcode.  */
6770               printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6771                                 " unknown opcode with %" PRIu8 " parameters:",
6772                                 standard_opcode_lengths[opcode]),
6773                       standard_opcode_lengths[opcode]);
6774               for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6775                 {
6776                   get_uleb128 (u128, linep);
6777                   if (n != standard_opcode_lengths[opcode])
6778                     putc_unlocked (',', stdout);
6779                   printf (" %u", u128);
6780                 }
6781
6782               /* Next round, ignore this opcode.  */
6783               continue;
6784             }
6785         }
6786     }
6787
6788   /* There must only be one data block.  */
6789   assert (elf_getdata (scn, data) == NULL);
6790 }
6791
6792
6793 static void
6794 print_debug_loc_section (Dwfl_Module *dwflmod,
6795                          Ebl *ebl, GElf_Ehdr *ehdr,
6796                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6797 {
6798   Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6799
6800   if (unlikely (data == NULL))
6801     {
6802       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6803              elf_errmsg (-1));
6804       return;
6805     }
6806
6807   printf (gettext ("\
6808 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6809           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6810           (uint64_t) shdr->sh_offset);
6811
6812   sort_listptr (&known_loclistptr, "loclistptr");
6813   size_t listptr_idx = 0;
6814
6815   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6816   uint_fast8_t offset_size = 4;
6817
6818   bool first = true;
6819   struct Dwarf_CU *cu = NULL;
6820   Dwarf_Addr base = 0;
6821   unsigned char *readp = data->d_buf;
6822   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6823   while (readp < endp)
6824     {
6825       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6826
6827       if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
6828                                       &address_size, &offset_size, &base,
6829                                       &cu, offset, &readp, endp))
6830         continue;
6831
6832       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6833         {
6834           printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
6835           break;
6836         }
6837
6838       Dwarf_Addr begin;
6839       Dwarf_Addr end;
6840       if (address_size == 8)
6841         {
6842           begin = read_8ubyte_unaligned_inc (dbg, readp);
6843           end = read_8ubyte_unaligned_inc (dbg, readp);
6844         }
6845       else
6846         {
6847           begin = read_4ubyte_unaligned_inc (dbg, readp);
6848           end = read_4ubyte_unaligned_inc (dbg, readp);
6849           if (begin == (Dwarf_Addr) (uint32_t) -1)
6850             begin = (Dwarf_Addr) -1l;
6851         }
6852
6853       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
6854         {
6855           char *b = format_dwarf_addr (dwflmod, address_size, end, end);
6856           printf (gettext (" [%6tx]  base address %s\n"), offset, b);
6857           free (b);
6858           base = end;
6859         }
6860       else if (begin == 0 && end == 0) /* End of list entry.  */
6861         {
6862           if (first)
6863             printf (gettext (" [%6tx]  empty list\n"), offset);
6864           first = true;
6865         }
6866       else
6867         {
6868           /* We have a location expression entry.  */
6869           uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
6870
6871           char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
6872                                        begin);
6873           char *e = format_dwarf_addr (dwflmod, address_size, base + end,
6874                                        end);
6875
6876           if (first)            /* First entry in a list.  */
6877             printf (gettext (" [%6tx]  %s..%s"), offset, b, e);
6878           else
6879             printf (gettext ("           %s..%s"), b, e);
6880
6881           free (b);
6882           free (e);
6883
6884           if (endp - readp <= (ptrdiff_t) len)
6885             {
6886               fputs (gettext ("   <INVALID DATA>\n"), stdout);
6887               break;
6888             }
6889
6890           print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
6891                      3 /*XXX*/, address_size, offset_size, cu, len, readp);
6892
6893           first = false;
6894           readp += len;
6895         }
6896     }
6897 }
6898
6899 struct mac_culist
6900 {
6901   Dwarf_Die die;
6902   Dwarf_Off offset;
6903   Dwarf_Files *files;
6904   struct mac_culist *next;
6905 };
6906
6907
6908 static int
6909 mac_compare (const void *p1, const void *p2)
6910 {
6911   struct mac_culist *m1 = (struct mac_culist *) p1;
6912   struct mac_culist *m2 = (struct mac_culist *) p2;
6913
6914   if (m1->offset < m2->offset)
6915     return -1;
6916   if (m1->offset > m2->offset)
6917     return 1;
6918   return 0;
6919 }
6920
6921
6922 static void
6923 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6924                              Ebl *ebl, GElf_Ehdr *ehdr,
6925                              Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6926 {
6927   printf (gettext ("\
6928 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6929           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6930           (uint64_t) shdr->sh_offset);
6931   putc_unlocked ('\n', stdout);
6932
6933   /* There is no function in libdw to iterate over the raw content of
6934      the section but it is easy enough to do.  */
6935   Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
6936   if (unlikely (data == NULL || data->d_buf == NULL))
6937     {
6938       error (0, 0, gettext ("cannot get macro information section data: %s"),
6939              elf_errmsg (-1));
6940       return;
6941     }
6942
6943   /* Get the source file information for all CUs.  */
6944   Dwarf_Off offset;
6945   Dwarf_Off ncu = 0;
6946   size_t hsize;
6947   struct mac_culist *culist = NULL;
6948   size_t nculist = 0;
6949   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
6950     {
6951       Dwarf_Die cudie;
6952       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
6953         continue;
6954
6955       Dwarf_Attribute attr;
6956       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
6957         continue;
6958
6959       Dwarf_Word macoff;
6960       if (dwarf_formudata (&attr, &macoff) != 0)
6961         continue;
6962
6963       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
6964       newp->die = cudie;
6965       newp->offset = macoff;
6966       newp->files = NULL;
6967       newp->next = culist;
6968       culist = newp;
6969       ++nculist;
6970     }
6971
6972   /* Convert the list into an array for easier consumption.  */
6973   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
6974                                                          * sizeof (*cus));
6975   /* Add sentinel.  */
6976   cus[nculist].offset = data->d_size;
6977   if (nculist > 0)
6978     {
6979       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
6980         {
6981           assert (cnt < nculist);
6982           cus[cnt] = *culist;
6983           culist = culist->next;
6984         }
6985
6986       /* Sort the array according to the offset in the .debug_macinfo
6987          section.  Note we keep the sentinel at the end.  */
6988       qsort (cus, nculist, sizeof (*cus), mac_compare);
6989     }
6990
6991   const unsigned char *readp = (const unsigned char *) data->d_buf;
6992   const unsigned char *readendp = readp + data->d_size;
6993   int level = 1;
6994
6995   while (readp < readendp)
6996     {
6997       unsigned int opcode = *readp++;
6998       unsigned int u128;
6999       unsigned int u128_2;
7000       const unsigned char *endp;
7001
7002       switch (opcode)
7003         {
7004         case DW_MACINFO_define:
7005         case DW_MACINFO_undef:
7006         case DW_MACINFO_vendor_ext:
7007           /*  For the first two opcodes the parameters are
7008                 line, string
7009               For the latter
7010                 number, string.
7011               We can treat these cases together.  */
7012           get_uleb128 (u128, readp);
7013
7014           endp = memchr (readp, '\0', readendp - readp);
7015           if (unlikely (endp == NULL))
7016             {
7017               printf (gettext ("\
7018 %*s*** non-terminated string at end of section"),
7019                       level, "");
7020               return;
7021             }
7022
7023           if (opcode == DW_MACINFO_define)
7024             printf ("%*s#define %s, line %u\n",
7025                     level, "", (char *) readp, u128);
7026           else if (opcode == DW_MACINFO_undef)
7027             printf ("%*s#undef %s, line %u\n",
7028                     level, "", (char *) readp, u128);
7029           else
7030             printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7031
7032           readp = endp + 1;
7033           break;
7034
7035         case DW_MACINFO_start_file:
7036           /* The two parameters are line and file index, in this order.  */
7037           get_uleb128 (u128, readp);
7038           get_uleb128 (u128_2, readp);
7039
7040           /* Find the CU DIE for this file.  */
7041           size_t macoff = readp - (const unsigned char *) data->d_buf;
7042           const char *fname = "???";
7043           if (macoff >= cus[0].offset)
7044             {
7045               while (macoff >= cus[1].offset)
7046                 ++cus;
7047
7048               if (cus[0].files == NULL
7049                 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7050                 cus[0].files = (Dwarf_Files *) -1l;
7051
7052               if (cus[0].files != (Dwarf_Files *) -1l)
7053                 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7054                          ?: "???");
7055             }
7056
7057           printf ("%*sstart_file %u, [%u] %s\n",
7058                   level, "", u128, u128_2, fname);
7059           ++level;
7060           break;
7061
7062         case DW_MACINFO_end_file:
7063           --level;
7064           printf ("%*send_file\n", level, "");
7065           /* Nothing more to do.  */
7066           break;
7067
7068         default:
7069           // XXX gcc seems to generate files with a trailing zero.
7070           if (unlikely (opcode != 0 || readp != readendp))
7071             printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7072           break;
7073         }
7074     }
7075 }
7076
7077
7078 static void
7079 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7080                            Ebl *ebl, GElf_Ehdr *ehdr,
7081                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7082 {
7083   printf (gettext ("\
7084 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7085           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7086           (uint64_t) shdr->sh_offset);
7087   putc_unlocked ('\n', stdout);
7088
7089   Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7090   if (unlikely (data == NULL || data->d_buf == NULL))
7091     {
7092       error (0, 0, gettext ("cannot get macro information section data: %s"),
7093              elf_errmsg (-1));
7094       return;
7095     }
7096
7097   /* Get the source file information for all CUs.  Uses same
7098      datastructure as macinfo.  But uses offset field to directly
7099      match .debug_line offset.  And just stored in a list.  */
7100   Dwarf_Off offset;
7101   Dwarf_Off ncu = 0;
7102   size_t hsize;
7103   struct mac_culist *culist = NULL;
7104   size_t nculist = 0;
7105   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7106     {
7107       Dwarf_Die cudie;
7108       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7109         continue;
7110
7111       Dwarf_Attribute attr;
7112       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7113         continue;
7114
7115       Dwarf_Word lineoff;
7116       if (dwarf_formudata (&attr, &lineoff) != 0)
7117         continue;
7118
7119       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7120       newp->die = cudie;
7121       newp->offset = lineoff;
7122       newp->files = NULL;
7123       newp->next = culist;
7124       culist = newp;
7125       ++nculist;
7126     }
7127
7128   const unsigned char *readp = (const unsigned char *) data->d_buf;
7129   const unsigned char *readendp = readp + data->d_size;
7130
7131   while (readp < readendp)
7132     {
7133       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
7134               (uint64_t) (readp - (const unsigned char *) data->d_buf));
7135
7136       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7137       // optional vendor extension macro entry table.
7138       if (readp + 2 > readendp)
7139         {
7140         invalid_data:
7141           error (0, 0, gettext ("invalid data"));
7142           return;
7143         }
7144       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7145       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
7146
7147       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
7148       // 5 when it gets standardized.
7149       if (vers != 4)
7150         {
7151           printf (gettext ("  unknown version, cannot parse section\n"));
7152           return;
7153         }
7154
7155       if (readp + 1 > readendp)
7156         goto invalid_data;
7157       const unsigned char flag = *readp++;
7158       printf (gettext (" Flag:               0x%" PRIx8 "\n"), flag);
7159
7160       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7161       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
7162       Dwarf_Off line_offset = -1;
7163       if (flag & 0x02)
7164         {
7165           if (offset_len == 8)
7166             line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7167           else
7168             line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7169           printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7170                   line_offset);
7171         }
7172
7173       const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7174       memset (vendor, 0, sizeof vendor);
7175       if (flag & 0x04)
7176         {
7177           // 1 byte length, for each item, 1 byte opcode, uleb128 number
7178           // of arguments, for each argument 1 byte form code.
7179           if (readp + 1 > readendp)
7180             goto invalid_data;
7181           unsigned int tlen = *readp++;
7182           printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
7183                   tlen);
7184           for (unsigned int i = 0; i < tlen; i++)
7185             {
7186               if (readp + 1 > readendp)
7187                 goto invalid_data;
7188               unsigned int opcode = *readp++;
7189               printf (gettext ("    [%" PRIx8 "]"), opcode);
7190               if (opcode < DW_MACRO_GNU_lo_user
7191                   || opcode > DW_MACRO_GNU_hi_user)
7192                 goto invalid_data;
7193               // Record the start of description for this vendor opcode.
7194               // uleb128 nr args, 1 byte per arg form.
7195               vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7196               if (readp + 1 > readendp)
7197                 goto invalid_data;
7198               unsigned int args = *readp++;
7199               if (args > 0)
7200                 {
7201                   printf (gettext (" %" PRIu8 " arguments:"), args);
7202                   while (args > 0)
7203                     {
7204                       if (readp + 1 > readendp)
7205                         goto invalid_data;
7206                       unsigned int form = *readp++;
7207                       printf (" %s", dwarf_form_string (form));
7208                       if (form != DW_FORM_data1
7209                           && form != DW_FORM_data2
7210                           && form != DW_FORM_data4
7211                           && form != DW_FORM_data8
7212                           && form != DW_FORM_sdata
7213                           && form != DW_FORM_udata
7214                           && form != DW_FORM_block
7215                           && form != DW_FORM_block1
7216                           && form != DW_FORM_block2
7217                           && form != DW_FORM_block4
7218                           && form != DW_FORM_flag
7219                           && form != DW_FORM_string
7220                           && form != DW_FORM_strp
7221                           && form != DW_FORM_sec_offset)
7222                         goto invalid_data;
7223                       args--;
7224                       if (args > 0)
7225                         putchar_unlocked (',');
7226                     }
7227                 }
7228               else
7229                 printf (gettext (" no arguments."));
7230               putchar_unlocked ('\n');
7231             }
7232         }
7233       putchar_unlocked ('\n');
7234
7235       int level = 1;
7236       if (readp + 1 > readendp)
7237         goto invalid_data;
7238       unsigned int opcode = *readp++;
7239       while (opcode != 0)
7240         {
7241           unsigned int u128;
7242           unsigned int u128_2;
7243           const unsigned char *endp;
7244           uint64_t off;
7245
7246           switch (opcode)
7247             {
7248             case DW_MACRO_GNU_start_file:
7249               get_uleb128 (u128, readp);
7250               get_uleb128 (u128_2, readp);
7251
7252               /* Find the CU DIE that matches this line offset.  */
7253               const char *fname = "???";
7254               if (line_offset != (Dwarf_Off) -1)
7255                 {
7256                   struct mac_culist *cu = culist;
7257                   while (cu != NULL && line_offset != cu->offset)
7258                     cu = cu->next;
7259                   if (cu != NULL)
7260                     {
7261                       if (cu->files == NULL
7262                           && dwarf_getsrcfiles (&cu->die, &cu->files,
7263                                                 NULL) != 0)
7264                         cu->files = (Dwarf_Files *) -1l;
7265
7266                       if (cu->files != (Dwarf_Files *) -1l)
7267                         fname = (dwarf_filesrc (cu->files, u128_2,
7268                                                 NULL, NULL) ?: "???");
7269                     }
7270                 }
7271               printf ("%*sstart_file %u, [%u] %s\n",
7272                       level, "", u128, u128_2, fname);
7273               ++level;
7274               break;
7275
7276             case DW_MACRO_GNU_end_file:
7277               --level;
7278               printf ("%*send_file\n", level, "");
7279               break;
7280
7281             case DW_MACRO_GNU_define:
7282               get_uleb128 (u128, readp);
7283               endp = memchr (readp, '\0', readendp - readp);
7284               if (endp == NULL)
7285                 goto invalid_data;
7286               printf ("%*s#define %s, line %u\n",
7287                       level, "", readp, u128);
7288               readp = endp + 1;
7289               break;
7290
7291             case DW_MACRO_GNU_undef:
7292               get_uleb128 (u128, readp);
7293               endp = memchr (readp, '\0', readendp - readp);
7294               if (endp == NULL)
7295                 goto invalid_data;
7296               printf ("%*s#undef %s, line %u\n",
7297                       level, "", readp, u128);
7298               readp = endp + 1;
7299               break;
7300
7301             case DW_MACRO_GNU_define_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#define %s, line %u (indirect)\n",
7310                       level, "", dwarf_getstring (dbg, off, NULL), u128);
7311               break;
7312
7313             case DW_MACRO_GNU_undef_indirect:
7314               get_uleb128 (u128, readp);
7315               if (readp + offset_len > readendp)
7316                 goto invalid_data;
7317               if (offset_len == 8)
7318                 off = read_8ubyte_unaligned_inc (dbg, readp);
7319               else
7320                 off = read_4ubyte_unaligned_inc (dbg, readp);
7321               printf ("%*s#undef %s, line %u (indirect)\n",
7322                       level, "", dwarf_getstring (dbg, off, NULL), u128);
7323               break;
7324
7325             case DW_MACRO_GNU_transparent_include:
7326               if (readp + offset_len > readendp)
7327                 goto invalid_data;
7328               if (offset_len == 8)
7329                 off = read_8ubyte_unaligned_inc (dbg, readp);
7330               else
7331                 off = read_4ubyte_unaligned_inc (dbg, readp);
7332               printf ("%*s#include offset 0x%" PRIx64 "\n",
7333                       level, "", off);
7334               break;
7335
7336             default:
7337               printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7338               if (opcode < DW_MACRO_GNU_lo_user
7339                   || opcode > DW_MACRO_GNU_lo_user
7340                   || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7341                 goto invalid_data;
7342
7343               const unsigned char *op_desc;
7344               op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7345
7346               // Just skip the arguments, we cannot really interpret them,
7347               // but print as much as we can.
7348               unsigned int args = *op_desc++;
7349               while (args > 0)
7350                 {
7351                   unsigned int form = *op_desc++;
7352                   Dwarf_Word val;
7353                   switch (form)
7354                     {
7355                     case DW_FORM_data1:
7356                       if (readp + 1 > readendp)
7357                         goto invalid_data;
7358                       val = *readp++;
7359                       printf (" %" PRIx8, (unsigned int) val);
7360                       break;
7361
7362                     case DW_FORM_data2:
7363                       if (readp + 2 > readendp)
7364                         goto invalid_data;
7365                       val = read_2ubyte_unaligned_inc (dbg, readp);
7366                       printf(" %" PRIx16, (unsigned int) val);
7367                       break;
7368
7369                     case DW_FORM_data4:
7370                       if (readp + 4 > readendp)
7371                         goto invalid_data;
7372                       val = read_4ubyte_unaligned_inc (dbg, readp);
7373                       printf (" %" PRIx32, (unsigned int) val);
7374                       break;
7375
7376                     case DW_FORM_data8:
7377                       if (readp + 8 > readendp)
7378                         goto invalid_data;
7379                       val = read_8ubyte_unaligned_inc (dbg, readp);
7380                       printf (" %" PRIx64, val);
7381                       break;
7382
7383                     case DW_FORM_sdata:
7384                       get_sleb128 (val, readp);
7385                       printf (" %" PRIx64, val);
7386                       break;
7387
7388                     case DW_FORM_udata:
7389                       get_uleb128 (val, readp);
7390                       printf (" %" PRIx64, val);
7391                       break;
7392
7393                     case DW_FORM_block:
7394                       get_uleb128 (val, readp);
7395                       printf (" block[%" PRIu64 "]", val);
7396                       if (readp + val > readendp)
7397                         goto invalid_data;
7398                       readp += val;
7399                       break;
7400
7401                     case DW_FORM_block1:
7402                       if (readp + 1 > readendp)
7403                         goto invalid_data;
7404                       val = *readp++;
7405                       printf (" block[%" PRIu64 "]", val);
7406                       if (readp + val > readendp)
7407                         goto invalid_data;
7408                       break;
7409
7410                     case DW_FORM_block2:
7411                       if (readp + 2 > readendp)
7412                         goto invalid_data;
7413                       val = read_2ubyte_unaligned_inc (dbg, readp);
7414                       printf (" block[%" PRIu64 "]", val);
7415                       if (readp + val > readendp)
7416                         goto invalid_data;
7417                       break;
7418
7419                     case DW_FORM_block4:
7420                       if (readp + 2 > readendp)
7421                         goto invalid_data;
7422                       val =read_4ubyte_unaligned_inc (dbg, readp);
7423                       printf (" block[%" PRIu64 "]", val);
7424                       if (readp + val > readendp)
7425                         goto invalid_data;
7426                       break;
7427
7428                     case DW_FORM_flag:
7429                       if (readp + 1 > readendp)
7430                         goto invalid_data;
7431                       val = *readp++;
7432                       printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7433                       break;
7434
7435                     case DW_FORM_string:
7436                       endp = memchr (readp, '\0', readendp - readp);
7437                       if (endp == NULL)
7438                         goto invalid_data;
7439                       printf (" %s", readp);
7440                       readp = endp + 1;
7441                       break;
7442
7443                     case DW_FORM_strp:
7444                       if (readp + offset_len > readendp)
7445                         goto invalid_data;
7446                       if (offset_len == 8)
7447                         val = read_8ubyte_unaligned_inc (dbg, readp);
7448                       else
7449                         val = read_4ubyte_unaligned_inc (dbg, readp);
7450                       printf (" %s", dwarf_getstring (dbg, val, NULL));
7451                       break;
7452
7453                     case DW_FORM_sec_offset:
7454                       if (readp + offset_len > readendp)
7455                         goto invalid_data;
7456                       if (offset_len == 8)
7457                         val = read_8ubyte_unaligned_inc (dbg, readp);
7458                       else
7459                         val = read_4ubyte_unaligned_inc (dbg, readp);
7460                       printf (" %" PRIx64, val);
7461                       break;
7462
7463                       default:
7464                         error (0, 0, gettext ("vendor opcode not verified?"));
7465                         return;
7466                     }
7467
7468                   args--;
7469                   if (args > 0)
7470                     putchar_unlocked (',');
7471                 }
7472               putchar_unlocked ('\n');
7473             }
7474
7475           if (readp + 1 > readendp)
7476             goto invalid_data;
7477           opcode = *readp++;
7478           if (opcode == 0)
7479             putchar_unlocked ('\n');
7480         }
7481     }
7482 }
7483
7484
7485 /* Callback for printing global names.  */
7486 static int
7487 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7488                 void *arg)
7489 {
7490   int *np = (int *) arg;
7491
7492   printf (gettext (" [%5d] DIE offset: %6" PRId64
7493                    ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7494           (*np)++, global->die_offset, global->cu_offset, global->name);
7495
7496   return 0;
7497 }
7498
7499
7500 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
7501 static void
7502 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7503                               Ebl *ebl, GElf_Ehdr *ehdr,
7504                               Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7505 {
7506   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7507           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7508           (uint64_t) shdr->sh_offset);
7509
7510   int n = 0;
7511   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7512 }
7513
7514 /* Print the content of the DWARF string section '.debug_str'.  */
7515 static void
7516 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7517                          Ebl *ebl, GElf_Ehdr *ehdr,
7518                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7519 {
7520   const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7521                           dbg->sectiondata[IDX_debug_str]->d_size : 0);
7522
7523   /* Compute floor(log16(shdr->sh_size)).  */
7524   GElf_Addr tmp = sh_size;
7525   int digits = 1;
7526   while (tmp >= 16)
7527     {
7528       ++digits;
7529       tmp >>= 4;
7530     }
7531   digits = MAX (4, digits);
7532
7533   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7534                    " %*s  String\n"),
7535           elf_ndxscn (scn),
7536           section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7537           /* TRANS: the debugstr| prefix makes the string unique.  */
7538           digits + 2, sgettext ("debugstr|Offset"));
7539
7540   Dwarf_Off offset = 0;
7541   while (offset < sh_size)
7542     {
7543       size_t len;
7544       const char *str = dwarf_getstring (dbg, offset, &len);
7545       if (unlikely (str == NULL))
7546         {
7547           printf (gettext (" *** error while reading strings: %s\n"),
7548                   dwarf_errmsg (-1));
7549           break;
7550         }
7551
7552       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
7553
7554       offset += len + 1;
7555     }
7556 }
7557
7558
7559 /* Print the content of the call frame search table section
7560    '.eh_frame_hdr'.  */
7561 static void
7562 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7563                                Ebl *ebl __attribute__ ((unused)),
7564                                GElf_Ehdr *ehdr __attribute__ ((unused)),
7565                                Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7566 {
7567   printf (gettext ("\
7568 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7569           elf_ndxscn (scn));
7570
7571   Elf_Data *data = elf_rawdata (scn, NULL);
7572
7573   if (unlikely (data == NULL))
7574     {
7575       error (0, 0, gettext ("cannot get %s content: %s"),
7576              ".eh_frame_hdr", elf_errmsg (-1));
7577       return;
7578     }
7579
7580   const unsigned char *readp = data->d_buf;
7581   const unsigned char *const dataend = ((unsigned char *) data->d_buf
7582                                         + data->d_size);
7583
7584   if (unlikely (readp + 4 > dataend))
7585     {
7586     invalid_data:
7587       error (0, 0, gettext ("invalid data"));
7588       return;
7589     }
7590
7591   unsigned int version = *readp++;
7592   unsigned int eh_frame_ptr_enc = *readp++;
7593   unsigned int fde_count_enc = *readp++;
7594   unsigned int table_enc = *readp++;
7595
7596   printf (" version:          %u\n"
7597           " eh_frame_ptr_enc: %#x ",
7598           version, eh_frame_ptr_enc);
7599   print_encoding_base ("", eh_frame_ptr_enc);
7600   printf (" fde_count_enc:    %#x ", fde_count_enc);
7601   print_encoding_base ("", fde_count_enc);
7602   printf (" table_enc:        %#x ", table_enc);
7603   print_encoding_base ("", table_enc);
7604
7605   uint64_t eh_frame_ptr = 0;
7606   if (eh_frame_ptr_enc != DW_EH_PE_omit)
7607     {
7608       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7609                             dbg);
7610       if (unlikely (readp == NULL))
7611         goto invalid_data;
7612
7613       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
7614       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7615         printf (" (offset: %#" PRIx64 ")",
7616                 /* +4 because of the 4 byte header of the section.  */
7617                 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7618
7619       putchar_unlocked ('\n');
7620     }
7621
7622   uint64_t fde_count = 0;
7623   if (fde_count_enc != DW_EH_PE_omit)
7624     {
7625       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7626       if (unlikely (readp == NULL))
7627         goto invalid_data;
7628
7629       printf (" fde_count:        %" PRIu64 "\n", fde_count);
7630     }
7631
7632   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7633     return;
7634
7635   puts (" Table:");
7636
7637   /* Optimize for the most common case.  */
7638   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7639     while (fde_count > 0 && readp + 8 <= dataend)
7640       {
7641         int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7642         uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7643                                    + (int64_t) initial_location);
7644         int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7645         // XXX Possibly print symbol name or section offset for initial_offset
7646         printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7647                 " fde=[%6" PRIx64 "]\n",
7648                 initial_location, initial_offset,
7649                 address, address - (eh_frame_ptr + 4));
7650       }
7651   else
7652     while (0 && readp < dataend)
7653       {
7654
7655       }
7656 }
7657
7658
7659 /* Print the content of the exception handling table section
7660    '.eh_frame_hdr'.  */
7661 static void
7662 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7663                              Ebl *ebl __attribute__ ((unused)),
7664                              GElf_Ehdr *ehdr __attribute__ ((unused)),
7665                              Elf_Scn *scn,
7666                              GElf_Shdr *shdr __attribute__ ((unused)),
7667                              Dwarf *dbg __attribute__ ((unused)))
7668 {
7669   printf (gettext ("\
7670 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7671           elf_ndxscn (scn));
7672
7673   Elf_Data *data = elf_rawdata (scn, NULL);
7674
7675   if (unlikely (data == NULL))
7676     {
7677       error (0, 0, gettext ("cannot get %s content: %s"),
7678              ".gcc_except_table", elf_errmsg (-1));
7679       return;
7680     }
7681
7682   const unsigned char *readp = data->d_buf;
7683   const unsigned char *const dataend = readp + data->d_size;
7684
7685   if (unlikely (readp + 1 > dataend))
7686     {
7687     invalid_data:
7688       error (0, 0, gettext ("invalid data"));
7689       return;
7690     }
7691   unsigned int lpstart_encoding = *readp++;
7692   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
7693   print_encoding_base ("", lpstart_encoding);
7694   if (lpstart_encoding != DW_EH_PE_omit)
7695     {
7696       uint64_t lpstart;
7697       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7698       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
7699     }
7700
7701   if (unlikely (readp + 1 > dataend))
7702     goto invalid_data;
7703   unsigned int ttype_encoding = *readp++;
7704   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
7705   print_encoding_base ("", ttype_encoding);
7706   const unsigned char *ttype_base = NULL;
7707   if (ttype_encoding != DW_EH_PE_omit)
7708     {
7709       unsigned int ttype_base_offset;
7710       get_uleb128 (ttype_base_offset, readp);
7711       printf (" TType base offset:   %#x\n", ttype_base_offset);
7712       ttype_base = readp + ttype_base_offset;
7713     }
7714
7715   if (unlikely (readp + 1 > dataend))
7716     goto invalid_data;
7717   unsigned int call_site_encoding = *readp++;
7718   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
7719   print_encoding_base ("", call_site_encoding);
7720   unsigned int call_site_table_len;
7721   get_uleb128 (call_site_table_len, readp);
7722
7723   const unsigned char *const action_table = readp + call_site_table_len;
7724   if (unlikely (action_table > dataend))
7725     goto invalid_data;
7726   unsigned int u = 0;
7727   unsigned int max_action = 0;
7728   while (readp < action_table)
7729     {
7730       if (u == 0)
7731         puts (gettext ("\n Call site table:"));
7732
7733       uint64_t call_site_start;
7734       readp = read_encoded (call_site_encoding, readp, dataend,
7735                             &call_site_start, dbg);
7736       uint64_t call_site_length;
7737       readp = read_encoded (call_site_encoding, readp, dataend,
7738                             &call_site_length, dbg);
7739       uint64_t landing_pad;
7740       readp = read_encoded (call_site_encoding, readp, dataend,
7741                             &landing_pad, dbg);
7742       unsigned int action;
7743       get_uleb128 (action, readp);
7744       max_action = MAX (action, max_action);
7745       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
7746                        "        Call site length:  %" PRIu64 "\n"
7747                        "        Landing pad:       %#" PRIx64 "\n"
7748                        "        Action:            %u\n"),
7749               u++, call_site_start, call_site_length, landing_pad, action);
7750     }
7751   assert (readp == action_table);
7752
7753   unsigned int max_ar_filter = 0;
7754   if (max_action > 0)
7755     {
7756       puts ("\n Action table:");
7757
7758       const unsigned char *const action_table_end
7759         = action_table + max_action + 1;
7760
7761       u = 0;
7762       do
7763         {
7764           int ar_filter;
7765           get_sleb128 (ar_filter, readp);
7766           if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7767             max_ar_filter = ar_filter;
7768           int ar_disp;
7769           get_sleb128 (ar_disp, readp);
7770
7771           printf (" [%4u] ar_filter:  % d\n"
7772                   "        ar_disp:    % -5d",
7773                   u, ar_filter, ar_disp);
7774           if (abs (ar_disp) & 1)
7775             printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7776           else if (ar_disp != 0)
7777             puts (" -> ???");
7778           else
7779             putchar_unlocked ('\n');
7780           ++u;
7781         }
7782       while (readp < action_table_end);
7783     }
7784
7785   if (max_ar_filter > 0)
7786     {
7787       puts ("\n TType table:");
7788
7789       // XXX Not *4, size of encoding;
7790       switch (ttype_encoding & 7)
7791         {
7792         case DW_EH_PE_udata2:
7793         case DW_EH_PE_sdata2:
7794           readp = ttype_base - max_ar_filter * 2;
7795           break;
7796         case DW_EH_PE_udata4:
7797         case DW_EH_PE_sdata4:
7798           readp = ttype_base - max_ar_filter * 4;
7799           break;
7800         case DW_EH_PE_udata8:
7801         case DW_EH_PE_sdata8:
7802           readp = ttype_base - max_ar_filter * 8;
7803           break;
7804         default:
7805           error (1, 0, gettext ("invalid TType encoding"));
7806         }
7807
7808       do
7809         {
7810           uint64_t ttype;
7811           readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
7812                                 dbg);
7813           printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
7814         }
7815       while (readp < ttype_base);
7816     }
7817 }
7818
7819 /* Print the content of the '.gdb_index' section.
7820    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
7821 */
7822 static void
7823 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7824                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7825 {
7826   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
7827                    " contains %" PRId64 " bytes :\n"),
7828           elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7829           (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
7830
7831   Elf_Data *data = elf_rawdata (scn, NULL);
7832
7833   if (unlikely (data == NULL))
7834     {
7835       error (0, 0, gettext ("cannot get %s content: %s"),
7836              ".gdb_index", elf_errmsg (-1));
7837       return;
7838     }
7839
7840   // .gdb_index is always in little endian.
7841   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
7842   dbg = &dummy_dbg;
7843
7844   const unsigned char *readp = data->d_buf;
7845   const unsigned char *const dataend = readp + data->d_size;
7846
7847   if (unlikely (readp + 4 > dataend))
7848     {
7849     invalid_data:
7850       error (0, 0, gettext ("invalid data"));
7851       return;
7852     }
7853
7854   int32_t vers = read_4ubyte_unaligned (dbg, readp);
7855   printf (gettext (" Version:         %" PRId32 "\n"), vers);
7856
7857   // The only difference between version 4 and version 5 is the
7858   // hash used for generating the table.  Version 6 contains symbols
7859   // for inlined functions, older versions didn't.  Version 7 adds
7860   // symbol kinds.  Version 8 just indicates that it correctly includes
7861   // TUs for symbols.
7862   if (vers < 4 || vers > 8)
7863     {
7864       printf (gettext ("  unknown version, cannot parse section\n"));
7865       return;
7866     }
7867
7868   readp += 4;
7869   if (unlikely (readp + 4 > dataend))
7870     goto invalid_data;
7871
7872   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
7873   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
7874
7875   readp += 4;
7876   if (unlikely (readp + 4 > dataend))
7877     goto invalid_data;
7878
7879   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
7880   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
7881
7882   readp += 4;
7883   if (unlikely (readp + 4 > dataend))
7884     goto invalid_data;
7885
7886   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
7887   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
7888
7889   readp += 4;
7890   if (unlikely (readp + 4 > dataend))
7891     goto invalid_data;
7892
7893   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
7894   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
7895
7896   readp += 4;
7897   if (unlikely (readp + 4 > dataend))
7898     goto invalid_data;
7899
7900   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
7901   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
7902
7903   readp = data->d_buf + cu_off;
7904
7905   const unsigned char *nextp = data->d_buf + tu_off;
7906   size_t cu_nr = (nextp - readp) / 16;
7907
7908   printf (gettext ("\n CU list at offset %#" PRIx32
7909                    " contains %zu entries:\n"),
7910           cu_off, cu_nr);
7911
7912   size_t n = 0;
7913   while (readp + 16 <= dataend && n < cu_nr)
7914     {
7915       uint64_t off = read_8ubyte_unaligned (dbg, readp);
7916       readp += 8;
7917
7918       uint64_t len = read_8ubyte_unaligned (dbg, readp);
7919       readp += 8;
7920
7921       printf (" [%4zu] start: %0#8" PRIx64
7922               ", length: %5" PRIu64 "\n", n, off, len);
7923       n++;
7924     }
7925
7926   readp = data->d_buf + tu_off;
7927   nextp = data->d_buf + addr_off;
7928   size_t tu_nr = (nextp - readp) / 24;
7929
7930   printf (gettext ("\n TU list at offset %#" PRIx32
7931                    " contains %zu entries:\n"),
7932           tu_off, tu_nr);
7933
7934   n = 0;
7935   while (readp + 24 <= dataend && n < tu_nr)
7936     {
7937       uint64_t off = read_8ubyte_unaligned (dbg, readp);
7938       readp += 8;
7939
7940       uint64_t type = read_8ubyte_unaligned (dbg, readp);
7941       readp += 8;
7942
7943       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
7944       readp += 8;
7945
7946       printf (" [%4zu] CU offset: %5" PRId64
7947               ", type offset: %5" PRId64
7948               ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
7949       n++;
7950     }
7951
7952   readp = data->d_buf + addr_off;
7953   nextp = data->d_buf + sym_off;
7954   size_t addr_nr = (nextp - readp) / 20;
7955
7956   printf (gettext ("\n Address list at offset %#" PRIx32
7957                    " contains %zu entries:\n"),
7958           addr_off, addr_nr);
7959
7960   n = 0;
7961   while (readp + 20 <= dataend && n < addr_nr)
7962     {
7963       uint64_t low = read_8ubyte_unaligned (dbg, readp);
7964       readp += 8;
7965
7966       uint64_t high = read_8ubyte_unaligned (dbg, readp);
7967       readp += 8;
7968
7969       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
7970       readp += 4;
7971
7972       char *l = format_dwarf_addr (dwflmod, 8, low, low);
7973       char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
7974       printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
7975               n, l, h, idx);
7976       free (l);
7977       free (h);
7978       n++;
7979     }
7980
7981   readp = data->d_buf + sym_off;
7982   nextp = data->d_buf + const_off;
7983   size_t sym_nr = (nextp - readp) / 8;
7984
7985   printf (gettext ("\n Symbol table at offset %#" PRIx32
7986                    " contains %zu slots:\n"),
7987           addr_off, sym_nr);
7988
7989   n = 0;
7990   while (readp + 8 <= dataend && n < sym_nr)
7991     {
7992       uint32_t name = read_4ubyte_unaligned (dbg, readp);
7993       readp += 4;
7994
7995       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
7996       readp += 4;
7997
7998       if (name != 0 || vector != 0)
7999         {
8000           const unsigned char *sym = data->d_buf + const_off + name;
8001           if (unlikely (sym > dataend))
8002             goto invalid_data;
8003
8004           printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8005
8006           const unsigned char *readcus = data->d_buf + const_off + vector;
8007           if (unlikely (readcus + 8 > dataend))
8008             goto invalid_data;
8009
8010           uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8011           while (cus--)
8012             {
8013               uint32_t cu_kind, cu, kind;
8014               bool is_static;
8015               readcus += 4;
8016               cu_kind = read_4ubyte_unaligned (dbg, readcus);
8017               cu = cu_kind & ((1 << 24) - 1);
8018               kind = (cu_kind >> 28) & 7;
8019               is_static = cu_kind & (1U << 31);
8020               if (cu > cu_nr - 1)
8021                 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8022               else
8023                 printf ("%" PRId32, cu);
8024               if (kind != 0)
8025                 {
8026                   printf (" (");
8027                   switch (kind)
8028                     {
8029                     case 1:
8030                       printf ("type");
8031                       break;
8032                     case 2:
8033                       printf ("var");
8034                       break;
8035                     case 3:
8036                       printf ("func");
8037                       break;
8038                     case 4:
8039                       printf ("other");
8040                       break;
8041                     default:
8042                       printf ("unknown-0x%" PRIx32, kind);
8043                       break;
8044                     }
8045                   printf (":%c)", (is_static ? 'S' : 'G'));
8046                 }
8047               if (cus > 0)
8048                 printf (", ");
8049             }
8050           printf ("\n");
8051         }
8052       n++;
8053     }
8054 }
8055
8056 static void
8057 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8058 {
8059   /* Before we start the real work get a debug context descriptor.  */
8060   Dwarf_Addr dwbias;
8061   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8062   Dwarf dummy_dbg =
8063     {
8064       .elf = ebl->elf,
8065       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8066     };
8067   if (dbg == NULL)
8068     {
8069       if ((print_debug_sections & ~section_exception) != 0)
8070         error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8071                dwfl_errmsg (-1));
8072       if ((print_debug_sections & section_exception) == 0)
8073         return;
8074       dbg = &dummy_dbg;
8075     }
8076
8077   /* Get the section header string table index.  */
8078   size_t shstrndx;
8079   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8080     error (EXIT_FAILURE, 0,
8081            gettext ("cannot get section header string table index"));
8082
8083   /* Look through all the sections for the debugging sections to print.  */
8084   Elf_Scn *scn = NULL;
8085   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8086     {
8087       GElf_Shdr shdr_mem;
8088       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8089
8090       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8091         {
8092           static const struct
8093           {
8094             const char *name;
8095             enum section_e bitmask;
8096             void (*fp) (Dwfl_Module *, Ebl *,
8097                         GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8098           } debug_sections[] =
8099             {
8100 #define NEW_SECTION(name) \
8101               { ".debug_" #name, section_##name, print_debug_##name##_section }
8102               NEW_SECTION (abbrev),
8103               NEW_SECTION (aranges),
8104               NEW_SECTION (frame),
8105               NEW_SECTION (info),
8106               NEW_SECTION (types),
8107               NEW_SECTION (line),
8108               NEW_SECTION (loc),
8109               NEW_SECTION (pubnames),
8110               NEW_SECTION (str),
8111               NEW_SECTION (macinfo),
8112               NEW_SECTION (macro),
8113               NEW_SECTION (ranges),
8114               { ".eh_frame", section_frame | section_exception,
8115                 print_debug_frame_section },
8116               { ".eh_frame_hdr", section_frame | section_exception,
8117                 print_debug_frame_hdr_section },
8118               { ".gcc_except_table", section_frame | section_exception,
8119                 print_debug_exception_table },
8120               { ".gdb_index", section_gdb_index, print_gdb_index_section }
8121             };
8122           const int ndebug_sections = (sizeof (debug_sections)
8123                                        / sizeof (debug_sections[0]));
8124           const char *name = elf_strptr (ebl->elf, shstrndx,
8125                                          shdr->sh_name);
8126           if (name == NULL)
8127             continue;
8128
8129           int n;
8130           for (n = 0; n < ndebug_sections; ++n)
8131             if (strcmp (name, debug_sections[n].name) == 0
8132 #if USE_ZLIB
8133                 || (name[0] == '.' && name[1] == 'z'
8134                     && debug_sections[n].name[1] == 'd'
8135                     && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8136 #endif
8137                 )
8138               {
8139                 if ((print_debug_sections | implicit_debug_sections)
8140                     & debug_sections[n].bitmask)
8141                   debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8142                 break;
8143               }
8144         }
8145     }
8146
8147   reset_listptr (&known_loclistptr);
8148   reset_listptr (&known_rangelistptr);
8149 }
8150
8151
8152 #define ITEM_INDENT             4
8153 #define WRAP_COLUMN             75
8154
8155 /* Print "NAME: FORMAT", wrapping when output text would make the line
8156    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
8157    but this function is also used for registers which should be printed
8158    aligned.  Fortunately registers output uses fixed fields width (such
8159    as %11d) for the alignment.
8160
8161    Line breaks should not depend on the particular values although that
8162    may happen in some cases of the core items.  */
8163
8164 static unsigned int
8165 __attribute__ ((format (printf, 6, 7)))
8166 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8167                  size_t name_width, const char *name, const char *format, ...)
8168 {
8169   size_t len = strlen (name);
8170   if (name_width < len)
8171     name_width = len;
8172
8173   char *out;
8174   va_list ap;
8175   va_start (ap, format);
8176   int out_len = vasprintf (&out, format, ap);
8177   va_end (ap);
8178   if (out_len == -1)
8179     error (EXIT_FAILURE, 0, _("memory exhausted"));
8180
8181   size_t n = name_width + sizeof ": " - 1 + out_len;
8182
8183   if (colno == 0)
8184     {
8185       printf ("%*s", ITEM_INDENT, "");
8186       colno = ITEM_INDENT + n;
8187     }
8188   else if (colno + 2 + n < wrap)
8189     {
8190       printf ("%c ", sep);
8191       colno += 2 + n;
8192     }
8193   else
8194     {
8195       printf ("\n%*s", ITEM_INDENT, "");
8196       colno = ITEM_INDENT + n;
8197     }
8198
8199   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8200
8201   free (out);
8202
8203   return colno;
8204 }
8205
8206 static const void *
8207 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8208          void *value, const void *data, size_t size)
8209 {
8210   Elf_Data valuedata =
8211     {
8212       .d_type = type,
8213       .d_buf = value,
8214       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8215       .d_version = EV_CURRENT,
8216     };
8217   Elf_Data indata =
8218     {
8219       .d_type = type,
8220       .d_buf = (void *) data,
8221       .d_size = valuedata.d_size,
8222       .d_version = EV_CURRENT,
8223     };
8224
8225   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8226                  ? elf32_xlatetom : elf64_xlatetom)
8227     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8228   if (d == NULL)
8229     error (EXIT_FAILURE, 0,
8230            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8231
8232   return data + indata.d_size;
8233 }
8234
8235 typedef uint8_t GElf_Byte;
8236
8237 static unsigned int
8238 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8239                   unsigned int colno, size_t *repeated_size)
8240 {
8241   uint_fast16_t count = item->count ?: 1;
8242
8243 #define TYPES                                                                 \
8244   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);                             \
8245   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);                           \
8246   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);                           \
8247   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);                             \
8248   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);                        \
8249   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8250
8251 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
8252   union { TYPES; } value;
8253 #undef DO_TYPE
8254
8255   void *data = &value;
8256   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8257   size_t convsize = size;
8258   if (repeated_size != NULL)
8259     {
8260       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8261         {
8262           data = alloca (*repeated_size);
8263           count *= *repeated_size / size;
8264           convsize = count * size;
8265           *repeated_size -= convsize;
8266         }
8267       else if (item->count != 0 || item->format != '\n')
8268         *repeated_size -= size;
8269     }
8270
8271   convert (core, item->type, count, data, desc + item->offset, convsize);
8272
8273   Elf_Type type = item->type;
8274   if (type == ELF_T_ADDR)
8275     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8276
8277   switch (item->format)
8278     {
8279     case 'd':
8280       assert (count == 1);
8281       switch (type)
8282         {
8283 #define DO_TYPE(NAME, Name, hex, dec)                                         \
8284           case ELF_T_##NAME:                                                  \
8285             colno = print_core_item (colno, ',', WRAP_COLUMN,                 \
8286                                      0, item->name, dec, value.Name[0]); \
8287             break
8288           TYPES;
8289 #undef DO_TYPE
8290         default:
8291           abort ();
8292         }
8293       break;
8294
8295     case 'x':
8296       assert (count == 1);
8297       switch (type)
8298         {
8299 #define DO_TYPE(NAME, Name, hex, dec)                                         \
8300           case ELF_T_##NAME:                                                  \
8301             colno = print_core_item (colno, ',', WRAP_COLUMN,                 \
8302                                      0, item->name, hex, value.Name[0]);      \
8303             break
8304           TYPES;
8305 #undef DO_TYPE
8306         default:
8307           abort ();
8308         }
8309       break;
8310
8311     case 'b':
8312     case 'B':
8313       assert (size % sizeof (unsigned int) == 0);
8314       unsigned int nbits = count * size * 8;
8315       unsigned int pop = 0;
8316       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8317         pop += __builtin_popcount (*i);
8318       bool negate = pop > nbits / 2;
8319       const unsigned int bias = item->format == 'b';
8320
8321       {
8322         char printed[(negate ? nbits - pop : pop) * 16 + 1];
8323         char *p = printed;
8324         *p = '\0';
8325
8326         if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8327           {
8328             assert (size == sizeof (unsigned int) * 2);
8329             for (unsigned int *i = data;
8330                  (void *) i < data + count * size; i += 2)
8331               {
8332                 unsigned int w = i[1];
8333                 i[1] = i[0];
8334                 i[0] = w;
8335               }
8336           }
8337
8338         unsigned int lastbit = 0;
8339         unsigned int run = 0;
8340         for (const unsigned int *i = data;
8341              (void *) i < data + count * size; ++i)
8342           {
8343             unsigned int bit = ((void *) i - data) * 8;
8344             unsigned int w = negate ? ~*i : *i;
8345             while (w != 0)
8346               {
8347                 int n = ffs (w);
8348                 w >>= n;
8349                 bit += n;
8350
8351                 if (lastbit != 0 && lastbit + 1 == bit)
8352                   ++run;
8353                 else
8354                   {
8355                     if (lastbit == 0)
8356                       p += sprintf (p, "%u", bit - bias);
8357                     else if (run == 0)
8358                       p += sprintf (p, ",%u", bit - bias);
8359                     else
8360                       p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8361                     run = 0;
8362                   }
8363
8364                 lastbit = bit;
8365               }
8366           }
8367         if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8368           p += sprintf (p, "-%u", lastbit - bias);
8369
8370         colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8371                                  negate ? "~<%s>" : "<%s>", printed);
8372       }
8373       break;
8374
8375     case 'T':
8376     case (char) ('T'|0x80):
8377       assert (count == 2);
8378       Dwarf_Word sec;
8379       Dwarf_Word usec;
8380       switch (type)
8381         {
8382 #define DO_TYPE(NAME, Name, hex, dec)                                         \
8383           case ELF_T_##NAME:                                                  \
8384             sec = value.Name[0];                                              \
8385             usec = value.Name[1];                                             \
8386             break
8387           TYPES;
8388 #undef DO_TYPE
8389         default:
8390           abort ();
8391         }
8392       if (unlikely (item->format == (char) ('T'|0x80)))
8393         {
8394           /* This is a hack for an ill-considered 64-bit ABI where
8395              tv_usec is actually a 32-bit field with 32 bits of padding
8396              rounding out struct timeval.  We've already converted it as
8397              a 64-bit field.  For little-endian, this just means the
8398              high half is the padding; it's presumably zero, but should
8399              be ignored anyway.  For big-endian, it means the 32-bit
8400              field went into the high half of USEC.  */
8401           GElf_Ehdr ehdr_mem;
8402           GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8403           if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8404             usec >>= 32;
8405           else
8406             usec &= UINT32_MAX;
8407         }
8408       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8409                                "%" PRIu64 ".%.6" PRIu64, sec, usec);
8410       break;
8411
8412     case 'c':
8413       assert (count == 1);
8414       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8415                                "%c", value.Byte[0]);
8416       break;
8417
8418     case 's':
8419       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8420                                "%.*s", (int) count, value.Byte);
8421       break;
8422
8423     case '\n':
8424       /* This is a list of strings separated by '\n'.  */
8425       assert (item->count == 0);
8426       assert (repeated_size != NULL);
8427       assert (item->name == NULL);
8428       if (unlikely (item->offset >= *repeated_size))
8429         break;
8430
8431       const char *s = desc + item->offset;
8432       size = *repeated_size - item->offset;
8433       *repeated_size = 0;
8434       while (size > 0)
8435         {
8436           const char *eol = memchr (s, '\n', size);
8437           int len = size;
8438           if (eol != NULL)
8439             len = eol - s;
8440           printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8441           if (eol == NULL)
8442             break;
8443           size -= eol + 1 - s;
8444           s = eol + 1;
8445         }
8446
8447       colno = WRAP_COLUMN;
8448       break;
8449
8450     case 'h':
8451       break;
8452
8453     default:
8454       error (0, 0, "XXX not handling format '%c' for %s",
8455              item->format, item->name);
8456       break;
8457     }
8458
8459 #undef TYPES
8460
8461   return colno;
8462 }
8463
8464
8465 /* Sort items by group, and by layout offset within each group.  */
8466 static int
8467 compare_core_items (const void *a, const void *b)
8468 {
8469   const Ebl_Core_Item *const *p1 = a;
8470   const Ebl_Core_Item *const *p2 = b;
8471   const Ebl_Core_Item *item1 = *p1;
8472   const Ebl_Core_Item *item2 = *p2;
8473
8474   return ((item1->group == item2->group ? 0
8475            : strcmp (item1->group, item2->group))
8476           ?: (int) item1->offset - (int) item2->offset);
8477 }
8478
8479 /* Sort item groups by layout offset of the first item in the group.  */
8480 static int
8481 compare_core_item_groups (const void *a, const void *b)
8482 {
8483   const Ebl_Core_Item *const *const *p1 = a;
8484   const Ebl_Core_Item *const *const *p2 = b;
8485   const Ebl_Core_Item *const *group1 = *p1;
8486   const Ebl_Core_Item *const *group2 = *p2;
8487   const Ebl_Core_Item *item1 = *group1;
8488   const Ebl_Core_Item *item2 = *group2;
8489
8490   return (int) item1->offset - (int) item2->offset;
8491 }
8492
8493 static unsigned int
8494 handle_core_items (Elf *core, const void *desc, size_t descsz,
8495                    const Ebl_Core_Item *items, size_t nitems)
8496 {
8497   if (nitems == 0)
8498     return 0;
8499   unsigned int colno = 0;
8500
8501   /* FORMAT '\n' makes sense to be present only as a single item as it
8502      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
8503      if present as a single item but they can be also processed with other
8504      items below.  */
8505   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8506                       || items[0].format == 'B'))
8507     {
8508       assert (items[0].offset == 0);
8509       size_t size = descsz;
8510       colno = handle_core_item (core, items, desc, colno, &size);
8511       /* If SIZE is not zero here there is some remaining data.  But we do not
8512          know how to process it anyway.  */
8513       return colno;
8514     }
8515   for (size_t i = 0; i < nitems; ++i)
8516     assert (items[i].format != '\n');
8517
8518   /* Sort to collect the groups together.  */
8519   const Ebl_Core_Item *sorted_items[nitems];
8520   for (size_t i = 0; i < nitems; ++i)
8521     sorted_items[i] = &items[i];
8522   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8523
8524   /* Collect the unique groups and sort them.  */
8525   const Ebl_Core_Item **groups[nitems];
8526   groups[0] = &sorted_items[0];
8527   size_t ngroups = 1;
8528   for (size_t i = 1; i < nitems; ++i)
8529     if (sorted_items[i]->group != sorted_items[i - 1]->group
8530         && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8531       groups[ngroups++] = &sorted_items[i];
8532   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8533
8534   /* Write out all the groups.  */
8535   const void *last = desc;
8536   do
8537     {
8538       for (size_t i = 0; i < ngroups; ++i)
8539         {
8540           for (const Ebl_Core_Item **item = groups[i];
8541                (item < &sorted_items[nitems]
8542                 && ((*item)->group == groups[i][0]->group
8543                     || !strcmp ((*item)->group, groups[i][0]->group)));
8544                ++item)
8545             colno = handle_core_item (core, *item, desc, colno, NULL);
8546
8547           /* Force a line break at the end of the group.  */
8548           colno = WRAP_COLUMN;
8549         }
8550
8551       if (descsz == 0)
8552         break;
8553
8554       /* This set of items consumed a certain amount of the note's data.
8555          If there is more data there, we have another unit of the same size.
8556          Loop to print that out too.  */
8557       const Ebl_Core_Item *item = &items[nitems - 1];
8558       size_t eltsz = item->offset + gelf_fsize (core, item->type,
8559                                                 item->count ?: 1, EV_CURRENT);
8560
8561       int reps = -1;
8562       do
8563         {
8564           ++reps;
8565           desc += eltsz;
8566           descsz -= eltsz;
8567         }
8568       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8569
8570       if (reps == 1)
8571         {
8572           /* For just one repeat, print it unabridged twice.  */
8573           desc -= eltsz;
8574           descsz += eltsz;
8575         }
8576       else if (reps > 1)
8577         printf (gettext ("\n%*s... <repeats %u more times> ..."),
8578                 ITEM_INDENT, "", reps);
8579
8580       last = desc;
8581     }
8582   while (descsz > 0);
8583
8584   return colno;
8585 }
8586
8587 static unsigned int
8588 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8589                       unsigned int colno)
8590 {
8591   desc += regloc->offset;
8592
8593   abort ();                     /* XXX */
8594   return colno;
8595 }
8596
8597
8598 static unsigned int
8599 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8600                       const Ebl_Register_Location *regloc, const void *desc,
8601                       unsigned int colno)
8602 {
8603   if (regloc->bits % 8 != 0)
8604     return handle_bit_registers (regloc, desc, colno);
8605
8606   desc += regloc->offset;
8607
8608   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8609     {
8610       char name[REGNAMESZ];
8611       int bits;
8612       int type;
8613       register_info (ebl, reg, regloc, name, &bits, &type);
8614
8615 #define TYPES                                                                 \
8616       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);                              \
8617       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);                           \
8618       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);                         \
8619       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
8620
8621 #define BITS(bits, xtype, sfmt, ufmt)                           \
8622       uint##bits##_t b##bits; int##bits##_t b##bits##s
8623       union { TYPES; uint64_t b128[2]; } value;
8624 #undef  BITS
8625
8626       switch (type)
8627         {
8628         case DW_ATE_unsigned:
8629         case DW_ATE_signed:
8630         case DW_ATE_address:
8631           switch (bits)
8632             {
8633 #define BITS(bits, xtype, sfmt, ufmt)                                         \
8634             case bits:                                                        \
8635               desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);       \
8636               if (type == DW_ATE_signed)                                      \
8637                 colno = print_core_item (colno, ' ', WRAP_COLUMN,             \
8638                                          maxregname, name,                    \
8639                                          sfmt, value.b##bits##s);             \
8640               else                                                            \
8641                 colno = print_core_item (colno, ' ', WRAP_COLUMN,             \
8642                                          maxregname, name,                    \
8643                                          ufmt, value.b##bits);                \
8644               break
8645
8646             TYPES;
8647
8648             case 128:
8649               assert (type == DW_ATE_unsigned);
8650               desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8651               int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8652               colno = print_core_item (colno, ' ', WRAP_COLUMN,
8653                                        maxregname, name,
8654                                        "0x%.16" PRIx64 "%.16" PRIx64,
8655                                        value.b128[!be], value.b128[be]);
8656               break;
8657
8658             default:
8659               abort ();
8660 #undef  BITS
8661             }
8662           break;
8663
8664         default:
8665           /* Print each byte in hex, the whole thing in native byte order.  */
8666           assert (bits % 8 == 0);
8667           const uint8_t *bytes = desc;
8668           desc += bits / 8;
8669           char hex[bits / 4 + 1];
8670           hex[bits / 4] = '\0';
8671           int incr = 1;
8672           if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8673             {
8674               bytes += bits / 8 - 1;
8675               incr = -1;
8676             }
8677           size_t idx = 0;
8678           for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8679             {
8680               *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8681               *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8682             }
8683           colno = print_core_item (colno, ' ', WRAP_COLUMN,
8684                                    maxregname, name, "0x%s", hex);
8685           break;
8686         }
8687       desc += regloc->pad;
8688
8689 #undef TYPES
8690     }
8691
8692   return colno;
8693 }
8694
8695
8696 struct register_info
8697 {
8698   const Ebl_Register_Location *regloc;
8699   const char *set;
8700   char name[REGNAMESZ];
8701   int regno;
8702   int bits;
8703   int type;
8704 };
8705
8706 static int
8707 register_bitpos (const struct register_info *r)
8708 {
8709   return (r->regloc->offset * 8
8710           + ((r->regno - r->regloc->regno)
8711              * (r->regloc->bits + r->regloc->pad * 8)));
8712 }
8713
8714 static int
8715 compare_sets_by_info (const struct register_info *r1,
8716                       const struct register_info *r2)
8717 {
8718   return ((int) r2->bits - (int) r1->bits
8719           ?: register_bitpos (r1) - register_bitpos (r2));
8720 }
8721
8722 /* Sort registers by set, and by size and layout offset within each set.  */
8723 static int
8724 compare_registers (const void *a, const void *b)
8725 {
8726   const struct register_info *r1 = a;
8727   const struct register_info *r2 = b;
8728
8729   /* Unused elements sort last.  */
8730   if (r1->regloc == NULL)
8731     return r2->regloc == NULL ? 0 : 1;
8732   if (r2->regloc == NULL)
8733     return -1;
8734
8735   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8736           ?: compare_sets_by_info (r1, r2));
8737 }
8738
8739 /* Sort register sets by layout offset of the first register in the set.  */
8740 static int
8741 compare_register_sets (const void *a, const void *b)
8742 {
8743   const struct register_info *const *p1 = a;
8744   const struct register_info *const *p2 = b;
8745   return compare_sets_by_info (*p1, *p2);
8746 }
8747
8748 static unsigned int
8749 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
8750                        const Ebl_Register_Location *reglocs, size_t nregloc)
8751 {
8752   if (nregloc == 0)
8753     return 0;
8754
8755   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
8756   if (maxnreg <= 0)
8757     {
8758       for (size_t i = 0; i < nregloc; ++i)
8759         if (maxnreg < reglocs[i].regno + reglocs[i].count)
8760           maxnreg = reglocs[i].regno + reglocs[i].count;
8761       assert (maxnreg > 0);
8762     }
8763
8764   struct register_info regs[maxnreg];
8765   memset (regs, 0, sizeof regs);
8766
8767   /* Sort to collect the sets together.  */
8768   int maxreg = 0;
8769   for (size_t i = 0; i < nregloc; ++i)
8770     for (int reg = reglocs[i].regno;
8771          reg < reglocs[i].regno + reglocs[i].count;
8772          ++reg)
8773       {
8774         assert (reg < maxnreg);
8775         if (reg > maxreg)
8776           maxreg = reg;
8777         struct register_info *info = &regs[reg];
8778         info->regloc = &reglocs[i];
8779         info->regno = reg;
8780         info->set = register_info (ebl, reg, &reglocs[i],
8781                                    info->name, &info->bits, &info->type);
8782       }
8783   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
8784
8785   /* Collect the unique sets and sort them.  */
8786   inline bool same_set (const struct register_info *a,
8787                         const struct register_info *b)
8788   {
8789     return (a < &regs[maxnreg] && a->regloc != NULL
8790             && b < &regs[maxnreg] && b->regloc != NULL
8791             && a->bits == b->bits
8792             && (a->set == b->set || !strcmp (a->set, b->set)));
8793   }
8794   struct register_info *sets[maxreg + 1];
8795   sets[0] = &regs[0];
8796   size_t nsets = 1;
8797   for (int i = 1; i <= maxreg; ++i)
8798     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
8799       sets[nsets++] = &regs[i];
8800   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
8801
8802   /* Write out all the sets.  */
8803   unsigned int colno = 0;
8804   for (size_t i = 0; i < nsets; ++i)
8805     {
8806       /* Find the longest name of a register in this set.  */
8807       size_t maxname = 0;
8808       const struct register_info *end;
8809       for (end = sets[i]; same_set (sets[i], end); ++end)
8810         {
8811           size_t len = strlen (end->name);
8812           if (len > maxname)
8813             maxname = len;
8814         }
8815
8816       for (const struct register_info *reg = sets[i];
8817            reg < end;
8818            reg += reg->regloc->count ?: 1)
8819         colno = handle_core_register (ebl, core, maxname,
8820                                       reg->regloc, desc, colno);
8821
8822       /* Force a line break at the end of the group.  */
8823       colno = WRAP_COLUMN;
8824     }
8825
8826   return colno;
8827 }
8828
8829 static void
8830 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8831 {
8832   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
8833   if (data == NULL)
8834   elf_error:
8835     error (EXIT_FAILURE, 0,
8836            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8837
8838   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
8839   for (size_t i = 0; i < nauxv; ++i)
8840     {
8841       GElf_auxv_t av_mem;
8842       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
8843       if (av == NULL)
8844         goto elf_error;
8845
8846       const char *name;
8847       const char *fmt;
8848       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
8849         {
8850           /* Unknown type.  */
8851           if (av->a_un.a_val == 0)
8852             printf ("    %" PRIu64 "\n", av->a_type);
8853           else
8854             printf ("    %" PRIu64 ": %#" PRIx64 "\n",
8855                     av->a_type, av->a_un.a_val);
8856         }
8857       else
8858         switch (fmt[0])
8859           {
8860           case '\0':            /* Normally zero.  */
8861             if (av->a_un.a_val == 0)
8862               {
8863                 printf ("    %s\n", name);
8864                 break;
8865               }
8866             /* Fall through */
8867           case 'x':             /* hex */
8868           case 'p':             /* address */
8869           case 's':             /* address of string */
8870             printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
8871             break;
8872           case 'u':
8873             printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
8874             break;
8875           case 'd':
8876             printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
8877             break;
8878
8879           case 'b':
8880             printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
8881             GElf_Xword bit = 1;
8882             const char *pfx = "<";
8883             for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
8884               {
8885                 if (av->a_un.a_val & bit)
8886                   {
8887                     printf ("%s%s", pfx, p);
8888                     pfx = " ";
8889                   }
8890                 bit <<= 1;
8891               }
8892             printf (">\n");
8893             break;
8894
8895           default:
8896             abort ();
8897           }
8898     }
8899 }
8900
8901 static bool
8902 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
8903 {
8904   return ptr < end && (size_t) (end - ptr) >= sz;
8905 }
8906
8907 static bool
8908 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8909               int *retp)
8910 {
8911   if (! buf_has_data (*ptrp, end, 4))
8912     return false;
8913
8914   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
8915   return true;
8916 }
8917
8918 static bool
8919 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
8920                 uint64_t *retp)
8921 {
8922   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
8923   if (! buf_has_data (*ptrp, end, sz))
8924     return false;
8925
8926   union
8927   {
8928     uint64_t u64;
8929     uint32_t u32;
8930   } u;
8931
8932   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
8933
8934   if (sz == 4)
8935     *retp = u.u32;
8936   else
8937     *retp = u.u64;
8938   return true;
8939 }
8940
8941 static void
8942 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
8943 {
8944   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
8945   if (data == NULL)
8946     error (EXIT_FAILURE, 0,
8947            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8948
8949   unsigned char const *ptr = data->d_buf;
8950   unsigned char const *const end = data->d_buf + data->d_size;
8951
8952   /* Siginfo head is three ints: signal number, error number, origin
8953      code.  */
8954   int si_signo, si_errno, si_code;
8955   if (! buf_read_int (core, &ptr, end, &si_signo)
8956       || ! buf_read_int (core, &ptr, end, &si_errno)
8957       || ! buf_read_int (core, &ptr, end, &si_code))
8958     {
8959     fail:
8960       printf ("    Not enough data in NT_SIGINFO note.\n");
8961       return;
8962     }
8963
8964   /* Next is a pointer-aligned union of structures.  On 64-bit
8965      machines, that implies a word of padding.  */
8966   if (gelf_getclass (core) == ELFCLASS64)
8967     ptr += 4;
8968
8969   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
8970           si_signo, si_errno, si_code);
8971
8972   if (si_code > 0)
8973     switch (si_signo)
8974       {
8975       case SIGILL:
8976       case SIGFPE:
8977       case SIGSEGV:
8978       case SIGBUS:
8979         {
8980           uint64_t addr;
8981           if (! buf_read_ulong (core, &ptr, end, &addr))
8982             goto fail;
8983           printf ("    fault address: %#" PRIx64 "\n", addr);
8984           break;
8985         }
8986       default:
8987         ;
8988       }
8989   else if (si_code == SI_USER)
8990     {
8991       int pid, uid;
8992       if (! buf_read_int (core, &ptr, end, &pid)
8993           || ! buf_read_int (core, &ptr, end, &uid))
8994         goto fail;
8995       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
8996     }
8997 }
8998
8999 static void
9000 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9001 {
9002   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9003   if (data == NULL)
9004     error (EXIT_FAILURE, 0,
9005            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9006
9007   unsigned char const *ptr = data->d_buf;
9008   unsigned char const *const end = data->d_buf + data->d_size;
9009
9010   uint64_t count, page_size;
9011   if (! buf_read_ulong (core, &ptr, end, &count)
9012       || ! buf_read_ulong (core, &ptr, end, &page_size))
9013     {
9014     fail:
9015       printf ("    Not enough data in NT_FILE note.\n");
9016       return;
9017     }
9018
9019   /* Where file names are stored.  */
9020   unsigned char const *const fstart
9021     = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9022   char const *fptr = (char *) fstart;
9023
9024   printf ("    %" PRId64 " files:\n", count);
9025   for (uint64_t i = 0; i < count; ++i)
9026     {
9027       uint64_t mstart, mend, moffset;
9028       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9029           || ! buf_read_ulong (core, &ptr, fstart, &mend)
9030           || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9031         goto fail;
9032
9033       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9034       if (fnext == NULL)
9035         goto fail;
9036
9037       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
9038                        " %08" PRIx64 " %" PRId64,
9039                        mstart, mend, moffset * page_size, mend - mstart);
9040       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9041
9042       fptr = fnext + 1;
9043     }
9044 }
9045
9046 static void
9047 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9048                   const char *name, const void *desc)
9049 {
9050   GElf_Word regs_offset;
9051   size_t nregloc;
9052   const Ebl_Register_Location *reglocs;
9053   size_t nitems;
9054   const Ebl_Core_Item *items;
9055
9056   if (! ebl_core_note (ebl, nhdr, name,
9057                        &regs_offset, &nregloc, &reglocs, &nitems, &items))
9058     return;
9059
9060   /* Pass 0 for DESCSZ when there are registers in the note,
9061      so that the ITEMS array does not describe the whole thing.
9062      For non-register notes, the actual descsz might be a multiple
9063      of the unit size, not just exactly the unit size.  */
9064   unsigned int colno = handle_core_items (ebl->elf, desc,
9065                                           nregloc == 0 ? nhdr->n_descsz : 0,
9066                                           items, nitems);
9067   if (colno != 0)
9068     putchar_unlocked ('\n');
9069
9070   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9071                                  reglocs, nregloc);
9072   if (colno != 0)
9073     putchar_unlocked ('\n');
9074 }
9075
9076 static void
9077 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9078                    GElf_Off start, Elf_Data *data)
9079 {
9080   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
9081
9082   if (data == NULL)
9083     goto bad_note;
9084
9085   size_t offset = 0;
9086   GElf_Nhdr nhdr;
9087   size_t name_offset;
9088   size_t desc_offset;
9089   while (offset < data->d_size
9090          && (offset = gelf_getnote (data, offset,
9091                                     &nhdr, &name_offset, &desc_offset)) > 0)
9092     {
9093       const char *name = data->d_buf + name_offset;
9094       const char *desc = data->d_buf + desc_offset;
9095
9096       char buf[100];
9097       char buf2[100];
9098       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
9099               (int) nhdr.n_namesz, name, nhdr.n_descsz,
9100               ehdr->e_type == ET_CORE
9101               ? ebl_core_note_type_name (ebl, nhdr.n_type,
9102                                          buf, sizeof (buf))
9103               : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9104                                            buf2, sizeof (buf2)));
9105
9106       /* Filter out invalid entries.  */
9107       if (memchr (name, '\0', nhdr.n_namesz) != NULL
9108           /* XXX For now help broken Linux kernels.  */
9109           || 1)
9110         {
9111           if (ehdr->e_type == ET_CORE)
9112             {
9113               if (nhdr.n_type == NT_AUXV
9114                   && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
9115                       || (nhdr.n_namesz == 5 && name[4] == '\0'))
9116                   && !memcmp (name, "CORE", 4))
9117                 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9118                                   start + desc_offset);
9119               else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9120                 switch (nhdr.n_type)
9121                   {
9122                   case NT_SIGINFO:
9123                     handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9124                                          start + desc_offset);
9125                     break;
9126
9127                   case NT_FILE:
9128                     handle_file_note (ebl->elf, nhdr.n_descsz,
9129                                       start + desc_offset);
9130                     break;
9131
9132                   default:
9133                     handle_core_note (ebl, &nhdr, name, desc);
9134                   }
9135               else
9136                 handle_core_note (ebl, &nhdr, name, desc);
9137             }
9138           else
9139             ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9140         }
9141     }
9142
9143   if (offset == data->d_size)
9144     return;
9145
9146  bad_note:
9147   error (EXIT_FAILURE, 0,
9148          gettext ("cannot get content of note section: %s"),
9149          elf_errmsg (-1));
9150 }
9151
9152 static void
9153 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9154 {
9155   /* If we have section headers, just look for SHT_NOTE sections.
9156      In a debuginfo file, the program headers are not reliable.  */
9157   if (shnum != 0)
9158     {
9159       /* Get the section header string table index.  */
9160       size_t shstrndx;
9161       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9162         error (EXIT_FAILURE, 0,
9163                gettext ("cannot get section header string table index"));
9164
9165       Elf_Scn *scn = NULL;
9166       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9167         {
9168           GElf_Shdr shdr_mem;
9169           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9170
9171           if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9172             /* Not what we are looking for.  */
9173             continue;
9174
9175           printf (gettext ("\
9176 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9177                   elf_ndxscn (scn),
9178                   elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9179                   shdr->sh_size, shdr->sh_offset);
9180
9181           handle_notes_data (ebl, ehdr, shdr->sh_offset,
9182                              elf_getdata (scn, NULL));
9183         }
9184       return;
9185     }
9186
9187   /* We have to look through the program header to find the note
9188      sections.  There can be more than one.  */
9189   for (size_t cnt = 0; cnt < phnum; ++cnt)
9190     {
9191       GElf_Phdr mem;
9192       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9193
9194       if (phdr == NULL || phdr->p_type != PT_NOTE)
9195         /* Not what we are looking for.  */
9196         continue;
9197
9198       printf (gettext ("\
9199 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9200               phdr->p_filesz, phdr->p_offset);
9201
9202       handle_notes_data (ebl, ehdr, phdr->p_offset,
9203                          elf_getdata_rawchunk (ebl->elf,
9204                                                phdr->p_offset, phdr->p_filesz,
9205                                                ELF_T_NHDR));
9206     }
9207 }
9208
9209
9210 static void
9211 hex_dump (const uint8_t *data, size_t len)
9212 {
9213   size_t pos = 0;
9214   while (pos < len)
9215     {
9216       printf ("  0x%08Zx ", pos);
9217
9218       const size_t chunk = MIN (len - pos, 16);
9219
9220       for (size_t i = 0; i < chunk; ++i)
9221         if (i % 4 == 3)
9222           printf ("%02x ", data[pos + i]);
9223         else
9224           printf ("%02x", data[pos + i]);
9225
9226       if (chunk < 16)
9227         printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9228
9229       for (size_t i = 0; i < chunk; ++i)
9230         {
9231           unsigned char b = data[pos + i];
9232           printf ("%c", isprint (b) ? b : '.');
9233         }
9234
9235       putchar ('\n');
9236       pos += chunk;
9237     }
9238 }
9239
9240 static void
9241 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9242 {
9243   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9244     printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
9245             elf_ndxscn (scn), name);
9246   else
9247     {
9248       Elf_Data *data = elf_rawdata (scn, NULL);
9249       if (data == NULL)
9250         error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9251                elf_ndxscn (scn), name, elf_errmsg (-1));
9252       else
9253         {
9254           printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
9255                            " bytes at offset %#0" PRIx64 ":\n"),
9256                   elf_ndxscn (scn), name,
9257                   shdr->sh_size, shdr->sh_offset);
9258           hex_dump (data->d_buf, data->d_size);
9259         }
9260     }
9261 }
9262
9263 static void
9264 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9265 {
9266   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9267     printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"),
9268             elf_ndxscn (scn), name);
9269   else
9270     {
9271       Elf_Data *data = elf_rawdata (scn, NULL);
9272       if (data == NULL)
9273         error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
9274                elf_ndxscn (scn), name, elf_errmsg (-1));
9275       else
9276         {
9277           printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
9278                            " bytes at offset %#0" PRIx64 ":\n"),
9279                   elf_ndxscn (scn), name,
9280                   shdr->sh_size, shdr->sh_offset);
9281
9282           const char *start = data->d_buf;
9283           const char *const limit = start + data->d_size;
9284           do
9285             {
9286               const char *end = memchr (start, '\0', limit - start);
9287               const size_t pos = start - (const char *) data->d_buf;
9288               if (unlikely (end == NULL))
9289                 {
9290                   printf ("  [%6Zx]- %.*s\n",
9291                           pos, (int) (limit - start), start);
9292                   break;
9293                 }
9294               printf ("  [%6Zx]  %s\n", pos, start);
9295               start = end + 1;
9296             } while (start < limit);
9297         }
9298     }
9299 }
9300
9301 static void
9302 for_each_section_argument (Elf *elf, const struct section_argument *list,
9303                            void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9304                                          const char *name))
9305 {
9306   /* Get the section header string table index.  */
9307   size_t shstrndx;
9308   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9309     error (EXIT_FAILURE, 0,
9310            gettext ("cannot get section header string table index"));
9311
9312   for (const struct section_argument *a = list; a != NULL; a = a->next)
9313     {
9314       Elf_Scn *scn;
9315       GElf_Shdr shdr_mem;
9316       const char *name = NULL;
9317
9318       char *endp = NULL;
9319       unsigned long int shndx = strtoul (a->arg, &endp, 0);
9320       if (endp != a->arg && *endp == '\0')
9321         {
9322           scn = elf_getscn (elf, shndx);
9323           if (scn == NULL)
9324             {
9325               error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9326               continue;
9327             }
9328
9329           if (gelf_getshdr (scn, &shdr_mem) == NULL)
9330             error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9331                    elf_errmsg (-1));
9332           name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9333         }
9334       else
9335         {
9336           /* Need to look up the section by name.  */
9337           scn = NULL;
9338           bool found = false;
9339           while ((scn = elf_nextscn (elf, scn)) != NULL)
9340             {
9341               if (gelf_getshdr (scn, &shdr_mem) == NULL)
9342                 continue;
9343               name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9344               if (name == NULL)
9345                 continue;
9346               if (!strcmp (name, a->arg))
9347                 {
9348                   found = true;
9349                   (*dump) (scn, &shdr_mem, name);
9350                 }
9351             }
9352
9353           if (unlikely (!found) && !a->implicit)
9354             error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9355         }
9356     }
9357 }
9358
9359 static void
9360 dump_data (Ebl *ebl)
9361 {
9362   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9363 }
9364
9365 static void
9366 dump_strings (Ebl *ebl)
9367 {
9368   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9369 }
9370
9371 static void
9372 print_strings (Ebl *ebl)
9373 {
9374   /* Get the section header string table index.  */
9375   size_t shstrndx;
9376   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9377     error (EXIT_FAILURE, 0,
9378            gettext ("cannot get section header string table index"));
9379
9380   Elf_Scn *scn;
9381   GElf_Shdr shdr_mem;
9382   const char *name;
9383   scn = NULL;
9384   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9385     {
9386       if (gelf_getshdr (scn, &shdr_mem) == NULL)
9387         continue;
9388
9389       if (shdr_mem.sh_type != SHT_PROGBITS
9390           || !(shdr_mem.sh_flags & SHF_STRINGS))
9391         continue;
9392
9393       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9394       if (name == NULL)
9395         continue;
9396
9397       print_string_section (scn, &shdr_mem, name);
9398     }
9399 }
9400
9401 static void
9402 dump_archive_index (Elf *elf, const char *fname)
9403 {
9404   size_t narsym;
9405   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9406   if (arsym == NULL)
9407     {
9408       int result = elf_errno ();
9409       if (unlikely (result != ELF_E_NO_INDEX))
9410         error (EXIT_FAILURE, 0,
9411                gettext ("cannot get symbol index of archive '%s': %s"),
9412                fname, elf_errmsg (result));
9413       else
9414         printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9415       return;
9416     }
9417
9418   printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"),
9419           fname, narsym);
9420
9421   size_t as_off = 0;
9422   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9423     {
9424       if (s->as_off != as_off)
9425         {
9426           as_off = s->as_off;
9427
9428           Elf *subelf;
9429           if (unlikely (elf_rand (elf, as_off) == 0)
9430               || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9431                            == NULL))
9432 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9433             while (1)
9434 #endif
9435               error (EXIT_FAILURE, 0,
9436                      gettext ("cannot extract member at offset %Zu in '%s': %s"),
9437                      as_off, fname, elf_errmsg (-1));
9438
9439           const Elf_Arhdr *h = elf_getarhdr (subelf);
9440
9441           printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9442
9443           elf_end (subelf);
9444         }
9445
9446       printf ("\t%s\n", s->as_name);
9447     }
9448 }
9449
9450 #include "debugpred.h"