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