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