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