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