Home | History | Annotate | Download | only in src
      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 (at) redhat.com>, 1999.
      5 
      6    This file is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    elfutils is distributed in the hope that it will be useful, but
     12    WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18 
     19 #ifdef HAVE_CONFIG_H
     20 # include <config.h>
     21 #endif
     22 
     23 #include <argp.h>
     24 #include <assert.h>
     25 #include <ctype.h>
     26 #include <dwarf.h>
     27 #include <errno.h>
     28 #include <error.h>
     29 #include <fcntl.h>
     30 #include <gelf.h>
     31 #include <inttypes.h>
     32 #include <langinfo.h>
     33 #include <libdw.h>
     34 #include <libdwfl.h>
     35 #include <libintl.h>
     36 #include <locale.h>
     37 #include <stdarg.h>
     38 #include <stdbool.h>
     39 #include <stdlib.h>
     40 #include <string.h>
     41 #include <time.h>
     42 #include <unistd.h>
     43 #include <sys/param.h>
     44 #include <sys/stat.h>
     45 #include <signal.h>
     46 
     47 #include <system.h>
     48 #include "../libelf/libelfP.h"
     49 #include "../libelf/common.h"
     50 #include "../libebl/libeblP.h"
     51 #include "../libdw/libdwP.h"
     52 #include "../libdwfl/libdwflP.h"
     53 #include "../libdw/memory-access.h"
     54 
     55 #include "../libdw/known-dwarf.h"
     56 
     57 
     58 /* Name and version of program.  */
     59 static void print_version (FILE *stream, struct argp_state *state);
     60 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
     61 
     62 /* Bug report address.  */
     63 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
     64 
     65 /* argp key value for --elf-section, non-ascii.  */
     66 #define ELF_INPUT_SECTION 256
     67 
     68 /* Definitions of arguments for argp functions.  */
     69 static const struct argp_option options[] =
     70 {
     71   { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
     72   { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
     73     N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
     74        "input data"), 0 },
     75   { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
     76   { "all", 'a', NULL, 0,
     77     N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
     78   { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
     79   { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
     80   { "histogram", 'I', NULL, 0,
     81     N_("Display histogram of bucket list lengths"), 0 },
     82   { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
     83   { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
     84   { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
     85   { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
     86   { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
     87   { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
     88   { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
     89   { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
     90   { "arch-specific", 'A', NULL, 0,
     91     N_("Display architecture specific information, if any"), 0 },
     92   { "exception", 'e', NULL, 0,
     93     N_("Display sections for exception handling"), 0 },
     94 
     95   { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
     96   { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
     97     N_("Display DWARF section content.  SECTION can be one of abbrev, "
     98        "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
     99        "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
    100   { "hex-dump", 'x', "SECTION", 0,
    101     N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
    102   { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
    103     N_("Print string contents of sections"), 0 },
    104   { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
    105   { "archive-index", 'c', NULL, 0,
    106     N_("Display the symbol index of an archive"), 0 },
    107 
    108   { NULL, 0, NULL, 0, N_("Output control:"), 0 },
    109   { "numeric-addresses", 'N', NULL, 0,
    110     N_("Do not find symbol names for addresses in DWARF data"), 0 },
    111   { "unresolved-address-offsets", 'U', NULL, 0,
    112     N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
    113   { "wide", 'W', NULL, 0,
    114     N_("Ignored for compatibility (lines always wide)"), 0 },
    115   { NULL, 0, NULL, 0, NULL, 0 }
    116 };
    117 
    118 /* Short description of program.  */
    119 static const char doc[] = N_("\
    120 Print information from ELF file in human-readable form.");
    121 
    122 /* Strings for arguments in help texts.  */
    123 static const char args_doc[] = N_("FILE...");
    124 
    125 /* Prototype for option handler.  */
    126 static error_t parse_opt (int key, char *arg, struct argp_state *state);
    127 
    128 /* Data structure to communicate with argp functions.  */
    129 static struct argp argp =
    130 {
    131   options, parse_opt, args_doc, doc, NULL, NULL, NULL
    132 };
    133 
    134 /* If non-null, the section from which we should read to (compressed) ELF.  */
    135 static const char *elf_input_section = NULL;
    136 
    137 /* Flags set by the option controlling the output.  */
    138 
    139 /* True if dynamic segment should be printed.  */
    140 static bool print_dynamic_table;
    141 
    142 /* True if the file header should be printed.  */
    143 static bool print_file_header;
    144 
    145 /* True if the program headers should be printed.  */
    146 static bool print_program_header;
    147 
    148 /* True if relocations should be printed.  */
    149 static bool print_relocations;
    150 
    151 /* True if the section headers should be printed.  */
    152 static bool print_section_header;
    153 
    154 /* True if the symbol table should be printed.  */
    155 static bool print_symbol_table;
    156 
    157 /* True if the version information should be printed.  */
    158 static bool print_version_info;
    159 
    160 /* True if section groups should be printed.  */
    161 static bool print_section_groups;
    162 
    163 /* True if bucket list length histogram should be printed.  */
    164 static bool print_histogram;
    165 
    166 /* True if the architecture specific data should be printed.  */
    167 static bool print_arch;
    168 
    169 /* True if note section content should be printed.  */
    170 static bool print_notes;
    171 
    172 /* True if SHF_STRINGS section content should be printed.  */
    173 static bool print_string_sections;
    174 
    175 /* True if archive index should be printed.  */
    176 static bool print_archive_index;
    177 
    178 /* True if any of the control options except print_archive_index is set.  */
    179 static bool any_control_option;
    180 
    181 /* True if we should print addresses from DWARF in symbolic form.  */
    182 static bool print_address_names = true;
    183 
    184 /* True if we should print raw values instead of relativized addresses.  */
    185 static bool print_unresolved_addresses = false;
    186 
    187 /* True if we should print the .debug_aranges section using libdw.  */
    188 static bool decodedaranges = false;
    189 
    190 /* True if we should print the .debug_aranges section using libdw.  */
    191 static bool decodedline = false;
    192 
    193 /* Select printing of debugging sections.  */
    194 static enum section_e
    195 {
    196   section_abbrev = 1,		/* .debug_abbrev  */
    197   section_aranges = 2,		/* .debug_aranges  */
    198   section_frame = 4,		/* .debug_frame or .eh_frame & al.  */
    199   section_info = 8,		/* .debug_info, .debug_types  */
    200   section_types = section_info,
    201   section_line = 16,		/* .debug_line  */
    202   section_loc = 32,		/* .debug_loc  */
    203   section_pubnames = 64,	/* .debug_pubnames  */
    204   section_str = 128,		/* .debug_str  */
    205   section_macinfo = 256,	/* .debug_macinfo  */
    206   section_ranges = 512, 	/* .debug_ranges  */
    207   section_exception = 1024,	/* .eh_frame & al.  */
    208   section_gdb_index = 2048,	/* .gdb_index  */
    209   section_macro = 4096,		/* .debug_macro  */
    210   section_all = (section_abbrev | section_aranges | section_frame
    211 		 | section_info | section_line | section_loc
    212 		 | section_pubnames | section_str | section_macinfo
    213 		 | section_ranges | section_exception | section_gdb_index
    214 		 | section_macro)
    215 } print_debug_sections, implicit_debug_sections;
    216 
    217 /* Select hex dumping of sections.  */
    218 static struct section_argument *dump_data_sections;
    219 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
    220 
    221 /* Select string dumping of sections.  */
    222 static struct section_argument *string_sections;
    223 static struct section_argument **string_sections_tail = &string_sections;
    224 
    225 struct section_argument
    226 {
    227   struct section_argument *next;
    228   const char *arg;
    229   bool implicit;
    230 };
    231 
    232 /* Numbers of sections and program headers in the file.  */
    233 static size_t shnum;
    234 static size_t phnum;
    235 
    236 
    237 /* Declarations of local functions.  */
    238 static void process_file (int fd, const char *fname, bool only_one);
    239 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
    240 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
    241 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
    242 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
    243 static void print_scngrp (Ebl *ebl);
    244 static void print_dynamic (Ebl *ebl);
    245 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
    246 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
    247 			       GElf_Shdr *shdr);
    248 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
    249 				GElf_Shdr *shdr);
    250 static void print_symtab (Ebl *ebl, int type);
    251 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
    252 static void print_verinfo (Ebl *ebl);
    253 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
    254 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
    255 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
    256 			   GElf_Shdr *shdr);
    257 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
    258 static void handle_hash (Ebl *ebl);
    259 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
    260 static void print_liblist (Ebl *ebl);
    261 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
    262 static void dump_data (Ebl *ebl);
    263 static void dump_strings (Ebl *ebl);
    264 static void print_strings (Ebl *ebl);
    265 static void dump_archive_index (Elf *, const char *);
    266 
    267 
    268 int
    269 main (int argc, char *argv[])
    270 {
    271   /* Set locale.  */
    272   setlocale (LC_ALL, "");
    273 
    274   /* Initialize the message catalog.  */
    275   textdomain (PACKAGE_TARNAME);
    276 
    277   /* Parse and process arguments.  */
    278   int remaining;
    279   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
    280 
    281   /* Before we start tell the ELF library which version we are using.  */
    282   elf_version (EV_CURRENT);
    283 
    284   /* Now process all the files given at the command line.  */
    285   bool only_one = remaining + 1 == argc;
    286   do
    287     {
    288       /* Open the file.  */
    289       int fd = open (argv[remaining], O_RDONLY);
    290       if (fd == -1)
    291 	{
    292 	  error (0, errno, gettext ("cannot open input file"));
    293 	  continue;
    294 	}
    295 
    296       process_file (fd, argv[remaining], only_one);
    297 
    298       close (fd);
    299     }
    300   while (++remaining < argc);
    301 
    302   return error_message_count != 0;
    303 }
    304 
    305 
    306 /* Handle program arguments.  */
    307 static error_t
    308 parse_opt (int key, char *arg,
    309 	   struct argp_state *state __attribute__ ((unused)))
    310 {
    311   void add_dump_section (const char *name, bool implicit)
    312   {
    313     struct section_argument *a = xmalloc (sizeof *a);
    314     a->arg = name;
    315     a->next = NULL;
    316     a->implicit = implicit;
    317     struct section_argument ***tailp
    318       = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
    319     **tailp = a;
    320     *tailp = &a->next;
    321   }
    322 
    323   switch (key)
    324     {
    325     case 'a':
    326       print_file_header = true;
    327       print_program_header = true;
    328       print_relocations = true;
    329       print_section_header = true;
    330       print_symbol_table = true;
    331       print_version_info = true;
    332       print_dynamic_table = true;
    333       print_section_groups = true;
    334       print_histogram = true;
    335       print_arch = true;
    336       print_notes = true;
    337       implicit_debug_sections |= section_exception;
    338       add_dump_section (".strtab", true);
    339       add_dump_section (".dynstr", true);
    340       add_dump_section (".comment", true);
    341       any_control_option = true;
    342       break;
    343     case 'A':
    344       print_arch = true;
    345       any_control_option = true;
    346       break;
    347     case 'd':
    348       print_dynamic_table = true;
    349       any_control_option = true;
    350       break;
    351     case 'e':
    352       print_debug_sections |= section_exception;
    353       any_control_option = true;
    354       break;
    355     case 'g':
    356       print_section_groups = true;
    357       any_control_option = true;
    358       break;
    359     case 'h':
    360       print_file_header = true;
    361       any_control_option = true;
    362       break;
    363     case 'I':
    364       print_histogram = true;
    365       any_control_option = true;
    366       break;
    367     case 'l':
    368       print_program_header = true;
    369       any_control_option = true;
    370       break;
    371     case 'n':
    372       print_notes = true;
    373       any_control_option = true;
    374       break;
    375     case 'r':
    376       print_relocations = true;
    377       any_control_option = true;
    378      break;
    379     case 'S':
    380       print_section_header = true;
    381       any_control_option = true;
    382       break;
    383     case 's':
    384       print_symbol_table = true;
    385       any_control_option = true;
    386       break;
    387     case 'V':
    388       print_version_info = true;
    389       any_control_option = true;
    390       break;
    391     case 'c':
    392       print_archive_index = true;
    393       break;
    394     case 'w':
    395       if (arg == NULL)
    396 	print_debug_sections = section_all;
    397       else if (strcmp (arg, "abbrev") == 0)
    398 	print_debug_sections |= section_abbrev;
    399       else if (strcmp (arg, "aranges") == 0)
    400 	print_debug_sections |= section_aranges;
    401       else if (strcmp (arg, "decodedaranges") == 0)
    402 	{
    403 	  print_debug_sections |= section_aranges;
    404 	  decodedaranges = true;
    405 	}
    406       else if (strcmp (arg, "ranges") == 0)
    407 	{
    408 	  print_debug_sections |= section_ranges;
    409 	  implicit_debug_sections |= section_info;
    410 	}
    411       else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
    412 	print_debug_sections |= section_frame;
    413       else if (strcmp (arg, "info") == 0)
    414 	print_debug_sections |= section_info;
    415       else if (strcmp (arg, "loc") == 0)
    416 	{
    417 	  print_debug_sections |= section_loc;
    418 	  implicit_debug_sections |= section_info;
    419 	}
    420       else if (strcmp (arg, "line") == 0)
    421 	print_debug_sections |= section_line;
    422       else if (strcmp (arg, "decodedline") == 0)
    423 	{
    424 	  print_debug_sections |= section_line;
    425 	  decodedline = true;
    426 	}
    427       else if (strcmp (arg, "pubnames") == 0)
    428 	print_debug_sections |= section_pubnames;
    429       else if (strcmp (arg, "str") == 0)
    430 	print_debug_sections |= section_str;
    431       else if (strcmp (arg, "macinfo") == 0)
    432 	print_debug_sections |= section_macinfo;
    433       else if (strcmp (arg, "macro") == 0)
    434 	print_debug_sections |= section_macro;
    435       else if (strcmp (arg, "exception") == 0)
    436 	print_debug_sections |= section_exception;
    437       else if (strcmp (arg, "gdb_index") == 0)
    438 	print_debug_sections |= section_gdb_index;
    439       else
    440 	{
    441 	  fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
    442 		   arg);
    443 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
    444 		     program_invocation_short_name);
    445 	  exit (1);
    446 	}
    447       any_control_option = true;
    448       break;
    449     case 'p':
    450       any_control_option = true;
    451       if (arg == NULL)
    452 	{
    453 	  print_string_sections = true;
    454 	  break;
    455 	}
    456       /* Fall through.  */
    457     case 'x':
    458       add_dump_section (arg, false);
    459       any_control_option = true;
    460       break;
    461     case 'N':
    462       print_address_names = false;
    463       break;
    464     case 'U':
    465       print_unresolved_addresses = true;
    466       break;
    467     case ARGP_KEY_NO_ARGS:
    468       fputs (gettext ("Missing file name.\n"), stderr);
    469       goto do_argp_help;
    470     case ARGP_KEY_FINI:
    471       if (! any_control_option && ! print_archive_index)
    472 	{
    473 	  fputs (gettext ("No operation specified.\n"), stderr);
    474 	do_argp_help:
    475 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
    476 		     program_invocation_short_name);
    477 	  exit (EXIT_FAILURE);
    478 	}
    479       break;
    480     case 'W':			/* Ignored.  */
    481       break;
    482     case ELF_INPUT_SECTION:
    483       if (arg == NULL)
    484 	elf_input_section = ".gnu_debugdata";
    485       else
    486 	elf_input_section = arg;
    487       break;
    488     default:
    489       return ARGP_ERR_UNKNOWN;
    490     }
    491   return 0;
    492 }
    493 
    494 
    495 /* Print the version information.  */
    496 static void
    497 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
    498 {
    499   fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
    500   fprintf (stream, gettext ("\
    501 Copyright (C) %s Red Hat, Inc.\n\
    502 This is free software; see the source for copying conditions.  There is NO\n\
    503 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
    504 "), "2012");
    505   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
    506 }
    507 
    508 
    509 /* Create a file descriptor to read the data from the
    510    elf_input_section given a file descriptor to an ELF file.  */
    511 static int
    512 open_input_section (int fd)
    513 {
    514   size_t shnums;
    515   size_t cnt;
    516   size_t shstrndx;
    517   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
    518   if (elf == NULL)
    519     {
    520       error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
    521 	     elf_errmsg (-1));
    522       return -1;
    523     }
    524 
    525   if (elf_getshdrnum (elf, &shnums) < 0)
    526     {
    527       error (0, 0, gettext ("cannot determine number of sections: %s"),
    528 	     elf_errmsg (-1));
    529     open_error:
    530       elf_end (elf);
    531       return -1;
    532     }
    533 
    534   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
    535     {
    536       error (0, 0, gettext ("cannot get section header string table index"));
    537       goto open_error;
    538     }
    539 
    540   for (cnt = 0; cnt < shnums; ++cnt)
    541     {
    542       Elf_Scn *scn = elf_getscn (elf, cnt);
    543       if (scn == NULL)
    544 	{
    545 	  error (0, 0, gettext ("cannot get section: %s"),
    546 		 elf_errmsg (-1));
    547 	  goto open_error;
    548 	}
    549 
    550       GElf_Shdr shdr_mem;
    551       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    552       if (unlikely (shdr == NULL))
    553 	{
    554 	  error (0, 0, gettext ("cannot get section header: %s"),
    555 		 elf_errmsg (-1));
    556 	  goto open_error;
    557 	}
    558 
    559       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
    560       if (sname == NULL)
    561 	{
    562 	  error (0, 0, gettext ("cannot get section name"));
    563 	  goto open_error;
    564 	}
    565 
    566       if (strcmp (sname, elf_input_section) == 0)
    567 	{
    568 	  Elf_Data *data = elf_rawdata (scn, NULL);
    569 	  if (data == NULL)
    570 	    {
    571 	      error (0, 0, gettext ("cannot get %s content: %s"),
    572 		     sname, elf_errmsg (-1));
    573 	      goto open_error;
    574 	    }
    575 
    576 	  /* Create (and immediately unlink) a temporary file to store
    577 	     section data in to create a file descriptor for it.  */
    578 	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
    579 	  static const char suffix[] = "/readelfXXXXXX";
    580 	  int tmplen = strlen (tmpdir) + sizeof (suffix);
    581 	  char *tempname = alloca (tmplen);
    582 	  sprintf (tempname, "%s%s", tmpdir, suffix);
    583 
    584 	  int sfd = mkstemp (tempname);
    585 	  if (sfd == -1)
    586 	    {
    587 	      error (0, 0, gettext ("cannot create temp file '%s'"),
    588 		     tempname);
    589 	      goto open_error;
    590 	    }
    591 	  unlink (tempname);
    592 
    593 	  ssize_t size = data->d_size;
    594 	  if (write_retry (sfd, data->d_buf, size) != size)
    595 	    {
    596 	      error (0, 0, gettext ("cannot write section data"));
    597 	      goto open_error;
    598 	    }
    599 
    600 	  if (elf_end (elf) != 0)
    601 	    {
    602 	      error (0, 0, gettext ("error while closing Elf descriptor: %s"),
    603 		     elf_errmsg (-1));
    604 	      return -1;
    605 	    }
    606 
    607 	  if (lseek (sfd, 0, SEEK_SET) == -1)
    608 	    {
    609 	      error (0, 0, gettext ("error while rewinding file descriptor"));
    610 	      return -1;
    611 	    }
    612 
    613 	  return sfd;
    614 	}
    615     }
    616 
    617   /* Named section not found.  */
    618   if (elf_end (elf) != 0)
    619     error (0, 0, gettext ("error while closing Elf descriptor: %s"),
    620 	   elf_errmsg (-1));
    621   return -1;
    622 }
    623 
    624 /* Check if the file is an archive, and if so dump its index.  */
    625 static void
    626 check_archive_index (int fd, const char *fname, bool only_one)
    627 {
    628   /* Create an `Elf' descriptor.  */
    629   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
    630   if (elf == NULL)
    631     error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
    632 	   elf_errmsg (-1));
    633   else
    634     {
    635       if (elf_kind (elf) == ELF_K_AR)
    636 	{
    637 	  if (!only_one)
    638 	    printf ("\n%s:\n\n", fname);
    639 	  dump_archive_index (elf, fname);
    640 	}
    641       else
    642 	error (0, 0,
    643 	       gettext ("'%s' is not an archive, cannot print archive index"),
    644 	       fname);
    645 
    646       /* Now we can close the descriptor.  */
    647       if (elf_end (elf) != 0)
    648 	error (0, 0, gettext ("error while closing Elf descriptor: %s"),
    649 	       elf_errmsg (-1));
    650     }
    651 }
    652 
    653 /* Trivial callback used for checking if we opened an archive.  */
    654 static int
    655 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
    656 	       void **userdata __attribute__ ((unused)),
    657 	       const char *name __attribute__ ((unused)),
    658 	       Dwarf_Addr base __attribute__ ((unused)),
    659 	       void *arg)
    660 {
    661   if (*(bool *) arg)
    662     return DWARF_CB_ABORT;
    663   *(bool *) arg = true;
    664   return DWARF_CB_OK;
    665 }
    666 
    667 struct process_dwflmod_args
    668 {
    669   int fd;
    670   bool only_one;
    671 };
    672 
    673 static int
    674 process_dwflmod (Dwfl_Module *dwflmod,
    675 		 void **userdata __attribute__ ((unused)),
    676 		 const char *name __attribute__ ((unused)),
    677 		 Dwarf_Addr base __attribute__ ((unused)),
    678 		 void *arg)
    679 {
    680   const struct process_dwflmod_args *a = arg;
    681 
    682   /* Print the file name.  */
    683   if (!a->only_one)
    684     {
    685       const char *fname;
    686       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
    687 
    688       printf ("\n%s:\n\n", fname);
    689     }
    690 
    691   process_elf_file (dwflmod, a->fd);
    692 
    693   return DWARF_CB_OK;
    694 }
    695 
    696 /* Stub libdwfl callback, only the ELF handle already open is ever used.
    697    Only used for finding the alternate debug file if the Dwarf comes from
    698    the main file.  We are not interested in separate debuginfo.  */
    699 static int
    700 find_no_debuginfo (Dwfl_Module *mod,
    701 		   void **userdata,
    702 		   const char *modname,
    703 		   Dwarf_Addr base,
    704 		   const char *file_name,
    705 		   const char *debuglink_file,
    706 		   GElf_Word debuglink_crc,
    707 		   char **debuginfo_file_name)
    708 {
    709   Dwarf_Addr dwbias;
    710   dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
    711 
    712   /* We are only interested if the Dwarf has been setup on the main
    713      elf file but is only missing the alternate debug link.  If dwbias
    714      hasn't even been setup, this is searching for separate debuginfo
    715      for the main elf.  We don't care in that case.  */
    716   if (dwbias == (Dwarf_Addr) -1)
    717     return -1;
    718 
    719   return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
    720 				       file_name, debuglink_file,
    721 				       debuglink_crc, debuginfo_file_name);
    722 }
    723 
    724 /* Process one input file.  */
    725 static void
    726 process_file (int fd, const char *fname, bool only_one)
    727 {
    728   if (print_archive_index)
    729     check_archive_index (fd, fname, only_one);
    730 
    731   if (!any_control_option)
    732     return;
    733 
    734   if (elf_input_section != NULL)
    735     {
    736       /* Replace fname and fd with section content. */
    737       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
    738       sprintf (fnname, "%s:%s", fname, elf_input_section);
    739       fd = open_input_section (fd);
    740       if (fd == -1)
    741         {
    742           error (0, 0, gettext ("No such section '%s' in '%s'"),
    743 		 elf_input_section, fname);
    744           return;
    745         }
    746       fname = fnname;
    747     }
    748 
    749   /* Duplicate an fd for dwfl_report_offline to swallow.  */
    750   int dwfl_fd = dup (fd);
    751   if (unlikely (dwfl_fd < 0))
    752     error (EXIT_FAILURE, errno, "dup");
    753 
    754   /* Use libdwfl in a trivial way to open the libdw handle for us.
    755      This takes care of applying relocations to DWARF data in ET_REL files.  */
    756   static const Dwfl_Callbacks callbacks =
    757     {
    758       .section_address = dwfl_offline_section_address,
    759       .find_debuginfo = find_no_debuginfo
    760     };
    761   Dwfl *dwfl = dwfl_begin (&callbacks);
    762   if (likely (dwfl != NULL))
    763     /* Let 0 be the logical address of the file (or first in archive).  */
    764     dwfl->offline_next_address = 0;
    765   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
    766     {
    767       struct stat64 st;
    768       if (fstat64 (dwfl_fd, &st) != 0)
    769 	error (0, errno, gettext ("cannot stat input file"));
    770       else if (unlikely (st.st_size == 0))
    771 	error (0, 0, gettext ("input file is empty"));
    772       else
    773 	error (0, 0, gettext ("failed reading '%s': %s"),
    774 	       fname, dwfl_errmsg (-1));
    775       close (dwfl_fd);		/* Consumed on success, not on failure.  */
    776     }
    777   else
    778     {
    779       dwfl_report_end (dwfl, NULL, NULL);
    780 
    781       if (only_one)
    782 	{
    783 	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
    784 	  bool seen = false;
    785 	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
    786 	}
    787 
    788       /* Process the one or more modules gleaned from this file.  */
    789       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
    790       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
    791     }
    792   dwfl_end (dwfl);
    793 
    794   /* Need to close the replaced fd if we created it.  Caller takes
    795      care of original.  */
    796   if (elf_input_section != NULL)
    797     close (fd);
    798 }
    799 
    800 
    801 /* Process one ELF file.  */
    802 static void
    803 process_elf_file (Dwfl_Module *dwflmod, int fd)
    804 {
    805   GElf_Addr dwflbias;
    806   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
    807 
    808   GElf_Ehdr ehdr_mem;
    809   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
    810 
    811   if (ehdr == NULL)
    812     {
    813     elf_error:
    814       error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
    815       return;
    816     }
    817 
    818   Ebl *ebl = ebl_openbackend (elf);
    819   if (unlikely (ebl == NULL))
    820     {
    821     ebl_error:
    822       error (0, errno, gettext ("cannot create EBL handle"));
    823       return;
    824     }
    825 
    826   /* Determine the number of sections.  */
    827   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
    828     error (EXIT_FAILURE, 0,
    829 	   gettext ("cannot determine number of sections: %s"),
    830 	   elf_errmsg (-1));
    831 
    832   /* Determine the number of phdrs.  */
    833   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
    834     error (EXIT_FAILURE, 0,
    835 	   gettext ("cannot determine number of program headers: %s"),
    836 	   elf_errmsg (-1));
    837 
    838   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs
    839      and may have applied relocation to some sections.
    840      So we need to get a fresh Elf handle on the file to display those.  */
    841   bool print_unrelocated = (print_section_header
    842 			    || print_relocations
    843 			    || dump_data_sections != NULL
    844 			    || print_notes);
    845 
    846   Elf *pure_elf = NULL;
    847   Ebl *pure_ebl = ebl;
    848   if (ehdr->e_type == ET_REL && print_unrelocated)
    849     {
    850       /* Read the file afresh.  */
    851       off64_t aroff = elf_getaroff (elf);
    852       pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
    853       if (aroff > 0)
    854 	{
    855 	  /* Archive member.  */
    856 	  (void) elf_rand (pure_elf, aroff);
    857 	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
    858 	  elf_end (pure_elf);
    859 	  pure_elf = armem;
    860 	}
    861       if (pure_elf == NULL)
    862 	goto elf_error;
    863       pure_ebl = ebl_openbackend (pure_elf);
    864       if (pure_ebl == NULL)
    865 	goto ebl_error;
    866     }
    867 
    868   if (print_file_header)
    869     print_ehdr (ebl, ehdr);
    870   if (print_section_header)
    871     print_shdr (pure_ebl, ehdr);
    872   if (print_program_header)
    873     print_phdr (ebl, ehdr);
    874   if (print_section_groups)
    875     print_scngrp (ebl);
    876   if (print_dynamic_table)
    877     print_dynamic (ebl);
    878   if (print_relocations)
    879     print_relocs (pure_ebl, ehdr);
    880   if (print_histogram)
    881     handle_hash (ebl);
    882   if (print_symbol_table)
    883     print_symtab (ebl, SHT_DYNSYM);
    884   if (print_version_info)
    885     print_verinfo (ebl);
    886   if (print_symbol_table)
    887     print_symtab (ebl, SHT_SYMTAB);
    888   if (print_arch)
    889     print_liblist (ebl);
    890   if (print_arch)
    891     print_attributes (ebl, ehdr);
    892   if (dump_data_sections != NULL)
    893     dump_data (pure_ebl);
    894   if (string_sections != NULL)
    895     dump_strings (ebl);
    896   if ((print_debug_sections | implicit_debug_sections) != 0)
    897     print_debug (dwflmod, ebl, ehdr);
    898   if (print_notes)
    899     handle_notes (pure_ebl, ehdr);
    900   if (print_string_sections)
    901     print_strings (ebl);
    902 
    903   ebl_closebackend (ebl);
    904 
    905   if (pure_ebl != ebl)
    906     {
    907       ebl_closebackend (pure_ebl);
    908       elf_end (pure_elf);
    909     }
    910 }
    911 
    912 
    913 /* Print file type.  */
    914 static void
    915 print_file_type (unsigned short int e_type)
    916 {
    917   if (likely (e_type <= ET_CORE))
    918     {
    919       static const char *const knowntypes[] =
    920       {
    921 	N_("NONE (None)"),
    922 	N_("REL (Relocatable file)"),
    923 	N_("EXEC (Executable file)"),
    924 	N_("DYN (Shared object file)"),
    925 	N_("CORE (Core file)")
    926       };
    927       puts (gettext (knowntypes[e_type]));
    928     }
    929   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
    930     printf (gettext ("OS Specific: (%x)\n"),  e_type);
    931   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
    932     printf (gettext ("Processor Specific: (%x)\n"),  e_type);
    933   else
    934     puts ("???");
    935 }
    936 
    937 
    938 /* Print ELF header.  */
    939 static void
    940 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
    941 {
    942   fputs_unlocked (gettext ("ELF Header:\n  Magic:  "), stdout);
    943   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
    944     printf (" %02hhx", ehdr->e_ident[cnt]);
    945 
    946   printf (gettext ("\n  Class:                             %s\n"),
    947 	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
    948 	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
    949 	  : "\?\?\?");
    950 
    951   printf (gettext ("  Data:                              %s\n"),
    952 	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
    953 	  ? "2's complement, little endian"
    954 	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
    955 	  ? "2's complement, big endian" : "\?\?\?");
    956 
    957   printf (gettext ("  Ident Version:                     %hhd %s\n"),
    958 	  ehdr->e_ident[EI_VERSION],
    959 	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
    960 	  : "(\?\?\?)");
    961 
    962   char buf[512];
    963   printf (gettext ("  OS/ABI:                            %s\n"),
    964 	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
    965 
    966   printf (gettext ("  ABI Version:                       %hhd\n"),
    967 	  ehdr->e_ident[EI_ABIVERSION]);
    968 
    969   fputs_unlocked (gettext ("  Type:                              "), stdout);
    970   print_file_type (ehdr->e_type);
    971 
    972   printf (gettext ("  Machine:                           %s\n"), ebl->name);
    973 
    974   printf (gettext ("  Version:                           %d %s\n"),
    975 	  ehdr->e_version,
    976 	  ehdr->e_version  == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
    977 
    978   printf (gettext ("  Entry point address:               %#" PRIx64 "\n"),
    979 	  ehdr->e_entry);
    980 
    981   printf (gettext ("  Start of program headers:          %" PRId64 " %s\n"),
    982 	  ehdr->e_phoff, gettext ("(bytes into file)"));
    983 
    984   printf (gettext ("  Start of section headers:          %" PRId64 " %s\n"),
    985 	  ehdr->e_shoff, gettext ("(bytes into file)"));
    986 
    987   printf (gettext ("  Flags:                             %s\n"),
    988 	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
    989 
    990   printf (gettext ("  Size of this header:               %" PRId16 " %s\n"),
    991 	  ehdr->e_ehsize, gettext ("(bytes)"));
    992 
    993   printf (gettext ("  Size of program header entries:    %" PRId16 " %s\n"),
    994 	  ehdr->e_phentsize, gettext ("(bytes)"));
    995 
    996   printf (gettext ("  Number of program headers entries: %" PRId16),
    997 	  ehdr->e_phnum);
    998   if (ehdr->e_phnum == PN_XNUM)
    999     {
   1000       GElf_Shdr shdr_mem;
   1001       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
   1002       if (shdr != NULL)
   1003 	printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
   1004 		(uint32_t) shdr->sh_info);
   1005       else
   1006 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
   1007     }
   1008   fputc_unlocked ('\n', stdout);
   1009 
   1010   printf (gettext ("  Size of section header entries:    %" PRId16 " %s\n"),
   1011 	  ehdr->e_shentsize, gettext ("(bytes)"));
   1012 
   1013   printf (gettext ("  Number of section headers entries: %" PRId16),
   1014 	  ehdr->e_shnum);
   1015   if (ehdr->e_shnum == 0)
   1016     {
   1017       GElf_Shdr shdr_mem;
   1018       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
   1019       if (shdr != NULL)
   1020 	printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
   1021 		(uint32_t) shdr->sh_size);
   1022       else
   1023 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
   1024     }
   1025   fputc_unlocked ('\n', stdout);
   1026 
   1027   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
   1028     {
   1029       GElf_Shdr shdr_mem;
   1030       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
   1031       if (shdr != NULL)
   1032 	/* We managed to get the zeroth section.  */
   1033 	snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
   1034 		  (uint32_t) shdr->sh_link);
   1035       else
   1036 	{
   1037 	  strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
   1038 	  buf[sizeof (buf) - 1] = '\0';
   1039 	}
   1040 
   1041       printf (gettext ("  Section header string table index: XINDEX%s\n\n"),
   1042 	      buf);
   1043     }
   1044   else
   1045     printf (gettext ("  Section header string table index: %" PRId16 "\n\n"),
   1046 	    ehdr->e_shstrndx);
   1047 }
   1048 
   1049 
   1050 static const char *
   1051 get_visibility_type (int value)
   1052 {
   1053   switch (value)
   1054     {
   1055     case STV_DEFAULT:
   1056       return "DEFAULT";
   1057     case STV_INTERNAL:
   1058       return "INTERNAL";
   1059     case STV_HIDDEN:
   1060       return "HIDDEN";
   1061     case STV_PROTECTED:
   1062       return "PROTECTED";
   1063     default:
   1064       return "???";
   1065     }
   1066 }
   1067 
   1068 
   1069 /* Print the section headers.  */
   1070 static void
   1071 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
   1072 {
   1073   size_t cnt;
   1074   size_t shstrndx;
   1075 
   1076   if (! print_file_header)
   1077     printf (gettext ("\
   1078 There are %d section headers, starting at offset %#" PRIx64 ":\n\
   1079 \n"),
   1080 	    ehdr->e_shnum, ehdr->e_shoff);
   1081 
   1082   /* Get the section header string table index.  */
   1083   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1084     error (EXIT_FAILURE, 0,
   1085 	   gettext ("cannot get section header string table index"));
   1086 
   1087   puts (gettext ("Section Headers:"));
   1088 
   1089   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
   1090     puts (gettext ("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
   1091   else
   1092     puts (gettext ("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
   1093 
   1094   for (cnt = 0; cnt < shnum; ++cnt)
   1095     {
   1096       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
   1097 
   1098       if (unlikely (scn == NULL))
   1099 	error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
   1100 	       elf_errmsg (-1));
   1101 
   1102       /* Get the section header.  */
   1103       GElf_Shdr shdr_mem;
   1104       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1105       if (unlikely (shdr == NULL))
   1106 	error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
   1107 	       elf_errmsg (-1));
   1108 
   1109       char flagbuf[20];
   1110       char *cp = flagbuf;
   1111       if (shdr->sh_flags & SHF_WRITE)
   1112 	*cp++ = 'W';
   1113       if (shdr->sh_flags & SHF_ALLOC)
   1114 	*cp++ = 'A';
   1115       if (shdr->sh_flags & SHF_EXECINSTR)
   1116 	*cp++ = 'X';
   1117       if (shdr->sh_flags & SHF_MERGE)
   1118 	*cp++ = 'M';
   1119       if (shdr->sh_flags & SHF_STRINGS)
   1120 	*cp++ = 'S';
   1121       if (shdr->sh_flags & SHF_INFO_LINK)
   1122 	*cp++ = 'I';
   1123       if (shdr->sh_flags & SHF_LINK_ORDER)
   1124 	*cp++ = 'L';
   1125       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
   1126 	*cp++ = 'N';
   1127       if (shdr->sh_flags & SHF_GROUP)
   1128 	*cp++ = 'G';
   1129       if (shdr->sh_flags & SHF_TLS)
   1130 	*cp++ = 'T';
   1131       if (shdr->sh_flags & SHF_ORDERED)
   1132 	*cp++ = 'O';
   1133       if (shdr->sh_flags & SHF_EXCLUDE)
   1134 	*cp++ = 'E';
   1135       *cp = '\0';
   1136 
   1137       char buf[128];
   1138       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
   1139 	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
   1140 	      " %2" PRId64 "\n",
   1141 	      cnt,
   1142 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name)
   1143 	      ?: "<corrupt>",
   1144 	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
   1145 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
   1146 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
   1147 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
   1148 	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
   1149 	      shdr->sh_addralign);
   1150     }
   1151 
   1152   fputc_unlocked ('\n', stdout);
   1153 }
   1154 
   1155 
   1156 /* Print the program header.  */
   1157 static void
   1158 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
   1159 {
   1160   if (phnum == 0)
   1161     /* No program header, this is OK in relocatable objects.  */
   1162     return;
   1163 
   1164   puts (gettext ("Program Headers:"));
   1165   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
   1166     puts (gettext ("\
   1167   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
   1168   else
   1169     puts (gettext ("\
   1170   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
   1171 
   1172   /* Process all program headers.  */
   1173   bool has_relro = false;
   1174   GElf_Addr relro_from = 0;
   1175   GElf_Addr relro_to = 0;
   1176   for (size_t cnt = 0; cnt < phnum; ++cnt)
   1177     {
   1178       char buf[128];
   1179       GElf_Phdr mem;
   1180       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
   1181 
   1182       /* If for some reason the header cannot be returned show this.  */
   1183       if (unlikely (phdr == NULL))
   1184 	{
   1185 	  puts ("  ???");
   1186 	  continue;
   1187 	}
   1188 
   1189       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
   1190 	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
   1191 	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
   1192 	      phdr->p_offset,
   1193 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
   1194 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
   1195 	      phdr->p_filesz,
   1196 	      phdr->p_memsz,
   1197 	      phdr->p_flags & PF_R ? 'R' : ' ',
   1198 	      phdr->p_flags & PF_W ? 'W' : ' ',
   1199 	      phdr->p_flags & PF_X ? 'E' : ' ',
   1200 	      phdr->p_align);
   1201 
   1202       if (phdr->p_type == PT_INTERP)
   1203 	{
   1204 	  /* If we are sure the file offset is valid then we can show
   1205 	     the user the name of the interpreter.  We check whether
   1206 	     there is a section at the file offset.  Normally there
   1207 	     would be a section called ".interp".  But in separate
   1208 	     .debug files it is a NOBITS section (and so doesn't match
   1209 	     with gelf_offscn).  Which probably means the offset is
   1210 	     not valid another reason could be because the ELF file
   1211 	     just doesn't contain any section headers, in that case
   1212 	     just play it safe and don't display anything.  */
   1213 
   1214 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
   1215 	  GElf_Shdr shdr_mem;
   1216 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1217 
   1218 	  size_t maxsize;
   1219 	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
   1220 
   1221 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
   1222 	      && filedata != NULL && phdr->p_offset < maxsize
   1223 	      && phdr->p_filesz <= maxsize - phdr->p_offset
   1224 	      && memchr (filedata + phdr->p_offset, '\0',
   1225 			 phdr->p_filesz) != NULL)
   1226 	    printf (gettext ("\t[Requesting program interpreter: %s]\n"),
   1227 		    filedata + phdr->p_offset);
   1228 	}
   1229       else if (phdr->p_type == PT_GNU_RELRO)
   1230 	{
   1231 	  has_relro = true;
   1232 	  relro_from = phdr->p_vaddr;
   1233 	  relro_to = relro_from + phdr->p_memsz;
   1234 	}
   1235     }
   1236 
   1237   if (ehdr->e_shnum == 0)
   1238     /* No sections in the file.  Punt.  */
   1239     return;
   1240 
   1241   /* Get the section header string table index.  */
   1242   size_t shstrndx;
   1243   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1244     error (EXIT_FAILURE, 0,
   1245 	   gettext ("cannot get section header string table index"));
   1246 
   1247   puts (gettext ("\n Section to Segment mapping:\n  Segment Sections..."));
   1248 
   1249   for (size_t cnt = 0; cnt < phnum; ++cnt)
   1250     {
   1251       /* Print the segment number.  */
   1252       printf ("   %2.2zu     ", cnt);
   1253 
   1254       GElf_Phdr phdr_mem;
   1255       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
   1256       /* This must not happen.  */
   1257       if (unlikely (phdr == NULL))
   1258 	error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
   1259 	       elf_errmsg (-1));
   1260 
   1261       /* Iterate over the sections.  */
   1262       bool in_relro = false;
   1263       bool in_ro = false;
   1264       for (size_t inner = 1; inner < shnum; ++inner)
   1265 	{
   1266 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
   1267 	  /* This should not happen.  */
   1268 	  if (unlikely (scn == NULL))
   1269 	    error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
   1270 		   elf_errmsg (-1));
   1271 
   1272 	  /* Get the section header.  */
   1273 	  GElf_Shdr shdr_mem;
   1274 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1275 	  if (unlikely (shdr == NULL))
   1276 	    error (EXIT_FAILURE, 0,
   1277 		   gettext ("cannot get section header: %s"),
   1278 		   elf_errmsg (-1));
   1279 
   1280 	  if (shdr->sh_size > 0
   1281 	      /* Compare allocated sections by VMA, unallocated
   1282 		 sections by file offset.  */
   1283 	      && (shdr->sh_flags & SHF_ALLOC
   1284 		  ? (shdr->sh_addr >= phdr->p_vaddr
   1285 		     && (shdr->sh_addr + shdr->sh_size
   1286 			 <= phdr->p_vaddr + phdr->p_memsz))
   1287 		  : (shdr->sh_offset >= phdr->p_offset
   1288 		     && (shdr->sh_offset + shdr->sh_size
   1289 			 <= phdr->p_offset + phdr->p_filesz))))
   1290 	    {
   1291 	      if (has_relro && !in_relro
   1292 		  && shdr->sh_addr >= relro_from
   1293 		  && shdr->sh_addr + shdr->sh_size <= relro_to)
   1294 		{
   1295 		  fputs_unlocked (" [RELRO:", stdout);
   1296 		  in_relro = true;
   1297 		}
   1298 	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
   1299 		{
   1300 		  fputs_unlocked ("]", stdout);
   1301 		  in_relro =  false;
   1302 		}
   1303 	      else if (has_relro && in_relro
   1304 		       && shdr->sh_addr + shdr->sh_size > relro_to)
   1305 		fputs_unlocked ("] <RELRO:", stdout);
   1306 	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
   1307 		{
   1308 		  if (!in_ro)
   1309 		    {
   1310 		      fputs_unlocked (" [RO:", stdout);
   1311 		      in_ro = true;
   1312 		    }
   1313 		}
   1314 	      else
   1315 		{
   1316 		  /* Determine the segment this section is part of.  */
   1317 		  size_t cnt2;
   1318 		  GElf_Phdr *phdr2 = NULL;
   1319 		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
   1320 		    {
   1321 		      GElf_Phdr phdr2_mem;
   1322 		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
   1323 
   1324 		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
   1325 			  && shdr->sh_addr >= phdr2->p_vaddr
   1326 			  && (shdr->sh_addr + shdr->sh_size
   1327 			      <= phdr2->p_vaddr + phdr2->p_memsz))
   1328 			break;
   1329 		    }
   1330 
   1331 		  if (cnt2 < phnum)
   1332 		    {
   1333 		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
   1334 			{
   1335 			  fputs_unlocked (" [RO:", stdout);
   1336 			  in_ro = true;
   1337 			}
   1338 		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
   1339 			{
   1340 			  fputs_unlocked ("]", stdout);
   1341 			  in_ro = false;
   1342 			}
   1343 		    }
   1344 		}
   1345 
   1346 	      printf (" %s",
   1347 		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
   1348 
   1349 	      /* Signal that this sectin is only partially covered.  */
   1350 	      if (has_relro && in_relro
   1351 		       && shdr->sh_addr + shdr->sh_size > relro_to)
   1352 		{
   1353 		  fputs_unlocked (">", stdout);
   1354 		  in_relro =  false;
   1355 		}
   1356 	    }
   1357 	}
   1358       if (in_relro || in_ro)
   1359 	fputs_unlocked ("]", stdout);
   1360 
   1361       /* Finish the line.  */
   1362       fputc_unlocked ('\n', stdout);
   1363     }
   1364 }
   1365 
   1366 
   1367 static const char *
   1368 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
   1369 {
   1370   return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
   1371 }
   1372 
   1373 
   1374 static void
   1375 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   1376 {
   1377   /* Get the data of the section.  */
   1378   Elf_Data *data = elf_getdata (scn, NULL);
   1379 
   1380   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
   1381   GElf_Shdr symshdr_mem;
   1382   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   1383   Elf_Data *symdata = elf_getdata (symscn, NULL);
   1384 
   1385   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
   1386       || symdata == NULL)
   1387     return;
   1388 
   1389   /* Get the section header string table index.  */
   1390   size_t shstrndx;
   1391   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1392     error (EXIT_FAILURE, 0,
   1393 	   gettext ("cannot get section header string table index"));
   1394 
   1395   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
   1396 
   1397   GElf_Sym sym_mem;
   1398   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
   1399 
   1400   printf ((grpref[0] & GRP_COMDAT)
   1401 	  ? ngettext ("\
   1402 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
   1403 		      "\
   1404 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
   1405 		      data->d_size / sizeof (Elf32_Word) - 1)
   1406 	  : ngettext ("\
   1407 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
   1408 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
   1409 		      data->d_size / sizeof (Elf32_Word) - 1),
   1410 	  elf_ndxscn (scn),
   1411 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1412 	  (sym == NULL ? NULL
   1413 	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
   1414 	  ?: gettext ("<INVALID SYMBOL>"),
   1415 	  data->d_size / sizeof (Elf32_Word) - 1);
   1416 
   1417   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
   1418     {
   1419       GElf_Shdr grpshdr_mem;
   1420       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
   1421 					 &grpshdr_mem);
   1422 
   1423       const char *str;
   1424       printf ("  [%2u] %s\n",
   1425 	      grpref[cnt],
   1426 	      grpshdr != NULL
   1427 	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
   1428 	      ? str : gettext ("<INVALID SECTION>"));
   1429     }
   1430 }
   1431 
   1432 
   1433 static void
   1434 print_scngrp (Ebl *ebl)
   1435 {
   1436   /* Find all relocation sections and handle them.  */
   1437   Elf_Scn *scn = NULL;
   1438 
   1439   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   1440     {
   1441        /* Handle the section if it is a symbol table.  */
   1442       GElf_Shdr shdr_mem;
   1443       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1444 
   1445       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
   1446 	handle_scngrp (ebl, scn, shdr);
   1447     }
   1448 }
   1449 
   1450 
   1451 static const struct flags
   1452 {
   1453   int mask;
   1454   const char *str;
   1455 } dt_flags[] =
   1456   {
   1457     { DF_ORIGIN, "ORIGIN" },
   1458     { DF_SYMBOLIC, "SYMBOLIC" },
   1459     { DF_TEXTREL, "TEXTREL" },
   1460     { DF_BIND_NOW, "BIND_NOW" },
   1461     { DF_STATIC_TLS, "STATIC_TLS" }
   1462   };
   1463 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
   1464 
   1465 static const struct flags dt_flags_1[] =
   1466   {
   1467     { DF_1_NOW, "NOW" },
   1468     { DF_1_GLOBAL, "GLOBAL" },
   1469     { DF_1_GROUP, "GROUP" },
   1470     { DF_1_NODELETE, "NODELETE" },
   1471     { DF_1_LOADFLTR, "LOADFLTR" },
   1472     { DF_1_INITFIRST, "INITFIRST" },
   1473     { DF_1_NOOPEN, "NOOPEN" },
   1474     { DF_1_ORIGIN, "ORIGIN" },
   1475     { DF_1_DIRECT, "DIRECT" },
   1476     { DF_1_TRANS, "TRANS" },
   1477     { DF_1_INTERPOSE, "INTERPOSE" },
   1478     { DF_1_NODEFLIB, "NODEFLIB" },
   1479     { DF_1_NODUMP, "NODUMP" },
   1480     { DF_1_CONFALT, "CONFALT" },
   1481     { DF_1_ENDFILTEE, "ENDFILTEE" },
   1482     { DF_1_DISPRELDNE, "DISPRELDNE" },
   1483     { DF_1_DISPRELPND, "DISPRELPND" },
   1484   };
   1485 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
   1486 
   1487 static const struct flags dt_feature_1[] =
   1488   {
   1489     { DTF_1_PARINIT, "PARINIT" },
   1490     { DTF_1_CONFEXP, "CONFEXP" }
   1491   };
   1492 static const int ndt_feature_1 = (sizeof (dt_feature_1)
   1493 				  / sizeof (dt_feature_1[0]));
   1494 
   1495 static const struct flags dt_posflag_1[] =
   1496   {
   1497     { DF_P1_LAZYLOAD, "LAZYLOAD" },
   1498     { DF_P1_GROUPPERM, "GROUPPERM" }
   1499   };
   1500 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
   1501 				  / sizeof (dt_posflag_1[0]));
   1502 
   1503 
   1504 static void
   1505 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
   1506 		int nflags)
   1507 {
   1508   bool first = true;
   1509   int cnt;
   1510 
   1511   for (cnt = 0; cnt < nflags; ++cnt)
   1512     if (d_val & flags[cnt].mask)
   1513       {
   1514 	if (!first)
   1515 	  putchar_unlocked (' ');
   1516 	fputs_unlocked (flags[cnt].str, stdout);
   1517 	d_val &= ~flags[cnt].mask;
   1518 	first = false;
   1519       }
   1520 
   1521   if (d_val != 0)
   1522     {
   1523       if (!first)
   1524 	putchar_unlocked (' ');
   1525       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
   1526     }
   1527 
   1528   putchar_unlocked ('\n');
   1529 }
   1530 
   1531 
   1532 static void
   1533 print_dt_flags (int class, GElf_Xword d_val)
   1534 {
   1535   print_flags (class, d_val, dt_flags, ndt_flags);
   1536 }
   1537 
   1538 
   1539 static void
   1540 print_dt_flags_1 (int class, GElf_Xword d_val)
   1541 {
   1542   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
   1543 }
   1544 
   1545 
   1546 static void
   1547 print_dt_feature_1 (int class, GElf_Xword d_val)
   1548 {
   1549   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
   1550 }
   1551 
   1552 
   1553 static void
   1554 print_dt_posflag_1 (int class, GElf_Xword d_val)
   1555 {
   1556   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
   1557 }
   1558 
   1559 
   1560 static void
   1561 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   1562 {
   1563   int class = gelf_getclass (ebl->elf);
   1564   GElf_Shdr glink_mem;
   1565   GElf_Shdr *glink;
   1566   Elf_Data *data;
   1567   size_t cnt;
   1568   size_t shstrndx;
   1569   size_t sh_entsize;
   1570 
   1571   /* Get the data of the section.  */
   1572   data = elf_getdata (scn, NULL);
   1573   if (data == NULL)
   1574     return;
   1575 
   1576   /* Get the section header string table index.  */
   1577   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1578     error (EXIT_FAILURE, 0,
   1579 	   gettext ("cannot get section header string table index"));
   1580 
   1581   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
   1582 
   1583   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
   1584   if (glink == NULL)
   1585     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
   1586 	   elf_ndxscn (scn));
   1587 
   1588   printf (ngettext ("\
   1589 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   1590 		    "\
   1591 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   1592 		    shdr->sh_size / sh_entsize),
   1593 	  (unsigned long int) (shdr->sh_size / sh_entsize),
   1594 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   1595 	  shdr->sh_offset,
   1596 	  (int) shdr->sh_link,
   1597 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   1598   fputs_unlocked (gettext ("  Type              Value\n"), stdout);
   1599 
   1600   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
   1601     {
   1602       GElf_Dyn dynmem;
   1603       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
   1604       if (dyn == NULL)
   1605 	break;
   1606 
   1607       char buf[64];
   1608       printf ("  %-17s ",
   1609 	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
   1610 
   1611       switch (dyn->d_tag)
   1612 	{
   1613 	case DT_NULL:
   1614 	case DT_DEBUG:
   1615 	case DT_BIND_NOW:
   1616 	case DT_TEXTREL:
   1617 	  /* No further output.  */
   1618 	  fputc_unlocked ('\n', stdout);
   1619 	  break;
   1620 
   1621 	case DT_NEEDED:
   1622 	  printf (gettext ("Shared library: [%s]\n"),
   1623 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1624 	  break;
   1625 
   1626 	case DT_SONAME:
   1627 	  printf (gettext ("Library soname: [%s]\n"),
   1628 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1629 	  break;
   1630 
   1631 	case DT_RPATH:
   1632 	  printf (gettext ("Library rpath: [%s]\n"),
   1633 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1634 	  break;
   1635 
   1636 	case DT_RUNPATH:
   1637 	  printf (gettext ("Library runpath: [%s]\n"),
   1638 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1639 	  break;
   1640 
   1641 	case DT_PLTRELSZ:
   1642 	case DT_RELASZ:
   1643 	case DT_STRSZ:
   1644 	case DT_RELSZ:
   1645 	case DT_RELAENT:
   1646 	case DT_SYMENT:
   1647 	case DT_RELENT:
   1648 	case DT_PLTPADSZ:
   1649 	case DT_MOVEENT:
   1650 	case DT_MOVESZ:
   1651 	case DT_INIT_ARRAYSZ:
   1652 	case DT_FINI_ARRAYSZ:
   1653 	case DT_SYMINSZ:
   1654 	case DT_SYMINENT:
   1655 	case DT_GNU_CONFLICTSZ:
   1656 	case DT_GNU_LIBLISTSZ:
   1657 	  printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
   1658 	  break;
   1659 
   1660 	case DT_VERDEFNUM:
   1661 	case DT_VERNEEDNUM:
   1662 	case DT_RELACOUNT:
   1663 	case DT_RELCOUNT:
   1664 	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
   1665 	  break;
   1666 
   1667 	case DT_PLTREL:;
   1668 	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
   1669 						      NULL, 0);
   1670 	  puts (tagname ?: "???");
   1671 	  break;
   1672 
   1673 	case DT_FLAGS:
   1674 	  print_dt_flags (class, dyn->d_un.d_val);
   1675 	  break;
   1676 
   1677 	case DT_FLAGS_1:
   1678 	  print_dt_flags_1 (class, dyn->d_un.d_val);
   1679 	  break;
   1680 
   1681 	case DT_FEATURE_1:
   1682 	  print_dt_feature_1 (class, dyn->d_un.d_val);
   1683 	  break;
   1684 
   1685 	case DT_POSFLAG_1:
   1686 	  print_dt_posflag_1 (class, dyn->d_un.d_val);
   1687 	  break;
   1688 
   1689 	default:
   1690 	  printf ("%#0*" PRIx64 "\n",
   1691 		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
   1692 	  break;
   1693 	}
   1694     }
   1695 }
   1696 
   1697 
   1698 /* Print the dynamic segment.  */
   1699 static void
   1700 print_dynamic (Ebl *ebl)
   1701 {
   1702   for (size_t i = 0; i < phnum; ++i)
   1703     {
   1704       GElf_Phdr phdr_mem;
   1705       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
   1706 
   1707       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
   1708 	{
   1709 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
   1710 	  GElf_Shdr shdr_mem;
   1711 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1712 	  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
   1713 	    handle_dynamic (ebl, scn, shdr);
   1714 	  break;
   1715 	}
   1716     }
   1717 }
   1718 
   1719 
   1720 /* Print relocations.  */
   1721 static void
   1722 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
   1723 {
   1724   /* Find all relocation sections and handle them.  */
   1725   Elf_Scn *scn = NULL;
   1726 
   1727   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   1728     {
   1729        /* Handle the section if it is a symbol table.  */
   1730       GElf_Shdr shdr_mem;
   1731       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1732 
   1733       if (likely (shdr != NULL))
   1734 	{
   1735 	  if (shdr->sh_type == SHT_REL)
   1736 	    handle_relocs_rel (ebl, ehdr, scn, shdr);
   1737 	  else if (shdr->sh_type == SHT_RELA)
   1738 	    handle_relocs_rela (ebl, ehdr, scn, shdr);
   1739 	}
   1740     }
   1741 }
   1742 
   1743 
   1744 /* Handle a relocation section.  */
   1745 static void
   1746 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
   1747 {
   1748   int class = gelf_getclass (ebl->elf);
   1749   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
   1750   int nentries = shdr->sh_size / sh_entsize;
   1751 
   1752   /* Get the data of the section.  */
   1753   Elf_Data *data = elf_getdata (scn, NULL);
   1754   if (data == NULL)
   1755     return;
   1756 
   1757   /* Get the symbol table information.  */
   1758   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
   1759   GElf_Shdr symshdr_mem;
   1760   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   1761   Elf_Data *symdata = elf_getdata (symscn, NULL);
   1762 
   1763   /* Get the section header of the section the relocations are for.  */
   1764   GElf_Shdr destshdr_mem;
   1765   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
   1766 				      &destshdr_mem);
   1767 
   1768   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
   1769     {
   1770       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
   1771 	      shdr->sh_offset);
   1772       return;
   1773     }
   1774 
   1775   /* Search for the optional extended section index table.  */
   1776   Elf_Data *xndxdata = NULL;
   1777   int xndxscnidx = elf_scnshndx (scn);
   1778   if (unlikely (xndxscnidx > 0))
   1779     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
   1780 
   1781   /* Get the section header string table index.  */
   1782   size_t shstrndx;
   1783   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1784     error (EXIT_FAILURE, 0,
   1785 	   gettext ("cannot get section header string table index"));
   1786 
   1787   if (shdr->sh_info != 0)
   1788     printf (ngettext ("\
   1789 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   1790 		    "\
   1791 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   1792 		      nentries),
   1793 	    elf_ndxscn (scn),
   1794 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1795 	    (unsigned int) shdr->sh_info,
   1796 	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
   1797 	    shdr->sh_offset,
   1798 	    nentries);
   1799   else
   1800     /* The .rel.dyn section does not refer to a specific section but
   1801        instead of section index zero.  Do not try to print a section
   1802        name.  */
   1803     printf (ngettext ("\
   1804 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   1805 		    "\
   1806 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   1807 		      nentries),
   1808 	    (unsigned int) elf_ndxscn (scn),
   1809 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1810 	    shdr->sh_offset,
   1811 	    nentries);
   1812   fputs_unlocked (class == ELFCLASS32
   1813 		  ? gettext ("\
   1814   Offset      Type                 Value       Name\n")
   1815 		  : gettext ("\
   1816   Offset              Type                 Value               Name\n"),
   1817 	 stdout);
   1818 
   1819   int is_statically_linked = 0;
   1820   for (int cnt = 0; cnt < nentries; ++cnt)
   1821     {
   1822       GElf_Rel relmem;
   1823       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
   1824       if (likely (rel != NULL))
   1825 	{
   1826 	  char buf[128];
   1827 	  GElf_Sym symmem;
   1828 	  Elf32_Word xndx;
   1829 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
   1830 					    GELF_R_SYM (rel->r_info),
   1831 					    &symmem, &xndx);
   1832 	  if (unlikely (sym == NULL))
   1833 	    {
   1834 	      /* As a special case we have to handle relocations in static
   1835 		 executables.  This only happens for IRELATIVE relocations
   1836 		 (so far).  There is no symbol table.  */
   1837 	      if (is_statically_linked == 0)
   1838 		{
   1839 		  /* Find the program header and look for a PT_INTERP entry. */
   1840 		  is_statically_linked = -1;
   1841 		  if (ehdr->e_type == ET_EXEC)
   1842 		    {
   1843 		      is_statically_linked = 1;
   1844 
   1845 		      for (size_t inner = 0; inner < phnum; ++inner)
   1846 			{
   1847 			  GElf_Phdr phdr_mem;
   1848 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
   1849 							  &phdr_mem);
   1850 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
   1851 			    {
   1852 			      is_statically_linked = -1;
   1853 			      break;
   1854 			    }
   1855 			}
   1856 		    }
   1857 		}
   1858 
   1859 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
   1860 		printf ("\
   1861   %#0*" PRIx64 "  %-20s %*s  %s\n",
   1862 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   1863 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   1864 			/* Avoid the leading R_ which isn't carrying any
   1865 			   information.  */
   1866 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   1867 					       buf, sizeof (buf)) + 2
   1868 			: gettext ("<INVALID RELOC>"),
   1869 			class == ELFCLASS32 ? 10 : 18, "",
   1870 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
   1871 	      else
   1872 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
   1873 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   1874 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   1875 			/* Avoid the leading R_ which isn't carrying any
   1876 			   information.  */
   1877 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   1878 					       buf, sizeof (buf)) + 2
   1879 			: gettext ("<INVALID RELOC>"),
   1880 			gettext ("INVALID SYMBOL"),
   1881 			(long int) GELF_R_SYM (rel->r_info));
   1882 	    }
   1883 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
   1884 	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
   1885 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   1886 		    likely (ebl_reloc_type_check (ebl,
   1887 						  GELF_R_TYPE (rel->r_info)))
   1888 		    /* Avoid the leading R_ which isn't carrying any
   1889 		       information.  */
   1890 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   1891 					   buf, sizeof (buf)) + 2
   1892 		    : gettext ("<INVALID RELOC>"),
   1893 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
   1894 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
   1895 	  else
   1896 	    {
   1897 	      /* This is a relocation against a STT_SECTION symbol.  */
   1898 	      GElf_Shdr secshdr_mem;
   1899 	      GElf_Shdr *secshdr;
   1900 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
   1901 						  sym->st_shndx == SHN_XINDEX
   1902 						  ? xndx : sym->st_shndx),
   1903 				      &secshdr_mem);
   1904 
   1905 	      if (unlikely (secshdr == NULL))
   1906 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
   1907 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   1908 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   1909 			/* Avoid the leading R_ which isn't carrying any
   1910 			   information.  */
   1911 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   1912 					       buf, sizeof (buf)) + 2
   1913 			: gettext ("<INVALID RELOC>"),
   1914 			gettext ("INVALID SECTION"),
   1915 			(long int) (sym->st_shndx == SHN_XINDEX
   1916 				    ? xndx : sym->st_shndx));
   1917 	      else
   1918 		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
   1919 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   1920 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   1921 			/* Avoid the leading R_ which isn't carrying any
   1922 			   information.  */
   1923 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   1924 					       buf, sizeof (buf)) + 2
   1925 			: gettext ("<INVALID RELOC>"),
   1926 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
   1927 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
   1928 	    }
   1929 	}
   1930     }
   1931 }
   1932 
   1933 
   1934 /* Handle a relocation section.  */
   1935 static void
   1936 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
   1937 {
   1938   int class = gelf_getclass (ebl->elf);
   1939   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
   1940   int nentries = shdr->sh_size / sh_entsize;
   1941 
   1942   /* Get the data of the section.  */
   1943   Elf_Data *data = elf_getdata (scn, NULL);
   1944   if (data == NULL)
   1945     return;
   1946 
   1947   /* Get the symbol table information.  */
   1948   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
   1949   GElf_Shdr symshdr_mem;
   1950   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   1951   Elf_Data *symdata = elf_getdata (symscn, NULL);
   1952 
   1953   /* Get the section header of the section the relocations are for.  */
   1954   GElf_Shdr destshdr_mem;
   1955   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
   1956 				      &destshdr_mem);
   1957 
   1958   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
   1959     {
   1960       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
   1961 	      shdr->sh_offset);
   1962       return;
   1963     }
   1964 
   1965   /* Search for the optional extended section index table.  */
   1966   Elf_Data *xndxdata = NULL;
   1967   int xndxscnidx = elf_scnshndx (scn);
   1968   if (unlikely (xndxscnidx > 0))
   1969     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
   1970 
   1971   /* Get the section header string table index.  */
   1972   size_t shstrndx;
   1973   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1974     error (EXIT_FAILURE, 0,
   1975 	   gettext ("cannot get section header string table index"));
   1976 
   1977   if (shdr->sh_info != 0)
   1978     printf (ngettext ("\
   1979 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   1980 		    "\
   1981 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   1982 		    nentries),
   1983 	  elf_ndxscn (scn),
   1984 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1985 	  (unsigned int) shdr->sh_info,
   1986 	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
   1987 	  shdr->sh_offset,
   1988 	  nentries);
   1989   else
   1990     /* The .rela.dyn section does not refer to a specific section but
   1991        instead of section index zero.  Do not try to print a section
   1992        name.  */
   1993     printf (ngettext ("\
   1994 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   1995 		    "\
   1996 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   1997 		      nentries),
   1998 	    (unsigned int) elf_ndxscn (scn),
   1999 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2000 	    shdr->sh_offset,
   2001 	    nentries);
   2002   fputs_unlocked (class == ELFCLASS32
   2003 		  ? gettext ("\
   2004   Offset      Type            Value       Addend Name\n")
   2005 		  : gettext ("\
   2006   Offset              Type            Value               Addend Name\n"),
   2007 		  stdout);
   2008 
   2009   int is_statically_linked = 0;
   2010   for (int cnt = 0; cnt < nentries; ++cnt)
   2011     {
   2012       GElf_Rela relmem;
   2013       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
   2014       if (likely (rel != NULL))
   2015 	{
   2016 	  char buf[64];
   2017 	  GElf_Sym symmem;
   2018 	  Elf32_Word xndx;
   2019 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
   2020 					    GELF_R_SYM (rel->r_info),
   2021 					    &symmem, &xndx);
   2022 
   2023 	  if (unlikely (sym == NULL))
   2024 	    {
   2025 	      /* As a special case we have to handle relocations in static
   2026 		 executables.  This only happens for IRELATIVE relocations
   2027 		 (so far).  There is no symbol table.  */
   2028 	      if (is_statically_linked == 0)
   2029 		{
   2030 		  /* Find the program header and look for a PT_INTERP entry. */
   2031 		  is_statically_linked = -1;
   2032 		  if (ehdr->e_type == ET_EXEC)
   2033 		    {
   2034 		      is_statically_linked = 1;
   2035 
   2036 		      for (size_t inner = 0; inner < phnum; ++inner)
   2037 			{
   2038 			  GElf_Phdr phdr_mem;
   2039 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
   2040 							  &phdr_mem);
   2041 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
   2042 			    {
   2043 			      is_statically_linked = -1;
   2044 			      break;
   2045 			    }
   2046 			}
   2047 		    }
   2048 		}
   2049 
   2050 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
   2051 		printf ("\
   2052   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
   2053 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2054 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2055 			/* Avoid the leading R_ which isn't carrying any
   2056 			   information.  */
   2057 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2058 					       buf, sizeof (buf)) + 2
   2059 			: gettext ("<INVALID RELOC>"),
   2060 			class == ELFCLASS32 ? 10 : 18, "",
   2061 			rel->r_addend,
   2062 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
   2063 	      else
   2064 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
   2065 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2066 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2067 			/* Avoid the leading R_ which isn't carrying any
   2068 			   information.  */
   2069 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2070 					       buf, sizeof (buf)) + 2
   2071 			: gettext ("<INVALID RELOC>"),
   2072 			gettext ("INVALID SYMBOL"),
   2073 			(long int) GELF_R_SYM (rel->r_info));
   2074 	    }
   2075 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
   2076 	    printf ("\
   2077   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
   2078 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2079 		    likely (ebl_reloc_type_check (ebl,
   2080 						  GELF_R_TYPE (rel->r_info)))
   2081 		    /* Avoid the leading R_ which isn't carrying any
   2082 		       information.  */
   2083 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2084 					   buf, sizeof (buf)) + 2
   2085 		    : gettext ("<INVALID RELOC>"),
   2086 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
   2087 		    rel->r_addend,
   2088 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
   2089 	  else
   2090 	    {
   2091 	      /* This is a relocation against a STT_SECTION symbol.  */
   2092 	      GElf_Shdr secshdr_mem;
   2093 	      GElf_Shdr *secshdr;
   2094 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
   2095 						  sym->st_shndx == SHN_XINDEX
   2096 						  ? xndx : sym->st_shndx),
   2097 				      &secshdr_mem);
   2098 
   2099 	      if (unlikely (secshdr == NULL))
   2100 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
   2101 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2102 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2103 			/* Avoid the leading R_ which isn't carrying any
   2104 			   information.  */
   2105 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2106 					       buf, sizeof (buf)) + 2
   2107 			: gettext ("<INVALID RELOC>"),
   2108 			gettext ("INVALID SECTION"),
   2109 			(long int) (sym->st_shndx == SHN_XINDEX
   2110 				    ? xndx : sym->st_shndx));
   2111 	      else
   2112 		printf ("\
   2113   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
   2114 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2115 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2116 			/* Avoid the leading R_ which isn't carrying any
   2117 			   information.  */
   2118 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2119 					       buf, sizeof (buf)) + 2
   2120 			: gettext ("<INVALID RELOC>"),
   2121 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
   2122 			rel->r_addend,
   2123 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
   2124 	    }
   2125 	}
   2126     }
   2127 }
   2128 
   2129 
   2130 /* Print the program header.  */
   2131 static void
   2132 print_symtab (Ebl *ebl, int type)
   2133 {
   2134   /* Find the symbol table(s).  For this we have to search through the
   2135      section table.  */
   2136   Elf_Scn *scn = NULL;
   2137 
   2138   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   2139     {
   2140       /* Handle the section if it is a symbol table.  */
   2141       GElf_Shdr shdr_mem;
   2142       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   2143 
   2144       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
   2145 	handle_symtab (ebl, scn, shdr);
   2146     }
   2147 }
   2148 
   2149 
   2150 static void
   2151 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2152 {
   2153   Elf_Data *versym_data = NULL;
   2154   Elf_Data *verneed_data = NULL;
   2155   Elf_Data *verdef_data = NULL;
   2156   Elf_Data *xndx_data = NULL;
   2157   int class = gelf_getclass (ebl->elf);
   2158   Elf32_Word verneed_stridx = 0;
   2159   Elf32_Word verdef_stridx = 0;
   2160 
   2161   /* Get the data of the section.  */
   2162   Elf_Data *data = elf_getdata (scn, NULL);
   2163   if (data == NULL)
   2164     return;
   2165 
   2166   /* Find out whether we have other sections we might need.  */
   2167   Elf_Scn *runscn = NULL;
   2168   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
   2169     {
   2170       GElf_Shdr runshdr_mem;
   2171       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
   2172 
   2173       if (likely (runshdr != NULL))
   2174 	{
   2175 	  if (runshdr->sh_type == SHT_GNU_versym
   2176 	      && runshdr->sh_link == elf_ndxscn (scn))
   2177 	    /* Bingo, found the version information.  Now get the data.  */
   2178 	    versym_data = elf_getdata (runscn, NULL);
   2179 	  else if (runshdr->sh_type == SHT_GNU_verneed)
   2180 	    {
   2181 	      /* This is the information about the needed versions.  */
   2182 	      verneed_data = elf_getdata (runscn, NULL);
   2183 	      verneed_stridx = runshdr->sh_link;
   2184 	    }
   2185 	  else if (runshdr->sh_type == SHT_GNU_verdef)
   2186 	    {
   2187 	      /* This is the information about the defined versions.  */
   2188 	      verdef_data = elf_getdata (runscn, NULL);
   2189 	      verdef_stridx = runshdr->sh_link;
   2190 	    }
   2191 	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
   2192 	      && runshdr->sh_link == elf_ndxscn (scn))
   2193 	    /* Extended section index.  */
   2194 	    xndx_data = elf_getdata (runscn, NULL);
   2195 	}
   2196     }
   2197 
   2198   /* Get the section header string table index.  */
   2199   size_t shstrndx;
   2200   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2201     error (EXIT_FAILURE, 0,
   2202 	   gettext ("cannot get section header string table index"));
   2203 
   2204   GElf_Shdr glink_mem;
   2205   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2206 				   &glink_mem);
   2207   if (glink == NULL)
   2208     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
   2209 	   elf_ndxscn (scn));
   2210 
   2211   /* Now we can compute the number of entries in the section.  */
   2212   unsigned int nsyms = data->d_size / (class == ELFCLASS32
   2213 				       ? sizeof (Elf32_Sym)
   2214 				       : sizeof (Elf64_Sym));
   2215 
   2216   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
   2217 		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
   2218 		    nsyms),
   2219 	  (unsigned int) elf_ndxscn (scn),
   2220 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
   2221   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
   2222 		    " %lu local symbols  String table: [%2u] '%s'\n",
   2223 		    shdr->sh_info),
   2224 	  (unsigned long int) shdr->sh_info,
   2225 	  (unsigned int) shdr->sh_link,
   2226 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2227 
   2228   fputs_unlocked (class == ELFCLASS32
   2229 		  ? gettext ("\
   2230   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
   2231 		  : gettext ("\
   2232   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
   2233 		  stdout);
   2234 
   2235   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
   2236     {
   2237       char typebuf[64];
   2238       char bindbuf[64];
   2239       char scnbuf[64];
   2240       Elf32_Word xndx;
   2241       GElf_Sym sym_mem;
   2242       GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
   2243 
   2244       if (unlikely (sym == NULL))
   2245 	continue;
   2246 
   2247       /* Determine the real section index.  */
   2248       if (likely (sym->st_shndx != SHN_XINDEX))
   2249 	xndx = sym->st_shndx;
   2250 
   2251       printf (gettext ("\
   2252 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
   2253 	      cnt,
   2254 	      class == ELFCLASS32 ? 8 : 16,
   2255 	      sym->st_value,
   2256 	      sym->st_size,
   2257 	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
   2258 				    typebuf, sizeof (typebuf)),
   2259 	      ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
   2260 				       bindbuf, sizeof (bindbuf)),
   2261 	      get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
   2262 	      ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
   2263 				sizeof (scnbuf), NULL, shnum),
   2264 	      elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
   2265 
   2266       if (versym_data != NULL)
   2267 	{
   2268 	  /* Get the version information.  */
   2269 	  GElf_Versym versym_mem;
   2270 	  GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
   2271 
   2272 	  if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
   2273 	    {
   2274 	      bool is_nobits = false;
   2275 	      bool check_def = xndx != SHN_UNDEF;
   2276 
   2277 	      if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
   2278 		{
   2279 		  GElf_Shdr symshdr_mem;
   2280 		  GElf_Shdr *symshdr =
   2281 		    gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
   2282 
   2283 		  is_nobits = (symshdr != NULL
   2284 			       && symshdr->sh_type == SHT_NOBITS);
   2285 		}
   2286 
   2287 	      if (is_nobits || ! check_def)
   2288 		{
   2289 		  /* We must test both.  */
   2290 		  GElf_Vernaux vernaux_mem;
   2291 		  GElf_Vernaux *vernaux = NULL;
   2292 		  size_t vn_offset = 0;
   2293 
   2294 		  GElf_Verneed verneed_mem;
   2295 		  GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
   2296 							   &verneed_mem);
   2297 		  while (verneed != NULL)
   2298 		    {
   2299 		      size_t vna_offset = vn_offset;
   2300 
   2301 		      vernaux = gelf_getvernaux (verneed_data,
   2302 						 vna_offset += verneed->vn_aux,
   2303 						 &vernaux_mem);
   2304 		      while (vernaux != NULL
   2305 			     && vernaux->vna_other != *versym
   2306 			     && vernaux->vna_next != 0)
   2307 			{
   2308 			  /* Update the offset.  */
   2309 			  vna_offset += vernaux->vna_next;
   2310 
   2311 			  vernaux = (vernaux->vna_next == 0
   2312 				     ? NULL
   2313 				     : gelf_getvernaux (verneed_data,
   2314 							vna_offset,
   2315 							&vernaux_mem));
   2316 			}
   2317 
   2318 		      /* Check whether we found the version.  */
   2319 		      if (vernaux != NULL && vernaux->vna_other == *versym)
   2320 			/* Found it.  */
   2321 			break;
   2322 
   2323 		      vn_offset += verneed->vn_next;
   2324 		      verneed = (verneed->vn_next == 0
   2325 				 ? NULL
   2326 				 : gelf_getverneed (verneed_data, vn_offset,
   2327 						    &verneed_mem));
   2328 		    }
   2329 
   2330 		  if (vernaux != NULL && vernaux->vna_other == *versym)
   2331 		    {
   2332 		      printf ("@%s (%u)",
   2333 			      elf_strptr (ebl->elf, verneed_stridx,
   2334 					  vernaux->vna_name),
   2335 			      (unsigned int) vernaux->vna_other);
   2336 		      check_def = 0;
   2337 		    }
   2338 		  else if (unlikely (! is_nobits))
   2339 		    error (0, 0, gettext ("bad dynamic symbol"));
   2340 		  else
   2341 		    check_def = 1;
   2342 		}
   2343 
   2344 	      if (check_def && *versym != 0x8001)
   2345 		{
   2346 		  /* We must test both.  */
   2347 		  size_t vd_offset = 0;
   2348 
   2349 		  GElf_Verdef verdef_mem;
   2350 		  GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
   2351 							&verdef_mem);
   2352 		  while (verdef != NULL)
   2353 		    {
   2354 		      if (verdef->vd_ndx == (*versym & 0x7fff))
   2355 			/* Found the definition.  */
   2356 			break;
   2357 
   2358 		      vd_offset += verdef->vd_next;
   2359 		      verdef = (verdef->vd_next == 0
   2360 				? NULL
   2361 				: gelf_getverdef (verdef_data, vd_offset,
   2362 						  &verdef_mem));
   2363 		    }
   2364 
   2365 		  if (verdef != NULL)
   2366 		    {
   2367 		      GElf_Verdaux verdaux_mem;
   2368 		      GElf_Verdaux *verdaux
   2369 			= gelf_getverdaux (verdef_data,
   2370 					   vd_offset + verdef->vd_aux,
   2371 					   &verdaux_mem);
   2372 
   2373 		      if (verdaux != NULL)
   2374 			printf ((*versym & 0x8000) ? "@%s" : "@@%s",
   2375 				elf_strptr (ebl->elf, verdef_stridx,
   2376 					    verdaux->vda_name));
   2377 		    }
   2378 		}
   2379 	    }
   2380 	}
   2381 
   2382       putchar_unlocked ('\n');
   2383     }
   2384 }
   2385 
   2386 
   2387 /* Print version information.  */
   2388 static void
   2389 print_verinfo (Ebl *ebl)
   2390 {
   2391   /* Find the version information sections.  For this we have to
   2392      search through the section table.  */
   2393   Elf_Scn *scn = NULL;
   2394 
   2395   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   2396     {
   2397       /* Handle the section if it is part of the versioning handling.  */
   2398       GElf_Shdr shdr_mem;
   2399       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   2400 
   2401       if (likely (shdr != NULL))
   2402 	{
   2403 	  if (shdr->sh_type == SHT_GNU_verneed)
   2404 	    handle_verneed (ebl, scn, shdr);
   2405 	  else if (shdr->sh_type == SHT_GNU_verdef)
   2406 	    handle_verdef (ebl, scn, shdr);
   2407 	  else if (shdr->sh_type == SHT_GNU_versym)
   2408 	    handle_versym (ebl, scn, shdr);
   2409 	}
   2410     }
   2411 }
   2412 
   2413 
   2414 static const char *
   2415 get_ver_flags (unsigned int flags)
   2416 {
   2417   static char buf[32];
   2418   char *endp;
   2419 
   2420   if (flags == 0)
   2421     return gettext ("none");
   2422 
   2423   if (flags & VER_FLG_BASE)
   2424     endp = stpcpy (buf, "BASE ");
   2425   else
   2426     endp = buf;
   2427 
   2428   if (flags & VER_FLG_WEAK)
   2429     {
   2430       if (endp != buf)
   2431 	endp = stpcpy (endp, "| ");
   2432 
   2433       endp = stpcpy (endp, "WEAK ");
   2434     }
   2435 
   2436   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
   2437     {
   2438       strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
   2439       buf[sizeof (buf) - 1] = '\0';
   2440     }
   2441 
   2442   return buf;
   2443 }
   2444 
   2445 
   2446 static void
   2447 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2448 {
   2449   int class = gelf_getclass (ebl->elf);
   2450 
   2451   /* Get the data of the section.  */
   2452   Elf_Data *data = elf_getdata (scn, NULL);
   2453   if (data == NULL)
   2454     return;
   2455 
   2456   /* Get the section header string table index.  */
   2457   size_t shstrndx;
   2458   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2459     error (EXIT_FAILURE, 0,
   2460 	   gettext ("cannot get section header string table index"));
   2461 
   2462   GElf_Shdr glink_mem;
   2463   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2464 				   &glink_mem);
   2465   if (glink == NULL)
   2466     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
   2467 	   elf_ndxscn (scn));
   2468 
   2469   printf (ngettext ("\
   2470 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2471 		    "\
   2472 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2473 		    shdr->sh_info),
   2474 	  (unsigned int) elf_ndxscn (scn),
   2475 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
   2476 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   2477 	  shdr->sh_offset,
   2478 	  (unsigned int) shdr->sh_link,
   2479 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2480 
   2481   unsigned int offset = 0;
   2482   for (int cnt = shdr->sh_info; --cnt >= 0; )
   2483     {
   2484       /* Get the data at the next offset.  */
   2485       GElf_Verneed needmem;
   2486       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
   2487       if (unlikely (need == NULL))
   2488 	break;
   2489 
   2490       printf (gettext ("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
   2491 	      offset, (unsigned short int) need->vn_version,
   2492 	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
   2493 	      (unsigned short int) need->vn_cnt);
   2494 
   2495       unsigned int auxoffset = offset + need->vn_aux;
   2496       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
   2497 	{
   2498 	  GElf_Vernaux auxmem;
   2499 	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
   2500 	  if (unlikely (aux == NULL))
   2501 	    break;
   2502 
   2503 	  printf (gettext ("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
   2504 		  auxoffset,
   2505 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
   2506 		  get_ver_flags (aux->vna_flags),
   2507 		  (unsigned short int) aux->vna_other);
   2508 
   2509 	  if (aux->vna_next == 0)
   2510 	    break;
   2511 
   2512 	  auxoffset += aux->vna_next;
   2513 	}
   2514 
   2515       /* Find the next offset.  */
   2516       if (need->vn_next == 0)
   2517 	break;
   2518 
   2519       offset += need->vn_next;
   2520     }
   2521 }
   2522 
   2523 
   2524 static void
   2525 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2526 {
   2527   /* Get the data of the section.  */
   2528   Elf_Data *data = elf_getdata (scn, NULL);
   2529   if (data == NULL)
   2530     return;
   2531 
   2532   /* Get the section header string table index.  */
   2533   size_t shstrndx;
   2534   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2535     error (EXIT_FAILURE, 0,
   2536 	   gettext ("cannot get section header string table index"));
   2537 
   2538   GElf_Shdr glink_mem;
   2539   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2540 				   &glink_mem);
   2541   if (glink == NULL)
   2542     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
   2543 	   elf_ndxscn (scn));
   2544 
   2545   int class = gelf_getclass (ebl->elf);
   2546   printf (ngettext ("\
   2547 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2548 		    "\
   2549 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2550 		    shdr->sh_info),
   2551 	  (unsigned int) elf_ndxscn (scn),
   2552 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2553 	  shdr->sh_info,
   2554 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   2555 	  shdr->sh_offset,
   2556 	  (unsigned int) shdr->sh_link,
   2557 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2558 
   2559   unsigned int offset = 0;
   2560   for (int cnt = shdr->sh_info; --cnt >= 0; )
   2561     {
   2562       /* Get the data at the next offset.  */
   2563       GElf_Verdef defmem;
   2564       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
   2565       if (unlikely (def == NULL))
   2566 	break;
   2567 
   2568       unsigned int auxoffset = offset + def->vd_aux;
   2569       GElf_Verdaux auxmem;
   2570       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
   2571       if (unlikely (aux == NULL))
   2572 	break;
   2573 
   2574       printf (gettext ("\
   2575   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
   2576 	      offset, def->vd_version,
   2577 	      get_ver_flags (def->vd_flags),
   2578 	      def->vd_ndx,
   2579 	      def->vd_cnt,
   2580 	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
   2581 
   2582       auxoffset += aux->vda_next;
   2583       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
   2584 	{
   2585 	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
   2586 	  if (unlikely (aux == NULL))
   2587 	    break;
   2588 
   2589 	  printf (gettext ("  %#06x: Parent %d: %s\n"),
   2590 		  auxoffset, cnt2,
   2591 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
   2592 
   2593 	  if (aux->vda_next == 0)
   2594 	    break;
   2595 
   2596 	  auxoffset += aux->vda_next;
   2597 	}
   2598 
   2599       /* Find the next offset.  */
   2600       if (def->vd_next == 0)
   2601 	break;
   2602       offset += def->vd_next;
   2603     }
   2604 }
   2605 
   2606 
   2607 static void
   2608 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2609 {
   2610   int class = gelf_getclass (ebl->elf);
   2611   const char **vername;
   2612   const char **filename;
   2613 
   2614   /* Get the data of the section.  */
   2615   Elf_Data *data = elf_getdata (scn, NULL);
   2616   if (data == NULL)
   2617     return;
   2618 
   2619   /* Get the section header string table index.  */
   2620   size_t shstrndx;
   2621   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2622     error (EXIT_FAILURE, 0,
   2623 	   gettext ("cannot get section header string table index"));
   2624 
   2625   /* We have to find the version definition section and extract the
   2626      version names.  */
   2627   Elf_Scn *defscn = NULL;
   2628   Elf_Scn *needscn = NULL;
   2629 
   2630   Elf_Scn *verscn = NULL;
   2631   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
   2632     {
   2633       GElf_Shdr vershdr_mem;
   2634       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
   2635 
   2636       if (likely (vershdr != NULL))
   2637 	{
   2638 	  if (vershdr->sh_type == SHT_GNU_verdef)
   2639 	    defscn = verscn;
   2640 	  else if (vershdr->sh_type == SHT_GNU_verneed)
   2641 	    needscn = verscn;
   2642 	}
   2643     }
   2644 
   2645   size_t nvername;
   2646   if (defscn != NULL || needscn != NULL)
   2647     {
   2648       /* We have a version information (better should have).  Now get
   2649 	 the version names.  First find the maximum version number.  */
   2650       nvername = 0;
   2651       if (defscn != NULL)
   2652 	{
   2653 	  /* Run through the version definitions and find the highest
   2654 	     index.  */
   2655 	  unsigned int offset = 0;
   2656 	  Elf_Data *defdata;
   2657 	  GElf_Shdr defshdrmem;
   2658 	  GElf_Shdr *defshdr;
   2659 
   2660 	  defdata = elf_getdata (defscn, NULL);
   2661 	  if (unlikely (defdata == NULL))
   2662 	    return;
   2663 
   2664 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
   2665 	  if (unlikely (defshdr == NULL))
   2666 	    return;
   2667 
   2668 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
   2669 	    {
   2670 	      GElf_Verdef defmem;
   2671 	      GElf_Verdef *def;
   2672 
   2673 	      /* Get the data at the next offset.  */
   2674 	      def = gelf_getverdef (defdata, offset, &defmem);
   2675 	      if (unlikely (def == NULL))
   2676 		break;
   2677 
   2678 	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
   2679 
   2680 	      if (def->vd_next == 0)
   2681 		break;
   2682 	      offset += def->vd_next;
   2683 	    }
   2684 	}
   2685       if (needscn != NULL)
   2686 	{
   2687 	  unsigned int offset = 0;
   2688 	  Elf_Data *needdata;
   2689 	  GElf_Shdr needshdrmem;
   2690 	  GElf_Shdr *needshdr;
   2691 
   2692 	  needdata = elf_getdata (needscn, NULL);
   2693 	  if (unlikely (needdata == NULL))
   2694 	    return;
   2695 
   2696 	  needshdr = gelf_getshdr (needscn, &needshdrmem);
   2697 	  if (unlikely (needshdr == NULL))
   2698 	    return;
   2699 
   2700 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
   2701 	    {
   2702 	      GElf_Verneed needmem;
   2703 	      GElf_Verneed *need;
   2704 	      unsigned int auxoffset;
   2705 	      int cnt2;
   2706 
   2707 	      /* Get the data at the next offset.  */
   2708 	      need = gelf_getverneed (needdata, offset, &needmem);
   2709 	      if (unlikely (need == NULL))
   2710 		break;
   2711 
   2712 	      /* Run through the auxiliary entries.  */
   2713 	      auxoffset = offset + need->vn_aux;
   2714 	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
   2715 		{
   2716 		  GElf_Vernaux auxmem;
   2717 		  GElf_Vernaux *aux;
   2718 
   2719 		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
   2720 		  if (unlikely (aux == NULL))
   2721 		    break;
   2722 
   2723 		  nvername = MAX (nvername,
   2724 				  (size_t) (aux->vna_other & 0x7fff));
   2725 
   2726 		  if (aux->vna_next == 0)
   2727 		    break;
   2728 		  auxoffset += aux->vna_next;
   2729 		}
   2730 
   2731 	      if (need->vn_next == 0)
   2732 		break;
   2733 	      offset += need->vn_next;
   2734 	    }
   2735 	}
   2736 
   2737       /* This is the number of versions we know about.  */
   2738       ++nvername;
   2739 
   2740       /* Allocate the array.  */
   2741       vername = (const char **) alloca (nvername * sizeof (const char *));
   2742       memset(vername, 0, nvername * sizeof (const char *));
   2743       filename = (const char **) alloca (nvername * sizeof (const char *));
   2744       memset(filename, 0, nvername * sizeof (const char *));
   2745 
   2746       /* Run through the data structures again and collect the strings.  */
   2747       if (defscn != NULL)
   2748 	{
   2749 	  /* Run through the version definitions and find the highest
   2750 	     index.  */
   2751 	  unsigned int offset = 0;
   2752 	  Elf_Data *defdata;
   2753 	  GElf_Shdr defshdrmem;
   2754 	  GElf_Shdr *defshdr;
   2755 
   2756 	  defdata = elf_getdata (defscn, NULL);
   2757 	  if (unlikely (defdata == NULL))
   2758 	    return;
   2759 
   2760 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
   2761 	  if (unlikely (defshdr == NULL))
   2762 	    return;
   2763 
   2764 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
   2765 	    {
   2766 
   2767 	      /* Get the data at the next offset.  */
   2768 	      GElf_Verdef defmem;
   2769 	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
   2770 	      if (unlikely (def == NULL))
   2771 		break;
   2772 
   2773 	      GElf_Verdaux auxmem;
   2774 	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
   2775 						   offset + def->vd_aux,
   2776 						   &auxmem);
   2777 	      if (unlikely (aux == NULL))
   2778 		break;
   2779 
   2780 	      vername[def->vd_ndx & 0x7fff]
   2781 		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
   2782 	      filename[def->vd_ndx & 0x7fff] = NULL;
   2783 
   2784 	      if (def->vd_next == 0)
   2785 		break;
   2786 	      offset += def->vd_next;
   2787 	    }
   2788 	}
   2789       if (needscn != NULL)
   2790 	{
   2791 	  unsigned int offset = 0;
   2792 
   2793 	  Elf_Data *needdata = elf_getdata (needscn, NULL);
   2794 	  GElf_Shdr needshdrmem;
   2795 	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
   2796 	  if (unlikely (needdata == NULL || needshdr == NULL))
   2797 	    return;
   2798 
   2799 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
   2800 	    {
   2801 	      /* Get the data at the next offset.  */
   2802 	      GElf_Verneed needmem;
   2803 	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
   2804 						    &needmem);
   2805 	      if (unlikely (need == NULL))
   2806 		break;
   2807 
   2808 	      /* Run through the auxiliary entries.  */
   2809 	      unsigned int auxoffset = offset + need->vn_aux;
   2810 	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
   2811 		{
   2812 		  GElf_Vernaux auxmem;
   2813 		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
   2814 						       &auxmem);
   2815 		  if (unlikely (aux == NULL))
   2816 		    break;
   2817 
   2818 		  vername[aux->vna_other & 0x7fff]
   2819 		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
   2820 		  filename[aux->vna_other & 0x7fff]
   2821 		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
   2822 
   2823 		  if (aux->vna_next == 0)
   2824 		    break;
   2825 		  auxoffset += aux->vna_next;
   2826 		}
   2827 
   2828 	      if (need->vn_next == 0)
   2829 		break;
   2830 	      offset += need->vn_next;
   2831 	    }
   2832 	}
   2833     }
   2834   else
   2835     {
   2836       vername = NULL;
   2837       nvername = 1;
   2838       filename = NULL;
   2839     }
   2840 
   2841   GElf_Shdr glink_mem;
   2842   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2843 				   &glink_mem);
   2844   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
   2845   if (glink == NULL)
   2846     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
   2847 	   elf_ndxscn (scn));
   2848 
   2849   /* Print the header.  */
   2850   printf (ngettext ("\
   2851 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
   2852 		    "\
   2853 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
   2854 		    shdr->sh_size / sh_entsize),
   2855 	  (unsigned int) elf_ndxscn (scn),
   2856 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2857 	  (int) (shdr->sh_size / sh_entsize),
   2858 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   2859 	  shdr->sh_offset,
   2860 	  (unsigned int) shdr->sh_link,
   2861 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2862 
   2863   /* Now we can finally look at the actual contents of this section.  */
   2864   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
   2865     {
   2866       if (cnt % 2 == 0)
   2867 	printf ("\n %4d:", cnt);
   2868 
   2869       GElf_Versym symmem;
   2870       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
   2871       if (sym == NULL)
   2872 	break;
   2873 
   2874       switch (*sym)
   2875 	{
   2876 	  ssize_t n;
   2877 	case 0:
   2878 	  fputs_unlocked (gettext ("   0 *local*                     "),
   2879 			  stdout);
   2880 	  break;
   2881 
   2882 	case 1:
   2883 	  fputs_unlocked (gettext ("   1 *global*                    "),
   2884 			  stdout);
   2885 	  break;
   2886 
   2887 	default:
   2888 	  n = printf ("%4d%c%s",
   2889 		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
   2890 		      (vername != NULL
   2891 		       && (unsigned int) (*sym & 0x7fff) < nvername)
   2892 		      ? vername[*sym & 0x7fff] : "???");
   2893 	  if ((unsigned int) (*sym & 0x7fff) < nvername
   2894 	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
   2895 	    n += printf ("(%s)", filename[*sym & 0x7fff]);
   2896 	  printf ("%*s", MAX (0, 33 - (int) n), " ");
   2897 	  break;
   2898 	}
   2899     }
   2900   putchar_unlocked ('\n');
   2901 }
   2902 
   2903 
   2904 static void
   2905 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
   2906 		 uint_fast32_t maxlength, Elf32_Word nbucket,
   2907 		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
   2908 {
   2909   uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
   2910 
   2911   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   2912     ++counts[lengths[cnt]];
   2913 
   2914   GElf_Shdr glink_mem;
   2915   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
   2916 					       shdr->sh_link),
   2917 				   &glink_mem);
   2918   if (glink == NULL)
   2919     {
   2920       error (0, 0, gettext ("invalid sh_link value in section %Zu"),
   2921 	     elf_ndxscn (scn));
   2922       return;
   2923     }
   2924 
   2925   printf (ngettext ("\
   2926 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2927 		    "\
   2928 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2929 		    nbucket),
   2930 	  (unsigned int) elf_ndxscn (scn),
   2931 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2932 	  (int) nbucket,
   2933 	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
   2934 	  shdr->sh_addr,
   2935 	  shdr->sh_offset,
   2936 	  (unsigned int) shdr->sh_link,
   2937 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2938 
   2939   if (extrastr != NULL)
   2940     fputs (extrastr, stdout);
   2941 
   2942   if (likely (nbucket > 0))
   2943     {
   2944       uint64_t success = 0;
   2945 
   2946       /* xgettext:no-c-format */
   2947       fputs_unlocked (gettext ("\
   2948  Length  Number  % of total  Coverage\n"), stdout);
   2949       printf (gettext ("      0  %6" PRIu32 "      %5.1f%%\n"),
   2950 	      counts[0], (counts[0] * 100.0) / nbucket);
   2951 
   2952       uint64_t nzero_counts = 0;
   2953       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
   2954 	{
   2955 	  nzero_counts += counts[cnt] * cnt;
   2956 	  printf (gettext ("\
   2957 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
   2958 		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
   2959 		  (nzero_counts * 100.0) / nsyms);
   2960 	}
   2961 
   2962       Elf32_Word acc = 0;
   2963       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
   2964 	{
   2965 	  acc += cnt;
   2966 	  success += counts[cnt] * acc;
   2967 	}
   2968 
   2969       printf (gettext ("\
   2970  Average number of tests:   successful lookup: %f\n\
   2971 			  unsuccessful lookup: %f\n"),
   2972 	      (double) success / (double) nzero_counts,
   2973 	      (double) nzero_counts / (double) nbucket);
   2974     }
   2975 
   2976   free (counts);
   2977 }
   2978 
   2979 
   2980 /* This function handles the traditional System V-style hash table format.  */
   2981 static void
   2982 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   2983 {
   2984   Elf_Data *data = elf_getdata (scn, NULL);
   2985   if (unlikely (data == NULL))
   2986     {
   2987       error (0, 0, gettext ("cannot get data for section %d: %s"),
   2988 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
   2989       return;
   2990     }
   2991 
   2992   if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
   2993     {
   2994     invalid_data:
   2995       error (0, 0, gettext ("invalid data in sysv.hash section %d"),
   2996 	     (int) elf_ndxscn (scn));
   2997       return;
   2998     }
   2999 
   3000   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
   3001   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
   3002 
   3003   uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
   3004   if (used_buf > data->d_size)
   3005     goto invalid_data;
   3006 
   3007   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
   3008   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
   3009 
   3010   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
   3011 
   3012   uint_fast32_t maxlength = 0;
   3013   uint_fast32_t nsyms = 0;
   3014   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   3015     {
   3016       Elf32_Word inner = bucket[cnt];
   3017       while (inner > 0 && inner < nchain)
   3018 	{
   3019 	  ++nsyms;
   3020 	  if (maxlength < ++lengths[cnt])
   3021 	    ++maxlength;
   3022 
   3023 	  inner = chain[inner];
   3024 	}
   3025     }
   3026 
   3027   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
   3028 		   lengths, NULL);
   3029 
   3030   free (lengths);
   3031 }
   3032 
   3033 
   3034 /* This function handles the incorrect, System V-style hash table
   3035    format some 64-bit architectures use.  */
   3036 static void
   3037 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   3038 {
   3039   Elf_Data *data = elf_getdata (scn, NULL);
   3040   if (unlikely (data == NULL))
   3041     {
   3042       error (0, 0, gettext ("cannot get data for section %d: %s"),
   3043 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
   3044       return;
   3045     }
   3046 
   3047   if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
   3048     {
   3049     invalid_data:
   3050       error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
   3051 	     (int) elf_ndxscn (scn));
   3052       return;
   3053     }
   3054 
   3055   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
   3056   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
   3057 
   3058   uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
   3059   if (maxwords < 2
   3060       || maxwords - 2 < nbucket
   3061       || maxwords - 2 - nbucket < nchain)
   3062     goto invalid_data;
   3063 
   3064   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
   3065   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
   3066 
   3067   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
   3068 
   3069   uint_fast32_t maxlength = 0;
   3070   uint_fast32_t nsyms = 0;
   3071   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
   3072     {
   3073       Elf64_Xword inner = bucket[cnt];
   3074       while (inner > 0 && inner < nchain)
   3075 	{
   3076 	  ++nsyms;
   3077 	  if (maxlength < ++lengths[cnt])
   3078 	    ++maxlength;
   3079 
   3080 	  inner = chain[inner];
   3081 	}
   3082     }
   3083 
   3084   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
   3085 		   lengths, NULL);
   3086 
   3087   free (lengths);
   3088 }
   3089 
   3090 
   3091 /* This function handles the GNU-style hash table format.  */
   3092 static void
   3093 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   3094 {
   3095   Elf_Data *data = elf_getdata (scn, NULL);
   3096   if (unlikely (data == NULL))
   3097     {
   3098       error (0, 0, gettext ("cannot get data for section %d: %s"),
   3099 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
   3100       return;
   3101     }
   3102 
   3103   if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
   3104     {
   3105     invalid_data:
   3106       error (0, 0, gettext ("invalid data in gnu.hash section %d"),
   3107 	     (int) elf_ndxscn (scn));
   3108       return;
   3109     }
   3110 
   3111   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
   3112   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
   3113 
   3114   /* Next comes the size of the bitmap.  It's measured in words for
   3115      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
   3116      64 bit archs.  There is always a bloom filter present, so zero is
   3117      an invalid value.  */
   3118   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
   3119   if (gelf_getclass (ebl->elf) == ELFCLASS64)
   3120     bitmask_words *= 2;
   3121 
   3122   if (bitmask_words == 0)
   3123     goto invalid_data;
   3124 
   3125   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
   3126 
   3127   /* Is there still room for the sym chain?
   3128      Use uint64_t calculation to prevent 32bit overlow.  */
   3129   uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
   3130   uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
   3131   if (used_buf > data->d_size)
   3132     goto invalid_data;
   3133 
   3134   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
   3135 
   3136   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
   3137   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
   3138   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
   3139 						    + nbucket];
   3140 
   3141   /* Compute distribution of chain lengths.  */
   3142   uint_fast32_t maxlength = 0;
   3143   uint_fast32_t nsyms = 0;
   3144   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   3145     if (bucket[cnt] != 0)
   3146       {
   3147 	Elf32_Word inner = bucket[cnt] - symbias;
   3148 	do
   3149 	  {
   3150 	    ++nsyms;
   3151 	    if (maxlength < ++lengths[cnt])
   3152 	      ++maxlength;
   3153 	    if (inner > max_nsyms)
   3154 	      goto invalid_data;
   3155 	  }
   3156 	while ((chain[inner++] & 1) == 0);
   3157       }
   3158 
   3159   /* Count bits in bitmask.  */
   3160   uint_fast32_t nbits = 0;
   3161   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
   3162     {
   3163       uint_fast32_t word = bitmask[cnt];
   3164 
   3165       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
   3166       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
   3167       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
   3168       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
   3169       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
   3170     }
   3171 
   3172   char *str;
   3173   if (unlikely (asprintf (&str, gettext ("\
   3174  Symbol Bias: %u\n\
   3175  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
   3176 			  (unsigned int) symbias,
   3177 			  bitmask_words * sizeof (Elf32_Word),
   3178 			  ((nbits * 100 + 50)
   3179 			   / (uint_fast32_t) (bitmask_words
   3180 					      * sizeof (Elf32_Word) * 8)),
   3181 			  (unsigned int) shift) == -1))
   3182     error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
   3183 
   3184   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
   3185 		   lengths, str);
   3186 
   3187   free (str);
   3188   free (lengths);
   3189 }
   3190 
   3191 
   3192 /* Find the symbol table(s).  For this we have to search through the
   3193    section table.  */
   3194 static void
   3195 handle_hash (Ebl *ebl)
   3196 {
   3197   /* Get the section header string table index.  */
   3198   size_t shstrndx;
   3199   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   3200     error (EXIT_FAILURE, 0,
   3201 	   gettext ("cannot get section header string table index"));
   3202 
   3203   Elf_Scn *scn = NULL;
   3204   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   3205     {
   3206       /* Handle the section if it is a symbol table.  */
   3207       GElf_Shdr shdr_mem;
   3208       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   3209 
   3210       if (likely (shdr != NULL))
   3211 	{
   3212 	  if (shdr->sh_type == SHT_HASH)
   3213 	    {
   3214 	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
   3215 		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
   3216 	      else
   3217 		handle_sysv_hash (ebl, scn, shdr, shstrndx);
   3218 	    }
   3219 	  else if (shdr->sh_type == SHT_GNU_HASH)
   3220 	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
   3221 	}
   3222     }
   3223 }
   3224 
   3225 
   3226 static void
   3227 print_liblist (Ebl *ebl)
   3228 {
   3229   /* Find the library list sections.  For this we have to search
   3230      through the section table.  */
   3231   Elf_Scn *scn = NULL;
   3232 
   3233   /* Get the section header string table index.  */
   3234   size_t shstrndx;
   3235   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   3236     error (EXIT_FAILURE, 0,
   3237 	   gettext ("cannot get section header string table index"));
   3238 
   3239   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   3240     {
   3241       GElf_Shdr shdr_mem;
   3242       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   3243 
   3244       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
   3245 	{
   3246 	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
   3247 	  int nentries = shdr->sh_size / sh_entsize;
   3248 	  printf (ngettext ("\
   3249 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   3250 			    "\
   3251 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   3252 			    nentries),
   3253 		  elf_ndxscn (scn),
   3254 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   3255 		  shdr->sh_offset,
   3256 		  nentries);
   3257 
   3258 	  Elf_Data *data = elf_getdata (scn, NULL);
   3259 	  if (data == NULL)
   3260 	    return;
   3261 
   3262 	  puts (gettext ("\
   3263        Library                       Time Stamp          Checksum Version Flags"));
   3264 
   3265 	  for (int cnt = 0; cnt < nentries; ++cnt)
   3266 	    {
   3267 	      GElf_Lib lib_mem;
   3268 	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
   3269 	      if (unlikely (lib == NULL))
   3270 		continue;
   3271 
   3272 	      time_t t = (time_t) lib->l_time_stamp;
   3273 	      struct tm *tm = gmtime (&t);
   3274 	      if (unlikely (tm == NULL))
   3275 		continue;
   3276 
   3277 	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
   3278 		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
   3279 		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
   3280 		      tm->tm_hour, tm->tm_min, tm->tm_sec,
   3281 		      (unsigned int) lib->l_checksum,
   3282 		      (unsigned int) lib->l_version,
   3283 		      (unsigned int) lib->l_flags);
   3284 	    }
   3285 	}
   3286     }
   3287 }
   3288 
   3289 static void
   3290 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
   3291 {
   3292   /* Find the object attributes sections.  For this we have to search
   3293      through the section table.  */
   3294   Elf_Scn *scn = NULL;
   3295 
   3296   /* Get the section header string table index.  */
   3297   size_t shstrndx;
   3298   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   3299     error (EXIT_FAILURE, 0,
   3300 	   gettext ("cannot get section header string table index"));
   3301 
   3302   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   3303     {
   3304       GElf_Shdr shdr_mem;
   3305       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   3306 
   3307       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
   3308 			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
   3309 			       || ehdr->e_machine != EM_ARM)))
   3310 	continue;
   3311 
   3312       printf (gettext ("\
   3313 \nObject attributes section [%2zu] '%s' of %" PRIu64
   3314 		       " bytes at offset %#0" PRIx64 ":\n"),
   3315 	      elf_ndxscn (scn),
   3316 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   3317 	      shdr->sh_size, shdr->sh_offset);
   3318 
   3319       Elf_Data *data = elf_rawdata (scn, NULL);
   3320       if (unlikely (data == NULL || data->d_size == 0))
   3321 	return;
   3322 
   3323       const unsigned char *p = data->d_buf;
   3324 
   3325       /* There is only one 'version', A.  */
   3326       if (unlikely (*p++ != 'A'))
   3327 	return;
   3328 
   3329       fputs_unlocked (gettext ("  Owner          Size\n"), stdout);
   3330 
   3331       inline size_t left (void)
   3332       {
   3333 	return (const unsigned char *) data->d_buf + data->d_size - p;
   3334       }
   3335 
   3336       /* Loop over the sections.  */
   3337       while (left () >= 4)
   3338 	{
   3339 	  /* Section length.  */
   3340 	  uint32_t len;
   3341 	  memcpy (&len, p, sizeof len);
   3342 
   3343 	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
   3344 	    CONVERT (len);
   3345 
   3346 	  if (unlikely (len > left ()))
   3347 	    break;
   3348 
   3349 	  /* Section vendor name.  */
   3350 	  const unsigned char *name = p + sizeof len;
   3351 	  p += len;
   3352 
   3353 	  unsigned const char *q = memchr (name, '\0', len);
   3354 	  if (unlikely (q == NULL))
   3355 	    break;
   3356 	  ++q;
   3357 
   3358 	  printf (gettext ("  %-13s  %4" PRIu32 "\n"), name, len);
   3359 
   3360 	  bool gnu_vendor = (q - name == sizeof "gnu"
   3361 			     && !memcmp (name, "gnu", sizeof "gnu"));
   3362 
   3363 	  /* Loop over subsections.  */
   3364 	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
   3365 	      || gnu_vendor)
   3366 	    while (q < p)
   3367 	      {
   3368 		const unsigned char *const sub = q;
   3369 
   3370 		unsigned int subsection_tag;
   3371 		get_uleb128 (subsection_tag, q, p);
   3372 		if (unlikely (q >= p))
   3373 		  break;
   3374 
   3375 		uint32_t subsection_len;
   3376 		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
   3377 		  break;
   3378 
   3379 		memcpy (&subsection_len, q, sizeof subsection_len);
   3380 
   3381 		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
   3382 		  CONVERT (subsection_len);
   3383 
   3384 		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
   3385 		if (unlikely (subsection_len == 0
   3386 			      || subsection_len >= (uint32_t) PTRDIFF_MAX
   3387 			      || p - sub < (ptrdiff_t) subsection_len))
   3388 		  break;
   3389 
   3390 		const unsigned char *r = q + sizeof subsection_len;
   3391 		q = sub + subsection_len;
   3392 
   3393 		switch (subsection_tag)
   3394 		  {
   3395 		  default:
   3396 		    /* Unknown subsection, print and skip.  */
   3397 		    printf (gettext ("    %-4u %12" PRIu32 "\n"),
   3398 			    subsection_tag, subsection_len);
   3399 		    break;
   3400 
   3401 		  case 1:	/* Tag_File */
   3402 		    printf (gettext ("    File: %11" PRIu32 "\n"),
   3403 			    subsection_len);
   3404 
   3405 		    while (r < q)
   3406 		      {
   3407 			unsigned int tag;
   3408 			get_uleb128 (tag, r, q);
   3409 			if (unlikely (r >= q))
   3410 			  break;
   3411 
   3412 			/* GNU style tags have either a uleb128 value,
   3413 			   when lowest bit is not set, or a string
   3414 			   when the lowest bit is set.
   3415 			   "compatibility" (32) is special.  It has
   3416 			   both a string and a uleb128 value.  For
   3417 			   non-gnu we assume 6 till 31 only take ints.
   3418 			   XXX see arm backend, do we need a separate
   3419 			   hook?  */
   3420 			uint64_t value = 0;
   3421 			const char *string = NULL;
   3422 			if (tag == 32 || (tag & 1) == 0
   3423 			    || (! gnu_vendor && (tag > 5 && tag < 32)))
   3424 			  {
   3425 			    get_uleb128 (value, r, q);
   3426 			    if (r > q)
   3427 			      break;
   3428 			  }
   3429 			if (tag == 32
   3430 			    || ((tag & 1) != 0
   3431 				&& (gnu_vendor
   3432 				    || (! gnu_vendor && tag > 32)))
   3433 			    || (! gnu_vendor && tag > 3 && tag < 6))
   3434 			  {
   3435 			    string = (const char *) r;
   3436 			    r = memchr (r, '\0', q - r);
   3437 			    if (r == NULL)
   3438 			      break;
   3439 			    ++r;
   3440 			  }
   3441 
   3442 			const char *tag_name = NULL;
   3443 			const char *value_name = NULL;
   3444 			ebl_check_object_attribute (ebl, (const char *) name,
   3445 						    tag, value,
   3446 						    &tag_name, &value_name);
   3447 
   3448 			if (tag_name != NULL)
   3449 			  {
   3450 			    if (tag == 32)
   3451 			      printf (gettext ("      %s: %" PRId64 ", %s\n"),
   3452 				      tag_name, value, string);
   3453 			    else if (string == NULL && value_name == NULL)
   3454 			      printf (gettext ("      %s: %" PRId64 "\n"),
   3455 				      tag_name, value);
   3456 			    else
   3457 			      printf (gettext ("      %s: %s\n"),
   3458 				      tag_name, string ?: value_name);
   3459 			  }
   3460 			else
   3461 			  {
   3462 			    /* For "gnu" vendor 32 "compatibility" has
   3463 			       already been handled above.  */
   3464 			    assert (tag != 32
   3465 				    || strcmp ((const char *) name, "gnu"));
   3466 			    if (string == NULL)
   3467 			      printf (gettext ("      %u: %" PRId64 "\n"),
   3468 				      tag, value);
   3469 			    else
   3470 			      printf (gettext ("      %u: %s\n"),
   3471 				      tag, string);
   3472 			  }
   3473 		      }
   3474 		  }
   3475 	      }
   3476 	}
   3477     }
   3478 }
   3479 
   3480 
   3481 static char *
   3482 format_dwarf_addr (Dwfl_Module *dwflmod,
   3483 		   int address_size, Dwarf_Addr address, Dwarf_Addr raw)
   3484 {
   3485   /* See if there is a name we can give for this address.  */
   3486   GElf_Sym sym;
   3487   GElf_Off off = 0;
   3488   const char *name = (print_address_names && ! print_unresolved_addresses)
   3489     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
   3490     : NULL;
   3491 
   3492   const char *scn;
   3493   if (print_unresolved_addresses)
   3494     {
   3495       address = raw;
   3496       scn = NULL;
   3497     }
   3498   else
   3499     {
   3500       /* Relativize the address.  */
   3501       int n = dwfl_module_relocations (dwflmod);
   3502       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
   3503 
   3504       /* In an ET_REL file there is a section name to refer to.  */
   3505       scn = (i < 0 ? NULL
   3506 	     : dwfl_module_relocation_info (dwflmod, i, NULL));
   3507     }
   3508 
   3509   char *result;
   3510   if ((name != NULL
   3511        ? (off != 0
   3512 	  ? (scn != NULL
   3513 	     ? (address_size == 0
   3514 		? asprintf (&result,
   3515 			    gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
   3516 			    scn, address, name, off)
   3517 		: asprintf (&result,
   3518 			    gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
   3519 			    scn, 2 + address_size * 2, address,
   3520 			    name, off))
   3521 	     : (address_size == 0
   3522 		? asprintf (&result,
   3523 			    gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
   3524 			    address, name, off)
   3525 		: asprintf (&result,
   3526 			    gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
   3527 			    2 + address_size * 2, address,
   3528 			    name, off)))
   3529 	  : (scn != NULL
   3530 	     ? (address_size == 0
   3531 		? asprintf (&result,
   3532 			    gettext ("%s+%#" PRIx64 " <%s>"),
   3533 			    scn, address, name)
   3534 		: asprintf (&result,
   3535 			    gettext ("%s+%#0*" PRIx64 " <%s>"),
   3536 			    scn, 2 + address_size * 2, address, name))
   3537 	     : (address_size == 0
   3538 		? asprintf (&result,
   3539 			    gettext ("%#" PRIx64 " <%s>"),
   3540 			    address, name)
   3541 		: asprintf (&result,
   3542 			    gettext ("%#0*" PRIx64 " <%s>"),
   3543 			    2 + address_size * 2, address, name))))
   3544        : (scn != NULL
   3545 	  ? (address_size == 0
   3546 	     ? asprintf (&result,
   3547 			 gettext ("%s+%#" PRIx64),
   3548 			 scn, address)
   3549 	     : asprintf (&result,
   3550 			 gettext ("%s+%#0*" PRIx64),
   3551 			 scn, 2 + address_size * 2, address))
   3552 	  : (address_size == 0
   3553 	     ? asprintf (&result,
   3554 			 "%#" PRIx64,
   3555 			 address)
   3556 	     : asprintf (&result,
   3557 			 "%#0*" PRIx64,
   3558 			 2 + address_size * 2, address)))) < 0)
   3559     error (EXIT_FAILURE, 0, _("memory exhausted"));
   3560 
   3561   return result;
   3562 }
   3563 
   3564 static const char *
   3565 dwarf_tag_string (unsigned int tag)
   3566 {
   3567   switch (tag)
   3568     {
   3569 #define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
   3570       ALL_KNOWN_DW_TAG
   3571 #undef ONE_KNOWN_DW_TAG
   3572     default:
   3573       return NULL;
   3574     }
   3575 }
   3576 
   3577 
   3578 static const char *
   3579 dwarf_attr_string (unsigned int attrnum)
   3580 {
   3581   switch (attrnum)
   3582     {
   3583 #define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
   3584       ALL_KNOWN_DW_AT
   3585 #undef ONE_KNOWN_DW_AT
   3586     default:
   3587       return NULL;
   3588     }
   3589 }
   3590 
   3591 
   3592 static const char *
   3593 dwarf_form_string (unsigned int form)
   3594 {
   3595   switch (form)
   3596     {
   3597 #define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE)
   3598 #define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
   3599       ALL_KNOWN_DW_FORM
   3600 #undef ONE_KNOWN_DW_FORM
   3601 #undef ONE_KNOWN_DW_FORM_DESC
   3602     default:
   3603       return NULL;
   3604     }
   3605 }
   3606 
   3607 
   3608 static const char *
   3609 dwarf_lang_string (unsigned int lang)
   3610 {
   3611   switch (lang)
   3612     {
   3613 #define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME;
   3614       ALL_KNOWN_DW_LANG
   3615 #undef ONE_KNOWN_DW_LANG_DESC
   3616     default:
   3617       return NULL;
   3618     }
   3619 }
   3620 
   3621 
   3622 static const char *
   3623 dwarf_inline_string (unsigned int code)
   3624 {
   3625   static const char *const known[] =
   3626     {
   3627 #define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
   3628       ALL_KNOWN_DW_INL
   3629 #undef ONE_KNOWN_DW_INL
   3630     };
   3631 
   3632   if (likely (code < sizeof (known) / sizeof (known[0])))
   3633     return known[code];
   3634 
   3635   return NULL;
   3636 }
   3637 
   3638 
   3639 static const char *
   3640 dwarf_encoding_string (unsigned int code)
   3641 {
   3642   static const char *const known[] =
   3643     {
   3644 #define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
   3645       ALL_KNOWN_DW_ATE
   3646 #undef ONE_KNOWN_DW_ATE
   3647     };
   3648 
   3649   if (likely (code < sizeof (known) / sizeof (known[0])))
   3650     return known[code];
   3651 
   3652   return NULL;
   3653 }
   3654 
   3655 
   3656 static const char *
   3657 dwarf_access_string (unsigned int code)
   3658 {
   3659   static const char *const known[] =
   3660     {
   3661 #define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
   3662       ALL_KNOWN_DW_ACCESS
   3663 #undef ONE_KNOWN_DW_ACCESS
   3664     };
   3665 
   3666   if (likely (code < sizeof (known) / sizeof (known[0])))
   3667     return known[code];
   3668 
   3669   return NULL;
   3670 }
   3671 
   3672 
   3673 static const char *
   3674 dwarf_visibility_string (unsigned int code)
   3675 {
   3676   static const char *const known[] =
   3677     {
   3678 #define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
   3679       ALL_KNOWN_DW_VIS
   3680 #undef ONE_KNOWN_DW_VIS
   3681     };
   3682 
   3683   if (likely (code < sizeof (known) / sizeof (known[0])))
   3684     return known[code];
   3685 
   3686   return NULL;
   3687 }
   3688 
   3689 
   3690 static const char *
   3691 dwarf_virtuality_string (unsigned int code)
   3692 {
   3693   static const char *const known[] =
   3694     {
   3695 #define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
   3696       ALL_KNOWN_DW_VIRTUALITY
   3697 #undef ONE_KNOWN_DW_VIRTUALITY
   3698     };
   3699 
   3700   if (likely (code < sizeof (known) / sizeof (known[0])))
   3701     return known[code];
   3702 
   3703   return NULL;
   3704 }
   3705 
   3706 
   3707 static const char *
   3708 dwarf_identifier_case_string (unsigned int code)
   3709 {
   3710   static const char *const known[] =
   3711     {
   3712 #define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
   3713       ALL_KNOWN_DW_ID
   3714 #undef ONE_KNOWN_DW_ID
   3715     };
   3716 
   3717   if (likely (code < sizeof (known) / sizeof (known[0])))
   3718     return known[code];
   3719 
   3720   return NULL;
   3721 }
   3722 
   3723 
   3724 static const char *
   3725 dwarf_calling_convention_string (unsigned int code)
   3726 {
   3727   static const char *const known[] =
   3728     {
   3729 #define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
   3730       ALL_KNOWN_DW_CC
   3731 #undef ONE_KNOWN_DW_CC
   3732     };
   3733 
   3734   if (likely (code < sizeof (known) / sizeof (known[0])))
   3735     return known[code];
   3736 
   3737   return NULL;
   3738 }
   3739 
   3740 
   3741 static const char *
   3742 dwarf_ordering_string (unsigned int code)
   3743 {
   3744   static const char *const known[] =
   3745     {
   3746 #define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
   3747       ALL_KNOWN_DW_ORD
   3748 #undef ONE_KNOWN_DW_ORD
   3749     };
   3750 
   3751   if (likely (code < sizeof (known) / sizeof (known[0])))
   3752     return known[code];
   3753 
   3754   return NULL;
   3755 }
   3756 
   3757 
   3758 static const char *
   3759 dwarf_discr_list_string (unsigned int code)
   3760 {
   3761   static const char *const known[] =
   3762     {
   3763 #define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
   3764       ALL_KNOWN_DW_DSC
   3765 #undef ONE_KNOWN_DW_DSC
   3766     };
   3767 
   3768   if (likely (code < sizeof (known) / sizeof (known[0])))
   3769     return known[code];
   3770 
   3771   return NULL;
   3772 }
   3773 
   3774 
   3775 static const char *
   3776 dwarf_locexpr_opcode_string (unsigned int code)
   3777 {
   3778   static const char *const known[] =
   3779     {
   3780       /* Normally we can't affort building huge table of 64K entries,
   3781 	 most of them zero, just because there are a couple defined
   3782 	 values at the far end.  In case of opcodes, it's OK.  */
   3783 #define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
   3784 #define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
   3785       ALL_KNOWN_DW_OP
   3786 #undef ONE_KNOWN_DW_OP
   3787 #undef ONE_KNOWN_DW_OP_DESC
   3788     };
   3789 
   3790   if (likely (code < sizeof (known) / sizeof (known[0])))
   3791     return known[code];
   3792 
   3793   return NULL;
   3794 }
   3795 
   3796 
   3797 /* Used by all dwarf_foo_name functions.  */
   3798 static const char *
   3799 string_or_unknown (const char *known, unsigned int code,
   3800                    unsigned int lo_user, unsigned int hi_user,
   3801 		   bool print_unknown_num)
   3802 {
   3803   static char unknown_buf[20];
   3804 
   3805   if (likely (known != NULL))
   3806     return known;
   3807 
   3808   if (lo_user != 0 && code >= lo_user && code <= hi_user)
   3809     {
   3810       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
   3811 		code - lo_user);
   3812       return unknown_buf;
   3813     }
   3814 
   3815   if (print_unknown_num)
   3816     {
   3817       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
   3818       return unknown_buf;
   3819     }
   3820 
   3821   return "???";
   3822 }
   3823 
   3824 
   3825 static const char *
   3826 dwarf_tag_name (unsigned int tag)
   3827 {
   3828   const char *ret = dwarf_tag_string (tag);
   3829   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
   3830 }
   3831 
   3832 static const char *
   3833 dwarf_attr_name (unsigned int attr)
   3834 {
   3835   const char *ret = dwarf_attr_string (attr);
   3836   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
   3837 }
   3838 
   3839 
   3840 static const char *
   3841 dwarf_form_name (unsigned int form)
   3842 {
   3843   const char *ret = dwarf_form_string (form);
   3844   return string_or_unknown (ret, form, 0, 0, true);
   3845 }
   3846 
   3847 
   3848 static const char *
   3849 dwarf_lang_name (unsigned int lang)
   3850 {
   3851   const char *ret = dwarf_lang_string (lang);
   3852   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
   3853 }
   3854 
   3855 
   3856 static const char *
   3857 dwarf_inline_name (unsigned int code)
   3858 {
   3859   const char *ret = dwarf_inline_string (code);
   3860   return string_or_unknown (ret, code, 0, 0, false);
   3861 }
   3862 
   3863 
   3864 static const char *
   3865 dwarf_encoding_name (unsigned int code)
   3866 {
   3867   const char *ret = dwarf_encoding_string (code);
   3868   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
   3869 }
   3870 
   3871 
   3872 static const char *
   3873 dwarf_access_name (unsigned int code)
   3874 {
   3875   const char *ret = dwarf_access_string (code);
   3876   return string_or_unknown (ret, code, 0, 0, false);
   3877 }
   3878 
   3879 
   3880 static const char *
   3881 dwarf_visibility_name (unsigned int code)
   3882 {
   3883   const char *ret = dwarf_visibility_string (code);
   3884   return string_or_unknown (ret, code, 0, 0, false);
   3885 }
   3886 
   3887 
   3888 static const char *
   3889 dwarf_virtuality_name (unsigned int code)
   3890 {
   3891   const char *ret = dwarf_virtuality_string (code);
   3892   return string_or_unknown (ret, code, 0, 0, false);
   3893 }
   3894 
   3895 
   3896 static const char *
   3897 dwarf_identifier_case_name (unsigned int code)
   3898 {
   3899   const char *ret = dwarf_identifier_case_string (code);
   3900   return string_or_unknown (ret, code, 0, 0, false);
   3901 }
   3902 
   3903 
   3904 static const char *
   3905 dwarf_calling_convention_name (unsigned int code)
   3906 {
   3907   const char *ret = dwarf_calling_convention_string (code);
   3908   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
   3909 }
   3910 
   3911 
   3912 static const char *
   3913 dwarf_ordering_name (unsigned int code)
   3914 {
   3915   const char *ret = dwarf_ordering_string (code);
   3916   return string_or_unknown (ret, code, 0, 0, false);
   3917 }
   3918 
   3919 
   3920 static const char *
   3921 dwarf_discr_list_name (unsigned int code)
   3922 {
   3923   const char *ret = dwarf_discr_list_string (code);
   3924   return string_or_unknown (ret, code, 0, 0, false);
   3925 }
   3926 
   3927 
   3928 static void
   3929 print_block (size_t n, const void *block)
   3930 {
   3931   if (n == 0)
   3932     puts (_("empty block"));
   3933   else
   3934     {
   3935       printf (_("%zu byte block:"), n);
   3936       const unsigned char *data = block;
   3937       do
   3938 	printf (" %02x", *data++);
   3939       while (--n > 0);
   3940       putchar ('\n');
   3941     }
   3942 }
   3943 
   3944 static void
   3945 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
   3946 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
   3947 	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
   3948 {
   3949   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
   3950 
   3951   if (len == 0)
   3952     {
   3953       printf ("%*s(empty)\n", indent, "");
   3954       return;
   3955     }
   3956 
   3957 #define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
   3958 #define CONSUME(n)	NEED (n); else len -= (n)
   3959 
   3960   Dwarf_Word offset = 0;
   3961   while (len-- > 0)
   3962     {
   3963       uint_fast8_t op = *data++;
   3964 
   3965       const char *op_name = dwarf_locexpr_opcode_string (op);
   3966       if (unlikely (op_name == NULL))
   3967 	{
   3968 	  static char buf[20];
   3969 	  if (op >= DW_OP_lo_user)
   3970 	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
   3971 	  else
   3972 	    snprintf (buf, sizeof buf, "??? (%#x)", op);
   3973 	  op_name = buf;
   3974 	}
   3975 
   3976       switch (op)
   3977 	{
   3978 	case DW_OP_addr:;
   3979 	  /* Address operand.  */
   3980 	  Dwarf_Word addr;
   3981 	  NEED (addrsize);
   3982 	  if (addrsize == 4)
   3983 	    addr = read_4ubyte_unaligned (dbg, data);
   3984 	  else if (addrsize == 8)
   3985 	    addr = read_8ubyte_unaligned (dbg, data);
   3986 	  else
   3987 	    goto invalid;
   3988 	  data += addrsize;
   3989 	  CONSUME (addrsize);
   3990 
   3991 	  char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
   3992 	  printf ("%*s[%4" PRIuMAX "] %s %s\n",
   3993 		  indent, "", (uintmax_t) offset, op_name, a);
   3994 	  free (a);
   3995 
   3996 	  offset += 1 + addrsize;
   3997 	  break;
   3998 
   3999 	case DW_OP_call_ref:
   4000 	  /* Offset operand.  */
   4001 	  if (ref_size != 4 && ref_size != 8)
   4002 	    goto invalid; /* Cannot be used in CFA.  */
   4003 	  NEED (ref_size);
   4004 	  if (ref_size == 4)
   4005 	    addr = read_4ubyte_unaligned (dbg, data);
   4006 	  else
   4007 	    addr = read_8ubyte_unaligned (dbg, data);
   4008 	  data += ref_size;
   4009 	  CONSUME (ref_size);
   4010 
   4011 	  printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
   4012 		  indent, "", (uintmax_t) offset,
   4013 		  op_name, (uintmax_t) addr);
   4014 	  offset += 1 + ref_size;
   4015 	  break;
   4016 
   4017 	case DW_OP_deref_size:
   4018 	case DW_OP_xderef_size:
   4019 	case DW_OP_pick:
   4020 	case DW_OP_const1u:
   4021 	  // XXX value might be modified by relocation
   4022 	  NEED (1);
   4023 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
   4024 		  indent, "", (uintmax_t) offset,
   4025 		  op_name, *((uint8_t *) data));
   4026 	  ++data;
   4027 	  --len;
   4028 	  offset += 2;
   4029 	  break;
   4030 
   4031 	case DW_OP_const2u:
   4032 	  NEED (2);
   4033 	  // XXX value might be modified by relocation
   4034 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
   4035 		  indent, "", (uintmax_t) offset,
   4036 		  op_name, read_2ubyte_unaligned (dbg, data));
   4037 	  CONSUME (2);
   4038 	  data += 2;
   4039 	  offset += 3;
   4040 	  break;
   4041 
   4042 	case DW_OP_const4u:
   4043 	  NEED (4);
   4044 	  // XXX value might be modified by relocation
   4045 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
   4046 		  indent, "", (uintmax_t) offset,
   4047 		  op_name, read_4ubyte_unaligned (dbg, data));
   4048 	  CONSUME (4);
   4049 	  data += 4;
   4050 	  offset += 5;
   4051 	  break;
   4052 
   4053 	case DW_OP_const8u:
   4054 	  NEED (8);
   4055 	  // XXX value might be modified by relocation
   4056 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
   4057 		  indent, "", (uintmax_t) offset,
   4058 		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
   4059 	  CONSUME (8);
   4060 	  data += 8;
   4061 	  offset += 9;
   4062 	  break;
   4063 
   4064 	case DW_OP_const1s:
   4065 	  NEED (1);
   4066 	  // XXX value might be modified by relocation
   4067 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
   4068 		  indent, "", (uintmax_t) offset,
   4069 		  op_name, *((int8_t *) data));
   4070 	  ++data;
   4071 	  --len;
   4072 	  offset += 2;
   4073 	  break;
   4074 
   4075 	case DW_OP_const2s:
   4076 	  NEED (2);
   4077 	  // XXX value might be modified by relocation
   4078 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
   4079 		  indent, "", (uintmax_t) offset,
   4080 		  op_name, read_2sbyte_unaligned (dbg, data));
   4081 	  CONSUME (2);
   4082 	  data += 2;
   4083 	  offset += 3;
   4084 	  break;
   4085 
   4086 	case DW_OP_const4s:
   4087 	  NEED (4);
   4088 	  // XXX value might be modified by relocation
   4089 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
   4090 		  indent, "", (uintmax_t) offset,
   4091 		  op_name, read_4sbyte_unaligned (dbg, data));
   4092 	  CONSUME (4);
   4093 	  data += 4;
   4094 	  offset += 5;
   4095 	  break;
   4096 
   4097 	case DW_OP_const8s:
   4098 	  NEED (8);
   4099 	  // XXX value might be modified by relocation
   4100 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
   4101 		  indent, "", (uintmax_t) offset,
   4102 		  op_name, read_8sbyte_unaligned (dbg, data));
   4103 	  CONSUME (8);
   4104 	  data += 8;
   4105 	  offset += 9;
   4106 	  break;
   4107 
   4108 	case DW_OP_piece:
   4109 	case DW_OP_regx:
   4110 	case DW_OP_plus_uconst:
   4111 	case DW_OP_constu:;
   4112 	  const unsigned char *start = data;
   4113 	  uint64_t uleb;
   4114 	  NEED (1);
   4115 	  get_uleb128 (uleb, data, data + len);
   4116 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
   4117 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4118 	  CONSUME (data - start);
   4119 	  offset += 1 + (data - start);
   4120 	  break;
   4121 
   4122 	case DW_OP_bit_piece:
   4123 	  start = data;
   4124 	  uint64_t uleb2;
   4125 	  NEED (1);
   4126 	  get_uleb128 (uleb, data, data + len);
   4127 	  NEED (1);
   4128 	  get_uleb128 (uleb2, data, data + len);
   4129 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
   4130 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
   4131 	  CONSUME (data - start);
   4132 	  offset += 1 + (data - start);
   4133 	  break;
   4134 
   4135 	case DW_OP_fbreg:
   4136 	case DW_OP_breg0 ... DW_OP_breg31:
   4137 	case DW_OP_consts:
   4138 	  start = data;
   4139 	  int64_t sleb;
   4140 	  NEED (1);
   4141 	  get_sleb128 (sleb, data, data + len);
   4142 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
   4143 		  indent, "", (uintmax_t) offset, op_name, sleb);
   4144 	  CONSUME (data - start);
   4145 	  offset += 1 + (data - start);
   4146 	  break;
   4147 
   4148 	case DW_OP_bregx:
   4149 	  start = data;
   4150 	  NEED (1);
   4151 	  get_uleb128 (uleb, data, data + len);
   4152 	  NEED (1);
   4153 	  get_sleb128 (sleb, data, data + len);
   4154 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
   4155 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
   4156 	  CONSUME (data - start);
   4157 	  offset += 1 + (data - start);
   4158 	  break;
   4159 
   4160 	case DW_OP_call2:
   4161 	  NEED (2);
   4162 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
   4163 		  indent, "", (uintmax_t) offset, op_name,
   4164 		  read_2ubyte_unaligned (dbg, data));
   4165 	  CONSUME (2);
   4166 	  offset += 3;
   4167 	  break;
   4168 
   4169 	case DW_OP_call4:
   4170 	  NEED (4);
   4171 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
   4172 		  indent, "", (uintmax_t) offset, op_name,
   4173 		  read_4ubyte_unaligned (dbg, data));
   4174 	  CONSUME (4);
   4175 	  offset += 5;
   4176 	  break;
   4177 
   4178 	case DW_OP_skip:
   4179 	case DW_OP_bra:
   4180 	  NEED (2);
   4181 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
   4182 		  indent, "", (uintmax_t) offset, op_name,
   4183 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
   4184 	  CONSUME (2);
   4185 	  data += 2;
   4186 	  offset += 3;
   4187 	  break;
   4188 
   4189 	case DW_OP_implicit_value:
   4190 	  start = data;
   4191 	  NEED (1);
   4192 	  get_uleb128 (uleb, data, data + len);
   4193 	  printf ("%*s[%4" PRIuMAX "] %s: ",
   4194 		  indent, "", (uintmax_t) offset, op_name);
   4195 	  NEED (uleb);
   4196 	  print_block (uleb, data);
   4197 	  data += uleb;
   4198 	  CONSUME (data - start);
   4199 	  offset += 1 + (data - start);
   4200 	  break;
   4201 
   4202 	case DW_OP_GNU_implicit_pointer:
   4203 	  /* DIE offset operand.  */
   4204 	  start = data;
   4205 	  NEED (ref_size);
   4206 	  if (ref_size != 4 && ref_size != 8)
   4207 	    goto invalid; /* Cannot be used in CFA.  */
   4208 	  if (ref_size == 4)
   4209 	    addr = read_4ubyte_unaligned (dbg, data);
   4210 	  else
   4211 	    addr = read_8ubyte_unaligned (dbg, data);
   4212 	  data += ref_size;
   4213 	  /* Byte offset operand.  */
   4214 	  NEED (1);
   4215 	  get_sleb128 (sleb, data, data + len);
   4216 
   4217 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
   4218 		  indent, "", (intmax_t) offset,
   4219 		  op_name, (uintmax_t) addr, sleb);
   4220 	  CONSUME (data - start);
   4221 	  offset += 1 + (data - start);
   4222 	  break;
   4223 
   4224 	case DW_OP_GNU_entry_value:
   4225 	  /* Size plus expression block.  */
   4226 	  start = data;
   4227 	  NEED (1);
   4228 	  get_uleb128 (uleb, data, data + len);
   4229 	  printf ("%*s[%4" PRIuMAX "] %s:\n",
   4230 		  indent, "", (uintmax_t) offset, op_name);
   4231 	  NEED (uleb);
   4232 	  print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
   4233 		     addrsize, offset_size, cu, uleb, data);
   4234 	  data += uleb;
   4235 	  CONSUME (data - start);
   4236 	  offset += 1 + (data - start);
   4237 	  break;
   4238 
   4239 	case DW_OP_GNU_const_type:
   4240 	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
   4241 	     unsigned size plus block.  */
   4242 	  start = data;
   4243 	  NEED (1);
   4244 	  get_uleb128 (uleb, data, data + len);
   4245 	  if (! print_unresolved_addresses && cu != NULL)
   4246 	    uleb += cu->start;
   4247 	  NEED (1);
   4248 	  uint8_t usize = *(uint8_t *) data++;
   4249 	  NEED (usize);
   4250 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
   4251 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4252 	  print_block (usize, data);
   4253 	  data += usize;
   4254 	  CONSUME (data - start);
   4255 	  offset += 1 + (data - start);
   4256 	  break;
   4257 
   4258 	case DW_OP_GNU_regval_type:
   4259 	  /* uleb128 register number, uleb128 CU relative
   4260 	     DW_TAG_base_type DIE offset.  */
   4261 	  start = data;
   4262 	  NEED (1);
   4263 	  get_uleb128 (uleb, data, data + len);
   4264 	  NEED (1);
   4265 	  get_uleb128 (uleb2, data, data + len);
   4266 	  if (! print_unresolved_addresses && cu != NULL)
   4267 	    uleb2 += cu->start;
   4268 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
   4269 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
   4270 	  CONSUME (data - start);
   4271 	  offset += 1 + (data - start);
   4272 	  break;
   4273 
   4274 	case DW_OP_GNU_deref_type:
   4275 	  /* 1-byte unsigned size of value, uleb128 CU relative
   4276 	     DW_TAG_base_type DIE offset.  */
   4277 	  start = data;
   4278 	  NEED (1);
   4279 	  usize = *(uint8_t *) data++;
   4280 	  NEED (1);
   4281 	  get_uleb128 (uleb, data, data + len);
   4282 	  if (! print_unresolved_addresses && cu != NULL)
   4283 	    uleb += cu->start;
   4284 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
   4285 		  indent, "", (uintmax_t) offset,
   4286 		  op_name, usize, uleb);
   4287 	  CONSUME (data - start);
   4288 	  offset += 1 + (data - start);
   4289 	  break;
   4290 
   4291 	case DW_OP_GNU_convert:
   4292 	case DW_OP_GNU_reinterpret:
   4293 	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
   4294 	     for conversion to untyped.  */
   4295 	  start = data;
   4296 	  NEED (1);
   4297 	  get_uleb128 (uleb, data, data + len);
   4298 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
   4299 	    uleb += cu->start;
   4300 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
   4301 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4302 	  CONSUME (data - start);
   4303 	  offset += 1 + (data - start);
   4304 	  break;
   4305 
   4306 	case DW_OP_GNU_parameter_ref:
   4307 	  /* 4 byte CU relative reference to the abstract optimized away
   4308 	     DW_TAG_formal_parameter.  */
   4309 	  NEED (4);
   4310 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
   4311 	  if (! print_unresolved_addresses && cu != NULL)
   4312 	    param_off += cu->start;
   4313 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
   4314 		  indent, "", (uintmax_t) offset, op_name, param_off);
   4315 	  CONSUME (4);
   4316 	  data += 4;
   4317 	  offset += 5;
   4318 	  break;
   4319 
   4320 	default:
   4321 	  /* No Operand.  */
   4322 	  printf ("%*s[%4" PRIuMAX "] %s\n",
   4323 		  indent, "", (uintmax_t) offset, op_name);
   4324 	  ++offset;
   4325 	  break;
   4326 	}
   4327 
   4328       indent = indentrest;
   4329       continue;
   4330 
   4331     invalid:
   4332       printf (gettext ("%*s[%4" PRIuMAX "] %s  <TRUNCATED>\n"),
   4333 	      indent, "", (uintmax_t) offset, op_name);
   4334       break;
   4335     }
   4336 }
   4337 
   4338 
   4339 struct listptr
   4340 {
   4341   Dwarf_Off offset:(64 - 3);
   4342   bool addr64:1;
   4343   bool dwarf64:1;
   4344   bool warned:1;
   4345   struct Dwarf_CU *cu;
   4346 };
   4347 
   4348 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
   4349 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
   4350 
   4351 static Dwarf_Addr
   4352 listptr_base (struct listptr *p)
   4353 {
   4354   Dwarf_Addr base;
   4355   Dwarf_Die cu = CUDIE (p->cu);
   4356   /* Find the base address of the compilation unit.  It will normally
   4357      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
   4358      address could be overridden by DW_AT_entry_pc.  It's been
   4359      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
   4360      compilation units with discontinuous ranges.  */
   4361   if (unlikely (dwarf_lowpc (&cu, &base) != 0))
   4362     {
   4363       Dwarf_Attribute attr_mem;
   4364       if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
   4365 			  &base) != 0)
   4366 	base = 0;
   4367     }
   4368   return base;
   4369 }
   4370 
   4371 static int
   4372 compare_listptr (const void *a, const void *b, void *arg)
   4373 {
   4374   const char *name = arg;
   4375   struct listptr *p1 = (void *) a;
   4376   struct listptr *p2 = (void *) b;
   4377 
   4378   if (p1->offset < p2->offset)
   4379     return -1;
   4380   if (p1->offset > p2->offset)
   4381     return 1;
   4382 
   4383   if (!p1->warned && !p2->warned)
   4384     {
   4385       if (p1->addr64 != p2->addr64)
   4386 	{
   4387 	  p1->warned = p2->warned = true;
   4388 	  error (0, 0,
   4389 		 gettext ("%s %#" PRIx64 " used with different address sizes"),
   4390 		 name, (uint64_t) p1->offset);
   4391 	}
   4392       if (p1->dwarf64 != p2->dwarf64)
   4393 	{
   4394 	  p1->warned = p2->warned = true;
   4395 	  error (0, 0,
   4396 		 gettext ("%s %#" PRIx64 " used with different offset sizes"),
   4397 		 name, (uint64_t) p1->offset);
   4398 	}
   4399       if (listptr_base (p1) != listptr_base (p2))
   4400 	{
   4401 	  p1->warned = p2->warned = true;
   4402 	  error (0, 0,
   4403 		 gettext ("%s %#" PRIx64 " used with different base addresses"),
   4404 		 name, (uint64_t) p1->offset);
   4405 	}
   4406     }
   4407 
   4408   return 0;
   4409 }
   4410 
   4411 struct listptr_table
   4412 {
   4413   size_t n;
   4414   size_t alloc;
   4415   struct listptr *table;
   4416 };
   4417 
   4418 static struct listptr_table known_loclistptr;
   4419 static struct listptr_table known_rangelistptr;
   4420 
   4421 static void
   4422 reset_listptr (struct listptr_table *table)
   4423 {
   4424   free (table->table);
   4425   table->table = NULL;
   4426   table->n = table->alloc = 0;
   4427 }
   4428 
   4429 /* Returns false if offset doesn't fit.  See struct listptr.  */
   4430 static bool
   4431 notice_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 
   4466 static void
   4467 sort_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 
   4474 static bool
   4475 skip_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 
   4518 static void
   4519 print_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.  */
   4592 static void
   4593 print_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.  */
   4658 static void
   4659 print_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.  */
   4817 static void
   4818 print_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
   4909 static const char *
   4910 register_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 
   4941 static void
   4942 print_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 
   5201 static unsigned int
   5202 encoded_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 
   5220 static unsigned int
   5221 print_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 
   5261 static unsigned int
   5262 print_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 
   5289 static void
   5290 print_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 
   5318 static const unsigned char *
   5319 read_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 
   5374 static void
   5375 print_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 
   5754 struct 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 
   5768 static int
   5769 attr_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 
   6091 static void
   6092 print_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 
   6247 static void
   6248 print_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 
   6254 static void
   6255 print_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 
   6262 static void
   6263 print_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 
   6352 static void
   6353 print_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 
   6880 static void
   6881 print_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 
   6986 struct mac_culist
   6987 {
   6988   Dwarf_Die die;
   6989   Dwarf_Off offset;
   6990   Dwarf_Files *files;
   6991   struct mac_culist *next;
   6992 };
   6993 
   6994 
   6995 static int
   6996 mac_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 
   7009 static void
   7010 print_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 
   7172 static void
   7173 print_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.  */
   7582 static int
   7583 print_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'.  */
   7597 static void
   7598 print_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'.  */
   7611 static void
   7612 print_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'.  */
   7657 static void
   7658 print_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'.  */
   7757 static void
   7758 print_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 */
   7926 static void
   7927 print_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 
   8162 static void
   8163 print_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 
   8270 static unsigned int
   8271 __attribute__ ((format (printf, 6, 7)))
   8272 print_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 
   8312 static const void *
   8313 convert (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 
   8341 typedef uint8_t GElf_Byte;
   8342 
   8343 static unsigned int
   8344 handle_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.  */
   8572 static int
   8573 compare_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.  */
   8586 static int
   8587 compare_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 
   8599 static unsigned int
   8600 handle_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 
   8693 static unsigned int
   8694 handle_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 
   8704 static unsigned int
   8705 handle_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 
   8802 struct 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 
   8812 static int
   8813 register_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 
   8820 static int
   8821 compare_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.  */
   8829 static int
   8830 compare_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.  */
   8846 static int
   8847 compare_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 
   8854 static unsigned int
   8855 handle_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 
   8935 static void
   8936 handle_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 
   9007 static bool
   9008 buf_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 
   9013 static bool
   9014 buf_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 
   9024 static bool
   9025 buf_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 
   9047 static void
   9048 handle_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 
   9105 static void
   9106 handle_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 
   9156 static void
   9157 handle_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 
   9186 static void
   9187 handle_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 
   9262 static void
   9263 handle_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 
   9320 static void
   9321 hex_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 
   9350 static void
   9351 dump_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 
   9373 static void
   9374 print_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 
   9411 static void
   9412 for_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 
   9469 static void
   9470 dump_data (Ebl *ebl)
   9471 {
   9472   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
   9473 }
   9474 
   9475 static void
   9476 dump_strings (Ebl *ebl)
   9477 {
   9478   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
   9479 }
   9480 
   9481 static void
   9482 print_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 
   9511 static void
   9512 dump_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