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