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