Home | History | Annotate | Download | only in src
      1 /* Print information from ELF file in human-readable form.
      2    Copyright (C) 1999-2018 Red Hat, Inc.
      3    This file is part of elfutils.
      4 
      5    This file is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3 of the License, or
      8    (at your option) any later version.
      9 
     10    elfutils is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17 
     18 #ifdef HAVE_CONFIG_H
     19 # include <config.h>
     20 #endif
     21 
     22 #include <argp.h>
     23 #include <assert.h>
     24 #include <ctype.h>
     25 #include <dwarf.h>
     26 #include <errno.h>
     27 #include <fcntl.h>
     28 #include <gelf.h>
     29 #include <inttypes.h>
     30 #include <langinfo.h>
     31 #include <libdw.h>
     32 #include <libdwfl.h>
     33 #include <libintl.h>
     34 #include <locale.h>
     35 #include <stdarg.h>
     36 #include <stdbool.h>
     37 #include <stdio.h>
     38 #include <stdio_ext.h>
     39 #include <stdlib.h>
     40 #include <string.h>
     41 #include <strings.h>
     42 #include <time.h>
     43 #include <unistd.h>
     44 #include <sys/stat.h>
     45 #include <signal.h>
     46 
     47 #include <libeu.h>
     48 #include <system.h>
     49 #include <printversion.h>
     50 #include "../libelf/libelfP.h"
     51 #include "../libelf/common.h"
     52 #include "../libebl/libeblP.h"
     53 #include "../libdwelf/libdwelf.h"
     54 #include "../libdw/libdwP.h"
     55 #include "../libdwfl/libdwflP.h"
     56 #include "../libdw/memory-access.h"
     57 
     58 #include "../libdw/known-dwarf.h"
     59 
     60 #ifdef __linux__
     61 #define CORE_SIGILL  SIGILL
     62 #define CORE_SIGBUS  SIGBUS
     63 #define CORE_SIGFPE  SIGFPE
     64 #define CORE_SIGSEGV SIGSEGV
     65 #define CORE_SI_USER SI_USER
     66 #else
     67 /* We want the linux version of those as that is what shows up in the core files. */
     68 #define CORE_SIGILL  4  /* Illegal instruction (ANSI).  */
     69 #define CORE_SIGBUS  7  /* BUS error (4.2 BSD).  */
     70 #define CORE_SIGFPE  8  /* Floating-point exception (ANSI).  */
     71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI).  */
     72 #define CORE_SI_USER 0  /* Sent by kill, sigsend.  */
     73 #endif
     74 
     75 /* Name and version of program.  */
     76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
     77 
     78 /* Bug report address.  */
     79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
     80 
     81 /* argp key value for --elf-section, non-ascii.  */
     82 #define ELF_INPUT_SECTION 256
     83 
     84 /* argp key value for --dwarf-skeleton, non-ascii.  */
     85 #define DWARF_SKELETON 257
     86 
     87 /* Terrible hack for hooking unrelated skeleton/split compile units,
     88    see __libdw_link_skel_split in print_debug.  */
     89 static bool do_not_close_dwfl = false;
     90 
     91 /* Definitions of arguments for argp functions.  */
     92 static const struct argp_option options[] =
     93 {
     94   { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
     95   { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
     96     N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
     97        "input data"), 0 },
     98   { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
     99     N_("Used with -w to find the skeleton Compile Units in FILE associated "
    100        "with the Split Compile units in a .dwo input file"), 0 },
    101   { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
    102   { "all", 'a', NULL, 0,
    103     N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
    104   { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
    105   { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
    106   { "histogram", 'I', NULL, 0,
    107     N_("Display histogram of bucket list lengths"), 0 },
    108   { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
    109   { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
    110   { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
    111   { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
    112   { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
    113   { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
    114   { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
    115     N_("Display the symbol table sections"), 0 },
    116   { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
    117   { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
    118   { "arch-specific", 'A', NULL, 0,
    119     N_("Display architecture specific information, if any"), 0 },
    120   { "exception", 'e', NULL, 0,
    121     N_("Display sections for exception handling"), 0 },
    122 
    123   { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
    124   { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
    125     N_("Display DWARF section content.  SECTION can be one of abbrev, addr, "
    126        "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
    127        "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
    128   { "hex-dump", 'x', "SECTION", 0,
    129     N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
    130   { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
    131     N_("Print string contents of sections"), 0 },
    132   { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
    133   { "archive-index", 'c', NULL, 0,
    134     N_("Display the symbol index of an archive"), 0 },
    135 
    136   { NULL, 0, NULL, 0, N_("Output control:"), 0 },
    137   { "numeric-addresses", 'N', NULL, 0,
    138     N_("Do not find symbol names for addresses in DWARF data"), 0 },
    139   { "unresolved-address-offsets", 'U', NULL, 0,
    140     N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
    141   { "wide", 'W', NULL, 0,
    142     N_("Ignored for compatibility (lines always wide)"), 0 },
    143   { "decompress", 'z', NULL, 0,
    144     N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
    145   { NULL, 0, NULL, 0, NULL, 0 }
    146 };
    147 
    148 /* Short description of program.  */
    149 static const char doc[] = N_("\
    150 Print information from ELF file in human-readable form.");
    151 
    152 /* Strings for arguments in help texts.  */
    153 static const char args_doc[] = N_("FILE...");
    154 
    155 /* Prototype for option handler.  */
    156 static error_t parse_opt (int key, char *arg, struct argp_state *state);
    157 
    158 /* Data structure to communicate with argp functions.  */
    159 static struct argp argp =
    160 {
    161   options, parse_opt, args_doc, doc, NULL, NULL, NULL
    162 };
    163 
    164 /* If non-null, the section from which we should read to (compressed) ELF.  */
    165 static const char *elf_input_section = NULL;
    166 
    167 /* If non-null, the file that contains the skeleton CUs.  */
    168 static const char *dwarf_skeleton = NULL;
    169 
    170 /* Flags set by the option controlling the output.  */
    171 
    172 /* True if dynamic segment should be printed.  */
    173 static bool print_dynamic_table;
    174 
    175 /* True if the file header should be printed.  */
    176 static bool print_file_header;
    177 
    178 /* True if the program headers should be printed.  */
    179 static bool print_program_header;
    180 
    181 /* True if relocations should be printed.  */
    182 static bool print_relocations;
    183 
    184 /* True if the section headers should be printed.  */
    185 static bool print_section_header;
    186 
    187 /* True if the symbol table should be printed.  */
    188 static bool print_symbol_table;
    189 
    190 /* A specific section name, or NULL to print all symbol tables.  */
    191 static char *symbol_table_section;
    192 
    193 /* True if the version information should be printed.  */
    194 static bool print_version_info;
    195 
    196 /* True if section groups should be printed.  */
    197 static bool print_section_groups;
    198 
    199 /* True if bucket list length histogram should be printed.  */
    200 static bool print_histogram;
    201 
    202 /* True if the architecture specific data should be printed.  */
    203 static bool print_arch;
    204 
    205 /* True if note section content should be printed.  */
    206 static bool print_notes;
    207 
    208 /* True if SHF_STRINGS section content should be printed.  */
    209 static bool print_string_sections;
    210 
    211 /* True if archive index should be printed.  */
    212 static bool print_archive_index;
    213 
    214 /* True if any of the control options except print_archive_index is set.  */
    215 static bool any_control_option;
    216 
    217 /* True if we should print addresses from DWARF in symbolic form.  */
    218 static bool print_address_names = true;
    219 
    220 /* True if we should print raw values instead of relativized addresses.  */
    221 static bool print_unresolved_addresses = false;
    222 
    223 /* True if we should print the .debug_aranges section using libdw.  */
    224 static bool decodedaranges = false;
    225 
    226 /* True if we should print the .debug_aranges section using libdw.  */
    227 static bool decodedline = false;
    228 
    229 /* True if we want to show more information about compressed sections.  */
    230 static bool print_decompress = false;
    231 
    232 /* True if we want to show split compile units for debug_info skeletons.  */
    233 static bool show_split_units = false;
    234 
    235 /* Select printing of debugging sections.  */
    236 static enum section_e
    237 {
    238   section_abbrev = 1,		/* .debug_abbrev  */
    239   section_aranges = 2,		/* .debug_aranges  */
    240   section_frame = 4,		/* .debug_frame or .eh_frame & al.  */
    241   section_info = 8,		/* .debug_info, (implies .debug_types)  */
    242   section_line = 16,		/* .debug_line  */
    243   section_loc = 32,		/* .debug_loc  */
    244   section_pubnames = 64,	/* .debug_pubnames  */
    245   section_str = 128,		/* .debug_str  */
    246   section_macinfo = 256,	/* .debug_macinfo  */
    247   section_ranges = 512, 	/* .debug_ranges  */
    248   section_exception = 1024,	/* .eh_frame & al.  */
    249   section_gdb_index = 2048,	/* .gdb_index  */
    250   section_macro = 4096,		/* .debug_macro  */
    251   section_addr = 8192,		/* .debug_addr  */
    252   section_types = 16384,	/* .debug_types (implied by .debug_info)  */
    253   section_all = (section_abbrev | section_aranges | section_frame
    254 		 | section_info | section_line | section_loc
    255 		 | section_pubnames | section_str | section_macinfo
    256 		 | section_ranges | section_exception | section_gdb_index
    257 		 | section_macro | section_addr | section_types)
    258 } print_debug_sections, implicit_debug_sections;
    259 
    260 /* Select hex dumping of sections.  */
    261 static struct section_argument *dump_data_sections;
    262 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
    263 
    264 /* Select string dumping of sections.  */
    265 static struct section_argument *string_sections;
    266 static struct section_argument **string_sections_tail = &string_sections;
    267 
    268 struct section_argument
    269 {
    270   struct section_argument *next;
    271   const char *arg;
    272   bool implicit;
    273 };
    274 
    275 /* Numbers of sections and program headers in the file.  */
    276 static size_t shnum;
    277 static size_t phnum;
    278 
    279 
    280 /* Declarations of local functions.  */
    281 static void process_file (int fd, const char *fname, bool only_one);
    282 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
    283 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
    284 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
    285 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
    286 static void print_scngrp (Ebl *ebl);
    287 static void print_dynamic (Ebl *ebl);
    288 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
    289 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
    290 			       GElf_Shdr *shdr);
    291 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
    292 				GElf_Shdr *shdr);
    293 static void print_symtab (Ebl *ebl, int type);
    294 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
    295 static void print_verinfo (Ebl *ebl);
    296 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
    297 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
    298 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
    299 			   GElf_Shdr *shdr);
    300 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
    301 static void handle_hash (Ebl *ebl);
    302 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
    303 static void print_liblist (Ebl *ebl);
    304 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
    305 static void dump_data (Ebl *ebl);
    306 static void dump_strings (Ebl *ebl);
    307 static void print_strings (Ebl *ebl);
    308 static void dump_archive_index (Elf *, const char *);
    309 
    310 
    311 /* Looked up once with gettext in main.  */
    312 static char *yes_str;
    313 static char *no_str;
    314 
    315 int
    316 main (int argc, char *argv[])
    317 {
    318   /* We use no threads here which can interfere with handling a stream.  */
    319   (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
    320 
    321   /* Set locale.  */
    322   setlocale (LC_ALL, "");
    323 
    324   /* Initialize the message catalog.  */
    325   textdomain (PACKAGE_TARNAME);
    326 
    327   /* Look up once.  */
    328   yes_str = gettext ("yes");
    329   no_str = gettext ("no");
    330 
    331   /* Parse and process arguments.  */
    332   int remaining;
    333   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
    334 
    335   /* Before we start tell the ELF library which version we are using.  */
    336   elf_version (EV_CURRENT);
    337 
    338   /* Now process all the files given at the command line.  */
    339   bool only_one = remaining + 1 == argc;
    340   do
    341     {
    342       /* Open the file.  */
    343       int fd = open (argv[remaining], O_RDONLY);
    344       if (fd == -1)
    345 	{
    346 	  error (0, errno, gettext ("cannot open input file"));
    347 	  continue;
    348 	}
    349 
    350       process_file (fd, argv[remaining], only_one);
    351 
    352       close (fd);
    353     }
    354   while (++remaining < argc);
    355 
    356   return error_message_count != 0;
    357 }
    358 
    359 
    360 /* Handle program arguments.  */
    361 static error_t
    362 parse_opt (int key, char *arg,
    363 	   struct argp_state *state __attribute__ ((unused)))
    364 {
    365   void add_dump_section (const char *name, bool implicit)
    366   {
    367     struct section_argument *a = xmalloc (sizeof *a);
    368     a->arg = name;
    369     a->next = NULL;
    370     a->implicit = implicit;
    371     struct section_argument ***tailp
    372       = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
    373     **tailp = a;
    374     *tailp = &a->next;
    375   }
    376 
    377   switch (key)
    378     {
    379     case 'a':
    380       print_file_header = true;
    381       print_program_header = true;
    382       print_relocations = true;
    383       print_section_header = true;
    384       print_symbol_table = true;
    385       print_version_info = true;
    386       print_dynamic_table = true;
    387       print_section_groups = true;
    388       print_histogram = true;
    389       print_arch = true;
    390       print_notes = true;
    391       implicit_debug_sections |= section_exception;
    392       add_dump_section (".strtab", true);
    393       add_dump_section (".dynstr", true);
    394       add_dump_section (".comment", true);
    395       any_control_option = true;
    396       break;
    397     case 'A':
    398       print_arch = true;
    399       any_control_option = true;
    400       break;
    401     case 'd':
    402       print_dynamic_table = true;
    403       any_control_option = true;
    404       break;
    405     case 'e':
    406       print_debug_sections |= section_exception;
    407       any_control_option = true;
    408       break;
    409     case 'g':
    410       print_section_groups = true;
    411       any_control_option = true;
    412       break;
    413     case 'h':
    414       print_file_header = true;
    415       any_control_option = true;
    416       break;
    417     case 'I':
    418       print_histogram = true;
    419       any_control_option = true;
    420       break;
    421     case 'l':
    422       print_program_header = true;
    423       any_control_option = true;
    424       break;
    425     case 'n':
    426       print_notes = true;
    427       any_control_option = true;
    428       break;
    429     case 'r':
    430       print_relocations = true;
    431       any_control_option = true;
    432      break;
    433     case 'S':
    434       print_section_header = true;
    435       any_control_option = true;
    436       break;
    437     case 's':
    438       print_symbol_table = true;
    439       any_control_option = true;
    440       symbol_table_section = arg;
    441       break;
    442     case 'V':
    443       print_version_info = true;
    444       any_control_option = true;
    445       break;
    446     case 'c':
    447       print_archive_index = true;
    448       break;
    449     case 'w':
    450       if (arg == NULL)
    451 	{
    452 	  print_debug_sections = section_all;
    453 	  implicit_debug_sections = section_info;
    454 	  show_split_units = true;
    455 	}
    456       else if (strcmp (arg, "abbrev") == 0)
    457 	print_debug_sections |= section_abbrev;
    458       else if (strcmp (arg, "addr") == 0)
    459 	{
    460 	  print_debug_sections |= section_addr;
    461 	  implicit_debug_sections |= section_info;
    462 	}
    463       else if (strcmp (arg, "aranges") == 0)
    464 	print_debug_sections |= section_aranges;
    465       else if (strcmp (arg, "decodedaranges") == 0)
    466 	{
    467 	  print_debug_sections |= section_aranges;
    468 	  decodedaranges = true;
    469 	}
    470       else if (strcmp (arg, "ranges") == 0)
    471 	{
    472 	  print_debug_sections |= section_ranges;
    473 	  implicit_debug_sections |= section_info;
    474 	}
    475       else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
    476 	print_debug_sections |= section_frame;
    477       else if (strcmp (arg, "info") == 0)
    478 	{
    479 	  print_debug_sections |= section_info;
    480 	  print_debug_sections |= section_types;
    481 	}
    482       else if (strcmp (arg, "info+") == 0)
    483 	{
    484 	  print_debug_sections |= section_info;
    485 	  print_debug_sections |= section_types;
    486 	  show_split_units = true;
    487 	}
    488       else if (strcmp (arg, "loc") == 0)
    489 	{
    490 	  print_debug_sections |= section_loc;
    491 	  implicit_debug_sections |= section_info;
    492 	}
    493       else if (strcmp (arg, "line") == 0)
    494 	print_debug_sections |= section_line;
    495       else if (strcmp (arg, "decodedline") == 0)
    496 	{
    497 	  print_debug_sections |= section_line;
    498 	  decodedline = true;
    499 	}
    500       else if (strcmp (arg, "pubnames") == 0)
    501 	print_debug_sections |= section_pubnames;
    502       else if (strcmp (arg, "str") == 0)
    503 	{
    504 	  print_debug_sections |= section_str;
    505 	  /* For mapping string offset tables to CUs.  */
    506 	  implicit_debug_sections |= section_info;
    507 	}
    508       else if (strcmp (arg, "macinfo") == 0)
    509 	print_debug_sections |= section_macinfo;
    510       else if (strcmp (arg, "macro") == 0)
    511 	print_debug_sections |= section_macro;
    512       else if (strcmp (arg, "exception") == 0)
    513 	print_debug_sections |= section_exception;
    514       else if (strcmp (arg, "gdb_index") == 0)
    515 	print_debug_sections |= section_gdb_index;
    516       else
    517 	{
    518 	  fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
    519 		   arg);
    520 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
    521 		     program_invocation_short_name);
    522 	  exit (1);
    523 	}
    524       any_control_option = true;
    525       break;
    526     case 'p':
    527       any_control_option = true;
    528       if (arg == NULL)
    529 	{
    530 	  print_string_sections = true;
    531 	  break;
    532 	}
    533       FALLTHROUGH;
    534     case 'x':
    535       add_dump_section (arg, false);
    536       any_control_option = true;
    537       break;
    538     case 'N':
    539       print_address_names = false;
    540       break;
    541     case 'U':
    542       print_unresolved_addresses = true;
    543       break;
    544     case ARGP_KEY_NO_ARGS:
    545       fputs (gettext ("Missing file name.\n"), stderr);
    546       goto do_argp_help;
    547     case ARGP_KEY_FINI:
    548       if (! any_control_option && ! print_archive_index)
    549 	{
    550 	  fputs (gettext ("No operation specified.\n"), stderr);
    551 	do_argp_help:
    552 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
    553 		     program_invocation_short_name);
    554 	  exit (EXIT_FAILURE);
    555 	}
    556       break;
    557     case 'W':			/* Ignored.  */
    558       break;
    559     case 'z':
    560       print_decompress = true;
    561       break;
    562     case ELF_INPUT_SECTION:
    563       if (arg == NULL)
    564 	elf_input_section = ".gnu_debugdata";
    565       else
    566 	elf_input_section = arg;
    567       break;
    568     case DWARF_SKELETON:
    569       dwarf_skeleton = arg;
    570       break;
    571     default:
    572       return ARGP_ERR_UNKNOWN;
    573     }
    574   return 0;
    575 }
    576 
    577 
    578 /* Create a file descriptor to read the data from the
    579    elf_input_section given a file descriptor to an ELF file.  */
    580 static int
    581 open_input_section (int fd)
    582 {
    583   size_t shnums;
    584   size_t cnt;
    585   size_t shstrndx;
    586   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
    587   if (elf == NULL)
    588     {
    589       error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
    590 	     elf_errmsg (-1));
    591       return -1;
    592     }
    593 
    594   if (elf_getshdrnum (elf, &shnums) < 0)
    595     {
    596       error (0, 0, gettext ("cannot determine number of sections: %s"),
    597 	     elf_errmsg (-1));
    598     open_error:
    599       elf_end (elf);
    600       return -1;
    601     }
    602 
    603   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
    604     {
    605       error (0, 0, gettext ("cannot get section header string table index"));
    606       goto open_error;
    607     }
    608 
    609   for (cnt = 0; cnt < shnums; ++cnt)
    610     {
    611       Elf_Scn *scn = elf_getscn (elf, cnt);
    612       if (scn == NULL)
    613 	{
    614 	  error (0, 0, gettext ("cannot get section: %s"),
    615 		 elf_errmsg (-1));
    616 	  goto open_error;
    617 	}
    618 
    619       GElf_Shdr shdr_mem;
    620       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    621       if (unlikely (shdr == NULL))
    622 	{
    623 	  error (0, 0, gettext ("cannot get section header: %s"),
    624 		 elf_errmsg (-1));
    625 	  goto open_error;
    626 	}
    627 
    628       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
    629       if (sname == NULL)
    630 	{
    631 	  error (0, 0, gettext ("cannot get section name"));
    632 	  goto open_error;
    633 	}
    634 
    635       if (strcmp (sname, elf_input_section) == 0)
    636 	{
    637 	  Elf_Data *data = elf_rawdata (scn, NULL);
    638 	  if (data == NULL)
    639 	    {
    640 	      error (0, 0, gettext ("cannot get %s content: %s"),
    641 		     sname, elf_errmsg (-1));
    642 	      goto open_error;
    643 	    }
    644 
    645 	  /* Create (and immediately unlink) a temporary file to store
    646 	     section data in to create a file descriptor for it.  */
    647 	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
    648 	  static const char suffix[] = "/readelfXXXXXX";
    649 	  int tmplen = strlen (tmpdir) + sizeof (suffix);
    650 	  char *tempname = alloca (tmplen);
    651 	  sprintf (tempname, "%s%s", tmpdir, suffix);
    652 
    653 	  int sfd = mkstemp (tempname);
    654 	  if (sfd == -1)
    655 	    {
    656 	      error (0, 0, gettext ("cannot create temp file '%s'"),
    657 		     tempname);
    658 	      goto open_error;
    659 	    }
    660 	  unlink (tempname);
    661 
    662 	  ssize_t size = data->d_size;
    663 	  if (write_retry (sfd, data->d_buf, size) != size)
    664 	    {
    665 	      error (0, 0, gettext ("cannot write section data"));
    666 	      goto open_error;
    667 	    }
    668 
    669 	  if (elf_end (elf) != 0)
    670 	    {
    671 	      error (0, 0, gettext ("error while closing Elf descriptor: %s"),
    672 		     elf_errmsg (-1));
    673 	      return -1;
    674 	    }
    675 
    676 	  if (lseek (sfd, 0, SEEK_SET) == -1)
    677 	    {
    678 	      error (0, 0, gettext ("error while rewinding file descriptor"));
    679 	      return -1;
    680 	    }
    681 
    682 	  return sfd;
    683 	}
    684     }
    685 
    686   /* Named section not found.  */
    687   if (elf_end (elf) != 0)
    688     error (0, 0, gettext ("error while closing Elf descriptor: %s"),
    689 	   elf_errmsg (-1));
    690   return -1;
    691 }
    692 
    693 /* Check if the file is an archive, and if so dump its index.  */
    694 static void
    695 check_archive_index (int fd, const char *fname, bool only_one)
    696 {
    697   /* Create an `Elf' descriptor.  */
    698   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
    699   if (elf == NULL)
    700     error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
    701 	   elf_errmsg (-1));
    702   else
    703     {
    704       if (elf_kind (elf) == ELF_K_AR)
    705 	{
    706 	  if (!only_one)
    707 	    printf ("\n%s:\n\n", fname);
    708 	  dump_archive_index (elf, fname);
    709 	}
    710       else
    711 	error (0, 0,
    712 	       gettext ("'%s' is not an archive, cannot print archive index"),
    713 	       fname);
    714 
    715       /* Now we can close the descriptor.  */
    716       if (elf_end (elf) != 0)
    717 	error (0, 0, gettext ("error while closing Elf descriptor: %s"),
    718 	       elf_errmsg (-1));
    719     }
    720 }
    721 
    722 /* Trivial callback used for checking if we opened an archive.  */
    723 static int
    724 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
    725 	       void **userdata __attribute__ ((unused)),
    726 	       const char *name __attribute__ ((unused)),
    727 	       Dwarf_Addr base __attribute__ ((unused)),
    728 	       void *arg)
    729 {
    730   if (*(bool *) arg)
    731     return DWARF_CB_ABORT;
    732   *(bool *) arg = true;
    733   return DWARF_CB_OK;
    734 }
    735 
    736 struct process_dwflmod_args
    737 {
    738   int fd;
    739   bool only_one;
    740 };
    741 
    742 static int
    743 process_dwflmod (Dwfl_Module *dwflmod,
    744 		 void **userdata __attribute__ ((unused)),
    745 		 const char *name __attribute__ ((unused)),
    746 		 Dwarf_Addr base __attribute__ ((unused)),
    747 		 void *arg)
    748 {
    749   const struct process_dwflmod_args *a = arg;
    750 
    751   /* Print the file name.  */
    752   if (!a->only_one)
    753     {
    754       const char *fname;
    755       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
    756 
    757       printf ("\n%s:\n\n", fname);
    758     }
    759 
    760   process_elf_file (dwflmod, a->fd);
    761 
    762   return DWARF_CB_OK;
    763 }
    764 
    765 /* Stub libdwfl callback, only the ELF handle already open is ever used.
    766    Only used for finding the alternate debug file if the Dwarf comes from
    767    the main file.  We are not interested in separate debuginfo.  */
    768 static int
    769 find_no_debuginfo (Dwfl_Module *mod,
    770 		   void **userdata,
    771 		   const char *modname,
    772 		   Dwarf_Addr base,
    773 		   const char *file_name,
    774 		   const char *debuglink_file,
    775 		   GElf_Word debuglink_crc,
    776 		   char **debuginfo_file_name)
    777 {
    778   Dwarf_Addr dwbias;
    779   dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
    780 
    781   /* We are only interested if the Dwarf has been setup on the main
    782      elf file but is only missing the alternate debug link.  If dwbias
    783      hasn't even been setup, this is searching for separate debuginfo
    784      for the main elf.  We don't care in that case.  */
    785   if (dwbias == (Dwarf_Addr) -1)
    786     return -1;
    787 
    788   return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
    789 				       file_name, debuglink_file,
    790 				       debuglink_crc, debuginfo_file_name);
    791 }
    792 
    793 static Dwfl *
    794 create_dwfl (int fd, const char *fname)
    795 {
    796   /* Duplicate an fd for dwfl_report_offline to swallow.  */
    797   int dwfl_fd = dup (fd);
    798   if (unlikely (dwfl_fd < 0))
    799     error (EXIT_FAILURE, errno, "dup");
    800 
    801   /* Use libdwfl in a trivial way to open the libdw handle for us.
    802      This takes care of applying relocations to DWARF data in ET_REL files.  */
    803   static const Dwfl_Callbacks callbacks =
    804     {
    805       .section_address = dwfl_offline_section_address,
    806       .find_debuginfo = find_no_debuginfo
    807     };
    808   Dwfl *dwfl = dwfl_begin (&callbacks);
    809   if (likely (dwfl != NULL))
    810     /* Let 0 be the logical address of the file (or first in archive).  */
    811     dwfl->offline_next_address = 0;
    812   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
    813     {
    814       struct stat st;
    815       if (fstat (dwfl_fd, &st) != 0)
    816 	error (0, errno, gettext ("cannot stat input file"));
    817       else if (unlikely (st.st_size == 0))
    818 	error (0, 0, gettext ("input file is empty"));
    819       else
    820 	error (0, 0, gettext ("failed reading '%s': %s"),
    821 	       fname, dwfl_errmsg (-1));
    822       close (dwfl_fd);		/* Consumed on success, not on failure.  */
    823       dwfl = NULL;
    824     }
    825   else
    826     dwfl_report_end (dwfl, NULL, NULL);
    827 
    828   return dwfl;
    829 }
    830 
    831 /* Process one input file.  */
    832 static void
    833 process_file (int fd, const char *fname, bool only_one)
    834 {
    835   if (print_archive_index)
    836     check_archive_index (fd, fname, only_one);
    837 
    838   if (!any_control_option)
    839     return;
    840 
    841   if (elf_input_section != NULL)
    842     {
    843       /* Replace fname and fd with section content. */
    844       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
    845       sprintf (fnname, "%s:%s", fname, elf_input_section);
    846       fd = open_input_section (fd);
    847       if (fd == -1)
    848         {
    849           error (0, 0, gettext ("No such section '%s' in '%s'"),
    850 		 elf_input_section, fname);
    851           return;
    852         }
    853       fname = fnname;
    854     }
    855 
    856   Dwfl *dwfl = create_dwfl (fd, fname);
    857   if (dwfl != NULL)
    858     {
    859       if (only_one)
    860 	{
    861 	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
    862 	  bool seen = false;
    863 	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
    864 	}
    865 
    866       /* Process the one or more modules gleaned from this file.  */
    867       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
    868       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
    869     }
    870   /* Terrible hack for hooking unrelated skeleton/split compile units,
    871      see __libdw_link_skel_split in print_debug.  */
    872   if (! do_not_close_dwfl)
    873     dwfl_end (dwfl);
    874 
    875   /* Need to close the replaced fd if we created it.  Caller takes
    876      care of original.  */
    877   if (elf_input_section != NULL)
    878     close (fd);
    879 }
    880 
    881 /* Check whether there are any compressed sections in the ELF file.  */
    882 static bool
    883 elf_contains_chdrs (Elf *elf)
    884 {
    885   Elf_Scn *scn = NULL;
    886   while ((scn = elf_nextscn (elf, scn)) != NULL)
    887     {
    888       GElf_Shdr shdr_mem;
    889       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    890       if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
    891 	return true;
    892     }
    893   return false;
    894 }
    895 
    896 /* Process one ELF file.  */
    897 static void
    898 process_elf_file (Dwfl_Module *dwflmod, int fd)
    899 {
    900   GElf_Addr dwflbias;
    901   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
    902 
    903   GElf_Ehdr ehdr_mem;
    904   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
    905 
    906   if (ehdr == NULL)
    907     {
    908       error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
    909       return;
    910     }
    911 
    912   Ebl *ebl = ebl_openbackend (elf);
    913   if (unlikely (ebl == NULL))
    914     {
    915     ebl_error:
    916       error (0, errno, gettext ("cannot create EBL handle"));
    917       return;
    918     }
    919 
    920   /* Determine the number of sections.  */
    921   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
    922     error (EXIT_FAILURE, 0,
    923 	   gettext ("cannot determine number of sections: %s"),
    924 	   elf_errmsg (-1));
    925 
    926   /* Determine the number of phdrs.  */
    927   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
    928     error (EXIT_FAILURE, 0,
    929 	   gettext ("cannot determine number of program headers: %s"),
    930 	   elf_errmsg (-1));
    931 
    932   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
    933      may have applied relocation to some sections.  If there are any
    934      compressed sections, any pass (or libdw/libdwfl) might have
    935      uncompressed them.  So we need to get a fresh Elf handle on the
    936      file to display those.  */
    937   bool print_unchanged = ((print_section_header
    938 			   || print_relocations
    939 			   || dump_data_sections != NULL
    940 			   || print_notes)
    941 			  && (ehdr->e_type == ET_REL
    942 			      || elf_contains_chdrs (ebl->elf)));
    943 
    944   Elf *pure_elf = NULL;
    945   Ebl *pure_ebl = ebl;
    946   if (print_unchanged)
    947     {
    948       /* Read the file afresh.  */
    949       off_t aroff = elf_getaroff (elf);
    950       pure_elf = dwelf_elf_begin (fd);
    951       if (aroff > 0)
    952 	{
    953 	  /* Archive member.  */
    954 	  (void) elf_rand (pure_elf, aroff);
    955 	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
    956 	  elf_end (pure_elf);
    957 	  pure_elf = armem;
    958 	}
    959       if (pure_elf == NULL)
    960 	{
    961 	  error (0, 0, gettext ("cannot read ELF: %s"), elf_errmsg (-1));
    962 	  return;
    963 	}
    964       pure_ebl = ebl_openbackend (pure_elf);
    965       if (pure_ebl == NULL)
    966 	goto ebl_error;
    967     }
    968 
    969   if (print_file_header)
    970     print_ehdr (ebl, ehdr);
    971   if (print_section_header)
    972     print_shdr (pure_ebl, ehdr);
    973   if (print_program_header)
    974     print_phdr (ebl, ehdr);
    975   if (print_section_groups)
    976     print_scngrp (ebl);
    977   if (print_dynamic_table)
    978     print_dynamic (ebl);
    979   if (print_relocations)
    980     print_relocs (pure_ebl, ehdr);
    981   if (print_histogram)
    982     handle_hash (ebl);
    983   if (print_symbol_table)
    984     print_symtab (ebl, SHT_DYNSYM);
    985   if (print_version_info)
    986     print_verinfo (ebl);
    987   if (print_symbol_table)
    988     print_symtab (ebl, SHT_SYMTAB);
    989   if (print_arch)
    990     print_liblist (ebl);
    991   if (print_arch)
    992     print_attributes (ebl, ehdr);
    993   if (dump_data_sections != NULL)
    994     dump_data (pure_ebl);
    995   if (string_sections != NULL)
    996     dump_strings (ebl);
    997   if ((print_debug_sections | implicit_debug_sections) != 0)
    998     print_debug (dwflmod, ebl, ehdr);
    999   if (print_notes)
   1000     handle_notes (pure_ebl, ehdr);
   1001   if (print_string_sections)
   1002     print_strings (ebl);
   1003 
   1004   ebl_closebackend (ebl);
   1005 
   1006   if (pure_ebl != ebl)
   1007     {
   1008       ebl_closebackend (pure_ebl);
   1009       elf_end (pure_elf);
   1010     }
   1011 }
   1012 
   1013 
   1014 /* Print file type.  */
   1015 static void
   1016 print_file_type (unsigned short int e_type)
   1017 {
   1018   if (likely (e_type <= ET_CORE))
   1019     {
   1020       static const char *const knowntypes[] =
   1021       {
   1022 	N_("NONE (None)"),
   1023 	N_("REL (Relocatable file)"),
   1024 	N_("EXEC (Executable file)"),
   1025 	N_("DYN (Shared object file)"),
   1026 	N_("CORE (Core file)")
   1027       };
   1028       puts (gettext (knowntypes[e_type]));
   1029     }
   1030   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
   1031     printf (gettext ("OS Specific: (%x)\n"),  e_type);
   1032   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
   1033     printf (gettext ("Processor Specific: (%x)\n"),  e_type);
   1034   else
   1035     puts ("???");
   1036 }
   1037 
   1038 
   1039 /* Print ELF header.  */
   1040 static void
   1041 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
   1042 {
   1043   fputs_unlocked (gettext ("ELF Header:\n  Magic:  "), stdout);
   1044   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
   1045     printf (" %02hhx", ehdr->e_ident[cnt]);
   1046 
   1047   printf (gettext ("\n  Class:                             %s\n"),
   1048 	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
   1049 	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
   1050 	  : "\?\?\?");
   1051 
   1052   printf (gettext ("  Data:                              %s\n"),
   1053 	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
   1054 	  ? "2's complement, little endian"
   1055 	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
   1056 	  ? "2's complement, big endian" : "\?\?\?");
   1057 
   1058   printf (gettext ("  Ident Version:                     %hhd %s\n"),
   1059 	  ehdr->e_ident[EI_VERSION],
   1060 	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
   1061 	  : "(\?\?\?)");
   1062 
   1063   char buf[512];
   1064   printf (gettext ("  OS/ABI:                            %s\n"),
   1065 	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
   1066 
   1067   printf (gettext ("  ABI Version:                       %hhd\n"),
   1068 	  ehdr->e_ident[EI_ABIVERSION]);
   1069 
   1070   fputs_unlocked (gettext ("  Type:                              "), stdout);
   1071   print_file_type (ehdr->e_type);
   1072 
   1073   printf (gettext ("  Machine:                           %s\n"), ebl->name);
   1074 
   1075   printf (gettext ("  Version:                           %d %s\n"),
   1076 	  ehdr->e_version,
   1077 	  ehdr->e_version  == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
   1078 
   1079   printf (gettext ("  Entry point address:               %#" PRIx64 "\n"),
   1080 	  ehdr->e_entry);
   1081 
   1082   printf (gettext ("  Start of program headers:          %" PRId64 " %s\n"),
   1083 	  ehdr->e_phoff, gettext ("(bytes into file)"));
   1084 
   1085   printf (gettext ("  Start of section headers:          %" PRId64 " %s\n"),
   1086 	  ehdr->e_shoff, gettext ("(bytes into file)"));
   1087 
   1088   printf (gettext ("  Flags:                             %s\n"),
   1089 	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
   1090 
   1091   printf (gettext ("  Size of this header:               %" PRId16 " %s\n"),
   1092 	  ehdr->e_ehsize, gettext ("(bytes)"));
   1093 
   1094   printf (gettext ("  Size of program header entries:    %" PRId16 " %s\n"),
   1095 	  ehdr->e_phentsize, gettext ("(bytes)"));
   1096 
   1097   printf (gettext ("  Number of program headers entries: %" PRId16),
   1098 	  ehdr->e_phnum);
   1099   if (ehdr->e_phnum == PN_XNUM)
   1100     {
   1101       GElf_Shdr shdr_mem;
   1102       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
   1103       if (shdr != NULL)
   1104 	printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
   1105 		(uint32_t) shdr->sh_info);
   1106       else
   1107 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
   1108     }
   1109   fputc_unlocked ('\n', stdout);
   1110 
   1111   printf (gettext ("  Size of section header entries:    %" PRId16 " %s\n"),
   1112 	  ehdr->e_shentsize, gettext ("(bytes)"));
   1113 
   1114   printf (gettext ("  Number of section headers entries: %" PRId16),
   1115 	  ehdr->e_shnum);
   1116   if (ehdr->e_shnum == 0)
   1117     {
   1118       GElf_Shdr shdr_mem;
   1119       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
   1120       if (shdr != NULL)
   1121 	printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
   1122 		(uint32_t) shdr->sh_size);
   1123       else
   1124 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
   1125     }
   1126   fputc_unlocked ('\n', stdout);
   1127 
   1128   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
   1129     {
   1130       GElf_Shdr shdr_mem;
   1131       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
   1132       if (shdr != NULL)
   1133 	/* We managed to get the zeroth section.  */
   1134 	snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
   1135 		  (uint32_t) shdr->sh_link);
   1136       else
   1137 	{
   1138 	  strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
   1139 	  buf[sizeof (buf) - 1] = '\0';
   1140 	}
   1141 
   1142       printf (gettext ("  Section header string table index: XINDEX%s\n\n"),
   1143 	      buf);
   1144     }
   1145   else
   1146     printf (gettext ("  Section header string table index: %" PRId16 "\n\n"),
   1147 	    ehdr->e_shstrndx);
   1148 }
   1149 
   1150 
   1151 static const char *
   1152 get_visibility_type (int value)
   1153 {
   1154   switch (value)
   1155     {
   1156     case STV_DEFAULT:
   1157       return "DEFAULT";
   1158     case STV_INTERNAL:
   1159       return "INTERNAL";
   1160     case STV_HIDDEN:
   1161       return "HIDDEN";
   1162     case STV_PROTECTED:
   1163       return "PROTECTED";
   1164     default:
   1165       return "???";
   1166     }
   1167 }
   1168 
   1169 static const char *
   1170 elf_ch_type_name (unsigned int code)
   1171 {
   1172   if (code == 0)
   1173     return "NONE";
   1174 
   1175   if (code == ELFCOMPRESS_ZLIB)
   1176     return "ZLIB";
   1177 
   1178   return "UNKNOWN";
   1179 }
   1180 
   1181 /* Print the section headers.  */
   1182 static void
   1183 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
   1184 {
   1185   size_t cnt;
   1186   size_t shstrndx;
   1187 
   1188   if (! print_file_header)
   1189     {
   1190       size_t sections;
   1191       if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
   1192 	error (EXIT_FAILURE, 0,
   1193 	       gettext ("cannot get number of sections: %s"),
   1194 	       elf_errmsg (-1));
   1195 
   1196       printf (gettext ("\
   1197 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
   1198 \n"),
   1199 	      sections, ehdr->e_shoff);
   1200     }
   1201 
   1202   /* Get the section header string table index.  */
   1203   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1204     error (EXIT_FAILURE, 0,
   1205 	   gettext ("cannot get section header string table index: %s"),
   1206 	   elf_errmsg (-1));
   1207 
   1208   puts (gettext ("Section Headers:"));
   1209 
   1210   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
   1211     puts (gettext ("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
   1212   else
   1213     puts (gettext ("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
   1214 
   1215   if (print_decompress)
   1216     {
   1217       if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
   1218 	puts (gettext ("     [Compression  Size   Al]"));
   1219       else
   1220 	puts (gettext ("     [Compression  Size     Al]"));
   1221     }
   1222 
   1223   for (cnt = 0; cnt < shnum; ++cnt)
   1224     {
   1225       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
   1226 
   1227       if (unlikely (scn == NULL))
   1228 	error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
   1229 	       elf_errmsg (-1));
   1230 
   1231       /* Get the section header.  */
   1232       GElf_Shdr shdr_mem;
   1233       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1234       if (unlikely (shdr == NULL))
   1235 	error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
   1236 	       elf_errmsg (-1));
   1237 
   1238       char flagbuf[20];
   1239       char *cp = flagbuf;
   1240       if (shdr->sh_flags & SHF_WRITE)
   1241 	*cp++ = 'W';
   1242       if (shdr->sh_flags & SHF_ALLOC)
   1243 	*cp++ = 'A';
   1244       if (shdr->sh_flags & SHF_EXECINSTR)
   1245 	*cp++ = 'X';
   1246       if (shdr->sh_flags & SHF_MERGE)
   1247 	*cp++ = 'M';
   1248       if (shdr->sh_flags & SHF_STRINGS)
   1249 	*cp++ = 'S';
   1250       if (shdr->sh_flags & SHF_INFO_LINK)
   1251 	*cp++ = 'I';
   1252       if (shdr->sh_flags & SHF_LINK_ORDER)
   1253 	*cp++ = 'L';
   1254       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
   1255 	*cp++ = 'N';
   1256       if (shdr->sh_flags & SHF_GROUP)
   1257 	*cp++ = 'G';
   1258       if (shdr->sh_flags & SHF_TLS)
   1259 	*cp++ = 'T';
   1260       if (shdr->sh_flags & SHF_COMPRESSED)
   1261 	*cp++ = 'C';
   1262       if (shdr->sh_flags & SHF_ORDERED)
   1263 	*cp++ = 'O';
   1264       if (shdr->sh_flags & SHF_EXCLUDE)
   1265 	*cp++ = 'E';
   1266       *cp = '\0';
   1267 
   1268       const char *sname;
   1269       char buf[128];
   1270       sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
   1271       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
   1272 	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
   1273 	      " %2" PRId64 "\n",
   1274 	      cnt, sname,
   1275 	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
   1276 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
   1277 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
   1278 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
   1279 	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
   1280 	      shdr->sh_addralign);
   1281 
   1282       if (print_decompress)
   1283 	{
   1284 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
   1285 	    {
   1286 	      GElf_Chdr chdr;
   1287 	      if (gelf_getchdr (scn, &chdr) != NULL)
   1288 		printf ("     [ELF %s (%" PRId32 ") %0*" PRIx64
   1289 			" %2" PRId64 "]\n",
   1290 			elf_ch_type_name (chdr.ch_type),
   1291 			chdr.ch_type,
   1292 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
   1293 			chdr.ch_size, chdr.ch_addralign);
   1294 	      else
   1295 		error (0, 0,
   1296 		       gettext ("bad compression header for section %zd: %s"),
   1297 		       elf_ndxscn (scn), elf_errmsg (-1));
   1298 	    }
   1299 	  else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
   1300 	    {
   1301 	      ssize_t size;
   1302 	      if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
   1303 		printf ("     [GNU ZLIB     %0*zx   ]\n",
   1304 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
   1305 	      else
   1306 		error (0, 0,
   1307 		       gettext ("bad gnu compressed size for section %zd: %s"),
   1308 		       elf_ndxscn (scn), elf_errmsg (-1));
   1309 	    }
   1310 	}
   1311     }
   1312 
   1313   fputc_unlocked ('\n', stdout);
   1314 }
   1315 
   1316 
   1317 /* Print the program header.  */
   1318 static void
   1319 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
   1320 {
   1321   if (phnum == 0)
   1322     /* No program header, this is OK in relocatable objects.  */
   1323     return;
   1324 
   1325   puts (gettext ("Program Headers:"));
   1326   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
   1327     puts (gettext ("\
   1328   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
   1329   else
   1330     puts (gettext ("\
   1331   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
   1332 
   1333   /* Process all program headers.  */
   1334   bool has_relro = false;
   1335   GElf_Addr relro_from = 0;
   1336   GElf_Addr relro_to = 0;
   1337   for (size_t cnt = 0; cnt < phnum; ++cnt)
   1338     {
   1339       char buf[128];
   1340       GElf_Phdr mem;
   1341       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
   1342 
   1343       /* If for some reason the header cannot be returned show this.  */
   1344       if (unlikely (phdr == NULL))
   1345 	{
   1346 	  puts ("  ???");
   1347 	  continue;
   1348 	}
   1349 
   1350       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
   1351 	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
   1352 	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
   1353 	      phdr->p_offset,
   1354 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
   1355 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
   1356 	      phdr->p_filesz,
   1357 	      phdr->p_memsz,
   1358 	      phdr->p_flags & PF_R ? 'R' : ' ',
   1359 	      phdr->p_flags & PF_W ? 'W' : ' ',
   1360 	      phdr->p_flags & PF_X ? 'E' : ' ',
   1361 	      phdr->p_align);
   1362 
   1363       if (phdr->p_type == PT_INTERP)
   1364 	{
   1365 	  /* If we are sure the file offset is valid then we can show
   1366 	     the user the name of the interpreter.  We check whether
   1367 	     there is a section at the file offset.  Normally there
   1368 	     would be a section called ".interp".  But in separate
   1369 	     .debug files it is a NOBITS section (and so doesn't match
   1370 	     with gelf_offscn).  Which probably means the offset is
   1371 	     not valid another reason could be because the ELF file
   1372 	     just doesn't contain any section headers, in that case
   1373 	     just play it safe and don't display anything.  */
   1374 
   1375 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
   1376 	  GElf_Shdr shdr_mem;
   1377 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1378 
   1379 	  size_t maxsize;
   1380 	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
   1381 
   1382 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
   1383 	      && filedata != NULL && phdr->p_offset < maxsize
   1384 	      && phdr->p_filesz <= maxsize - phdr->p_offset
   1385 	      && memchr (filedata + phdr->p_offset, '\0',
   1386 			 phdr->p_filesz) != NULL)
   1387 	    printf (gettext ("\t[Requesting program interpreter: %s]\n"),
   1388 		    filedata + phdr->p_offset);
   1389 	}
   1390       else if (phdr->p_type == PT_GNU_RELRO)
   1391 	{
   1392 	  has_relro = true;
   1393 	  relro_from = phdr->p_vaddr;
   1394 	  relro_to = relro_from + phdr->p_memsz;
   1395 	}
   1396     }
   1397 
   1398   size_t sections;
   1399   if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
   1400     error (EXIT_FAILURE, 0,
   1401            gettext ("cannot get number of sections: %s"),
   1402            elf_errmsg (-1));
   1403 
   1404   if (sections == 0)
   1405     /* No sections in the file.  Punt.  */
   1406     return;
   1407 
   1408   /* Get the section header string table index.  */
   1409   size_t shstrndx;
   1410   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1411     error (EXIT_FAILURE, 0,
   1412 	   gettext ("cannot get section header string table index"));
   1413 
   1414   puts (gettext ("\n Section to Segment mapping:\n  Segment Sections..."));
   1415 
   1416   for (size_t cnt = 0; cnt < phnum; ++cnt)
   1417     {
   1418       /* Print the segment number.  */
   1419       printf ("   %2.2zu     ", cnt);
   1420 
   1421       GElf_Phdr phdr_mem;
   1422       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
   1423       /* This must not happen.  */
   1424       if (unlikely (phdr == NULL))
   1425 	error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
   1426 	       elf_errmsg (-1));
   1427 
   1428       /* Iterate over the sections.  */
   1429       bool in_relro = false;
   1430       bool in_ro = false;
   1431       for (size_t inner = 1; inner < shnum; ++inner)
   1432 	{
   1433 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
   1434 	  /* This should not happen.  */
   1435 	  if (unlikely (scn == NULL))
   1436 	    error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
   1437 		   elf_errmsg (-1));
   1438 
   1439 	  /* Get the section header.  */
   1440 	  GElf_Shdr shdr_mem;
   1441 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1442 	  if (unlikely (shdr == NULL))
   1443 	    error (EXIT_FAILURE, 0,
   1444 		   gettext ("cannot get section header: %s"),
   1445 		   elf_errmsg (-1));
   1446 
   1447 	  if (shdr->sh_size > 0
   1448 	      /* Compare allocated sections by VMA, unallocated
   1449 		 sections by file offset.  */
   1450 	      && (shdr->sh_flags & SHF_ALLOC
   1451 		  ? (shdr->sh_addr >= phdr->p_vaddr
   1452 		     && (shdr->sh_addr + shdr->sh_size
   1453 			 <= phdr->p_vaddr + phdr->p_memsz))
   1454 		  : (shdr->sh_offset >= phdr->p_offset
   1455 		     && (shdr->sh_offset + shdr->sh_size
   1456 			 <= phdr->p_offset + phdr->p_filesz))))
   1457 	    {
   1458 	      if (has_relro && !in_relro
   1459 		  && shdr->sh_addr >= relro_from
   1460 		  && shdr->sh_addr + shdr->sh_size <= relro_to)
   1461 		{
   1462 		  fputs_unlocked (" [RELRO:", stdout);
   1463 		  in_relro = true;
   1464 		}
   1465 	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
   1466 		{
   1467 		  fputs_unlocked ("]", stdout);
   1468 		  in_relro =  false;
   1469 		}
   1470 	      else if (has_relro && in_relro
   1471 		       && shdr->sh_addr + shdr->sh_size > relro_to)
   1472 		fputs_unlocked ("] <RELRO:", stdout);
   1473 	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
   1474 		{
   1475 		  if (!in_ro)
   1476 		    {
   1477 		      fputs_unlocked (" [RO:", stdout);
   1478 		      in_ro = true;
   1479 		    }
   1480 		}
   1481 	      else
   1482 		{
   1483 		  /* Determine the segment this section is part of.  */
   1484 		  size_t cnt2;
   1485 		  GElf_Phdr phdr2_mem;
   1486 		  GElf_Phdr *phdr2 = NULL;
   1487 		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
   1488 		    {
   1489 		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
   1490 
   1491 		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
   1492 			  && shdr->sh_addr >= phdr2->p_vaddr
   1493 			  && (shdr->sh_addr + shdr->sh_size
   1494 			      <= phdr2->p_vaddr + phdr2->p_memsz))
   1495 			break;
   1496 		    }
   1497 
   1498 		  if (cnt2 < phnum)
   1499 		    {
   1500 		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
   1501 			{
   1502 			  fputs_unlocked (" [RO:", stdout);
   1503 			  in_ro = true;
   1504 			}
   1505 		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
   1506 			{
   1507 			  fputs_unlocked ("]", stdout);
   1508 			  in_ro = false;
   1509 			}
   1510 		    }
   1511 		}
   1512 
   1513 	      printf (" %s",
   1514 		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
   1515 
   1516 	      /* Signal that this sectin is only partially covered.  */
   1517 	      if (has_relro && in_relro
   1518 		       && shdr->sh_addr + shdr->sh_size > relro_to)
   1519 		{
   1520 		  fputs_unlocked (">", stdout);
   1521 		  in_relro =  false;
   1522 		}
   1523 	    }
   1524 	}
   1525       if (in_relro || in_ro)
   1526 	fputs_unlocked ("]", stdout);
   1527 
   1528       /* Finish the line.  */
   1529       fputc_unlocked ('\n', stdout);
   1530     }
   1531 }
   1532 
   1533 
   1534 static const char *
   1535 section_name (Ebl *ebl, GElf_Shdr *shdr)
   1536 {
   1537   size_t shstrndx;
   1538   if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
   1539     return "???";
   1540   return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
   1541 }
   1542 
   1543 
   1544 static void
   1545 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   1546 {
   1547   /* Get the data of the section.  */
   1548   Elf_Data *data = elf_getdata (scn, NULL);
   1549 
   1550   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
   1551   GElf_Shdr symshdr_mem;
   1552   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   1553   Elf_Data *symdata = elf_getdata (symscn, NULL);
   1554 
   1555   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
   1556       || symdata == NULL)
   1557     return;
   1558 
   1559   /* Get the section header string table index.  */
   1560   size_t shstrndx;
   1561   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1562     error (EXIT_FAILURE, 0,
   1563 	   gettext ("cannot get section header string table index"));
   1564 
   1565   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
   1566 
   1567   GElf_Sym sym_mem;
   1568   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
   1569 
   1570   printf ((grpref[0] & GRP_COMDAT)
   1571 	  ? ngettext ("\
   1572 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
   1573 		      "\
   1574 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
   1575 		      data->d_size / sizeof (Elf32_Word) - 1)
   1576 	  : ngettext ("\
   1577 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
   1578 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
   1579 		      data->d_size / sizeof (Elf32_Word) - 1),
   1580 	  elf_ndxscn (scn),
   1581 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1582 	  (sym == NULL ? NULL
   1583 	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
   1584 	  ?: gettext ("<INVALID SYMBOL>"),
   1585 	  data->d_size / sizeof (Elf32_Word) - 1);
   1586 
   1587   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
   1588     {
   1589       GElf_Shdr grpshdr_mem;
   1590       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
   1591 					 &grpshdr_mem);
   1592 
   1593       const char *str;
   1594       printf ("  [%2u] %s\n",
   1595 	      grpref[cnt],
   1596 	      grpshdr != NULL
   1597 	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
   1598 	      ? str : gettext ("<INVALID SECTION>"));
   1599     }
   1600 }
   1601 
   1602 
   1603 static void
   1604 print_scngrp (Ebl *ebl)
   1605 {
   1606   /* Find all relocation sections and handle them.  */
   1607   Elf_Scn *scn = NULL;
   1608 
   1609   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   1610     {
   1611        /* Handle the section if it is a symbol table.  */
   1612       GElf_Shdr shdr_mem;
   1613       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1614 
   1615       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
   1616 	{
   1617 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
   1618 	    {
   1619 	      if (elf_compress (scn, 0, 0) < 0)
   1620 		printf ("WARNING: %s [%zd]\n",
   1621 			gettext ("Couldn't uncompress section"),
   1622 			elf_ndxscn (scn));
   1623 	      shdr = gelf_getshdr (scn, &shdr_mem);
   1624 	      if (unlikely (shdr == NULL))
   1625 		error (EXIT_FAILURE, 0,
   1626 		       gettext ("cannot get section [%zd] header: %s"),
   1627 		       elf_ndxscn (scn),
   1628 		       elf_errmsg (-1));
   1629 	    }
   1630 	  handle_scngrp (ebl, scn, shdr);
   1631 	}
   1632     }
   1633 }
   1634 
   1635 
   1636 static const struct flags
   1637 {
   1638   int mask;
   1639   const char *str;
   1640 } dt_flags[] =
   1641   {
   1642     { DF_ORIGIN, "ORIGIN" },
   1643     { DF_SYMBOLIC, "SYMBOLIC" },
   1644     { DF_TEXTREL, "TEXTREL" },
   1645     { DF_BIND_NOW, "BIND_NOW" },
   1646     { DF_STATIC_TLS, "STATIC_TLS" }
   1647   };
   1648 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
   1649 
   1650 static const struct flags dt_flags_1[] =
   1651   {
   1652     { DF_1_NOW, "NOW" },
   1653     { DF_1_GLOBAL, "GLOBAL" },
   1654     { DF_1_GROUP, "GROUP" },
   1655     { DF_1_NODELETE, "NODELETE" },
   1656     { DF_1_LOADFLTR, "LOADFLTR" },
   1657     { DF_1_INITFIRST, "INITFIRST" },
   1658     { DF_1_NOOPEN, "NOOPEN" },
   1659     { DF_1_ORIGIN, "ORIGIN" },
   1660     { DF_1_DIRECT, "DIRECT" },
   1661     { DF_1_TRANS, "TRANS" },
   1662     { DF_1_INTERPOSE, "INTERPOSE" },
   1663     { DF_1_NODEFLIB, "NODEFLIB" },
   1664     { DF_1_NODUMP, "NODUMP" },
   1665     { DF_1_CONFALT, "CONFALT" },
   1666     { DF_1_ENDFILTEE, "ENDFILTEE" },
   1667     { DF_1_DISPRELDNE, "DISPRELDNE" },
   1668     { DF_1_DISPRELPND, "DISPRELPND" },
   1669   };
   1670 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
   1671 
   1672 static const struct flags dt_feature_1[] =
   1673   {
   1674     { DTF_1_PARINIT, "PARINIT" },
   1675     { DTF_1_CONFEXP, "CONFEXP" }
   1676   };
   1677 static const int ndt_feature_1 = (sizeof (dt_feature_1)
   1678 				  / sizeof (dt_feature_1[0]));
   1679 
   1680 static const struct flags dt_posflag_1[] =
   1681   {
   1682     { DF_P1_LAZYLOAD, "LAZYLOAD" },
   1683     { DF_P1_GROUPPERM, "GROUPPERM" }
   1684   };
   1685 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
   1686 				  / sizeof (dt_posflag_1[0]));
   1687 
   1688 
   1689 static void
   1690 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
   1691 		int nflags)
   1692 {
   1693   bool first = true;
   1694   int cnt;
   1695 
   1696   for (cnt = 0; cnt < nflags; ++cnt)
   1697     if (d_val & flags[cnt].mask)
   1698       {
   1699 	if (!first)
   1700 	  putchar_unlocked (' ');
   1701 	fputs_unlocked (flags[cnt].str, stdout);
   1702 	d_val &= ~flags[cnt].mask;
   1703 	first = false;
   1704       }
   1705 
   1706   if (d_val != 0)
   1707     {
   1708       if (!first)
   1709 	putchar_unlocked (' ');
   1710       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
   1711     }
   1712 
   1713   putchar_unlocked ('\n');
   1714 }
   1715 
   1716 
   1717 static void
   1718 print_dt_flags (int class, GElf_Xword d_val)
   1719 {
   1720   print_flags (class, d_val, dt_flags, ndt_flags);
   1721 }
   1722 
   1723 
   1724 static void
   1725 print_dt_flags_1 (int class, GElf_Xword d_val)
   1726 {
   1727   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
   1728 }
   1729 
   1730 
   1731 static void
   1732 print_dt_feature_1 (int class, GElf_Xword d_val)
   1733 {
   1734   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
   1735 }
   1736 
   1737 
   1738 static void
   1739 print_dt_posflag_1 (int class, GElf_Xword d_val)
   1740 {
   1741   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
   1742 }
   1743 
   1744 
   1745 static void
   1746 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   1747 {
   1748   int class = gelf_getclass (ebl->elf);
   1749   GElf_Shdr glink_mem;
   1750   GElf_Shdr *glink;
   1751   Elf_Data *data;
   1752   size_t cnt;
   1753   size_t shstrndx;
   1754   size_t sh_entsize;
   1755 
   1756   /* Get the data of the section.  */
   1757   data = elf_getdata (scn, NULL);
   1758   if (data == NULL)
   1759     return;
   1760 
   1761   /* Get the section header string table index.  */
   1762   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1763     error (EXIT_FAILURE, 0,
   1764 	   gettext ("cannot get section header string table index"));
   1765 
   1766   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
   1767 
   1768   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
   1769   if (glink == NULL)
   1770     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
   1771 	   elf_ndxscn (scn));
   1772 
   1773   printf (ngettext ("\
   1774 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   1775 		    "\
   1776 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   1777 		    shdr->sh_size / sh_entsize),
   1778 	  (unsigned long int) (shdr->sh_size / sh_entsize),
   1779 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   1780 	  shdr->sh_offset,
   1781 	  (int) shdr->sh_link,
   1782 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   1783   fputs_unlocked (gettext ("  Type              Value\n"), stdout);
   1784 
   1785   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
   1786     {
   1787       GElf_Dyn dynmem;
   1788       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
   1789       if (dyn == NULL)
   1790 	break;
   1791 
   1792       char buf[64];
   1793       printf ("  %-17s ",
   1794 	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
   1795 
   1796       switch (dyn->d_tag)
   1797 	{
   1798 	case DT_NULL:
   1799 	case DT_DEBUG:
   1800 	case DT_BIND_NOW:
   1801 	case DT_TEXTREL:
   1802 	  /* No further output.  */
   1803 	  fputc_unlocked ('\n', stdout);
   1804 	  break;
   1805 
   1806 	case DT_NEEDED:
   1807 	  printf (gettext ("Shared library: [%s]\n"),
   1808 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1809 	  break;
   1810 
   1811 	case DT_SONAME:
   1812 	  printf (gettext ("Library soname: [%s]\n"),
   1813 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1814 	  break;
   1815 
   1816 	case DT_RPATH:
   1817 	  printf (gettext ("Library rpath: [%s]\n"),
   1818 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1819 	  break;
   1820 
   1821 	case DT_RUNPATH:
   1822 	  printf (gettext ("Library runpath: [%s]\n"),
   1823 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
   1824 	  break;
   1825 
   1826 	case DT_PLTRELSZ:
   1827 	case DT_RELASZ:
   1828 	case DT_STRSZ:
   1829 	case DT_RELSZ:
   1830 	case DT_RELAENT:
   1831 	case DT_SYMENT:
   1832 	case DT_RELENT:
   1833 	case DT_PLTPADSZ:
   1834 	case DT_MOVEENT:
   1835 	case DT_MOVESZ:
   1836 	case DT_INIT_ARRAYSZ:
   1837 	case DT_FINI_ARRAYSZ:
   1838 	case DT_SYMINSZ:
   1839 	case DT_SYMINENT:
   1840 	case DT_GNU_CONFLICTSZ:
   1841 	case DT_GNU_LIBLISTSZ:
   1842 	  printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
   1843 	  break;
   1844 
   1845 	case DT_VERDEFNUM:
   1846 	case DT_VERNEEDNUM:
   1847 	case DT_RELACOUNT:
   1848 	case DT_RELCOUNT:
   1849 	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
   1850 	  break;
   1851 
   1852 	case DT_PLTREL:;
   1853 	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
   1854 						      NULL, 0);
   1855 	  puts (tagname ?: "???");
   1856 	  break;
   1857 
   1858 	case DT_FLAGS:
   1859 	  print_dt_flags (class, dyn->d_un.d_val);
   1860 	  break;
   1861 
   1862 	case DT_FLAGS_1:
   1863 	  print_dt_flags_1 (class, dyn->d_un.d_val);
   1864 	  break;
   1865 
   1866 	case DT_FEATURE_1:
   1867 	  print_dt_feature_1 (class, dyn->d_un.d_val);
   1868 	  break;
   1869 
   1870 	case DT_POSFLAG_1:
   1871 	  print_dt_posflag_1 (class, dyn->d_un.d_val);
   1872 	  break;
   1873 
   1874 	default:
   1875 	  printf ("%#0*" PRIx64 "\n",
   1876 		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
   1877 	  break;
   1878 	}
   1879     }
   1880 }
   1881 
   1882 
   1883 /* Print the dynamic segment.  */
   1884 static void
   1885 print_dynamic (Ebl *ebl)
   1886 {
   1887   for (size_t i = 0; i < phnum; ++i)
   1888     {
   1889       GElf_Phdr phdr_mem;
   1890       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
   1891 
   1892       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
   1893 	{
   1894 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
   1895 	  GElf_Shdr shdr_mem;
   1896 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1897 	  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
   1898 	    handle_dynamic (ebl, scn, shdr);
   1899 	  break;
   1900 	}
   1901     }
   1902 }
   1903 
   1904 
   1905 /* Print relocations.  */
   1906 static void
   1907 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
   1908 {
   1909   /* Find all relocation sections and handle them.  */
   1910   Elf_Scn *scn = NULL;
   1911 
   1912   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   1913     {
   1914        /* Handle the section if it is a symbol table.  */
   1915       GElf_Shdr shdr_mem;
   1916       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1917 
   1918       if (likely (shdr != NULL))
   1919 	{
   1920 	  if (shdr->sh_type == SHT_REL)
   1921 	    handle_relocs_rel (ebl, ehdr, scn, shdr);
   1922 	  else if (shdr->sh_type == SHT_RELA)
   1923 	    handle_relocs_rela (ebl, ehdr, scn, shdr);
   1924 	}
   1925     }
   1926 }
   1927 
   1928 
   1929 /* Handle a relocation section.  */
   1930 static void
   1931 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
   1932 {
   1933   int class = gelf_getclass (ebl->elf);
   1934   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
   1935   int nentries = shdr->sh_size / sh_entsize;
   1936 
   1937   /* Get the data of the section.  */
   1938   Elf_Data *data = elf_getdata (scn, NULL);
   1939   if (data == NULL)
   1940     return;
   1941 
   1942   /* Get the symbol table information.  */
   1943   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
   1944   GElf_Shdr symshdr_mem;
   1945   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   1946   Elf_Data *symdata = elf_getdata (symscn, NULL);
   1947 
   1948   /* Get the section header of the section the relocations are for.  */
   1949   GElf_Shdr destshdr_mem;
   1950   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
   1951 				      &destshdr_mem);
   1952 
   1953   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
   1954     {
   1955       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
   1956 	      shdr->sh_offset);
   1957       return;
   1958     }
   1959 
   1960   /* Search for the optional extended section index table.  */
   1961   Elf_Data *xndxdata = NULL;
   1962   int xndxscnidx = elf_scnshndx (scn);
   1963   if (unlikely (xndxscnidx > 0))
   1964     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
   1965 
   1966   /* Get the section header string table index.  */
   1967   size_t shstrndx;
   1968   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   1969     error (EXIT_FAILURE, 0,
   1970 	   gettext ("cannot get section header string table index"));
   1971 
   1972   if (shdr->sh_info != 0)
   1973     printf (ngettext ("\
   1974 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   1975 		    "\
   1976 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   1977 		      nentries),
   1978 	    elf_ndxscn (scn),
   1979 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1980 	    (unsigned int) shdr->sh_info,
   1981 	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
   1982 	    shdr->sh_offset,
   1983 	    nentries);
   1984   else
   1985     /* The .rel.dyn section does not refer to a specific section but
   1986        instead of section index zero.  Do not try to print a section
   1987        name.  */
   1988     printf (ngettext ("\
   1989 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   1990 		    "\
   1991 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   1992 		      nentries),
   1993 	    (unsigned int) elf_ndxscn (scn),
   1994 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   1995 	    shdr->sh_offset,
   1996 	    nentries);
   1997   fputs_unlocked (class == ELFCLASS32
   1998 		  ? gettext ("\
   1999   Offset      Type                 Value       Name\n")
   2000 		  : gettext ("\
   2001   Offset              Type                 Value               Name\n"),
   2002 	 stdout);
   2003 
   2004   int is_statically_linked = 0;
   2005   for (int cnt = 0; cnt < nentries; ++cnt)
   2006     {
   2007       GElf_Rel relmem;
   2008       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
   2009       if (likely (rel != NULL))
   2010 	{
   2011 	  char buf[128];
   2012 	  GElf_Sym symmem;
   2013 	  Elf32_Word xndx;
   2014 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
   2015 					    GELF_R_SYM (rel->r_info),
   2016 					    &symmem, &xndx);
   2017 	  if (unlikely (sym == NULL))
   2018 	    {
   2019 	      /* As a special case we have to handle relocations in static
   2020 		 executables.  This only happens for IRELATIVE relocations
   2021 		 (so far).  There is no symbol table.  */
   2022 	      if (is_statically_linked == 0)
   2023 		{
   2024 		  /* Find the program header and look for a PT_INTERP entry. */
   2025 		  is_statically_linked = -1;
   2026 		  if (ehdr->e_type == ET_EXEC)
   2027 		    {
   2028 		      is_statically_linked = 1;
   2029 
   2030 		      for (size_t inner = 0; inner < phnum; ++inner)
   2031 			{
   2032 			  GElf_Phdr phdr_mem;
   2033 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
   2034 							  &phdr_mem);
   2035 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
   2036 			    {
   2037 			      is_statically_linked = -1;
   2038 			      break;
   2039 			    }
   2040 			}
   2041 		    }
   2042 		}
   2043 
   2044 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
   2045 		printf ("\
   2046   %#0*" PRIx64 "  %-20s %*s  %s\n",
   2047 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2048 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2049 			/* Avoid the leading R_ which isn't carrying any
   2050 			   information.  */
   2051 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2052 					       buf, sizeof (buf)) + 2
   2053 			: gettext ("<INVALID RELOC>"),
   2054 			class == ELFCLASS32 ? 10 : 18, "",
   2055 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
   2056 	      else
   2057 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
   2058 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2059 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2060 			/* Avoid the leading R_ which isn't carrying any
   2061 			   information.  */
   2062 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2063 					       buf, sizeof (buf)) + 2
   2064 			: gettext ("<INVALID RELOC>"),
   2065 			gettext ("INVALID SYMBOL"),
   2066 			(long int) GELF_R_SYM (rel->r_info));
   2067 	    }
   2068 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
   2069 	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
   2070 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2071 		    likely (ebl_reloc_type_check (ebl,
   2072 						  GELF_R_TYPE (rel->r_info)))
   2073 		    /* Avoid the leading R_ which isn't carrying any
   2074 		       information.  */
   2075 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2076 					   buf, sizeof (buf)) + 2
   2077 		    : gettext ("<INVALID RELOC>"),
   2078 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
   2079 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
   2080 	  else
   2081 	    {
   2082 	      /* This is a relocation against a STT_SECTION symbol.  */
   2083 	      GElf_Shdr secshdr_mem;
   2084 	      GElf_Shdr *secshdr;
   2085 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
   2086 						  sym->st_shndx == SHN_XINDEX
   2087 						  ? xndx : sym->st_shndx),
   2088 				      &secshdr_mem);
   2089 
   2090 	      if (unlikely (secshdr == NULL))
   2091 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
   2092 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2093 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2094 			/* Avoid the leading R_ which isn't carrying any
   2095 			   information.  */
   2096 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2097 					       buf, sizeof (buf)) + 2
   2098 			: gettext ("<INVALID RELOC>"),
   2099 			gettext ("INVALID SECTION"),
   2100 			(long int) (sym->st_shndx == SHN_XINDEX
   2101 				    ? xndx : sym->st_shndx));
   2102 	      else
   2103 		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
   2104 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2105 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2106 			/* Avoid the leading R_ which isn't carrying any
   2107 			   information.  */
   2108 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2109 					       buf, sizeof (buf)) + 2
   2110 			: gettext ("<INVALID RELOC>"),
   2111 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
   2112 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
   2113 	    }
   2114 	}
   2115     }
   2116 }
   2117 
   2118 
   2119 /* Handle a relocation section.  */
   2120 static void
   2121 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
   2122 {
   2123   int class = gelf_getclass (ebl->elf);
   2124   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
   2125   int nentries = shdr->sh_size / sh_entsize;
   2126 
   2127   /* Get the data of the section.  */
   2128   Elf_Data *data = elf_getdata (scn, NULL);
   2129   if (data == NULL)
   2130     return;
   2131 
   2132   /* Get the symbol table information.  */
   2133   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
   2134   GElf_Shdr symshdr_mem;
   2135   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   2136   Elf_Data *symdata = elf_getdata (symscn, NULL);
   2137 
   2138   /* Get the section header of the section the relocations are for.  */
   2139   GElf_Shdr destshdr_mem;
   2140   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
   2141 				      &destshdr_mem);
   2142 
   2143   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
   2144     {
   2145       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
   2146 	      shdr->sh_offset);
   2147       return;
   2148     }
   2149 
   2150   /* Search for the optional extended section index table.  */
   2151   Elf_Data *xndxdata = NULL;
   2152   int xndxscnidx = elf_scnshndx (scn);
   2153   if (unlikely (xndxscnidx > 0))
   2154     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
   2155 
   2156   /* Get the section header string table index.  */
   2157   size_t shstrndx;
   2158   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2159     error (EXIT_FAILURE, 0,
   2160 	   gettext ("cannot get section header string table index"));
   2161 
   2162   if (shdr->sh_info != 0)
   2163     printf (ngettext ("\
   2164 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   2165 		    "\
   2166 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   2167 		    nentries),
   2168 	  elf_ndxscn (scn),
   2169 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2170 	  (unsigned int) shdr->sh_info,
   2171 	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
   2172 	  shdr->sh_offset,
   2173 	  nentries);
   2174   else
   2175     /* The .rela.dyn section does not refer to a specific section but
   2176        instead of section index zero.  Do not try to print a section
   2177        name.  */
   2178     printf (ngettext ("\
   2179 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   2180 		    "\
   2181 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   2182 		      nentries),
   2183 	    (unsigned int) elf_ndxscn (scn),
   2184 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2185 	    shdr->sh_offset,
   2186 	    nentries);
   2187   fputs_unlocked (class == ELFCLASS32
   2188 		  ? gettext ("\
   2189   Offset      Type            Value       Addend Name\n")
   2190 		  : gettext ("\
   2191   Offset              Type            Value               Addend Name\n"),
   2192 		  stdout);
   2193 
   2194   int is_statically_linked = 0;
   2195   for (int cnt = 0; cnt < nentries; ++cnt)
   2196     {
   2197       GElf_Rela relmem;
   2198       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
   2199       if (likely (rel != NULL))
   2200 	{
   2201 	  char buf[64];
   2202 	  GElf_Sym symmem;
   2203 	  Elf32_Word xndx;
   2204 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
   2205 					    GELF_R_SYM (rel->r_info),
   2206 					    &symmem, &xndx);
   2207 
   2208 	  if (unlikely (sym == NULL))
   2209 	    {
   2210 	      /* As a special case we have to handle relocations in static
   2211 		 executables.  This only happens for IRELATIVE relocations
   2212 		 (so far).  There is no symbol table.  */
   2213 	      if (is_statically_linked == 0)
   2214 		{
   2215 		  /* Find the program header and look for a PT_INTERP entry. */
   2216 		  is_statically_linked = -1;
   2217 		  if (ehdr->e_type == ET_EXEC)
   2218 		    {
   2219 		      is_statically_linked = 1;
   2220 
   2221 		      for (size_t inner = 0; inner < phnum; ++inner)
   2222 			{
   2223 			  GElf_Phdr phdr_mem;
   2224 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
   2225 							  &phdr_mem);
   2226 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
   2227 			    {
   2228 			      is_statically_linked = -1;
   2229 			      break;
   2230 			    }
   2231 			}
   2232 		    }
   2233 		}
   2234 
   2235 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
   2236 		printf ("\
   2237   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
   2238 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2239 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2240 			/* Avoid the leading R_ which isn't carrying any
   2241 			   information.  */
   2242 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2243 					       buf, sizeof (buf)) + 2
   2244 			: gettext ("<INVALID RELOC>"),
   2245 			class == ELFCLASS32 ? 10 : 18, "",
   2246 			rel->r_addend,
   2247 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
   2248 	      else
   2249 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
   2250 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2251 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2252 			/* Avoid the leading R_ which isn't carrying any
   2253 			   information.  */
   2254 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2255 					       buf, sizeof (buf)) + 2
   2256 			: gettext ("<INVALID RELOC>"),
   2257 			gettext ("INVALID SYMBOL"),
   2258 			(long int) GELF_R_SYM (rel->r_info));
   2259 	    }
   2260 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
   2261 	    printf ("\
   2262   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
   2263 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2264 		    likely (ebl_reloc_type_check (ebl,
   2265 						  GELF_R_TYPE (rel->r_info)))
   2266 		    /* Avoid the leading R_ which isn't carrying any
   2267 		       information.  */
   2268 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2269 					   buf, sizeof (buf)) + 2
   2270 		    : gettext ("<INVALID RELOC>"),
   2271 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
   2272 		    rel->r_addend,
   2273 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
   2274 	  else
   2275 	    {
   2276 	      /* This is a relocation against a STT_SECTION symbol.  */
   2277 	      GElf_Shdr secshdr_mem;
   2278 	      GElf_Shdr *secshdr;
   2279 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
   2280 						  sym->st_shndx == SHN_XINDEX
   2281 						  ? xndx : sym->st_shndx),
   2282 				      &secshdr_mem);
   2283 
   2284 	      if (unlikely (secshdr == NULL))
   2285 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
   2286 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2287 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2288 			/* Avoid the leading R_ which isn't carrying any
   2289 			   information.  */
   2290 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2291 					       buf, sizeof (buf)) + 2
   2292 			: gettext ("<INVALID RELOC>"),
   2293 			gettext ("INVALID SECTION"),
   2294 			(long int) (sym->st_shndx == SHN_XINDEX
   2295 				    ? xndx : sym->st_shndx));
   2296 	      else
   2297 		printf ("\
   2298   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
   2299 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
   2300 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
   2301 			/* Avoid the leading R_ which isn't carrying any
   2302 			   information.  */
   2303 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
   2304 					       buf, sizeof (buf)) + 2
   2305 			: gettext ("<INVALID RELOC>"),
   2306 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
   2307 			rel->r_addend,
   2308 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
   2309 	    }
   2310 	}
   2311     }
   2312 }
   2313 
   2314 
   2315 /* Print the program header.  */
   2316 static void
   2317 print_symtab (Ebl *ebl, int type)
   2318 {
   2319   /* Find the symbol table(s).  For this we have to search through the
   2320      section table.  */
   2321   Elf_Scn *scn = NULL;
   2322 
   2323   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   2324     {
   2325       /* Handle the section if it is a symbol table.  */
   2326       GElf_Shdr shdr_mem;
   2327       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   2328 
   2329       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
   2330 	{
   2331 	  if (symbol_table_section != NULL)
   2332 	    {
   2333 	      /* Get the section header string table index.  */
   2334 	      size_t shstrndx;
   2335 	      const char *sname;
   2336 	      if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2337 		error (EXIT_FAILURE, 0,
   2338 		       gettext ("cannot get section header string table index"));
   2339 	      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
   2340 	      if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
   2341 		continue;
   2342 	    }
   2343 
   2344 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
   2345 	    {
   2346 	      if (elf_compress (scn, 0, 0) < 0)
   2347 		printf ("WARNING: %s [%zd]\n",
   2348 			gettext ("Couldn't uncompress section"),
   2349 			elf_ndxscn (scn));
   2350 	      shdr = gelf_getshdr (scn, &shdr_mem);
   2351 	      if (unlikely (shdr == NULL))
   2352 		error (EXIT_FAILURE, 0,
   2353 		       gettext ("cannot get section [%zd] header: %s"),
   2354 		       elf_ndxscn (scn), elf_errmsg (-1));
   2355 	    }
   2356 	  handle_symtab (ebl, scn, shdr);
   2357 	}
   2358     }
   2359 }
   2360 
   2361 
   2362 static void
   2363 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2364 {
   2365   Elf_Data *versym_data = NULL;
   2366   Elf_Data *verneed_data = NULL;
   2367   Elf_Data *verdef_data = NULL;
   2368   Elf_Data *xndx_data = NULL;
   2369   int class = gelf_getclass (ebl->elf);
   2370   Elf32_Word verneed_stridx = 0;
   2371   Elf32_Word verdef_stridx = 0;
   2372 
   2373   /* Get the data of the section.  */
   2374   Elf_Data *data = elf_getdata (scn, NULL);
   2375   if (data == NULL)
   2376     return;
   2377 
   2378   /* Find out whether we have other sections we might need.  */
   2379   Elf_Scn *runscn = NULL;
   2380   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
   2381     {
   2382       GElf_Shdr runshdr_mem;
   2383       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
   2384 
   2385       if (likely (runshdr != NULL))
   2386 	{
   2387 	  if (runshdr->sh_type == SHT_GNU_versym
   2388 	      && runshdr->sh_link == elf_ndxscn (scn))
   2389 	    /* Bingo, found the version information.  Now get the data.  */
   2390 	    versym_data = elf_getdata (runscn, NULL);
   2391 	  else if (runshdr->sh_type == SHT_GNU_verneed)
   2392 	    {
   2393 	      /* This is the information about the needed versions.  */
   2394 	      verneed_data = elf_getdata (runscn, NULL);
   2395 	      verneed_stridx = runshdr->sh_link;
   2396 	    }
   2397 	  else if (runshdr->sh_type == SHT_GNU_verdef)
   2398 	    {
   2399 	      /* This is the information about the defined versions.  */
   2400 	      verdef_data = elf_getdata (runscn, NULL);
   2401 	      verdef_stridx = runshdr->sh_link;
   2402 	    }
   2403 	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
   2404 	      && runshdr->sh_link == elf_ndxscn (scn))
   2405 	    /* Extended section index.  */
   2406 	    xndx_data = elf_getdata (runscn, NULL);
   2407 	}
   2408     }
   2409 
   2410   /* Get the section header string table index.  */
   2411   size_t shstrndx;
   2412   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2413     error (EXIT_FAILURE, 0,
   2414 	   gettext ("cannot get section header string table index"));
   2415 
   2416   GElf_Shdr glink_mem;
   2417   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2418 				   &glink_mem);
   2419   if (glink == NULL)
   2420     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
   2421 	   elf_ndxscn (scn));
   2422 
   2423   /* Now we can compute the number of entries in the section.  */
   2424   unsigned int nsyms = data->d_size / (class == ELFCLASS32
   2425 				       ? sizeof (Elf32_Sym)
   2426 				       : sizeof (Elf64_Sym));
   2427 
   2428   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
   2429 		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
   2430 		    nsyms),
   2431 	  (unsigned int) elf_ndxscn (scn),
   2432 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
   2433   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
   2434 		    " %lu local symbols  String table: [%2u] '%s'\n",
   2435 		    shdr->sh_info),
   2436 	  (unsigned long int) shdr->sh_info,
   2437 	  (unsigned int) shdr->sh_link,
   2438 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2439 
   2440   fputs_unlocked (class == ELFCLASS32
   2441 		  ? gettext ("\
   2442   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
   2443 		  : gettext ("\
   2444   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
   2445 		  stdout);
   2446 
   2447   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
   2448     {
   2449       char typebuf[64];
   2450       char bindbuf[64];
   2451       char scnbuf[64];
   2452       Elf32_Word xndx;
   2453       GElf_Sym sym_mem;
   2454       GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
   2455 
   2456       if (unlikely (sym == NULL))
   2457 	continue;
   2458 
   2459       /* Determine the real section index.  */
   2460       if (likely (sym->st_shndx != SHN_XINDEX))
   2461 	xndx = sym->st_shndx;
   2462 
   2463       printf (gettext ("\
   2464 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
   2465 	      cnt,
   2466 	      class == ELFCLASS32 ? 8 : 16,
   2467 	      sym->st_value,
   2468 	      sym->st_size,
   2469 	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
   2470 				    typebuf, sizeof (typebuf)),
   2471 	      ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
   2472 				       bindbuf, sizeof (bindbuf)),
   2473 	      get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
   2474 	      ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
   2475 				sizeof (scnbuf), NULL, shnum),
   2476 	      elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
   2477 
   2478       if (versym_data != NULL)
   2479 	{
   2480 	  /* Get the version information.  */
   2481 	  GElf_Versym versym_mem;
   2482 	  GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
   2483 
   2484 	  if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
   2485 	    {
   2486 	      bool is_nobits = false;
   2487 	      bool check_def = xndx != SHN_UNDEF;
   2488 
   2489 	      if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
   2490 		{
   2491 		  GElf_Shdr symshdr_mem;
   2492 		  GElf_Shdr *symshdr =
   2493 		    gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
   2494 
   2495 		  is_nobits = (symshdr != NULL
   2496 			       && symshdr->sh_type == SHT_NOBITS);
   2497 		}
   2498 
   2499 	      if (is_nobits || ! check_def)
   2500 		{
   2501 		  /* We must test both.  */
   2502 		  GElf_Vernaux vernaux_mem;
   2503 		  GElf_Vernaux *vernaux = NULL;
   2504 		  size_t vn_offset = 0;
   2505 
   2506 		  GElf_Verneed verneed_mem;
   2507 		  GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
   2508 							   &verneed_mem);
   2509 		  while (verneed != NULL)
   2510 		    {
   2511 		      size_t vna_offset = vn_offset;
   2512 
   2513 		      vernaux = gelf_getvernaux (verneed_data,
   2514 						 vna_offset += verneed->vn_aux,
   2515 						 &vernaux_mem);
   2516 		      while (vernaux != NULL
   2517 			     && vernaux->vna_other != *versym
   2518 			     && vernaux->vna_next != 0)
   2519 			{
   2520 			  /* Update the offset.  */
   2521 			  vna_offset += vernaux->vna_next;
   2522 
   2523 			  vernaux = (vernaux->vna_next == 0
   2524 				     ? NULL
   2525 				     : gelf_getvernaux (verneed_data,
   2526 							vna_offset,
   2527 							&vernaux_mem));
   2528 			}
   2529 
   2530 		      /* Check whether we found the version.  */
   2531 		      if (vernaux != NULL && vernaux->vna_other == *versym)
   2532 			/* Found it.  */
   2533 			break;
   2534 
   2535 		      vn_offset += verneed->vn_next;
   2536 		      verneed = (verneed->vn_next == 0
   2537 				 ? NULL
   2538 				 : gelf_getverneed (verneed_data, vn_offset,
   2539 						    &verneed_mem));
   2540 		    }
   2541 
   2542 		  if (vernaux != NULL && vernaux->vna_other == *versym)
   2543 		    {
   2544 		      printf ("@%s (%u)",
   2545 			      elf_strptr (ebl->elf, verneed_stridx,
   2546 					  vernaux->vna_name),
   2547 			      (unsigned int) vernaux->vna_other);
   2548 		      check_def = 0;
   2549 		    }
   2550 		  else if (unlikely (! is_nobits))
   2551 		    error (0, 0, gettext ("bad dynamic symbol"));
   2552 		  else
   2553 		    check_def = 1;
   2554 		}
   2555 
   2556 	      if (check_def && *versym != 0x8001)
   2557 		{
   2558 		  /* We must test both.  */
   2559 		  size_t vd_offset = 0;
   2560 
   2561 		  GElf_Verdef verdef_mem;
   2562 		  GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
   2563 							&verdef_mem);
   2564 		  while (verdef != NULL)
   2565 		    {
   2566 		      if (verdef->vd_ndx == (*versym & 0x7fff))
   2567 			/* Found the definition.  */
   2568 			break;
   2569 
   2570 		      vd_offset += verdef->vd_next;
   2571 		      verdef = (verdef->vd_next == 0
   2572 				? NULL
   2573 				: gelf_getverdef (verdef_data, vd_offset,
   2574 						  &verdef_mem));
   2575 		    }
   2576 
   2577 		  if (verdef != NULL)
   2578 		    {
   2579 		      GElf_Verdaux verdaux_mem;
   2580 		      GElf_Verdaux *verdaux
   2581 			= gelf_getverdaux (verdef_data,
   2582 					   vd_offset + verdef->vd_aux,
   2583 					   &verdaux_mem);
   2584 
   2585 		      if (verdaux != NULL)
   2586 			printf ((*versym & 0x8000) ? "@%s" : "@@%s",
   2587 				elf_strptr (ebl->elf, verdef_stridx,
   2588 					    verdaux->vda_name));
   2589 		    }
   2590 		}
   2591 	    }
   2592 	}
   2593 
   2594       putchar_unlocked ('\n');
   2595     }
   2596 }
   2597 
   2598 
   2599 /* Print version information.  */
   2600 static void
   2601 print_verinfo (Ebl *ebl)
   2602 {
   2603   /* Find the version information sections.  For this we have to
   2604      search through the section table.  */
   2605   Elf_Scn *scn = NULL;
   2606 
   2607   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   2608     {
   2609       /* Handle the section if it is part of the versioning handling.  */
   2610       GElf_Shdr shdr_mem;
   2611       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   2612 
   2613       if (likely (shdr != NULL))
   2614 	{
   2615 	  if (shdr->sh_type == SHT_GNU_verneed)
   2616 	    handle_verneed (ebl, scn, shdr);
   2617 	  else if (shdr->sh_type == SHT_GNU_verdef)
   2618 	    handle_verdef (ebl, scn, shdr);
   2619 	  else if (shdr->sh_type == SHT_GNU_versym)
   2620 	    handle_versym (ebl, scn, shdr);
   2621 	}
   2622     }
   2623 }
   2624 
   2625 
   2626 static const char *
   2627 get_ver_flags (unsigned int flags)
   2628 {
   2629   static char buf[32];
   2630   char *endp;
   2631 
   2632   if (flags == 0)
   2633     return gettext ("none");
   2634 
   2635   if (flags & VER_FLG_BASE)
   2636     endp = stpcpy (buf, "BASE ");
   2637   else
   2638     endp = buf;
   2639 
   2640   if (flags & VER_FLG_WEAK)
   2641     {
   2642       if (endp != buf)
   2643 	endp = stpcpy (endp, "| ");
   2644 
   2645       endp = stpcpy (endp, "WEAK ");
   2646     }
   2647 
   2648   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
   2649     {
   2650       strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
   2651       buf[sizeof (buf) - 1] = '\0';
   2652     }
   2653 
   2654   return buf;
   2655 }
   2656 
   2657 
   2658 static void
   2659 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2660 {
   2661   int class = gelf_getclass (ebl->elf);
   2662 
   2663   /* Get the data of the section.  */
   2664   Elf_Data *data = elf_getdata (scn, NULL);
   2665   if (data == NULL)
   2666     return;
   2667 
   2668   /* Get the section header string table index.  */
   2669   size_t shstrndx;
   2670   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2671     error (EXIT_FAILURE, 0,
   2672 	   gettext ("cannot get section header string table index"));
   2673 
   2674   GElf_Shdr glink_mem;
   2675   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2676 				   &glink_mem);
   2677   if (glink == NULL)
   2678     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
   2679 	   elf_ndxscn (scn));
   2680 
   2681   printf (ngettext ("\
   2682 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2683 		    "\
   2684 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2685 		    shdr->sh_info),
   2686 	  (unsigned int) elf_ndxscn (scn),
   2687 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
   2688 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   2689 	  shdr->sh_offset,
   2690 	  (unsigned int) shdr->sh_link,
   2691 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2692 
   2693   unsigned int offset = 0;
   2694   for (int cnt = shdr->sh_info; --cnt >= 0; )
   2695     {
   2696       /* Get the data at the next offset.  */
   2697       GElf_Verneed needmem;
   2698       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
   2699       if (unlikely (need == NULL))
   2700 	break;
   2701 
   2702       printf (gettext ("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
   2703 	      offset, (unsigned short int) need->vn_version,
   2704 	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
   2705 	      (unsigned short int) need->vn_cnt);
   2706 
   2707       unsigned int auxoffset = offset + need->vn_aux;
   2708       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
   2709 	{
   2710 	  GElf_Vernaux auxmem;
   2711 	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
   2712 	  if (unlikely (aux == NULL))
   2713 	    break;
   2714 
   2715 	  printf (gettext ("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
   2716 		  auxoffset,
   2717 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
   2718 		  get_ver_flags (aux->vna_flags),
   2719 		  (unsigned short int) aux->vna_other);
   2720 
   2721 	  if (aux->vna_next == 0)
   2722 	    break;
   2723 
   2724 	  auxoffset += aux->vna_next;
   2725 	}
   2726 
   2727       /* Find the next offset.  */
   2728       if (need->vn_next == 0)
   2729 	break;
   2730 
   2731       offset += need->vn_next;
   2732     }
   2733 }
   2734 
   2735 
   2736 static void
   2737 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2738 {
   2739   /* Get the data of the section.  */
   2740   Elf_Data *data = elf_getdata (scn, NULL);
   2741   if (data == NULL)
   2742     return;
   2743 
   2744   /* Get the section header string table index.  */
   2745   size_t shstrndx;
   2746   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2747     error (EXIT_FAILURE, 0,
   2748 	   gettext ("cannot get section header string table index"));
   2749 
   2750   GElf_Shdr glink_mem;
   2751   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   2752 				   &glink_mem);
   2753   if (glink == NULL)
   2754     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
   2755 	   elf_ndxscn (scn));
   2756 
   2757   int class = gelf_getclass (ebl->elf);
   2758   printf (ngettext ("\
   2759 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2760 		    "\
   2761 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
   2762 		    shdr->sh_info),
   2763 	  (unsigned int) elf_ndxscn (scn),
   2764 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   2765 	  shdr->sh_info,
   2766 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   2767 	  shdr->sh_offset,
   2768 	  (unsigned int) shdr->sh_link,
   2769 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   2770 
   2771   unsigned int offset = 0;
   2772   for (int cnt = shdr->sh_info; --cnt >= 0; )
   2773     {
   2774       /* Get the data at the next offset.  */
   2775       GElf_Verdef defmem;
   2776       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
   2777       if (unlikely (def == NULL))
   2778 	break;
   2779 
   2780       unsigned int auxoffset = offset + def->vd_aux;
   2781       GElf_Verdaux auxmem;
   2782       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
   2783       if (unlikely (aux == NULL))
   2784 	break;
   2785 
   2786       printf (gettext ("\
   2787   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
   2788 	      offset, def->vd_version,
   2789 	      get_ver_flags (def->vd_flags),
   2790 	      def->vd_ndx,
   2791 	      def->vd_cnt,
   2792 	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
   2793 
   2794       auxoffset += aux->vda_next;
   2795       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
   2796 	{
   2797 	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
   2798 	  if (unlikely (aux == NULL))
   2799 	    break;
   2800 
   2801 	  printf (gettext ("  %#06x: Parent %d: %s\n"),
   2802 		  auxoffset, cnt2,
   2803 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
   2804 
   2805 	  if (aux->vda_next == 0)
   2806 	    break;
   2807 
   2808 	  auxoffset += aux->vda_next;
   2809 	}
   2810 
   2811       /* Find the next offset.  */
   2812       if (def->vd_next == 0)
   2813 	break;
   2814       offset += def->vd_next;
   2815     }
   2816 }
   2817 
   2818 
   2819 static void
   2820 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   2821 {
   2822   int class = gelf_getclass (ebl->elf);
   2823   const char **vername;
   2824   const char **filename;
   2825 
   2826   /* Get the data of the section.  */
   2827   Elf_Data *data = elf_getdata (scn, NULL);
   2828   if (data == NULL)
   2829     return;
   2830 
   2831   /* Get the section header string table index.  */
   2832   size_t shstrndx;
   2833   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   2834     error (EXIT_FAILURE, 0,
   2835 	   gettext ("cannot get section header string table index"));
   2836 
   2837   /* We have to find the version definition section and extract the
   2838      version names.  */
   2839   Elf_Scn *defscn = NULL;
   2840   Elf_Scn *needscn = NULL;
   2841 
   2842   Elf_Scn *verscn = NULL;
   2843   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
   2844     {
   2845       GElf_Shdr vershdr_mem;
   2846       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
   2847 
   2848       if (likely (vershdr != NULL))
   2849 	{
   2850 	  if (vershdr->sh_type == SHT_GNU_verdef)
   2851 	    defscn = verscn;
   2852 	  else if (vershdr->sh_type == SHT_GNU_verneed)
   2853 	    needscn = verscn;
   2854 	}
   2855     }
   2856 
   2857   size_t nvername;
   2858   if (defscn != NULL || needscn != NULL)
   2859     {
   2860       /* We have a version information (better should have).  Now get
   2861 	 the version names.  First find the maximum version number.  */
   2862       nvername = 0;
   2863       if (defscn != NULL)
   2864 	{
   2865 	  /* Run through the version definitions and find the highest
   2866 	     index.  */
   2867 	  unsigned int offset = 0;
   2868 	  Elf_Data *defdata;
   2869 	  GElf_Shdr defshdrmem;
   2870 	  GElf_Shdr *defshdr;
   2871 
   2872 	  defdata = elf_getdata (defscn, NULL);
   2873 	  if (unlikely (defdata == NULL))
   2874 	    return;
   2875 
   2876 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
   2877 	  if (unlikely (defshdr == NULL))
   2878 	    return;
   2879 
   2880 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
   2881 	    {
   2882 	      GElf_Verdef defmem;
   2883 	      GElf_Verdef *def;
   2884 
   2885 	      /* Get the data at the next offset.  */
   2886 	      def = gelf_getverdef (defdata, offset, &defmem);
   2887 	      if (unlikely (def == NULL))
   2888 		break;
   2889 
   2890 	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
   2891 
   2892 	      if (def->vd_next == 0)
   2893 		break;
   2894 	      offset += def->vd_next;
   2895 	    }
   2896 	}
   2897       if (needscn != NULL)
   2898 	{
   2899 	  unsigned int offset = 0;
   2900 	  Elf_Data *needdata;
   2901 	  GElf_Shdr needshdrmem;
   2902 	  GElf_Shdr *needshdr;
   2903 
   2904 	  needdata = elf_getdata (needscn, NULL);
   2905 	  if (unlikely (needdata == NULL))
   2906 	    return;
   2907 
   2908 	  needshdr = gelf_getshdr (needscn, &needshdrmem);
   2909 	  if (unlikely (needshdr == NULL))
   2910 	    return;
   2911 
   2912 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
   2913 	    {
   2914 	      GElf_Verneed needmem;
   2915 	      GElf_Verneed *need;
   2916 	      unsigned int auxoffset;
   2917 	      int cnt2;
   2918 
   2919 	      /* Get the data at the next offset.  */
   2920 	      need = gelf_getverneed (needdata, offset, &needmem);
   2921 	      if (unlikely (need == NULL))
   2922 		break;
   2923 
   2924 	      /* Run through the auxiliary entries.  */
   2925 	      auxoffset = offset + need->vn_aux;
   2926 	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
   2927 		{
   2928 		  GElf_Vernaux auxmem;
   2929 		  GElf_Vernaux *aux;
   2930 
   2931 		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
   2932 		  if (unlikely (aux == NULL))
   2933 		    break;
   2934 
   2935 		  nvername = MAX (nvername,
   2936 				  (size_t) (aux->vna_other & 0x7fff));
   2937 
   2938 		  if (aux->vna_next == 0)
   2939 		    break;
   2940 		  auxoffset += aux->vna_next;
   2941 		}
   2942 
   2943 	      if (need->vn_next == 0)
   2944 		break;
   2945 	      offset += need->vn_next;
   2946 	    }
   2947 	}
   2948 
   2949       /* This is the number of versions we know about.  */
   2950       ++nvername;
   2951 
   2952       /* Allocate the array.  */
   2953       vername = (const char **) alloca (nvername * sizeof (const char *));
   2954       memset(vername, 0, nvername * sizeof (const char *));
   2955       filename = (const char **) alloca (nvername * sizeof (const char *));
   2956       memset(filename, 0, nvername * sizeof (const char *));
   2957 
   2958       /* Run through the data structures again and collect the strings.  */
   2959       if (defscn != NULL)
   2960 	{
   2961 	  /* Run through the version definitions and find the highest
   2962 	     index.  */
   2963 	  unsigned int offset = 0;
   2964 	  Elf_Data *defdata;
   2965 	  GElf_Shdr defshdrmem;
   2966 	  GElf_Shdr *defshdr;
   2967 
   2968 	  defdata = elf_getdata (defscn, NULL);
   2969 	  if (unlikely (defdata == NULL))
   2970 	    return;
   2971 
   2972 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
   2973 	  if (unlikely (defshdr == NULL))
   2974 	    return;
   2975 
   2976 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
   2977 	    {
   2978 
   2979 	      /* Get the data at the next offset.  */
   2980 	      GElf_Verdef defmem;
   2981 	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
   2982 	      if (unlikely (def == NULL))
   2983 		break;
   2984 
   2985 	      GElf_Verdaux auxmem;
   2986 	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
   2987 						   offset + def->vd_aux,
   2988 						   &auxmem);
   2989 	      if (unlikely (aux == NULL))
   2990 		break;
   2991 
   2992 	      vername[def->vd_ndx & 0x7fff]
   2993 		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
   2994 	      filename[def->vd_ndx & 0x7fff] = NULL;
   2995 
   2996 	      if (def->vd_next == 0)
   2997 		break;
   2998 	      offset += def->vd_next;
   2999 	    }
   3000 	}
   3001       if (needscn != NULL)
   3002 	{
   3003 	  unsigned int offset = 0;
   3004 
   3005 	  Elf_Data *needdata = elf_getdata (needscn, NULL);
   3006 	  GElf_Shdr needshdrmem;
   3007 	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
   3008 	  if (unlikely (needdata == NULL || needshdr == NULL))
   3009 	    return;
   3010 
   3011 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
   3012 	    {
   3013 	      /* Get the data at the next offset.  */
   3014 	      GElf_Verneed needmem;
   3015 	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
   3016 						    &needmem);
   3017 	      if (unlikely (need == NULL))
   3018 		break;
   3019 
   3020 	      /* Run through the auxiliary entries.  */
   3021 	      unsigned int auxoffset = offset + need->vn_aux;
   3022 	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
   3023 		{
   3024 		  GElf_Vernaux auxmem;
   3025 		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
   3026 						       &auxmem);
   3027 		  if (unlikely (aux == NULL))
   3028 		    break;
   3029 
   3030 		  vername[aux->vna_other & 0x7fff]
   3031 		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
   3032 		  filename[aux->vna_other & 0x7fff]
   3033 		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
   3034 
   3035 		  if (aux->vna_next == 0)
   3036 		    break;
   3037 		  auxoffset += aux->vna_next;
   3038 		}
   3039 
   3040 	      if (need->vn_next == 0)
   3041 		break;
   3042 	      offset += need->vn_next;
   3043 	    }
   3044 	}
   3045     }
   3046   else
   3047     {
   3048       vername = NULL;
   3049       nvername = 1;
   3050       filename = NULL;
   3051     }
   3052 
   3053   GElf_Shdr glink_mem;
   3054   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
   3055 				   &glink_mem);
   3056   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
   3057   if (glink == NULL)
   3058     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
   3059 	   elf_ndxscn (scn));
   3060 
   3061   /* Print the header.  */
   3062   printf (ngettext ("\
   3063 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
   3064 		    "\
   3065 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
   3066 		    shdr->sh_size / sh_entsize),
   3067 	  (unsigned int) elf_ndxscn (scn),
   3068 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   3069 	  (int) (shdr->sh_size / sh_entsize),
   3070 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
   3071 	  shdr->sh_offset,
   3072 	  (unsigned int) shdr->sh_link,
   3073 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   3074 
   3075   /* Now we can finally look at the actual contents of this section.  */
   3076   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
   3077     {
   3078       if (cnt % 2 == 0)
   3079 	printf ("\n %4d:", cnt);
   3080 
   3081       GElf_Versym symmem;
   3082       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
   3083       if (sym == NULL)
   3084 	break;
   3085 
   3086       switch (*sym)
   3087 	{
   3088 	  ssize_t n;
   3089 	case 0:
   3090 	  fputs_unlocked (gettext ("   0 *local*                     "),
   3091 			  stdout);
   3092 	  break;
   3093 
   3094 	case 1:
   3095 	  fputs_unlocked (gettext ("   1 *global*                    "),
   3096 			  stdout);
   3097 	  break;
   3098 
   3099 	default:
   3100 	  n = printf ("%4d%c%s",
   3101 		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
   3102 		      (vername != NULL
   3103 		       && (unsigned int) (*sym & 0x7fff) < nvername)
   3104 		      ? vername[*sym & 0x7fff] : "???");
   3105 	  if ((unsigned int) (*sym & 0x7fff) < nvername
   3106 	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
   3107 	    n += printf ("(%s)", filename[*sym & 0x7fff]);
   3108 	  printf ("%*s", MAX (0, 33 - (int) n), " ");
   3109 	  break;
   3110 	}
   3111     }
   3112   putchar_unlocked ('\n');
   3113 }
   3114 
   3115 
   3116 static void
   3117 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
   3118 		 uint_fast32_t maxlength, Elf32_Word nbucket,
   3119 		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
   3120 {
   3121   uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
   3122 
   3123   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   3124     ++counts[lengths[cnt]];
   3125 
   3126   GElf_Shdr glink_mem;
   3127   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
   3128 					       shdr->sh_link),
   3129 				   &glink_mem);
   3130   if (glink == NULL)
   3131     {
   3132       error (0, 0, gettext ("invalid sh_link value in section %zu"),
   3133 	     elf_ndxscn (scn));
   3134       return;
   3135     }
   3136 
   3137   printf (ngettext ("\
   3138 \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",
   3139 		    "\
   3140 \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",
   3141 		    nbucket),
   3142 	  (unsigned int) elf_ndxscn (scn),
   3143 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   3144 	  (int) nbucket,
   3145 	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
   3146 	  shdr->sh_addr,
   3147 	  shdr->sh_offset,
   3148 	  (unsigned int) shdr->sh_link,
   3149 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
   3150 
   3151   if (extrastr != NULL)
   3152     fputs (extrastr, stdout);
   3153 
   3154   if (likely (nbucket > 0))
   3155     {
   3156       uint64_t success = 0;
   3157 
   3158       /* xgettext:no-c-format */
   3159       fputs_unlocked (gettext ("\
   3160  Length  Number  % of total  Coverage\n"), stdout);
   3161       printf (gettext ("      0  %6" PRIu32 "      %5.1f%%\n"),
   3162 	      counts[0], (counts[0] * 100.0) / nbucket);
   3163 
   3164       uint64_t nzero_counts = 0;
   3165       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
   3166 	{
   3167 	  nzero_counts += counts[cnt] * cnt;
   3168 	  printf (gettext ("\
   3169 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
   3170 		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
   3171 		  (nzero_counts * 100.0) / nsyms);
   3172 	}
   3173 
   3174       Elf32_Word acc = 0;
   3175       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
   3176 	{
   3177 	  acc += cnt;
   3178 	  success += counts[cnt] * acc;
   3179 	}
   3180 
   3181       printf (gettext ("\
   3182  Average number of tests:   successful lookup: %f\n\
   3183 			  unsuccessful lookup: %f\n"),
   3184 	      (double) success / (double) nzero_counts,
   3185 	      (double) nzero_counts / (double) nbucket);
   3186     }
   3187 
   3188   free (counts);
   3189 }
   3190 
   3191 
   3192 /* This function handles the traditional System V-style hash table format.  */
   3193 static void
   3194 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   3195 {
   3196   Elf_Data *data = elf_getdata (scn, NULL);
   3197   if (unlikely (data == NULL))
   3198     {
   3199       error (0, 0, gettext ("cannot get data for section %d: %s"),
   3200 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
   3201       return;
   3202     }
   3203 
   3204   if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
   3205     {
   3206     invalid_data:
   3207       error (0, 0, gettext ("invalid data in sysv.hash section %d"),
   3208 	     (int) elf_ndxscn (scn));
   3209       return;
   3210     }
   3211 
   3212   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
   3213   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
   3214 
   3215   uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
   3216   if (used_buf > data->d_size)
   3217     goto invalid_data;
   3218 
   3219   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
   3220   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
   3221 
   3222   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
   3223 
   3224   uint_fast32_t maxlength = 0;
   3225   uint_fast32_t nsyms = 0;
   3226   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   3227     {
   3228       Elf32_Word inner = bucket[cnt];
   3229       Elf32_Word chain_len = 0;
   3230       while (inner > 0 && inner < nchain)
   3231 	{
   3232 	  ++nsyms;
   3233 	  ++chain_len;
   3234 	  if (chain_len > nchain)
   3235 	    {
   3236 	      error (0, 0, gettext ("invalid chain in sysv.hash section %d"),
   3237 		     (int) elf_ndxscn (scn));
   3238 	      free (lengths);
   3239 	      return;
   3240 	    }
   3241 	  if (maxlength < ++lengths[cnt])
   3242 	    ++maxlength;
   3243 
   3244 	  inner = chain[inner];
   3245 	}
   3246     }
   3247 
   3248   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
   3249 		   lengths, NULL);
   3250 
   3251   free (lengths);
   3252 }
   3253 
   3254 
   3255 /* This function handles the incorrect, System V-style hash table
   3256    format some 64-bit architectures use.  */
   3257 static void
   3258 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   3259 {
   3260   Elf_Data *data = elf_getdata (scn, NULL);
   3261   if (unlikely (data == NULL))
   3262     {
   3263       error (0, 0, gettext ("cannot get data for section %d: %s"),
   3264 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
   3265       return;
   3266     }
   3267 
   3268   if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
   3269     {
   3270     invalid_data:
   3271       error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
   3272 	     (int) elf_ndxscn (scn));
   3273       return;
   3274     }
   3275 
   3276   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
   3277   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
   3278 
   3279   uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
   3280   if (maxwords < 2
   3281       || maxwords - 2 < nbucket
   3282       || maxwords - 2 - nbucket < nchain)
   3283     goto invalid_data;
   3284 
   3285   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
   3286   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
   3287 
   3288   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
   3289 
   3290   uint_fast32_t maxlength = 0;
   3291   uint_fast32_t nsyms = 0;
   3292   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
   3293     {
   3294       Elf64_Xword inner = bucket[cnt];
   3295       Elf64_Xword chain_len = 0;
   3296       while (inner > 0 && inner < nchain)
   3297 	{
   3298 	  ++nsyms;
   3299 	  ++chain_len;
   3300 	  if (chain_len > nchain)
   3301 	    {
   3302 	      error (0, 0, gettext ("invalid chain in sysv.hash64 section %d"),
   3303 		     (int) elf_ndxscn (scn));
   3304 	      free (lengths);
   3305 	      return;
   3306 	    }
   3307 	  if (maxlength < ++lengths[cnt])
   3308 	    ++maxlength;
   3309 
   3310 	  inner = chain[inner];
   3311 	}
   3312     }
   3313 
   3314   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
   3315 		   lengths, NULL);
   3316 
   3317   free (lengths);
   3318 }
   3319 
   3320 
   3321 /* This function handles the GNU-style hash table format.  */
   3322 static void
   3323 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   3324 {
   3325   uint32_t *lengths = NULL;
   3326   Elf_Data *data = elf_getdata (scn, NULL);
   3327   if (unlikely (data == NULL))
   3328     {
   3329       error (0, 0, gettext ("cannot get data for section %d: %s"),
   3330 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
   3331       return;
   3332     }
   3333 
   3334   if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
   3335     {
   3336     invalid_data:
   3337       free (lengths);
   3338       error (0, 0, gettext ("invalid data in gnu.hash section %d"),
   3339 	     (int) elf_ndxscn (scn));
   3340       return;
   3341     }
   3342 
   3343   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
   3344   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
   3345 
   3346   /* Next comes the size of the bitmap.  It's measured in words for
   3347      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
   3348      64 bit archs.  There is always a bloom filter present, so zero is
   3349      an invalid value.  */
   3350   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
   3351   if (gelf_getclass (ebl->elf) == ELFCLASS64)
   3352     bitmask_words *= 2;
   3353 
   3354   if (bitmask_words == 0)
   3355     goto invalid_data;
   3356 
   3357   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
   3358 
   3359   /* Is there still room for the sym chain?
   3360      Use uint64_t calculation to prevent 32bit overlow.  */
   3361   uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
   3362   uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
   3363   if (used_buf > data->d_size)
   3364     goto invalid_data;
   3365 
   3366   lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
   3367 
   3368   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
   3369   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
   3370   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
   3371 						    + nbucket];
   3372 
   3373   /* Compute distribution of chain lengths.  */
   3374   uint_fast32_t maxlength = 0;
   3375   uint_fast32_t nsyms = 0;
   3376   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   3377     if (bucket[cnt] != 0)
   3378       {
   3379 	Elf32_Word inner = bucket[cnt] - symbias;
   3380 	do
   3381 	  {
   3382 	    ++nsyms;
   3383 	    if (maxlength < ++lengths[cnt])
   3384 	      ++maxlength;
   3385 	    if (inner >= max_nsyms)
   3386 	      goto invalid_data;
   3387 	  }
   3388 	while ((chain[inner++] & 1) == 0);
   3389       }
   3390 
   3391   /* Count bits in bitmask.  */
   3392   uint_fast32_t nbits = 0;
   3393   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
   3394     {
   3395       uint_fast32_t word = bitmask[cnt];
   3396 
   3397       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
   3398       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
   3399       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
   3400       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
   3401       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
   3402     }
   3403 
   3404   char *str;
   3405   if (unlikely (asprintf (&str, gettext ("\
   3406  Symbol Bias: %u\n\
   3407  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
   3408 			  (unsigned int) symbias,
   3409 			  bitmask_words * sizeof (Elf32_Word),
   3410 			  ((nbits * 100 + 50)
   3411 			   / (uint_fast32_t) (bitmask_words
   3412 					      * sizeof (Elf32_Word) * 8)),
   3413 			  (unsigned int) shift) == -1))
   3414     error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
   3415 
   3416   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
   3417 		   lengths, str);
   3418 
   3419   free (str);
   3420   free (lengths);
   3421 }
   3422 
   3423 
   3424 /* Find the symbol table(s).  For this we have to search through the
   3425    section table.  */
   3426 static void
   3427 handle_hash (Ebl *ebl)
   3428 {
   3429   /* Get the section header string table index.  */
   3430   size_t shstrndx;
   3431   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   3432     error (EXIT_FAILURE, 0,
   3433 	   gettext ("cannot get section header string table index"));
   3434 
   3435   Elf_Scn *scn = NULL;
   3436   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   3437     {
   3438       /* Handle the section if it is a symbol table.  */
   3439       GElf_Shdr shdr_mem;
   3440       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   3441 
   3442       if (likely (shdr != NULL))
   3443 	{
   3444 	  if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
   3445 	      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
   3446 	    {
   3447 	      if (elf_compress (scn, 0, 0) < 0)
   3448 		printf ("WARNING: %s [%zd]\n",
   3449 			gettext ("Couldn't uncompress section"),
   3450 			elf_ndxscn (scn));
   3451 	      shdr = gelf_getshdr (scn, &shdr_mem);
   3452 	      if (unlikely (shdr == NULL))
   3453 		error (EXIT_FAILURE, 0,
   3454 		       gettext ("cannot get section [%zd] header: %s"),
   3455 		       elf_ndxscn (scn), elf_errmsg (-1));
   3456 	    }
   3457 
   3458 	  if (shdr->sh_type == SHT_HASH)
   3459 	    {
   3460 	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
   3461 		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
   3462 	      else
   3463 		handle_sysv_hash (ebl, scn, shdr, shstrndx);
   3464 	    }
   3465 	  else if (shdr->sh_type == SHT_GNU_HASH)
   3466 	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
   3467 	}
   3468     }
   3469 }
   3470 
   3471 
   3472 static void
   3473 print_liblist (Ebl *ebl)
   3474 {
   3475   /* Find the library list sections.  For this we have to search
   3476      through the section table.  */
   3477   Elf_Scn *scn = NULL;
   3478 
   3479   /* Get the section header string table index.  */
   3480   size_t shstrndx;
   3481   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   3482     error (EXIT_FAILURE, 0,
   3483 	   gettext ("cannot get section header string table index"));
   3484 
   3485   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   3486     {
   3487       GElf_Shdr shdr_mem;
   3488       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   3489 
   3490       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
   3491 	{
   3492 	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
   3493 	  int nentries = shdr->sh_size / sh_entsize;
   3494 	  printf (ngettext ("\
   3495 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
   3496 			    "\
   3497 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
   3498 			    nentries),
   3499 		  elf_ndxscn (scn),
   3500 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   3501 		  shdr->sh_offset,
   3502 		  nentries);
   3503 
   3504 	  Elf_Data *data = elf_getdata (scn, NULL);
   3505 	  if (data == NULL)
   3506 	    return;
   3507 
   3508 	  puts (gettext ("\
   3509        Library                       Time Stamp          Checksum Version Flags"));
   3510 
   3511 	  for (int cnt = 0; cnt < nentries; ++cnt)
   3512 	    {
   3513 	      GElf_Lib lib_mem;
   3514 	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
   3515 	      if (unlikely (lib == NULL))
   3516 		continue;
   3517 
   3518 	      time_t t = (time_t) lib->l_time_stamp;
   3519 	      struct tm *tm = gmtime (&t);
   3520 	      if (unlikely (tm == NULL))
   3521 		continue;
   3522 
   3523 	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
   3524 		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
   3525 		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
   3526 		      tm->tm_hour, tm->tm_min, tm->tm_sec,
   3527 		      (unsigned int) lib->l_checksum,
   3528 		      (unsigned int) lib->l_version,
   3529 		      (unsigned int) lib->l_flags);
   3530 	    }
   3531 	}
   3532     }
   3533 }
   3534 
   3535 static void
   3536 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
   3537 {
   3538   /* Find the object attributes sections.  For this we have to search
   3539      through the section table.  */
   3540   Elf_Scn *scn = NULL;
   3541 
   3542   /* Get the section header string table index.  */
   3543   size_t shstrndx;
   3544   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
   3545     error (EXIT_FAILURE, 0,
   3546 	   gettext ("cannot get section header string table index"));
   3547 
   3548   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
   3549     {
   3550       GElf_Shdr shdr_mem;
   3551       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   3552 
   3553       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
   3554 			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
   3555 			       || ehdr->e_machine != EM_ARM)))
   3556 	continue;
   3557 
   3558       printf (gettext ("\
   3559 \nObject attributes section [%2zu] '%s' of %" PRIu64
   3560 		       " bytes at offset %#0" PRIx64 ":\n"),
   3561 	      elf_ndxscn (scn),
   3562 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
   3563 	      shdr->sh_size, shdr->sh_offset);
   3564 
   3565       Elf_Data *data = elf_rawdata (scn, NULL);
   3566       if (unlikely (data == NULL || data->d_size == 0))
   3567 	return;
   3568 
   3569       const unsigned char *p = data->d_buf;
   3570 
   3571       /* There is only one 'version', A.  */
   3572       if (unlikely (*p++ != 'A'))
   3573 	return;
   3574 
   3575       fputs_unlocked (gettext ("  Owner          Size\n"), stdout);
   3576 
   3577       inline size_t left (void)
   3578       {
   3579 	return (const unsigned char *) data->d_buf + data->d_size - p;
   3580       }
   3581 
   3582       /* Loop over the sections.  */
   3583       while (left () >= 4)
   3584 	{
   3585 	  /* Section length.  */
   3586 	  uint32_t len;
   3587 	  memcpy (&len, p, sizeof len);
   3588 
   3589 	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
   3590 	    CONVERT (len);
   3591 
   3592 	  if (unlikely (len > left ()))
   3593 	    break;
   3594 
   3595 	  /* Section vendor name.  */
   3596 	  const unsigned char *name = p + sizeof len;
   3597 	  p += len;
   3598 
   3599 	  unsigned const char *q = memchr (name, '\0', len);
   3600 	  if (unlikely (q == NULL))
   3601 	    break;
   3602 	  ++q;
   3603 
   3604 	  printf (gettext ("  %-13s  %4" PRIu32 "\n"), name, len);
   3605 
   3606 	  bool gnu_vendor = (q - name == sizeof "gnu"
   3607 			     && !memcmp (name, "gnu", sizeof "gnu"));
   3608 
   3609 	  /* Loop over subsections.  */
   3610 	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
   3611 	      || gnu_vendor)
   3612 	    while (q < p)
   3613 	      {
   3614 		const unsigned char *const sub = q;
   3615 
   3616 		unsigned int subsection_tag;
   3617 		get_uleb128 (subsection_tag, q, p);
   3618 		if (unlikely (q >= p))
   3619 		  break;
   3620 
   3621 		uint32_t subsection_len;
   3622 		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
   3623 		  break;
   3624 
   3625 		memcpy (&subsection_len, q, sizeof subsection_len);
   3626 
   3627 		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
   3628 		  CONVERT (subsection_len);
   3629 
   3630 		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
   3631 		if (unlikely (subsection_len == 0
   3632 			      || subsection_len >= (uint32_t) PTRDIFF_MAX
   3633 			      || p - sub < (ptrdiff_t) subsection_len))
   3634 		  break;
   3635 
   3636 		const unsigned char *r = q + sizeof subsection_len;
   3637 		q = sub + subsection_len;
   3638 
   3639 		switch (subsection_tag)
   3640 		  {
   3641 		  default:
   3642 		    /* Unknown subsection, print and skip.  */
   3643 		    printf (gettext ("    %-4u %12" PRIu32 "\n"),
   3644 			    subsection_tag, subsection_len);
   3645 		    break;
   3646 
   3647 		  case 1:	/* Tag_File */
   3648 		    printf (gettext ("    File: %11" PRIu32 "\n"),
   3649 			    subsection_len);
   3650 
   3651 		    while (r < q)
   3652 		      {
   3653 			unsigned int tag;
   3654 			get_uleb128 (tag, r, q);
   3655 			if (unlikely (r >= q))
   3656 			  break;
   3657 
   3658 			/* GNU style tags have either a uleb128 value,
   3659 			   when lowest bit is not set, or a string
   3660 			   when the lowest bit is set.
   3661 			   "compatibility" (32) is special.  It has
   3662 			   both a string and a uleb128 value.  For
   3663 			   non-gnu we assume 6 till 31 only take ints.
   3664 			   XXX see arm backend, do we need a separate
   3665 			   hook?  */
   3666 			uint64_t value = 0;
   3667 			const char *string = NULL;
   3668 			if (tag == 32 || (tag & 1) == 0
   3669 			    || (! gnu_vendor && (tag > 5 && tag < 32)))
   3670 			  {
   3671 			    get_uleb128 (value, r, q);
   3672 			    if (r > q)
   3673 			      break;
   3674 			  }
   3675 			if (tag == 32
   3676 			    || ((tag & 1) != 0
   3677 				&& (gnu_vendor
   3678 				    || (! gnu_vendor && tag > 32)))
   3679 			    || (! gnu_vendor && tag > 3 && tag < 6))
   3680 			  {
   3681 			    string = (const char *) r;
   3682 			    r = memchr (r, '\0', q - r);
   3683 			    if (r == NULL)
   3684 			      break;
   3685 			    ++r;
   3686 			  }
   3687 
   3688 			const char *tag_name = NULL;
   3689 			const char *value_name = NULL;
   3690 			ebl_check_object_attribute (ebl, (const char *) name,
   3691 						    tag, value,
   3692 						    &tag_name, &value_name);
   3693 
   3694 			if (tag_name != NULL)
   3695 			  {
   3696 			    if (tag == 32)
   3697 			      printf (gettext ("      %s: %" PRId64 ", %s\n"),
   3698 				      tag_name, value, string);
   3699 			    else if (string == NULL && value_name == NULL)
   3700 			      printf (gettext ("      %s: %" PRId64 "\n"),
   3701 				      tag_name, value);
   3702 			    else
   3703 			      printf (gettext ("      %s: %s\n"),
   3704 				      tag_name, string ?: value_name);
   3705 			  }
   3706 			else
   3707 			  {
   3708 			    /* For "gnu" vendor 32 "compatibility" has
   3709 			       already been handled above.  */
   3710 			    assert (tag != 32
   3711 				    || strcmp ((const char *) name, "gnu"));
   3712 			    if (string == NULL)
   3713 			      printf (gettext ("      %u: %" PRId64 "\n"),
   3714 				      tag, value);
   3715 			    else
   3716 			      printf (gettext ("      %u: %s\n"),
   3717 				      tag, string);
   3718 			  }
   3719 		      }
   3720 		  }
   3721 	      }
   3722 	}
   3723     }
   3724 }
   3725 
   3726 
   3727 void
   3728 print_dwarf_addr (Dwfl_Module *dwflmod,
   3729 		  int address_size, Dwarf_Addr address, Dwarf_Addr raw)
   3730 {
   3731   /* See if there is a name we can give for this address.  */
   3732   GElf_Sym sym;
   3733   GElf_Off off = 0;
   3734   const char *name = (print_address_names && ! print_unresolved_addresses)
   3735     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
   3736     : NULL;
   3737 
   3738   const char *scn;
   3739   if (print_unresolved_addresses)
   3740     {
   3741       address = raw;
   3742       scn = NULL;
   3743     }
   3744   else
   3745     {
   3746       /* Relativize the address.  */
   3747       int n = dwfl_module_relocations (dwflmod);
   3748       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
   3749 
   3750       /* In an ET_REL file there is a section name to refer to.  */
   3751       scn = (i < 0 ? NULL
   3752 	     : dwfl_module_relocation_info (dwflmod, i, NULL));
   3753     }
   3754 
   3755   if ((name != NULL
   3756        ? (off != 0
   3757 	  ? (scn != NULL
   3758 	     ? (address_size == 0
   3759 		? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
   3760 			  scn, address, name, off)
   3761 		: printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
   3762 			  scn, 2 + address_size * 2, address,
   3763 			  name, off))
   3764 	     : (address_size == 0
   3765 		? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
   3766 			  address, name, off)
   3767 		: printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
   3768 			  2 + address_size * 2, address,
   3769 			  name, off)))
   3770 	  : (scn != NULL
   3771 	     ? (address_size == 0
   3772 		? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
   3773 		: printf ("%s+%#0*" PRIx64 " <%s>",
   3774 			   scn, 2 + address_size * 2, address, name))
   3775 	     : (address_size == 0
   3776 		? printf ("%#" PRIx64 " <%s>", address, name)
   3777 		: printf ("%#0*" PRIx64 " <%s>",
   3778 			  2 + address_size * 2, address, name))))
   3779        : (scn != NULL
   3780 	  ? (address_size == 0
   3781 	     ? printf ("%s+%#" PRIx64, scn, address)
   3782 	     : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
   3783 	  : (address_size == 0
   3784 	     ? printf ("%#" PRIx64, address)
   3785 	     : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
   3786     error (EXIT_FAILURE, 0, _("sprintf failure"));
   3787 }
   3788 
   3789 
   3790 static const char *
   3791 dwarf_tag_string (unsigned int tag)
   3792 {
   3793   switch (tag)
   3794     {
   3795 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
   3796       DWARF_ALL_KNOWN_DW_TAG
   3797 #undef DWARF_ONE_KNOWN_DW_TAG
   3798     default:
   3799       return NULL;
   3800     }
   3801 }
   3802 
   3803 
   3804 static const char *
   3805 dwarf_attr_string (unsigned int attrnum)
   3806 {
   3807   switch (attrnum)
   3808     {
   3809 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
   3810       DWARF_ALL_KNOWN_DW_AT
   3811 #undef DWARF_ONE_KNOWN_DW_AT
   3812     default:
   3813       return NULL;
   3814     }
   3815 }
   3816 
   3817 
   3818 static const char *
   3819 dwarf_form_string (unsigned int form)
   3820 {
   3821   switch (form)
   3822     {
   3823 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
   3824       DWARF_ALL_KNOWN_DW_FORM
   3825 #undef DWARF_ONE_KNOWN_DW_FORM
   3826     default:
   3827       return NULL;
   3828     }
   3829 }
   3830 
   3831 
   3832 static const char *
   3833 dwarf_lang_string (unsigned int lang)
   3834 {
   3835   switch (lang)
   3836     {
   3837 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
   3838       DWARF_ALL_KNOWN_DW_LANG
   3839 #undef DWARF_ONE_KNOWN_DW_LANG
   3840     default:
   3841       return NULL;
   3842     }
   3843 }
   3844 
   3845 
   3846 static const char *
   3847 dwarf_inline_string (unsigned int code)
   3848 {
   3849   static const char *const known[] =
   3850     {
   3851 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
   3852       DWARF_ALL_KNOWN_DW_INL
   3853 #undef DWARF_ONE_KNOWN_DW_INL
   3854     };
   3855 
   3856   if (likely (code < sizeof (known) / sizeof (known[0])))
   3857     return known[code];
   3858 
   3859   return NULL;
   3860 }
   3861 
   3862 
   3863 static const char *
   3864 dwarf_encoding_string (unsigned int code)
   3865 {
   3866   static const char *const known[] =
   3867     {
   3868 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
   3869       DWARF_ALL_KNOWN_DW_ATE
   3870 #undef DWARF_ONE_KNOWN_DW_ATE
   3871     };
   3872 
   3873   if (likely (code < sizeof (known) / sizeof (known[0])))
   3874     return known[code];
   3875 
   3876   return NULL;
   3877 }
   3878 
   3879 
   3880 static const char *
   3881 dwarf_access_string (unsigned int code)
   3882 {
   3883   static const char *const known[] =
   3884     {
   3885 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
   3886       DWARF_ALL_KNOWN_DW_ACCESS
   3887 #undef DWARF_ONE_KNOWN_DW_ACCESS
   3888     };
   3889 
   3890   if (likely (code < sizeof (known) / sizeof (known[0])))
   3891     return known[code];
   3892 
   3893   return NULL;
   3894 }
   3895 
   3896 
   3897 static const char *
   3898 dwarf_defaulted_string (unsigned int code)
   3899 {
   3900   static const char *const known[] =
   3901     {
   3902 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
   3903       DWARF_ALL_KNOWN_DW_DEFAULTED
   3904 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
   3905     };
   3906 
   3907   if (likely (code < sizeof (known) / sizeof (known[0])))
   3908     return known[code];
   3909 
   3910   return NULL;
   3911 }
   3912 
   3913 
   3914 static const char *
   3915 dwarf_visibility_string (unsigned int code)
   3916 {
   3917   static const char *const known[] =
   3918     {
   3919 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
   3920       DWARF_ALL_KNOWN_DW_VIS
   3921 #undef DWARF_ONE_KNOWN_DW_VIS
   3922     };
   3923 
   3924   if (likely (code < sizeof (known) / sizeof (known[0])))
   3925     return known[code];
   3926 
   3927   return NULL;
   3928 }
   3929 
   3930 
   3931 static const char *
   3932 dwarf_virtuality_string (unsigned int code)
   3933 {
   3934   static const char *const known[] =
   3935     {
   3936 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
   3937       DWARF_ALL_KNOWN_DW_VIRTUALITY
   3938 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
   3939     };
   3940 
   3941   if (likely (code < sizeof (known) / sizeof (known[0])))
   3942     return known[code];
   3943 
   3944   return NULL;
   3945 }
   3946 
   3947 
   3948 static const char *
   3949 dwarf_identifier_case_string (unsigned int code)
   3950 {
   3951   static const char *const known[] =
   3952     {
   3953 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
   3954       DWARF_ALL_KNOWN_DW_ID
   3955 #undef DWARF_ONE_KNOWN_DW_ID
   3956     };
   3957 
   3958   if (likely (code < sizeof (known) / sizeof (known[0])))
   3959     return known[code];
   3960 
   3961   return NULL;
   3962 }
   3963 
   3964 
   3965 static const char *
   3966 dwarf_calling_convention_string (unsigned int code)
   3967 {
   3968   static const char *const known[] =
   3969     {
   3970 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
   3971       DWARF_ALL_KNOWN_DW_CC
   3972 #undef DWARF_ONE_KNOWN_DW_CC
   3973     };
   3974 
   3975   if (likely (code < sizeof (known) / sizeof (known[0])))
   3976     return known[code];
   3977 
   3978   return NULL;
   3979 }
   3980 
   3981 
   3982 static const char *
   3983 dwarf_ordering_string (unsigned int code)
   3984 {
   3985   static const char *const known[] =
   3986     {
   3987 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
   3988       DWARF_ALL_KNOWN_DW_ORD
   3989 #undef DWARF_ONE_KNOWN_DW_ORD
   3990     };
   3991 
   3992   if (likely (code < sizeof (known) / sizeof (known[0])))
   3993     return known[code];
   3994 
   3995   return NULL;
   3996 }
   3997 
   3998 
   3999 static const char *
   4000 dwarf_discr_list_string (unsigned int code)
   4001 {
   4002   static const char *const known[] =
   4003     {
   4004 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
   4005       DWARF_ALL_KNOWN_DW_DSC
   4006 #undef DWARF_ONE_KNOWN_DW_DSC
   4007     };
   4008 
   4009   if (likely (code < sizeof (known) / sizeof (known[0])))
   4010     return known[code];
   4011 
   4012   return NULL;
   4013 }
   4014 
   4015 
   4016 static const char *
   4017 dwarf_locexpr_opcode_string (unsigned int code)
   4018 {
   4019   static const char *const known[] =
   4020     {
   4021       /* Normally we can't affort building huge table of 64K entries,
   4022 	 most of them zero, just because there are a couple defined
   4023 	 values at the far end.  In case of opcodes, it's OK.  */
   4024 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
   4025       DWARF_ALL_KNOWN_DW_OP
   4026 #undef DWARF_ONE_KNOWN_DW_OP
   4027     };
   4028 
   4029   if (likely (code < sizeof (known) / sizeof (known[0])))
   4030     return known[code];
   4031 
   4032   return NULL;
   4033 }
   4034 
   4035 
   4036 static const char *
   4037 dwarf_unit_string (unsigned int type)
   4038 {
   4039   switch (type)
   4040     {
   4041 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
   4042       DWARF_ALL_KNOWN_DW_UT
   4043 #undef DWARF_ONE_KNOWN_DW_UT
   4044     default:
   4045       return NULL;
   4046     }
   4047 }
   4048 
   4049 
   4050 static const char *
   4051 dwarf_range_list_encoding_string (unsigned int kind)
   4052 {
   4053   switch (kind)
   4054     {
   4055 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
   4056       DWARF_ALL_KNOWN_DW_RLE
   4057 #undef DWARF_ONE_KNOWN_DW_RLE
   4058     default:
   4059       return NULL;
   4060     }
   4061 }
   4062 
   4063 
   4064 static const char *
   4065 dwarf_loc_list_encoding_string (unsigned int kind)
   4066 {
   4067   switch (kind)
   4068     {
   4069 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
   4070       DWARF_ALL_KNOWN_DW_LLE
   4071 #undef DWARF_ONE_KNOWN_DW_LLE
   4072     default:
   4073       return NULL;
   4074     }
   4075 }
   4076 
   4077 
   4078 static const char *
   4079 dwarf_line_content_description_string (unsigned int kind)
   4080 {
   4081   switch (kind)
   4082     {
   4083 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
   4084       DWARF_ALL_KNOWN_DW_LNCT
   4085 #undef DWARF_ONE_KNOWN_DW_LNCT
   4086     default:
   4087       return NULL;
   4088     }
   4089 }
   4090 
   4091 
   4092 /* Used by all dwarf_foo_name functions.  */
   4093 static const char *
   4094 string_or_unknown (const char *known, unsigned int code,
   4095                    unsigned int lo_user, unsigned int hi_user,
   4096 		   bool print_unknown_num)
   4097 {
   4098   static char unknown_buf[20];
   4099 
   4100   if (likely (known != NULL))
   4101     return known;
   4102 
   4103   if (lo_user != 0 && code >= lo_user && code <= hi_user)
   4104     {
   4105       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
   4106 		code - lo_user);
   4107       return unknown_buf;
   4108     }
   4109 
   4110   if (print_unknown_num)
   4111     {
   4112       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
   4113       return unknown_buf;
   4114     }
   4115 
   4116   return "???";
   4117 }
   4118 
   4119 
   4120 static const char *
   4121 dwarf_tag_name (unsigned int tag)
   4122 {
   4123   const char *ret = dwarf_tag_string (tag);
   4124   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
   4125 }
   4126 
   4127 static const char *
   4128 dwarf_attr_name (unsigned int attr)
   4129 {
   4130   const char *ret = dwarf_attr_string (attr);
   4131   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
   4132 }
   4133 
   4134 
   4135 static const char *
   4136 dwarf_form_name (unsigned int form)
   4137 {
   4138   const char *ret = dwarf_form_string (form);
   4139   return string_or_unknown (ret, form, 0, 0, true);
   4140 }
   4141 
   4142 
   4143 static const char *
   4144 dwarf_lang_name (unsigned int lang)
   4145 {
   4146   const char *ret = dwarf_lang_string (lang);
   4147   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
   4148 }
   4149 
   4150 
   4151 static const char *
   4152 dwarf_inline_name (unsigned int code)
   4153 {
   4154   const char *ret = dwarf_inline_string (code);
   4155   return string_or_unknown (ret, code, 0, 0, false);
   4156 }
   4157 
   4158 
   4159 static const char *
   4160 dwarf_encoding_name (unsigned int code)
   4161 {
   4162   const char *ret = dwarf_encoding_string (code);
   4163   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
   4164 }
   4165 
   4166 
   4167 static const char *
   4168 dwarf_access_name (unsigned int code)
   4169 {
   4170   const char *ret = dwarf_access_string (code);
   4171   return string_or_unknown (ret, code, 0, 0, false);
   4172 }
   4173 
   4174 
   4175 static const char *
   4176 dwarf_defaulted_name (unsigned int code)
   4177 {
   4178   const char *ret = dwarf_defaulted_string (code);
   4179   return string_or_unknown (ret, code, 0, 0, false);
   4180 }
   4181 
   4182 
   4183 static const char *
   4184 dwarf_visibility_name (unsigned int code)
   4185 {
   4186   const char *ret = dwarf_visibility_string (code);
   4187   return string_or_unknown (ret, code, 0, 0, false);
   4188 }
   4189 
   4190 
   4191 static const char *
   4192 dwarf_virtuality_name (unsigned int code)
   4193 {
   4194   const char *ret = dwarf_virtuality_string (code);
   4195   return string_or_unknown (ret, code, 0, 0, false);
   4196 }
   4197 
   4198 
   4199 static const char *
   4200 dwarf_identifier_case_name (unsigned int code)
   4201 {
   4202   const char *ret = dwarf_identifier_case_string (code);
   4203   return string_or_unknown (ret, code, 0, 0, false);
   4204 }
   4205 
   4206 
   4207 static const char *
   4208 dwarf_calling_convention_name (unsigned int code)
   4209 {
   4210   const char *ret = dwarf_calling_convention_string (code);
   4211   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
   4212 }
   4213 
   4214 
   4215 static const char *
   4216 dwarf_ordering_name (unsigned int code)
   4217 {
   4218   const char *ret = dwarf_ordering_string (code);
   4219   return string_or_unknown (ret, code, 0, 0, false);
   4220 }
   4221 
   4222 
   4223 static const char *
   4224 dwarf_discr_list_name (unsigned int code)
   4225 {
   4226   const char *ret = dwarf_discr_list_string (code);
   4227   return string_or_unknown (ret, code, 0, 0, false);
   4228 }
   4229 
   4230 
   4231 static const char *
   4232 dwarf_unit_name (unsigned int type)
   4233 {
   4234   const char *ret = dwarf_unit_string (type);
   4235   return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
   4236 }
   4237 
   4238 
   4239 static const char *
   4240 dwarf_range_list_encoding_name (unsigned int kind)
   4241 {
   4242   const char *ret = dwarf_range_list_encoding_string (kind);
   4243   return string_or_unknown (ret, kind, 0, 0, false);
   4244 }
   4245 
   4246 
   4247 static const char *
   4248 dwarf_loc_list_encoding_name (unsigned int kind)
   4249 {
   4250   const char *ret = dwarf_loc_list_encoding_string (kind);
   4251   return string_or_unknown (ret, kind, 0, 0, false);
   4252 }
   4253 
   4254 
   4255 static const char *
   4256 dwarf_line_content_description_name (unsigned int kind)
   4257 {
   4258   const char *ret = dwarf_line_content_description_string (kind);
   4259   return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
   4260 			    false);
   4261 }
   4262 
   4263 
   4264 static void
   4265 print_block (size_t n, const void *block)
   4266 {
   4267   if (n == 0)
   4268     puts (_("empty block"));
   4269   else
   4270     {
   4271       printf (_("%zu byte block:"), n);
   4272       const unsigned char *data = block;
   4273       do
   4274 	printf (" %02x", *data++);
   4275       while (--n > 0);
   4276       putchar ('\n');
   4277     }
   4278 }
   4279 
   4280 static void
   4281 print_bytes (size_t n, const unsigned char *bytes)
   4282 {
   4283   while (n-- > 0)
   4284     {
   4285       printf ("%02x", *bytes++);
   4286       if (n > 0)
   4287 	printf (" ");
   4288     }
   4289 }
   4290 
   4291 static int
   4292 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
   4293 {
   4294   if (cu == NULL)
   4295     return -1;
   4296 
   4297   Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
   4298   if (debug_addr == NULL)
   4299     return -1;
   4300 
   4301   Dwarf_Off base = __libdw_cu_addr_base (cu);
   4302   Dwarf_Word off = idx * cu->address_size;
   4303   if (base > debug_addr->d_size
   4304       || off > debug_addr->d_size - base
   4305       || cu->address_size > debug_addr->d_size - base - off)
   4306     return -1;
   4307 
   4308   const unsigned char *addrp = debug_addr->d_buf + base + off;
   4309   if (cu->address_size == 4)
   4310     *addr = read_4ubyte_unaligned (cu->dbg, addrp);
   4311   else
   4312     *addr = read_8ubyte_unaligned (cu->dbg, addrp);
   4313 
   4314   return 0;
   4315 }
   4316 
   4317 static void
   4318 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
   4319 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
   4320 	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
   4321 {
   4322   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
   4323 
   4324   if (len == 0)
   4325     {
   4326       printf ("%*s(empty)\n", indent, "");
   4327       return;
   4328     }
   4329 
   4330 #define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
   4331 #define CONSUME(n)	NEED (n); else len -= (n)
   4332 
   4333   Dwarf_Word offset = 0;
   4334   while (len-- > 0)
   4335     {
   4336       uint_fast8_t op = *data++;
   4337 
   4338       const char *op_name = dwarf_locexpr_opcode_string (op);
   4339       if (unlikely (op_name == NULL))
   4340 	{
   4341 	  static char buf[20];
   4342 	  if (op >= DW_OP_lo_user)
   4343 	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
   4344 	  else
   4345 	    snprintf (buf, sizeof buf, "??? (%#x)", op);
   4346 	  op_name = buf;
   4347 	}
   4348 
   4349       switch (op)
   4350 	{
   4351 	case DW_OP_addr:;
   4352 	  /* Address operand.  */
   4353 	  Dwarf_Word addr;
   4354 	  NEED (addrsize);
   4355 	  if (addrsize == 4)
   4356 	    addr = read_4ubyte_unaligned (dbg, data);
   4357 	  else if (addrsize == 8)
   4358 	    addr = read_8ubyte_unaligned (dbg, data);
   4359 	  else
   4360 	    goto invalid;
   4361 	  data += addrsize;
   4362 	  CONSUME (addrsize);
   4363 
   4364 	  printf ("%*s[%2" PRIuMAX "] %s ",
   4365 		  indent, "", (uintmax_t) offset, op_name);
   4366 	  print_dwarf_addr (dwflmod, 0, addr, addr);
   4367 	  printf ("\n");
   4368 
   4369 	  offset += 1 + addrsize;
   4370 	  break;
   4371 
   4372 	case DW_OP_call_ref:
   4373 	case DW_OP_GNU_variable_value:
   4374 	  /* Offset operand.  */
   4375 	  if (ref_size != 4 && ref_size != 8)
   4376 	    goto invalid; /* Cannot be used in CFA.  */
   4377 	  NEED (ref_size);
   4378 	  if (ref_size == 4)
   4379 	    addr = read_4ubyte_unaligned (dbg, data);
   4380 	  else
   4381 	    addr = read_8ubyte_unaligned (dbg, data);
   4382 	  data += ref_size;
   4383 	  CONSUME (ref_size);
   4384 	  /* addr is a DIE offset, so format it as one.  */
   4385 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
   4386 		  indent, "", (uintmax_t) offset,
   4387 		  op_name, (uintmax_t) addr);
   4388 	  offset += 1 + ref_size;
   4389 	  break;
   4390 
   4391 	case DW_OP_deref_size:
   4392 	case DW_OP_xderef_size:
   4393 	case DW_OP_pick:
   4394 	case DW_OP_const1u:
   4395 	  // XXX value might be modified by relocation
   4396 	  NEED (1);
   4397 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
   4398 		  indent, "", (uintmax_t) offset,
   4399 		  op_name, *((uint8_t *) data));
   4400 	  ++data;
   4401 	  --len;
   4402 	  offset += 2;
   4403 	  break;
   4404 
   4405 	case DW_OP_const2u:
   4406 	  NEED (2);
   4407 	  // XXX value might be modified by relocation
   4408 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
   4409 		  indent, "", (uintmax_t) offset,
   4410 		  op_name, read_2ubyte_unaligned (dbg, data));
   4411 	  CONSUME (2);
   4412 	  data += 2;
   4413 	  offset += 3;
   4414 	  break;
   4415 
   4416 	case DW_OP_const4u:
   4417 	  NEED (4);
   4418 	  // XXX value might be modified by relocation
   4419 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
   4420 		  indent, "", (uintmax_t) offset,
   4421 		  op_name, read_4ubyte_unaligned (dbg, data));
   4422 	  CONSUME (4);
   4423 	  data += 4;
   4424 	  offset += 5;
   4425 	  break;
   4426 
   4427 	case DW_OP_const8u:
   4428 	  NEED (8);
   4429 	  // XXX value might be modified by relocation
   4430 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
   4431 		  indent, "", (uintmax_t) offset,
   4432 		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
   4433 	  CONSUME (8);
   4434 	  data += 8;
   4435 	  offset += 9;
   4436 	  break;
   4437 
   4438 	case DW_OP_const1s:
   4439 	  NEED (1);
   4440 	  // XXX value might be modified by relocation
   4441 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
   4442 		  indent, "", (uintmax_t) offset,
   4443 		  op_name, *((int8_t *) data));
   4444 	  ++data;
   4445 	  --len;
   4446 	  offset += 2;
   4447 	  break;
   4448 
   4449 	case DW_OP_const2s:
   4450 	  NEED (2);
   4451 	  // XXX value might be modified by relocation
   4452 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
   4453 		  indent, "", (uintmax_t) offset,
   4454 		  op_name, read_2sbyte_unaligned (dbg, data));
   4455 	  CONSUME (2);
   4456 	  data += 2;
   4457 	  offset += 3;
   4458 	  break;
   4459 
   4460 	case DW_OP_const4s:
   4461 	  NEED (4);
   4462 	  // XXX value might be modified by relocation
   4463 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
   4464 		  indent, "", (uintmax_t) offset,
   4465 		  op_name, read_4sbyte_unaligned (dbg, data));
   4466 	  CONSUME (4);
   4467 	  data += 4;
   4468 	  offset += 5;
   4469 	  break;
   4470 
   4471 	case DW_OP_const8s:
   4472 	  NEED (8);
   4473 	  // XXX value might be modified by relocation
   4474 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
   4475 		  indent, "", (uintmax_t) offset,
   4476 		  op_name, read_8sbyte_unaligned (dbg, data));
   4477 	  CONSUME (8);
   4478 	  data += 8;
   4479 	  offset += 9;
   4480 	  break;
   4481 
   4482 	case DW_OP_piece:
   4483 	case DW_OP_regx:
   4484 	case DW_OP_plus_uconst:
   4485 	case DW_OP_constu:;
   4486 	  const unsigned char *start = data;
   4487 	  uint64_t uleb;
   4488 	  NEED (1);
   4489 	  get_uleb128 (uleb, data, data + len);
   4490 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
   4491 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4492 	  CONSUME (data - start);
   4493 	  offset += 1 + (data - start);
   4494 	  break;
   4495 
   4496 	case DW_OP_addrx:
   4497 	case DW_OP_GNU_addr_index:
   4498 	case DW_OP_constx:
   4499 	case DW_OP_GNU_const_index:;
   4500 	  start = data;
   4501 	  NEED (1);
   4502 	  get_uleb128 (uleb, data, data + len);
   4503 	  printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
   4504 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4505 	  CONSUME (data - start);
   4506 	  offset += 1 + (data - start);
   4507 	  if (get_indexed_addr (cu, uleb, &addr) != 0)
   4508 	    printf ("???\n");
   4509 	  else
   4510 	    {
   4511 	      print_dwarf_addr (dwflmod, 0, addr, addr);
   4512 	      printf ("\n");
   4513 	    }
   4514 	  break;
   4515 
   4516 	case DW_OP_bit_piece:
   4517 	  start = data;
   4518 	  uint64_t uleb2;
   4519 	  NEED (1);
   4520 	  get_uleb128 (uleb, data, data + len);
   4521 	  NEED (1);
   4522 	  get_uleb128 (uleb2, data, data + len);
   4523 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
   4524 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
   4525 	  CONSUME (data - start);
   4526 	  offset += 1 + (data - start);
   4527 	  break;
   4528 
   4529 	case DW_OP_fbreg:
   4530 	case DW_OP_breg0 ... DW_OP_breg31:
   4531 	case DW_OP_consts:
   4532 	  start = data;
   4533 	  int64_t sleb;
   4534 	  NEED (1);
   4535 	  get_sleb128 (sleb, data, data + len);
   4536 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
   4537 		  indent, "", (uintmax_t) offset, op_name, sleb);
   4538 	  CONSUME (data - start);
   4539 	  offset += 1 + (data - start);
   4540 	  break;
   4541 
   4542 	case DW_OP_bregx:
   4543 	  start = data;
   4544 	  NEED (1);
   4545 	  get_uleb128 (uleb, data, data + len);
   4546 	  NEED (1);
   4547 	  get_sleb128 (sleb, data, data + len);
   4548 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
   4549 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
   4550 	  CONSUME (data - start);
   4551 	  offset += 1 + (data - start);
   4552 	  break;
   4553 
   4554 	case DW_OP_call2:
   4555 	  NEED (2);
   4556 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
   4557 		  indent, "", (uintmax_t) offset, op_name,
   4558 		  read_2ubyte_unaligned (dbg, data));
   4559 	  CONSUME (2);
   4560 	  data += 2;
   4561 	  offset += 3;
   4562 	  break;
   4563 
   4564 	case DW_OP_call4:
   4565 	  NEED (4);
   4566 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
   4567 		  indent, "", (uintmax_t) offset, op_name,
   4568 		  read_4ubyte_unaligned (dbg, data));
   4569 	  CONSUME (4);
   4570 	  data += 4;
   4571 	  offset += 5;
   4572 	  break;
   4573 
   4574 	case DW_OP_skip:
   4575 	case DW_OP_bra:
   4576 	  NEED (2);
   4577 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
   4578 		  indent, "", (uintmax_t) offset, op_name,
   4579 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
   4580 	  CONSUME (2);
   4581 	  data += 2;
   4582 	  offset += 3;
   4583 	  break;
   4584 
   4585 	case DW_OP_implicit_value:
   4586 	  start = data;
   4587 	  NEED (1);
   4588 	  get_uleb128 (uleb, data, data + len);
   4589 	  printf ("%*s[%2" PRIuMAX "] %s: ",
   4590 		  indent, "", (uintmax_t) offset, op_name);
   4591 	  NEED (uleb);
   4592 	  print_block (uleb, data);
   4593 	  data += uleb;
   4594 	  CONSUME (data - start);
   4595 	  offset += 1 + (data - start);
   4596 	  break;
   4597 
   4598 	case DW_OP_implicit_pointer:
   4599 	case DW_OP_GNU_implicit_pointer:
   4600 	  /* DIE offset operand.  */
   4601 	  start = data;
   4602 	  NEED (ref_size);
   4603 	  if (ref_size != 4 && ref_size != 8)
   4604 	    goto invalid; /* Cannot be used in CFA.  */
   4605 	  if (ref_size == 4)
   4606 	    addr = read_4ubyte_unaligned (dbg, data);
   4607 	  else
   4608 	    addr = read_8ubyte_unaligned (dbg, data);
   4609 	  data += ref_size;
   4610 	  /* Byte offset operand.  */
   4611 	  NEED (1);
   4612 	  get_sleb128 (sleb, data, data + len);
   4613 
   4614 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
   4615 		  indent, "", (intmax_t) offset,
   4616 		  op_name, (uintmax_t) addr, sleb);
   4617 	  CONSUME (data - start);
   4618 	  offset += 1 + (data - start);
   4619 	  break;
   4620 
   4621 	case DW_OP_entry_value:
   4622 	case DW_OP_GNU_entry_value:
   4623 	  /* Size plus expression block.  */
   4624 	  start = data;
   4625 	  NEED (1);
   4626 	  get_uleb128 (uleb, data, data + len);
   4627 	  printf ("%*s[%2" PRIuMAX "] %s:\n",
   4628 		  indent, "", (uintmax_t) offset, op_name);
   4629 	  NEED (uleb);
   4630 	  print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
   4631 		     addrsize, offset_size, cu, uleb, data);
   4632 	  data += uleb;
   4633 	  CONSUME (data - start);
   4634 	  offset += 1 + (data - start);
   4635 	  break;
   4636 
   4637 	case DW_OP_const_type:
   4638 	case DW_OP_GNU_const_type:
   4639 	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
   4640 	     unsigned size plus block.  */
   4641 	  start = data;
   4642 	  NEED (1);
   4643 	  get_uleb128 (uleb, data, data + len);
   4644 	  if (! print_unresolved_addresses && cu != NULL)
   4645 	    uleb += cu->start;
   4646 	  NEED (1);
   4647 	  uint8_t usize = *(uint8_t *) data++;
   4648 	  NEED (usize);
   4649 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
   4650 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4651 	  print_block (usize, data);
   4652 	  data += usize;
   4653 	  CONSUME (data - start);
   4654 	  offset += 1 + (data - start);
   4655 	  break;
   4656 
   4657 	case DW_OP_regval_type:
   4658 	case DW_OP_GNU_regval_type:
   4659 	  /* uleb128 register number, uleb128 CU relative
   4660 	     DW_TAG_base_type DIE offset.  */
   4661 	  start = data;
   4662 	  NEED (1);
   4663 	  get_uleb128 (uleb, data, data + len);
   4664 	  NEED (1);
   4665 	  get_uleb128 (uleb2, data, data + len);
   4666 	  if (! print_unresolved_addresses && cu != NULL)
   4667 	    uleb2 += cu->start;
   4668 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
   4669 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
   4670 	  CONSUME (data - start);
   4671 	  offset += 1 + (data - start);
   4672 	  break;
   4673 
   4674 	case DW_OP_deref_type:
   4675 	case DW_OP_GNU_deref_type:
   4676 	  /* 1-byte unsigned size of value, uleb128 CU relative
   4677 	     DW_TAG_base_type DIE offset.  */
   4678 	  start = data;
   4679 	  NEED (1);
   4680 	  usize = *(uint8_t *) data++;
   4681 	  NEED (1);
   4682 	  get_uleb128 (uleb, data, data + len);
   4683 	  if (! print_unresolved_addresses && cu != NULL)
   4684 	    uleb += cu->start;
   4685 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
   4686 		  indent, "", (uintmax_t) offset,
   4687 		  op_name, usize, uleb);
   4688 	  CONSUME (data - start);
   4689 	  offset += 1 + (data - start);
   4690 	  break;
   4691 
   4692 	case DW_OP_xderef_type:
   4693 	  /* 1-byte unsigned size of value, uleb128 base_type DIE offset.  */
   4694 	  start = data;
   4695 	  NEED (1);
   4696 	  usize = *(uint8_t *) data++;
   4697 	  NEED (1);
   4698 	  get_uleb128 (uleb, data, data + len);
   4699 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
   4700 		  indent, "", (uintmax_t) offset,
   4701 		  op_name, usize, uleb);
   4702 	  CONSUME (data - start);
   4703 	  offset += 1 + (data - start);
   4704 	  break;
   4705 
   4706 	case DW_OP_convert:
   4707 	case DW_OP_GNU_convert:
   4708 	case DW_OP_reinterpret:
   4709 	case DW_OP_GNU_reinterpret:
   4710 	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
   4711 	     for conversion to untyped.  */
   4712 	  start = data;
   4713 	  NEED (1);
   4714 	  get_uleb128 (uleb, data, data + len);
   4715 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
   4716 	    uleb += cu->start;
   4717 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
   4718 		  indent, "", (uintmax_t) offset, op_name, uleb);
   4719 	  CONSUME (data - start);
   4720 	  offset += 1 + (data - start);
   4721 	  break;
   4722 
   4723 	case DW_OP_GNU_parameter_ref:
   4724 	  /* 4 byte CU relative reference to the abstract optimized away
   4725 	     DW_TAG_formal_parameter.  */
   4726 	  NEED (4);
   4727 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
   4728 	  if (! print_unresolved_addresses && cu != NULL)
   4729 	    param_off += cu->start;
   4730 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
   4731 		  indent, "", (uintmax_t) offset, op_name, param_off);
   4732 	  CONSUME (4);
   4733 	  data += 4;
   4734 	  offset += 5;
   4735 	  break;
   4736 
   4737 	default:
   4738 	  /* No Operand.  */
   4739 	  printf ("%*s[%2" PRIuMAX "] %s\n",
   4740 		  indent, "", (uintmax_t) offset, op_name);
   4741 	  ++offset;
   4742 	  break;
   4743 	}
   4744 
   4745       indent = indentrest;
   4746       continue;
   4747 
   4748     invalid:
   4749       printf (gettext ("%*s[%2" PRIuMAX "] %s  <TRUNCATED>\n"),
   4750 	      indent, "", (uintmax_t) offset, op_name);
   4751       break;
   4752     }
   4753 }
   4754 
   4755 
   4756 struct listptr
   4757 {
   4758   Dwarf_Off offset:(64 - 3);
   4759   bool addr64:1;
   4760   bool dwarf64:1;
   4761   bool warned:1;
   4762   struct Dwarf_CU *cu;
   4763   unsigned int attr;
   4764 };
   4765 
   4766 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
   4767 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
   4768 
   4769 static Dwarf_Addr
   4770 cudie_base (Dwarf_Die *cudie)
   4771 {
   4772   Dwarf_Addr base;
   4773   /* Find the base address of the compilation unit.  It will normally
   4774      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
   4775      address could be overridden by DW_AT_entry_pc.  It's been
   4776      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
   4777      compilation units with discontinuous ranges.  */
   4778   if (unlikely (dwarf_lowpc (cudie, &base) != 0))
   4779     {
   4780       Dwarf_Attribute attr_mem;
   4781       if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
   4782 			  &base) != 0)
   4783 	base = 0;
   4784     }
   4785   return base;
   4786 }
   4787 
   4788 static Dwarf_Addr
   4789 listptr_base (struct listptr *p)
   4790 {
   4791   Dwarf_Die cu = CUDIE (p->cu);
   4792   return cudie_base (&cu);
   4793 }
   4794 
   4795 static int
   4796 compare_listptr (const void *a, const void *b, void *arg)
   4797 {
   4798   const char *name = arg;
   4799   struct listptr *p1 = (void *) a;
   4800   struct listptr *p2 = (void *) b;
   4801 
   4802   if (p1->offset < p2->offset)
   4803     return -1;
   4804   if (p1->offset > p2->offset)
   4805     return 1;
   4806 
   4807   if (!p1->warned && !p2->warned)
   4808     {
   4809       if (p1->addr64 != p2->addr64)
   4810 	{
   4811 	  p1->warned = p2->warned = true;
   4812 	  error (0, 0,
   4813 		 gettext ("%s %#" PRIx64 " used with different address sizes"),
   4814 		 name, (uint64_t) p1->offset);
   4815 	}
   4816       if (p1->dwarf64 != p2->dwarf64)
   4817 	{
   4818 	  p1->warned = p2->warned = true;
   4819 	  error (0, 0,
   4820 		 gettext ("%s %#" PRIx64 " used with different offset sizes"),
   4821 		 name, (uint64_t) p1->offset);
   4822 	}
   4823       if (listptr_base (p1) != listptr_base (p2))
   4824 	{
   4825 	  p1->warned = p2->warned = true;
   4826 	  error (0, 0,
   4827 		 gettext ("%s %#" PRIx64 " used with different base addresses"),
   4828 		 name, (uint64_t) p1->offset);
   4829 	}
   4830       if (p1->attr != p2 ->attr)
   4831 	{
   4832 	  p1->warned = p2->warned = true;
   4833 	  error (0, 0,
   4834 		 gettext ("%s %#" PRIx64
   4835 			  " used with different attribute %s and %s"),
   4836 		 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
   4837 		 dwarf_attr_name (p2->attr));
   4838 	}
   4839     }
   4840 
   4841   return 0;
   4842 }
   4843 
   4844 struct listptr_table
   4845 {
   4846   size_t n;
   4847   size_t alloc;
   4848   struct listptr *table;
   4849 };
   4850 
   4851 static struct listptr_table known_locsptr;
   4852 static struct listptr_table known_loclistsptr;
   4853 static struct listptr_table known_rangelistptr;
   4854 static struct listptr_table known_rnglistptr;
   4855 static struct listptr_table known_addrbases;
   4856 static struct listptr_table known_stroffbases;
   4857 
   4858 static void
   4859 reset_listptr (struct listptr_table *table)
   4860 {
   4861   free (table->table);
   4862   table->table = NULL;
   4863   table->n = table->alloc = 0;
   4864 }
   4865 
   4866 /* Returns false if offset doesn't fit.  See struct listptr.  */
   4867 static bool
   4868 notice_listptr (enum section_e section, struct listptr_table *table,
   4869 		uint_fast8_t address_size, uint_fast8_t offset_size,
   4870 		struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
   4871 {
   4872   if (print_debug_sections & section)
   4873     {
   4874       if (table->n == table->alloc)
   4875 	{
   4876 	  if (table->alloc == 0)
   4877 	    table->alloc = 128;
   4878 	  else
   4879 	    table->alloc *= 2;
   4880 	  table->table = xrealloc (table->table,
   4881 				   table->alloc * sizeof table->table[0]);
   4882 	}
   4883 
   4884       struct listptr *p = &table->table[table->n++];
   4885 
   4886       *p = (struct listptr)
   4887 	{
   4888 	  .addr64 = address_size == 8,
   4889 	  .dwarf64 = offset_size == 8,
   4890 	  .offset = offset,
   4891 	  .cu = cu,
   4892 	  .attr = attr
   4893 	};
   4894 
   4895       if (p->offset != offset)
   4896 	{
   4897 	  table->n--;
   4898 	  return false;
   4899 	}
   4900     }
   4901   return true;
   4902 }
   4903 
   4904 static void
   4905 sort_listptr (struct listptr_table *table, const char *name)
   4906 {
   4907   if (table->n > 0)
   4908     qsort_r (table->table, table->n, sizeof table->table[0],
   4909 	     &compare_listptr, (void *) name);
   4910 }
   4911 
   4912 static bool
   4913 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
   4914 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
   4915 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
   4916 		   unsigned char **readp, unsigned char *endp,
   4917 		   unsigned int *attr)
   4918 {
   4919   if (table->n == 0)
   4920     return false;
   4921 
   4922   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
   4923     ++*idxp;
   4924 
   4925   struct listptr *p = &table->table[*idxp];
   4926 
   4927   if (*idxp == table->n
   4928       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
   4929     {
   4930       *readp = endp;
   4931       printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
   4932 	      offset);
   4933       return true;
   4934     }
   4935 
   4936   if (p->offset != (Dwarf_Off) offset)
   4937     {
   4938       *readp += p->offset - offset;
   4939       printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
   4940 	      offset, (Dwarf_Off) p->offset - offset);
   4941       return true;
   4942     }
   4943 
   4944   if (address_sizep != NULL)
   4945     *address_sizep = listptr_address_size (p);
   4946   if (offset_sizep != NULL)
   4947     *offset_sizep = listptr_offset_size (p);
   4948   if (base != NULL)
   4949     *base = listptr_base (p);
   4950   if (cu != NULL)
   4951     *cu = p->cu;
   4952   if (attr != NULL)
   4953     *attr = p->attr;
   4954 
   4955   return false;
   4956 }
   4957 
   4958 static Dwarf_Off
   4959 next_listptr_offset (struct listptr_table *table, size_t idx)
   4960 {
   4961   /* Note that multiple attributes could in theory point to the same loclist
   4962      offset, so make sure we pick one that is bigger than the current one.
   4963      The table is sorted on offset.  */
   4964   Dwarf_Off offset = table->table[idx].offset;
   4965   while (++idx < table->n)
   4966     {
   4967       Dwarf_Off next = table->table[idx].offset;
   4968       if (next > offset)
   4969 	return next;
   4970     }
   4971   return 0;
   4972 }
   4973 
   4974 /* Returns the listptr associated with the given index, or NULL.  */
   4975 static struct listptr *
   4976 get_listptr (struct listptr_table *table, size_t idx)
   4977 {
   4978   if (idx >= table->n)
   4979     return NULL;
   4980   return &table->table[idx];
   4981 }
   4982 
   4983 /* Returns the next index, base address and CU associated with the
   4984    list unit offsets.  If there is none false is returned, otherwise
   4985    true.  Assumes the table has been sorted.  */
   4986 static bool
   4987 listptr_cu (struct listptr_table *table, size_t *idxp,
   4988 	    Dwarf_Off start, Dwarf_Off end,
   4989 	    Dwarf_Addr *base, struct Dwarf_CU **cu)
   4990 {
   4991   while (*idxp < table->n
   4992 	 && table->table[*idxp].offset < start)
   4993     ++*idxp;
   4994 
   4995   if (*idxp < table->n
   4996       && table->table[*idxp].offset >= start
   4997       && table->table[*idxp].offset < end)
   4998     {
   4999       struct listptr *p = &table->table[*idxp];
   5000       *base = listptr_base (p);
   5001       *cu = p->cu;
   5002       ++*idxp;
   5003       return true;
   5004     }
   5005 
   5006   return false;
   5007 }
   5008 
   5009 static void
   5010 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
   5011 			    Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
   5012 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
   5013 {
   5014   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
   5015 			  dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
   5016 
   5017   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
   5018 		   " [ Code]\n"),
   5019 	  elf_ndxscn (scn), section_name (ebl, shdr),
   5020 	  (uint64_t) shdr->sh_offset);
   5021 
   5022   Dwarf_Off offset = 0;
   5023   while (offset < sh_size)
   5024     {
   5025       printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
   5026 	      offset);
   5027 
   5028       while (1)
   5029 	{
   5030 	  size_t length;
   5031 	  Dwarf_Abbrev abbrev;
   5032 
   5033 	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
   5034 	  if (res != 0)
   5035 	    {
   5036 	      if (unlikely (res < 0))
   5037 		{
   5038 		  printf (gettext ("\
   5039  *** error while reading abbreviation: %s\n"),
   5040 			  dwarf_errmsg (-1));
   5041 		  return;
   5042 		}
   5043 
   5044 	      /* This is the NUL byte at the end of the section.  */
   5045 	      ++offset;
   5046 	      break;
   5047 	    }
   5048 
   5049 	  /* We know these calls can never fail.  */
   5050 	  unsigned int code = dwarf_getabbrevcode (&abbrev);
   5051 	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
   5052 	  int has_children = dwarf_abbrevhaschildren (&abbrev);
   5053 
   5054 	  printf (gettext (" [%5u] offset: %" PRId64
   5055 			   ", children: %s, tag: %s\n"),
   5056 		  code, (int64_t) offset,
   5057 		  has_children ? yes_str : no_str,
   5058 		  dwarf_tag_name (tag));
   5059 
   5060 	  size_t cnt = 0;
   5061 	  unsigned int name;
   5062 	  unsigned int form;
   5063 	  Dwarf_Sword data;
   5064 	  Dwarf_Off enoffset;
   5065 	  while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
   5066 					   &data, &enoffset) == 0)
   5067 	    {
   5068 	      printf ("          attr: %s, form: %s",
   5069 		      dwarf_attr_name (name), dwarf_form_name (form));
   5070 	      if (form == DW_FORM_implicit_const)
   5071 		printf (" (%" PRId64 ")", data);
   5072 	      printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
   5073 	      ++cnt;
   5074 	    }
   5075 
   5076 	  offset += length;
   5077 	}
   5078     }
   5079 }
   5080 
   5081 
   5082 static void
   5083 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
   5084 			  Ebl *ebl, GElf_Ehdr *ehdr,
   5085 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
   5086 {
   5087   printf (gettext ("\
   5088 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
   5089 	  elf_ndxscn (scn), section_name (ebl, shdr),
   5090 	  (uint64_t) shdr->sh_offset);
   5091 
   5092   if (shdr->sh_size == 0)
   5093     return;
   5094 
   5095   /* We like to get the section from libdw to make sure they are relocated.  */
   5096   Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
   5097 		    ?: elf_rawdata (scn, NULL));
   5098   if (unlikely (data == NULL))
   5099     {
   5100       error (0, 0, gettext ("cannot get .debug_addr section data: %s"),
   5101 	     elf_errmsg (-1));
   5102       return;
   5103     }
   5104 
   5105   size_t idx = 0;
   5106   sort_listptr (&known_addrbases, "addr_base");
   5107 
   5108   const unsigned char *start = (const unsigned char *) data->d_buf;
   5109   const unsigned char *readp = start;
   5110   const unsigned char *readendp = ((const unsigned char *) data->d_buf
   5111 				   + data->d_size);
   5112 
   5113   while (readp < readendp)
   5114     {
   5115       /* We cannot really know whether or not there is an header.  The
   5116 	 DebugFission extension to DWARF4 doesn't add one.  The DWARF5
   5117 	 .debug_addr variant does.  Whether or not we have an header,
   5118 	 DW_AT_[GNU_]addr_base points at "index 0".  So if the current
   5119 	 offset equals the CU addr_base then we can just start
   5120 	 printing addresses.  If there is no CU with an exact match
   5121 	 then we'll try to parse the header first.  */
   5122       Dwarf_Off off = (Dwarf_Off) (readp
   5123 				   - (const unsigned char *) data->d_buf);
   5124 
   5125       printf ("Table at offset %" PRIx64 " ", off);
   5126 
   5127       struct listptr *listptr = get_listptr (&known_addrbases, idx++);
   5128       const unsigned char *next_unitp;
   5129 
   5130       uint64_t unit_length;
   5131       uint16_t version;
   5132       uint8_t address_size;
   5133       uint8_t segment_size;
   5134       if (listptr == NULL)
   5135 	{
   5136 	  error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
   5137 		 off);
   5138 
   5139 	  /* We will have to assume it is just addresses to the end... */
   5140 	  address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
   5141 	  next_unitp = readendp;
   5142 	  printf ("Unknown CU:\n");
   5143 	}
   5144       else
   5145 	{
   5146 	  Dwarf_Die cudie;
   5147 	  if (dwarf_cu_die (listptr->cu, &cudie,
   5148 			    NULL, NULL, NULL, NULL,
   5149 			    NULL, NULL) == NULL)
   5150 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
   5151 	  else
   5152 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
   5153 
   5154 	  if (listptr->offset == off)
   5155 	    {
   5156 	      address_size = listptr_address_size (listptr);
   5157 	      segment_size = 0;
   5158 	      version = 4;
   5159 
   5160 	      /* The addresses start here, but where do they end?  */
   5161 	      listptr = get_listptr (&known_addrbases, idx);
   5162 	      if (listptr == NULL)
   5163 		next_unitp = readendp;
   5164 	      else if (listptr->cu->version < 5)
   5165 		{
   5166 		  next_unitp = start + listptr->offset;
   5167 		  if (listptr->offset < off || listptr->offset > data->d_size)
   5168 		    {
   5169 		      error (0, 0,
   5170 			     "Warning: Bad address base for next unit at %"
   5171 			     PRIx64, off);
   5172 		      next_unitp = readendp;
   5173 		    }
   5174 		}
   5175 	      else
   5176 		{
   5177 		  /* Tricky, we don't have a header for this unit, but
   5178 		     there is one for the next.  We will have to
   5179 		     "guess" how big it is and subtract it from the
   5180 		     offset (because that points after the header).  */
   5181 		  unsigned int offset_size = listptr_offset_size (listptr);
   5182 		  Dwarf_Off next_off = (listptr->offset
   5183 					- (offset_size == 4 ? 4 : 12) /* len */
   5184 					- 2 /* version */
   5185 					- 1 /* address size */
   5186 					- 1); /* segment selector size */
   5187 		  next_unitp = start + next_off;
   5188 		  if (next_off < off || next_off > data->d_size)
   5189 		    {
   5190 		      error (0, 0,
   5191 			     "Warning: Couldn't calculate .debug_addr "
   5192 			     " unit lenght at %" PRIx64, off);
   5193 		      next_unitp = readendp;
   5194 		    }
   5195 		}
   5196 	      unit_length = (uint64_t) (next_unitp - readp);
   5197 
   5198 	      /* Pretend we have a header.  */
   5199 	      printf ("\n");
   5200 	      printf (gettext (" Length:         %8" PRIu64 "\n"),
   5201 		      unit_length);
   5202 	      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
   5203 	      printf (gettext (" Address size:   %8" PRIu64 "\n"),
   5204 		      (uint64_t) address_size);
   5205 	      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
   5206 		      (uint64_t) segment_size);
   5207 	      printf ("\n");
   5208 	    }
   5209 	  else
   5210 	    {
   5211 	      /* OK, we have to parse an header first.  */
   5212 	      unit_length = read_4ubyte_unaligned_inc (dbg, readp);
   5213 	      if (unlikely (unit_length == 0xffffffff))
   5214 		{
   5215 		  if (unlikely (readp > readendp - 8))
   5216 		    {
   5217 		    invalid_data:
   5218 		      error (0, 0, "Invalid data");
   5219 		      return;
   5220 		    }
   5221 		  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
   5222 		}
   5223 	      printf ("\n");
   5224 	      printf (gettext (" Length:         %8" PRIu64 "\n"),
   5225 		      unit_length);
   5226 
   5227 	      /* We need at least 2-bytes (version) + 1-byte
   5228 		 (addr_size) + 1-byte (segment_size) = 4 bytes to
   5229 		 complete the header.  And this unit cannot go beyond
   5230 		 the section data.  */
   5231 	      if (readp > readendp - 4
   5232 		  || unit_length < 4
   5233 		  || unit_length > (uint64_t) (readendp - readp))
   5234 		goto invalid_data;
   5235 
   5236 	      next_unitp = readp + unit_length;
   5237 
   5238 	      version = read_2ubyte_unaligned_inc (dbg, readp);
   5239 	      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
   5240 
   5241 	      if (version != 5)
   5242 		{
   5243 		  error (0, 0, gettext ("Unknown version"));
   5244 		  goto next_unit;
   5245 		}
   5246 
   5247 	      address_size = *readp++;
   5248 	      printf (gettext (" Address size:   %8" PRIu64 "\n"),
   5249 		      (uint64_t) address_size);
   5250 
   5251 	      if (address_size != 4 && address_size != 8)
   5252 		{
   5253 		  error (0, 0, gettext ("unsupported address size"));
   5254 		  goto next_unit;
   5255 		}
   5256 
   5257 	      segment_size = *readp++;
   5258 	      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
   5259 		      (uint64_t) segment_size);
   5260 	      printf ("\n");
   5261 
   5262 	      if (segment_size != 0)
   5263 		{
   5264 		  error (0, 0, gettext ("unsupported segment size"));
   5265 		  goto next_unit;
   5266 		}
   5267 
   5268 	      if (listptr->offset != (Dwarf_Off) (readp - start))
   5269 		{
   5270 		  error (0, 0, "Address index doesn't start after header");
   5271 		  goto next_unit;
   5272 		}
   5273 	    }
   5274 	}
   5275 
   5276       int digits = 1;
   5277       size_t addresses = (next_unitp - readp) / address_size;
   5278       while (addresses >= 10)
   5279 	{
   5280 	  ++digits;
   5281 	  addresses /= 10;
   5282 	}
   5283 
   5284       unsigned int uidx = 0;
   5285       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
   5286       printf (" Addresses start at offset 0x%zx:\n", index_offset);
   5287       while (readp <= next_unitp - address_size)
   5288 	{
   5289 	  Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
   5290 						     readp);
   5291 	  printf (" [%*u] ", digits, uidx++);
   5292 	  print_dwarf_addr (dwflmod, address_size, addr, addr);
   5293 	  printf ("\n");
   5294 	}
   5295       printf ("\n");
   5296 
   5297       if (readp != next_unitp)
   5298 	error (0, 0, "extra %zd bytes at end of unit",
   5299 	       (size_t) (next_unitp - readp));
   5300 
   5301     next_unit:
   5302       readp = next_unitp;
   5303     }
   5304 }
   5305 
   5306 /* Print content of DWARF .debug_aranges section.  We fortunately do
   5307    not have to know a bit about the structure of the section, libdwarf
   5308    takes care of it.  */
   5309 static void
   5310 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
   5311 			       GElf_Shdr *shdr, Dwarf *dbg)
   5312 {
   5313   Dwarf_Aranges *aranges;
   5314   size_t cnt;
   5315   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
   5316     {
   5317       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
   5318 	     dwarf_errmsg (-1));
   5319       return;
   5320     }
   5321 
   5322   GElf_Shdr glink_mem;
   5323   GElf_Shdr *glink;
   5324   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
   5325   if (glink == NULL)
   5326     {
   5327       error (0, 0, gettext ("invalid sh_link value in section %zu"),
   5328 	     elf_ndxscn (scn));
   5329       return;
   5330     }
   5331 
   5332   printf (ngettext ("\
   5333 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
   5334 		    "\
   5335 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
   5336 		    cnt),
   5337 	  elf_ndxscn (scn), section_name (ebl, shdr),
   5338 	  (uint64_t) shdr->sh_offset, cnt);
   5339 
   5340   /* Compute floor(log16(cnt)).  */
   5341   size_t tmp = cnt;
   5342   int digits = 1;
   5343   while (tmp >= 16)
   5344     {
   5345       ++digits;
   5346       tmp >>= 4;
   5347     }
   5348 
   5349   for (size_t n = 0; n < cnt; ++n)
   5350     {
   5351       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
   5352       if (unlikely (runp == NULL))
   5353 	{
   5354 	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
   5355 	  return;
   5356 	}
   5357 
   5358       Dwarf_Addr start;
   5359       Dwarf_Word length;
   5360       Dwarf_Off offset;
   5361 
   5362       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
   5363 	printf (gettext (" [%*zu] ???\n"), digits, n);
   5364       else
   5365 	printf (gettext (" [%*zu] start: %0#*" PRIx64
   5366 			 ", length: %5" PRIu64 ", CU DIE offset: %6"
   5367 			 PRId64 "\n"),
   5368 		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
   5369 		(uint64_t) start, (uint64_t) length, (int64_t) offset);
   5370     }
   5371 }
   5372 
   5373 
   5374 /* Print content of DWARF .debug_aranges section.  */
   5375 static void
   5376 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
   5377 			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
   5378 			     GElf_Shdr *shdr, Dwarf *dbg)
   5379 {
   5380   if (decodedaranges)
   5381     {
   5382       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
   5383       return;
   5384     }
   5385 
   5386   Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
   5387 		    ?: elf_rawdata (scn, NULL));
   5388 
   5389   if (unlikely (data == NULL))
   5390     {
   5391       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
   5392 	     elf_errmsg (-1));
   5393       return;
   5394     }
   5395 
   5396   printf (gettext ("\
   5397 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
   5398 	  elf_ndxscn (scn), section_name (ebl, shdr),
   5399 	  (uint64_t) shdr->sh_offset);
   5400 
   5401   const unsigned char *readp = data->d_buf;
   5402   const unsigned char *readendp = readp + data->d_size;
   5403 
   5404   while (readp < readendp)
   5405     {
   5406       const unsigned char *hdrstart = readp;
   5407       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
   5408 
   5409       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
   5410       if (readp + 4 > readendp)
   5411 	{
   5412 	invalid_data:
   5413 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
   5414 		 elf_ndxscn (scn), section_name (ebl, shdr));
   5415 	  return;
   5416 	}
   5417 
   5418       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
   5419       unsigned int length_bytes = 4;
   5420       if (length == DWARF3_LENGTH_64_BIT)
   5421 	{
   5422 	  if (readp + 8 > readendp)
   5423 	    goto invalid_data;
   5424 	  length = read_8ubyte_unaligned_inc (dbg, readp);
   5425 	  length_bytes = 8;
   5426 	}
   5427 
   5428       const unsigned char *nexthdr = readp + length;
   5429       printf (gettext ("\n Length:        %6" PRIu64 "\n"),
   5430 	      (uint64_t) length);
   5431 
   5432       if (unlikely (length > (size_t) (readendp - readp)))
   5433 	goto invalid_data;
   5434 
   5435       if (length == 0)
   5436 	continue;
   5437 
   5438       if (readp + 2 > readendp)
   5439 	goto invalid_data;
   5440       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
   5441       printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
   5442 	      version);
   5443       if (version != 2)
   5444 	{
   5445 	  error (0, 0, gettext ("unsupported aranges version"));
   5446 	  goto next_table;
   5447 	}
   5448 
   5449       Dwarf_Word offset;
   5450       if (readp + length_bytes > readendp)
   5451 	goto invalid_data;
   5452       if (length_bytes == 8)
   5453 	offset = read_8ubyte_unaligned_inc (dbg, readp);
   5454       else
   5455 	offset = read_4ubyte_unaligned_inc (dbg, readp);
   5456       printf (gettext (" CU offset:     %6" PRIx64 "\n"),
   5457 	      (uint64_t) offset);
   5458 
   5459       if (readp + 1 > readendp)
   5460 	goto invalid_data;
   5461       unsigned int address_size = *readp++;
   5462       printf (gettext (" Address size:  %6" PRIu64 "\n"),
   5463 	      (uint64_t) address_size);
   5464       if (address_size != 4 && address_size != 8)
   5465 	{
   5466 	  error (0, 0, gettext ("unsupported address size"));
   5467 	  goto next_table;
   5468 	}
   5469 
   5470       if (readp + 1 > readendp)
   5471 	goto invalid_data;
   5472       unsigned int segment_size = *readp++;
   5473       printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
   5474 	      (uint64_t) segment_size);
   5475       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
   5476 	{
   5477 	  error (0, 0, gettext ("unsupported segment size"));
   5478 	  goto next_table;
   5479 	}
   5480 
   5481       /* Round the address to the next multiple of 2*address_size.  */
   5482       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
   5483 		% (2 * address_size));
   5484 
   5485       while (readp < nexthdr)
   5486 	{
   5487 	  Dwarf_Word range_address;
   5488 	  Dwarf_Word range_length;
   5489 	  Dwarf_Word segment = 0;
   5490 	  if (readp + 2 * address_size + segment_size > readendp)
   5491 	    goto invalid_data;
   5492 	  if (address_size == 4)
   5493 	    {
   5494 	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
   5495 	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
   5496 	    }
   5497 	  else
   5498 	    {
   5499 	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
   5500 	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
   5501 	    }
   5502 
   5503 	  if (segment_size == 4)
   5504 	    segment = read_4ubyte_unaligned_inc (dbg, readp);
   5505 	  else if (segment_size == 8)
   5506 	    segment = read_8ubyte_unaligned_inc (dbg, readp);
   5507 
   5508 	  if (range_address == 0 && range_length == 0 && segment == 0)
   5509 	    break;
   5510 
   5511 	  printf ("   ");
   5512 	  print_dwarf_addr (dwflmod, address_size, range_address,
   5513 			    range_address);
   5514 	  printf ("..");
   5515 	  print_dwarf_addr (dwflmod, address_size,
   5516 			    range_address + range_length - 1,
   5517 			    range_length);
   5518 	  if (segment_size != 0)
   5519 	    printf (" (%" PRIx64 ")\n", (uint64_t) segment);
   5520 	  else
   5521 	    printf ("\n");
   5522 	}
   5523 
   5524     next_table:
   5525       if (readp != nexthdr)
   5526 	{
   5527 	  size_t padding = nexthdr - readp;
   5528 	  printf (gettext ("   %zu padding bytes\n"), padding);
   5529 	  readp = nexthdr;
   5530 	}
   5531     }
   5532 }
   5533 
   5534 
   5535 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
   5536 
   5537 /* Returns true and sets cu and cu_base if the given Dwarf is a split
   5538    DWARF (.dwo) file.  */
   5539 static bool
   5540 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
   5541 {
   5542   uint64_t id;
   5543   if (is_split_dwarf (dbg, &id, cu))
   5544     {
   5545       Dwarf_Die cudie;
   5546       if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
   5547 	{
   5548 	  *cu_base = cudie_base (&cudie);
   5549 	  return true;
   5550 	}
   5551     }
   5552   return false;
   5553 }
   5554 
   5555 /* Print content of DWARF .debug_rnglists section.  */
   5556 static void
   5557 print_debug_rnglists_section (Dwfl_Module *dwflmod,
   5558 			      Ebl *ebl,
   5559 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
   5560 			      Elf_Scn *scn, GElf_Shdr *shdr,
   5561 			      Dwarf *dbg __attribute__((unused)))
   5562 {
   5563   printf (gettext ("\
   5564 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
   5565 	  elf_ndxscn (scn), section_name (ebl, shdr),
   5566 	  (uint64_t) shdr->sh_offset);
   5567 
   5568   Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
   5569 		   ?: elf_rawdata (scn, NULL));
   5570   if (unlikely (data == NULL))
   5571     {
   5572       error (0, 0, gettext ("cannot get .debug_rnglists content: %s"),
   5573 	     elf_errmsg (-1));
   5574       return;
   5575     }
   5576 
   5577   /* For the listptr to get the base address/CU.  */
   5578   sort_listptr (&known_rnglistptr, "rnglistptr");
   5579   size_t listptr_idx = 0;
   5580 
   5581   const unsigned char *readp = data->d_buf;
   5582   const unsigned char *const dataend = ((unsigned char *) data->d_buf
   5583 					+ data->d_size);
   5584   while (readp < dataend)
   5585     {
   5586       if (unlikely (readp > dataend - 4))
   5587 	{
   5588 	invalid_data:
   5589 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
   5590 		 elf_ndxscn (scn), section_name (ebl, shdr));
   5591 	  return;
   5592 	}
   5593 
   5594       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
   5595       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
   5596 	      (uint64_t) offset);
   5597 
   5598       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
   5599       unsigned int offset_size = 4;
   5600       if (unlikely (unit_length == 0xffffffff))
   5601 	{
   5602 	  if (unlikely (readp > dataend - 8))
   5603 	    goto invalid_data;
   5604 
   5605 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
   5606 	  offset_size = 8;
   5607 	}
   5608       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
   5609 
   5610       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
   5611 	 bytes to complete the header.  And this unit cannot go beyond
   5612 	 the section data.  */
   5613       if (readp > dataend - 8
   5614 	  || unit_length < 8
   5615 	  || unit_length > (uint64_t) (dataend - readp))
   5616 	goto invalid_data;
   5617 
   5618       const unsigned char *nexthdr = readp + unit_length;
   5619 
   5620       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
   5621       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
   5622 
   5623       if (version != 5)
   5624 	{
   5625 	  error (0, 0, gettext ("Unknown version"));
   5626 	  goto next_table;
   5627 	}
   5628 
   5629       uint8_t address_size = *readp++;
   5630       printf (gettext (" Address size:   %8" PRIu64 "\n"),
   5631 	      (uint64_t) address_size);
   5632 
   5633       if (address_size != 4 && address_size != 8)
   5634 	{
   5635 	  error (0, 0, gettext ("unsupported address size"));
   5636 	  goto next_table;
   5637 	}
   5638 
   5639       uint8_t segment_size = *readp++;
   5640       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
   5641 	      (uint64_t) segment_size);
   5642 
   5643       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
   5644         {
   5645           error (0, 0, gettext ("unsupported segment size"));
   5646           goto next_table;
   5647         }
   5648 
   5649       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
   5650       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
   5651 	      (uint64_t) offset_entry_count);
   5652 
   5653       /* We need the CU that uses this unit to get the initial base address. */
   5654       Dwarf_Addr cu_base = 0;
   5655       struct Dwarf_CU *cu = NULL;
   5656       if (listptr_cu (&known_rnglistptr, &listptr_idx,
   5657 		      (Dwarf_Off) offset,
   5658 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
   5659 		      &cu_base, &cu)
   5660 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
   5661 	{
   5662 	  Dwarf_Die cudie;
   5663 	  if (dwarf_cu_die (cu, &cudie,
   5664 			    NULL, NULL, NULL, NULL,
   5665 			    NULL, NULL) == NULL)
   5666 	    printf (gettext (" Unknown CU base: "));
   5667 	  else
   5668 	    printf (gettext (" CU [%6" PRIx64 "] base: "),
   5669 		    dwarf_dieoffset (&cudie));
   5670 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
   5671 	  printf ("\n");
   5672 	}
   5673       else
   5674 	printf (gettext (" Not associated with a CU.\n"));
   5675 
   5676       printf ("\n");
   5677 
   5678       const unsigned char *offset_array_start = readp;
   5679       if (offset_entry_count > 0)
   5680 	{
   5681 	  uint64_t max_entries = (unit_length - 8) / offset_size;
   5682 	  if (offset_entry_count > max_entries)
   5683 	    {
   5684 	      error (0, 0,
   5685 		     gettext ("too many offset entries for unit length"));
   5686 	      offset_entry_count = max_entries;
   5687 	    }
   5688 
   5689 	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
   5690 		  (uint64_t) (offset_array_start
   5691 			      - (unsigned char *) data->d_buf));
   5692 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
   5693 	    {
   5694 	      printf ("   [%6" PRIu32 "] ", idx);
   5695 	      if (offset_size == 4)
   5696 		{
   5697 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
   5698 		  printf ("0x%" PRIx32 "\n", off);
   5699 		}
   5700 	      else
   5701 		{
   5702 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
   5703 		  printf ("0x%" PRIx64 "\n", off);
   5704 		}
   5705 	    }
   5706 	  printf ("\n");
   5707 	}
   5708 
   5709       Dwarf_Addr base = cu_base;
   5710       bool start_of_list = true;
   5711       while (readp < nexthdr)
   5712 	{
   5713 	  uint8_t kind = *readp++;
   5714 	  uint64_t op1, op2;
   5715 
   5716 	  /* Skip padding.  */
   5717 	  if (start_of_list && kind == DW_RLE_end_of_list)
   5718 	    continue;
   5719 
   5720 	  if (start_of_list)
   5721 	    {
   5722 	      base = cu_base;
   5723 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
   5724 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
   5725 		      (uint64_t) (readp - offset_array_start - 1));
   5726 	      start_of_list = false;
   5727 	    }
   5728 
   5729 	  printf ("    %s", dwarf_range_list_encoding_name (kind));
   5730 	  switch (kind)
   5731 	    {
   5732 	    case DW_RLE_end_of_list:
   5733 	      start_of_list = true;
   5734 	      printf ("\n\n");
   5735 	      break;
   5736 
   5737 	    case DW_RLE_base_addressx:
   5738 	      if ((uint64_t) (nexthdr - readp) < 1)
   5739 		{
   5740 		invalid_range:
   5741 		  error (0, 0, gettext ("invalid range list data"));
   5742 		  goto next_table;
   5743 		}
   5744 	      get_uleb128 (op1, readp, nexthdr);
   5745 	      printf (" %" PRIx64 "\n", op1);
   5746 	      if (! print_unresolved_addresses)
   5747 		{
   5748 		  Dwarf_Addr addr;
   5749 		  if (get_indexed_addr (cu, op1, &addr) != 0)
   5750 		    printf ("      ???\n");
   5751 		  else
   5752 		    {
   5753 		      printf ("      ");
   5754 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
   5755 		      printf ("\n");
   5756 		    }
   5757 		}
   5758 	      break;
   5759 
   5760 	    case DW_RLE_startx_endx:
   5761 	      if ((uint64_t) (nexthdr - readp) < 1)
   5762 		goto invalid_range;
   5763 	      get_uleb128 (op1, readp, nexthdr);
   5764 	      if ((uint64_t) (nexthdr - readp) < 1)
   5765 		goto invalid_range;
   5766 	      get_uleb128 (op2, readp, nexthdr);
   5767 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
   5768 	      if (! print_unresolved_addresses)
   5769 		{
   5770 		  Dwarf_Addr addr1;
   5771 		  Dwarf_Addr addr2;
   5772 		  if (get_indexed_addr (cu, op1, &addr1) != 0
   5773 		      || get_indexed_addr (cu, op2, &addr2) != 0)
   5774 		    {
   5775 		      printf ("      ???..\n");
   5776 		      printf ("      ???\n");
   5777 		    }
   5778 		  else
   5779 		    {
   5780 		      printf ("      ");
   5781 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
   5782 		      printf ("..\n      ");
   5783 		      print_dwarf_addr (dwflmod, address_size,
   5784 					addr2 - 1, addr2);
   5785 		      printf ("\n");
   5786 		    }
   5787 		}
   5788 	      break;
   5789 
   5790 	    case DW_RLE_startx_length:
   5791 	      if ((uint64_t) (nexthdr - readp) < 1)
   5792 		goto invalid_range;
   5793 	      get_uleb128 (op1, readp, nexthdr);
   5794 	      if ((uint64_t) (nexthdr - readp) < 1)
   5795 		goto invalid_range;
   5796 	      get_uleb128 (op2, readp, nexthdr);
   5797 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
   5798 	      if (! print_unresolved_addresses)
   5799 		{
   5800 		  Dwarf_Addr addr1;
   5801 		  Dwarf_Addr addr2;
   5802 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
   5803 		    {
   5804 		      printf ("      ???..\n");
   5805 		      printf ("      ???\n");
   5806 		    }
   5807 		  else
   5808 		    {
   5809 		      addr2 = addr1 + op2;
   5810 		      printf ("      ");
   5811 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
   5812 		      printf ("..\n      ");
   5813 		      print_dwarf_addr (dwflmod, address_size,
   5814 					addr2 - 1, addr2);
   5815 		      printf ("\n");
   5816 		    }
   5817 		}
   5818 	      break;
   5819 
   5820 	    case DW_RLE_offset_pair:
   5821 	      if ((uint64_t) (nexthdr - readp) < 1)
   5822 		goto invalid_range;
   5823 	      get_uleb128 (op1, readp, nexthdr);
   5824 	      if ((uint64_t) (nexthdr - readp) < 1)
   5825 		goto invalid_range;
   5826 	      get_uleb128 (op2, readp, nexthdr);
   5827 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
   5828 	      if (! print_unresolved_addresses)
   5829 		{
   5830 		  op1 += base;
   5831 		  op2 += base;
   5832 		  printf ("      ");
   5833 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
   5834 		  printf ("..\n      ");
   5835 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
   5836 		  printf ("\n");
   5837 		}
   5838 	      break;
   5839 
   5840 	    case DW_RLE_base_address:
   5841 	      if (address_size == 4)
   5842 		{
   5843 		  if ((uint64_t) (nexthdr - readp) < 4)
   5844 		    goto invalid_range;
   5845 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
   5846 		}
   5847 	      else
   5848 		{
   5849 		  if ((uint64_t) (nexthdr - readp) < 8)
   5850 		    goto invalid_range;
   5851 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
   5852 		}
   5853 	      base = op1;
   5854 	      printf (" 0x%" PRIx64 "\n", base);
   5855 	      if (! print_unresolved_addresses)
   5856 		{
   5857 		  printf ("      ");
   5858 		  print_dwarf_addr (dwflmod, address_size, base, base);
   5859 		  printf ("\n");
   5860 		}
   5861 	      break;
   5862 
   5863 	    case DW_RLE_start_end:
   5864 	      if (address_size == 4)
   5865 		{
   5866 		  if ((uint64_t) (nexthdr - readp) < 8)
   5867 		    goto invalid_range;
   5868 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
   5869 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
   5870 		}
   5871 	      else
   5872 		{
   5873 		  if ((uint64_t) (nexthdr - readp) < 16)
   5874 		    goto invalid_range;
   5875 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
   5876 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
   5877 		}
   5878 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
   5879 	      if (! print_unresolved_addresses)
   5880 		{
   5881 		  printf ("      ");
   5882 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
   5883 		  printf ("..\n      ");
   5884 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
   5885 		  printf ("\n");
   5886 		}
   5887 	      break;
   5888 
   5889 	    case DW_RLE_start_length:
   5890 	      if (address_size == 4)
   5891 		{
   5892 		  if ((uint64_t) (nexthdr - readp) < 4)
   5893 		    goto invalid_range;
   5894 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
   5895 		}
   5896 	      else
   5897 		{
   5898 		  if ((uint64_t) (nexthdr - readp) < 8)
   5899 		    goto invalid_range;
   5900 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
   5901 		}
   5902 	      if ((uint64_t) (nexthdr - readp) < 1)
   5903 		goto invalid_range;
   5904 	      get_uleb128 (op2, readp, nexthdr);
   5905 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
   5906 	      if (! print_unresolved_addresses)
   5907 		{
   5908 		  op2 = op1 + op2;
   5909 		  printf ("      ");
   5910 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
   5911 		  printf ("..\n      ");
   5912 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
   5913 		  printf ("\n");
   5914 		}
   5915 	      break;
   5916 
   5917 	    default:
   5918 	      goto invalid_range;
   5919 	    }
   5920 	}
   5921 
   5922     next_table:
   5923       if (readp != nexthdr)
   5924 	{
   5925           size_t padding = nexthdr - readp;
   5926           printf (gettext ("   %zu padding bytes\n\n"), padding);
   5927 	  readp = nexthdr;
   5928 	}
   5929     }
   5930 }
   5931 
   5932 /* Print content of DWARF .debug_ranges section.  */
   5933 static void
   5934 print_debug_ranges_section (Dwfl_Module *dwflmod,
   5935 			    Ebl *ebl, GElf_Ehdr *ehdr,
   5936 			    Elf_Scn *scn, GElf_Shdr *shdr,
   5937 			    Dwarf *dbg)
   5938 {
   5939   Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
   5940 		    ?: elf_rawdata (scn, NULL));
   5941   if (unlikely (data == NULL))
   5942     {
   5943       error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
   5944 	     elf_errmsg (-1));
   5945       return;
   5946     }
   5947 
   5948   printf (gettext ("\
   5949 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
   5950 	  elf_ndxscn (scn), section_name (ebl, shdr),
   5951 	  (uint64_t) shdr->sh_offset);
   5952 
   5953   sort_listptr (&known_rangelistptr, "rangelistptr");
   5954   size_t listptr_idx = 0;
   5955 
   5956   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
   5957 
   5958   bool first = true;
   5959   Dwarf_Addr base = 0;
   5960   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
   5961   unsigned char *readp = data->d_buf;
   5962   Dwarf_CU *last_cu = NULL;
   5963   while (readp < endp)
   5964     {
   5965       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
   5966       Dwarf_CU *cu = last_cu;
   5967 
   5968       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
   5969 				      &address_size, NULL, &base, &cu,
   5970 				      offset, &readp, endp, NULL))
   5971 	continue;
   5972 
   5973       if (last_cu != cu)
   5974 	{
   5975 	  Dwarf_Die cudie;
   5976 	  if (dwarf_cu_die (cu, &cudie,
   5977 			    NULL, NULL, NULL, NULL,
   5978 			    NULL, NULL) == NULL)
   5979 	    printf (gettext ("\n Unknown CU base: "));
   5980 	  else
   5981 	    printf (gettext ("\n CU [%6" PRIx64 "] base: "),
   5982 		    dwarf_dieoffset (&cudie));
   5983 	  print_dwarf_addr (dwflmod, address_size, base, base);
   5984 	  printf ("\n");
   5985 	}
   5986       last_cu = cu;
   5987 
   5988       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
   5989 	{
   5990 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
   5991 	  break;
   5992 	}
   5993 
   5994       Dwarf_Addr begin;
   5995       Dwarf_Addr end;
   5996       if (address_size == 8)
   5997 	{
   5998 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
   5999 	  end = read_8ubyte_unaligned_inc (dbg, readp);
   6000 	}
   6001       else
   6002 	{
   6003 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
   6004 	  end = read_4ubyte_unaligned_inc (dbg, readp);
   6005 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
   6006 	    begin = (Dwarf_Addr) -1l;
   6007 	}
   6008 
   6009       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
   6010 	{
   6011 	  printf (gettext (" [%6tx] base address\n          "), offset);
   6012 	  print_dwarf_addr (dwflmod, address_size, end, end);
   6013 	  printf ("\n");
   6014 	  base = end;
   6015 	}
   6016       else if (begin == 0 && end == 0) /* End of list entry.  */
   6017 	{
   6018 	  if (first)
   6019 	    printf (gettext (" [%6tx] empty list\n"), offset);
   6020 	  first = true;
   6021 	}
   6022       else
   6023 	{
   6024 	  /* We have an address range entry.  */
   6025 	  if (first)		/* First address range entry in a list.  */
   6026 	    printf (" [%6tx] ", offset);
   6027 	  else
   6028 	    printf ("          ");
   6029 
   6030 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
   6031 	  if (! print_unresolved_addresses)
   6032 	    {
   6033 	      printf ("          ");
   6034 	      print_dwarf_addr (dwflmod, address_size, base + begin,
   6035 			        base + begin);
   6036 	      printf ("..\n          ");
   6037 	      print_dwarf_addr (dwflmod, address_size,
   6038 				base + end - 1, base + end);
   6039 	      printf ("\n");
   6040 	    }
   6041 
   6042 	  first = false;
   6043 	}
   6044     }
   6045 }
   6046 
   6047 #define REGNAMESZ 16
   6048 static const char *
   6049 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
   6050 	       char name[REGNAMESZ], int *bits, int *type)
   6051 {
   6052   const char *set;
   6053   const char *pfx;
   6054   int ignore;
   6055   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
   6056 				 bits ?: &ignore, type ?: &ignore);
   6057   if (n <= 0)
   6058     {
   6059       if (loc != NULL)
   6060 	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
   6061       else
   6062 	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
   6063       if (bits != NULL)
   6064 	*bits = loc != NULL ? loc->bits : 0;
   6065       if (type != NULL)
   6066 	*type = DW_ATE_unsigned;
   6067       set = "??? unrecognized";
   6068     }
   6069   else
   6070     {
   6071       if (bits != NULL && *bits <= 0)
   6072 	*bits = loc != NULL ? loc->bits : 0;
   6073       if (type != NULL && *type == DW_ATE_void)
   6074 	*type = DW_ATE_unsigned;
   6075 
   6076     }
   6077   return set;
   6078 }
   6079 
   6080 static const unsigned char *
   6081 read_encoded (unsigned int encoding, const unsigned char *readp,
   6082 	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
   6083 {
   6084   if ((encoding & 0xf) == DW_EH_PE_absptr)
   6085     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
   6086       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
   6087 
   6088   switch (encoding & 0xf)
   6089     {
   6090     case DW_EH_PE_uleb128:
   6091       get_uleb128 (*res, readp, endp);
   6092       break;
   6093     case DW_EH_PE_sleb128:
   6094       get_sleb128 (*res, readp, endp);
   6095       break;
   6096     case DW_EH_PE_udata2:
   6097       if (readp + 2 > endp)
   6098 	goto invalid;
   6099       *res = read_2ubyte_unaligned_inc (dbg, readp);
   6100       break;
   6101     case DW_EH_PE_udata4:
   6102       if (readp + 4 > endp)
   6103 	goto invalid;
   6104       *res = read_4ubyte_unaligned_inc (dbg, readp);
   6105       break;
   6106     case DW_EH_PE_udata8:
   6107       if (readp + 8 > endp)
   6108 	goto invalid;
   6109       *res = read_8ubyte_unaligned_inc (dbg, readp);
   6110       break;
   6111     case DW_EH_PE_sdata2:
   6112       if (readp + 2 > endp)
   6113 	goto invalid;
   6114       *res = read_2sbyte_unaligned_inc (dbg, readp);
   6115       break;
   6116     case DW_EH_PE_sdata4:
   6117       if (readp + 4 > endp)
   6118 	goto invalid;
   6119       *res = read_4sbyte_unaligned_inc (dbg, readp);
   6120       break;
   6121     case DW_EH_PE_sdata8:
   6122       if (readp + 8 > endp)
   6123 	goto invalid;
   6124       *res = read_8sbyte_unaligned_inc (dbg, readp);
   6125       break;
   6126     default:
   6127     invalid:
   6128       error (1, 0,
   6129 	     gettext ("invalid encoding"));
   6130     }
   6131 
   6132   return readp;
   6133 }
   6134 
   6135 
   6136 static void
   6137 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
   6138 		   Dwarf_Word vma_base, unsigned int code_align,
   6139 		   int data_align,
   6140 		   unsigned int version, unsigned int ptr_size,
   6141 		   unsigned int encoding,
   6142 		   Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
   6143 {
   6144   char regnamebuf[REGNAMESZ];
   6145   const char *regname (unsigned int regno)
   6146   {
   6147     register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
   6148     return regnamebuf;
   6149   }
   6150 
   6151   puts ("\n   Program:");
   6152   Dwarf_Word pc = vma_base;
   6153   while (readp < endp)
   6154     {
   6155       unsigned int opcode = *readp++;
   6156 
   6157       if (opcode < DW_CFA_advance_loc)
   6158 	/* Extended opcode.  */
   6159 	switch (opcode)
   6160 	  {
   6161 	    uint64_t op1;
   6162 	    int64_t sop1;
   6163 	    uint64_t op2;
   6164 	    int64_t sop2;
   6165 
   6166 	  case DW_CFA_nop:
   6167 	    puts ("     nop");
   6168 	    break;
   6169 	  case DW_CFA_set_loc:
   6170 	    if ((uint64_t) (endp - readp) < 1)
   6171 	      goto invalid;
   6172 	    readp = read_encoded (encoding, readp, endp, &op1, dbg);
   6173 	    printf ("     set_loc %#" PRIx64 " to %#" PRIx64 "\n",
   6174 		    op1, pc = vma_base + op1);
   6175 	    break;
   6176 	  case DW_CFA_advance_loc1:
   6177 	    if ((uint64_t) (endp - readp) < 1)
   6178 	      goto invalid;
   6179 	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
   6180 		    *readp, pc += *readp * code_align);
   6181 	    ++readp;
   6182 	    break;
   6183 	  case DW_CFA_advance_loc2:
   6184 	    if ((uint64_t) (endp - readp) < 2)
   6185 	      goto invalid;
   6186 	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
   6187 	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
   6188 		    op1, pc += op1 * code_align);
   6189 	    break;
   6190 	  case DW_CFA_advance_loc4:
   6191 	    if ((uint64_t) (endp - readp) < 4)
   6192 	      goto invalid;
   6193 	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
   6194 	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
   6195 		    op1, pc += op1 * code_align);
   6196 	    break;
   6197 	  case DW_CFA_offset_extended:
   6198 	    if ((uint64_t) (endp - readp) < 1)
   6199 	      goto invalid;
   6200 	    get_uleb128 (op1, readp, endp);
   6201 	    if ((uint64_t) (endp - readp) < 1)
   6202 	      goto invalid;
   6203 	    get_uleb128 (op2, readp, endp);
   6204 	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
   6205 		    "\n",
   6206 		    op1, regname (op1), op2 * data_align);
   6207 	    break;
   6208 	  case DW_CFA_restore_extended:
   6209 	    if ((uint64_t) (endp - readp) < 1)
   6210 	      goto invalid;
   6211 	    get_uleb128 (op1, readp, endp);
   6212 	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
   6213 		    op1, regname (op1));
   6214 	    break;
   6215 	  case DW_CFA_undefined:
   6216 	    if ((uint64_t) (endp - readp) < 1)
   6217 	      goto invalid;
   6218 	    get_uleb128 (op1, readp, endp);
   6219 	    printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
   6220 	    break;
   6221 	  case DW_CFA_same_value:
   6222 	    if ((uint64_t) (endp - readp) < 1)
   6223 	      goto invalid;
   6224 	    get_uleb128 (op1, readp, endp);
   6225 	    printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
   6226 	    break;
   6227 	  case DW_CFA_register:
   6228 	    if ((uint64_t) (endp - readp) < 1)
   6229 	      goto invalid;
   6230 	    get_uleb128 (op1, readp, endp);
   6231 	    if ((uint64_t) (endp - readp) < 1)
   6232 	      goto invalid;
   6233 	    get_uleb128 (op2, readp, endp);
   6234 	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
   6235 		    op1, regname (op1), op2, regname (op2));
   6236 	    break;
   6237 	  case DW_CFA_remember_state:
   6238 	    puts ("     remember_state");
   6239 	    break;
   6240 	  case DW_CFA_restore_state:
   6241 	    puts ("     restore_state");
   6242 	    break;
   6243 	  case DW_CFA_def_cfa:
   6244 	    if ((uint64_t) (endp - readp) < 1)
   6245 	      goto invalid;
   6246 	    get_uleb128 (op1, readp, endp);
   6247 	    if ((uint64_t) (endp - readp) < 1)
   6248 	      goto invalid;
   6249 	    get_uleb128 (op2, readp, endp);
   6250 	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
   6251 		    op1, regname (op1), op2);
   6252 	    break;
   6253 	  case DW_CFA_def_cfa_register:
   6254 	    if ((uint64_t) (endp - readp) < 1)
   6255 	      goto invalid;
   6256 	    get_uleb128 (op1, readp, endp);
   6257 	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
   6258 		    op1, regname (op1));
   6259 	    break;
   6260 	  case DW_CFA_def_cfa_offset:
   6261 	    if ((uint64_t) (endp - readp) < 1)
   6262 	      goto invalid;
   6263 	    get_uleb128 (op1, readp, endp);
   6264 	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
   6265 	    break;
   6266 	  case DW_CFA_def_cfa_expression:
   6267 	    if ((uint64_t) (endp - readp) < 1)
   6268 	      goto invalid;
   6269 	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
   6270 	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
   6271 	    if ((uint64_t) (endp - readp) < op1)
   6272 	      {
   6273 	    invalid:
   6274 	        fputs (gettext ("         <INVALID DATA>\n"), stdout);
   6275 		return;
   6276 	      }
   6277 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
   6278 		       op1, readp);
   6279 	    readp += op1;
   6280 	    break;
   6281 	  case DW_CFA_expression:
   6282 	    if ((uint64_t) (endp - readp) < 1)
   6283 	      goto invalid;
   6284 	    get_uleb128 (op1, readp, endp);
   6285 	    if ((uint64_t) (endp - readp) < 1)
   6286 	      goto invalid;
   6287 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
   6288 	    printf ("     expression r%" PRIu64 " (%s) \n",
   6289 		    op1, regname (op1));
   6290 	    if ((uint64_t) (endp - readp) < op2)
   6291 	      goto invalid;
   6292 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
   6293 		       op2, readp);
   6294 	    readp += op2;
   6295 	    break;
   6296 	  case DW_CFA_offset_extended_sf:
   6297 	    if ((uint64_t) (endp - readp) < 1)
   6298 	      goto invalid;
   6299 	    get_uleb128 (op1, readp, endp);
   6300 	    if ((uint64_t) (endp - readp) < 1)
   6301 	      goto invalid;
   6302 	    get_sleb128 (sop2, readp, endp);
   6303 	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
   6304 		    PRId64 "\n",
   6305 		    op1, regname (op1), sop2 * data_align);
   6306 	    break;
   6307 	  case DW_CFA_def_cfa_sf:
   6308 	    if ((uint64_t) (endp - readp) < 1)
   6309 	      goto invalid;
   6310 	    get_uleb128 (op1, readp, endp);
   6311 	    if ((uint64_t) (endp - readp) < 1)
   6312 	      goto invalid;
   6313 	    get_sleb128 (sop2, readp, endp);
   6314 	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
   6315 		    op1, regname (op1), sop2 * data_align);
   6316 	    break;
   6317 	  case DW_CFA_def_cfa_offset_sf:
   6318 	    if ((uint64_t) (endp - readp) < 1)
   6319 	      goto invalid;
   6320 	    get_sleb128 (sop1, readp, endp);
   6321 	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
   6322 	    break;
   6323 	  case DW_CFA_val_offset:
   6324 	    if ((uint64_t) (endp - readp) < 1)
   6325 	      goto invalid;
   6326 	    get_uleb128 (op1, readp, endp);
   6327 	    if ((uint64_t) (endp - readp) < 1)
   6328 	      goto invalid;
   6329 	    get_uleb128 (op2, readp, endp);
   6330 	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
   6331 		    op1, op2 * data_align);
   6332 	    break;
   6333 	  case DW_CFA_val_offset_sf:
   6334 	    if ((uint64_t) (endp - readp) < 1)
   6335 	      goto invalid;
   6336 	    get_uleb128 (op1, readp, endp);
   6337 	    if ((uint64_t) (endp - readp) < 1)
   6338 	      goto invalid;
   6339 	    get_sleb128 (sop2, readp, endp);
   6340 	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
   6341 		    op1, sop2 * data_align);
   6342 	    break;
   6343 	  case DW_CFA_val_expression:
   6344 	    if ((uint64_t) (endp - readp) < 1)
   6345 	      goto invalid;
   6346 	    get_uleb128 (op1, readp, endp);
   6347 	    if ((uint64_t) (endp - readp) < 1)
   6348 	      goto invalid;
   6349 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
   6350 	    printf ("     val_expression r%" PRIu64 " (%s)\n",
   6351 		    op1, regname (op1));
   6352 	    if ((uint64_t) (endp - readp) < op2)
   6353 	      goto invalid;
   6354 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
   6355 		       NULL, op2, readp);
   6356 	    readp += op2;
   6357 	    break;
   6358 	  case DW_CFA_MIPS_advance_loc8:
   6359 	    if ((uint64_t) (endp - readp) < 8)
   6360 	      goto invalid;
   6361 	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
   6362 	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
   6363 		    op1, pc += op1 * code_align);
   6364 	    break;
   6365 	  case DW_CFA_GNU_window_save:
   6366 	    puts ("     GNU_window_save");
   6367 	    break;
   6368 	  case DW_CFA_GNU_args_size:
   6369 	    if ((uint64_t) (endp - readp) < 1)
   6370 	      goto invalid;
   6371 	    get_uleb128 (op1, readp, endp);
   6372 	    printf ("     args_size %" PRIu64 "\n", op1);
   6373 	    break;
   6374 	  default:
   6375 	    printf ("     ??? (%u)\n", opcode);
   6376 	    break;
   6377 	  }
   6378       else if (opcode < DW_CFA_offset)
   6379 	printf ("     advance_loc %u to %#" PRIx64 "\n",
   6380 		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
   6381       else if (opcode < DW_CFA_restore)
   6382 	{
   6383 	  uint64_t offset;
   6384 	  if ((uint64_t) (endp - readp) < 1)
   6385 	    goto invalid;
   6386 	  get_uleb128 (offset, readp, endp);
   6387 	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
   6388 		  opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
   6389 	}
   6390       else
   6391 	printf ("     restore r%u (%s)\n",
   6392 		opcode & 0x3f, regname (opcode & 0x3f));
   6393     }
   6394 }
   6395 
   6396 
   6397 static unsigned int
   6398 encoded_ptr_size (int encoding, unsigned int ptr_size)
   6399 {
   6400   switch (encoding & 7)
   6401     {
   6402     case DW_EH_PE_udata4:
   6403       return 4;
   6404     case DW_EH_PE_udata8:
   6405       return 8;
   6406     case 0:
   6407       return ptr_size;
   6408     }
   6409 
   6410   fprintf (stderr, "Unsupported pointer encoding: %#x, "
   6411 	   "assuming pointer size of %d.\n", encoding, ptr_size);
   6412   return ptr_size;
   6413 }
   6414 
   6415 
   6416 static unsigned int
   6417 print_encoding (unsigned int val)
   6418 {
   6419   switch (val & 0xf)
   6420     {
   6421     case DW_EH_PE_absptr:
   6422       fputs ("absptr", stdout);
   6423       break;
   6424     case DW_EH_PE_uleb128:
   6425       fputs ("uleb128", stdout);
   6426       break;
   6427     case DW_EH_PE_udata2:
   6428       fputs ("udata2", stdout);
   6429       break;
   6430     case DW_EH_PE_udata4:
   6431       fputs ("udata4", stdout);
   6432       break;
   6433     case DW_EH_PE_udata8:
   6434       fputs ("udata8", stdout);
   6435       break;
   6436     case DW_EH_PE_sleb128:
   6437       fputs ("sleb128", stdout);
   6438       break;
   6439     case DW_EH_PE_sdata2:
   6440       fputs ("sdata2", stdout);
   6441       break;
   6442     case DW_EH_PE_sdata4:
   6443       fputs ("sdata4", stdout);
   6444       break;
   6445     case DW_EH_PE_sdata8:
   6446       fputs ("sdata8", stdout);
   6447       break;
   6448     default:
   6449       /* We did not use any of the bits after all.  */
   6450       return val;
   6451     }
   6452 
   6453   return val & ~0xf;
   6454 }
   6455 
   6456 
   6457 static unsigned int
   6458 print_relinfo (unsigned int val)
   6459 {
   6460   switch (val & 0x70)
   6461     {
   6462     case DW_EH_PE_pcrel:
   6463       fputs ("pcrel", stdout);
   6464       break;
   6465     case DW_EH_PE_textrel:
   6466       fputs ("textrel", stdout);
   6467       break;
   6468     case DW_EH_PE_datarel:
   6469       fputs ("datarel", stdout);
   6470       break;
   6471     case DW_EH_PE_funcrel:
   6472       fputs ("funcrel", stdout);
   6473       break;
   6474     case DW_EH_PE_aligned:
   6475       fputs ("aligned", stdout);
   6476       break;
   6477     default:
   6478       return val;
   6479     }
   6480 
   6481   return val & ~0x70;
   6482 }
   6483 
   6484 
   6485 static void
   6486 print_encoding_base (const char *pfx, unsigned int fde_encoding)
   6487 {
   6488   printf ("(%s", pfx);
   6489 
   6490   if (fde_encoding == DW_EH_PE_omit)
   6491     puts ("omit)");
   6492   else
   6493     {
   6494       unsigned int w = fde_encoding;
   6495 
   6496       w = print_encoding (w);
   6497 
   6498       if (w & 0x70)
   6499 	{
   6500 	  if (w != fde_encoding)
   6501 	    fputc_unlocked (' ', stdout);
   6502 
   6503 	  w = print_relinfo (w);
   6504 	}
   6505 
   6506       if (w != 0)
   6507 	printf ("%s%x", w != fde_encoding ? " " : "", w);
   6508 
   6509       puts (")");
   6510     }
   6511 }
   6512 
   6513 
   6514 static void
   6515 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
   6516 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
   6517 {
   6518   size_t shstrndx;
   6519   /* We know this call will succeed since it did in the caller.  */
   6520   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
   6521   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
   6522 
   6523   /* Needed if we find PC-relative addresses.  */
   6524   GElf_Addr bias;
   6525   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
   6526     {
   6527       error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
   6528       return;
   6529     }
   6530 
   6531   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
   6532   Elf_Data *data = (is_eh_frame
   6533 		    ? elf_rawdata (scn, NULL)
   6534 		    : (dbg->sectiondata[IDX_debug_frame]
   6535 		       ?: elf_rawdata (scn, NULL)));
   6536 
   6537   if (unlikely (data == NULL))
   6538     {
   6539       error (0, 0, gettext ("cannot get %s content: %s"),
   6540 	     scnname, elf_errmsg (-1));
   6541       return;
   6542     }
   6543 
   6544   if (is_eh_frame)
   6545     printf (gettext ("\
   6546 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
   6547 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
   6548   else
   6549     printf (gettext ("\
   6550 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
   6551 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
   6552 
   6553   struct cieinfo
   6554   {
   6555     ptrdiff_t cie_offset;
   6556     const char *augmentation;
   6557     unsigned int code_alignment_factor;
   6558     unsigned int data_alignment_factor;
   6559     uint8_t address_size;
   6560     uint8_t fde_encoding;
   6561     uint8_t lsda_encoding;
   6562     struct cieinfo *next;
   6563   } *cies = NULL;
   6564 
   6565   const unsigned char *readp = data->d_buf;
   6566   const unsigned char *const dataend = ((unsigned char *) data->d_buf
   6567 					+ data->d_size);
   6568   while (readp < dataend)
   6569     {
   6570       if (unlikely (readp + 4 > dataend))
   6571 	{
   6572 	invalid_data:
   6573 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
   6574 		     elf_ndxscn (scn), scnname);
   6575 	      return;
   6576 	}
   6577 
   6578       /* At the beginning there must be a CIE.  There can be multiple,
   6579 	 hence we test tis in a loop.  */
   6580       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
   6581 
   6582       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
   6583       unsigned int length = 4;
   6584       if (unlikely (unit_length == 0xffffffff))
   6585 	{
   6586 	  if (unlikely (readp + 8 > dataend))
   6587 	    goto invalid_data;
   6588 
   6589 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
   6590 	  length = 8;
   6591 	}
   6592 
   6593       if (unlikely (unit_length == 0))
   6594 	{
   6595 	  printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
   6596 	  continue;
   6597 	}
   6598 
   6599       Dwarf_Word maxsize = dataend - readp;
   6600       if (unlikely (unit_length > maxsize))
   6601 	goto invalid_data;
   6602 
   6603       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
   6604 
   6605       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
   6606       const unsigned char *const cieend = readp + unit_length;
   6607       if (unlikely (cieend > dataend))
   6608 	goto invalid_data;
   6609 
   6610       Dwarf_Off cie_id;
   6611       if (length == 4)
   6612 	{
   6613 	  if (unlikely (cieend - readp < 4))
   6614 	    goto invalid_data;
   6615 	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
   6616 	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
   6617 	    cie_id = DW_CIE_ID_64;
   6618 	}
   6619       else
   6620 	{
   6621 	  if (unlikely (cieend - readp < 8))
   6622 	    goto invalid_data;
   6623 	  cie_id = read_8ubyte_unaligned_inc (dbg, readp);
   6624 	}
   6625 
   6626       uint_fast8_t version = 2;
   6627       unsigned int code_alignment_factor;
   6628       int data_alignment_factor;
   6629       unsigned int fde_encoding = 0;
   6630       unsigned int lsda_encoding = 0;
   6631       Dwarf_Word initial_location = 0;
   6632       Dwarf_Word vma_base = 0;
   6633 
   6634       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
   6635 	{
   6636 	  if (unlikely (cieend - readp < 2))
   6637 	    goto invalid_data;
   6638 	  version = *readp++;
   6639 	  const char *const augmentation = (const char *) readp;
   6640 	  readp = memchr (readp, '\0', cieend - readp);
   6641 	  if (unlikely (readp == NULL))
   6642 	    goto invalid_data;
   6643 	  ++readp;
   6644 
   6645 	  uint_fast8_t segment_size = 0;
   6646 	  if (version >= 4)
   6647 	    {
   6648 	      if (cieend - readp < 5)
   6649 		goto invalid_data;
   6650 	      ptr_size = *readp++;
   6651 	      segment_size = *readp++;
   6652 	    }
   6653 
   6654 	  if (cieend - readp < 1)
   6655 	    goto invalid_data;
   6656 	  get_uleb128 (code_alignment_factor, readp, cieend);
   6657 	  if (cieend - readp < 1)
   6658 	    goto invalid_data;
   6659 	  get_sleb128 (data_alignment_factor, readp, cieend);
   6660 
   6661 	  /* In some variant for unwind data there is another field.  */
   6662 	  if (strcmp (augmentation, "eh") == 0)
   6663 	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
   6664 
   6665 	  unsigned int return_address_register;
   6666 	  if (cieend - readp < 1)
   6667 	    goto invalid_data;
   6668 	  if (unlikely (version == 1))
   6669 	    return_address_register = *readp++;
   6670 	  else
   6671 	    get_uleb128 (return_address_register, readp, cieend);
   6672 
   6673 	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
   6674 		  "   CIE_id:                   %" PRIu64 "\n"
   6675 		  "   version:                  %u\n"
   6676 		  "   augmentation:             \"%s\"\n",
   6677 		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
   6678 		  version, augmentation);
   6679 	  if (version >= 4)
   6680 	    printf ("   address_size:             %u\n"
   6681 		    "   segment_size:             %u\n",
   6682 		    ptr_size, segment_size);
   6683 	  printf ("   code_alignment_factor:    %u\n"
   6684 		  "   data_alignment_factor:    %d\n"
   6685 		  "   return_address_register:  %u\n",
   6686 		  code_alignment_factor,
   6687 		  data_alignment_factor, return_address_register);
   6688 
   6689 	  if (augmentation[0] == 'z')
   6690 	    {
   6691 	      unsigned int augmentationlen;
   6692 	      get_uleb128 (augmentationlen, readp, cieend);
   6693 
   6694 	      if (augmentationlen > (size_t) (cieend - readp))
   6695 		{
   6696 		  error (0, 0, gettext ("invalid augmentation length"));
   6697 		  readp = cieend;
   6698 		  continue;
   6699 		}
   6700 
   6701 	      const char *hdr = "Augmentation data:";
   6702 	      const char *cp = augmentation + 1;
   6703 	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
   6704 		{
   6705 		  printf ("   %-26s%#x ", hdr, *readp);
   6706 		  hdr = "";
   6707 
   6708 		  if (*cp == 'R')
   6709 		    {
   6710 		      fde_encoding = *readp++;
   6711 		      print_encoding_base (gettext ("FDE address encoding: "),
   6712 					   fde_encoding);
   6713 		    }
   6714 		  else if (*cp == 'L')
   6715 		    {
   6716 		      lsda_encoding = *readp++;
   6717 		      print_encoding_base (gettext ("LSDA pointer encoding: "),
   6718 					   lsda_encoding);
   6719 		    }
   6720 		  else if (*cp == 'P')
   6721 		    {
   6722 		      /* Personality.  This field usually has a relocation
   6723 			 attached pointing to __gcc_personality_v0.  */
   6724 		      const unsigned char *startp = readp;
   6725 		      unsigned int encoding = *readp++;
   6726 		      uint64_t val = 0;
   6727 		      readp = read_encoded (encoding, readp,
   6728 					    readp - 1 + augmentationlen,
   6729 					    &val, dbg);
   6730 
   6731 		      while (++startp < readp)
   6732 			printf ("%#x ", *startp);
   6733 
   6734 		      putchar ('(');
   6735 		      print_encoding (encoding);
   6736 		      putchar (' ');
   6737 		      switch (encoding & 0xf)
   6738 			{
   6739 			case DW_EH_PE_sleb128:
   6740 			case DW_EH_PE_sdata2:
   6741 			case DW_EH_PE_sdata4:
   6742 			  printf ("%" PRId64 ")\n", val);
   6743 			  break;
   6744 			default:
   6745 			  printf ("%#" PRIx64 ")\n", val);
   6746 			  break;
   6747 			}
   6748 		    }
   6749 		  else
   6750 		    printf ("(%x)\n", *readp++);
   6751 
   6752 		  ++cp;
   6753 		}
   6754 	    }
   6755 
   6756 	  if (likely (ptr_size == 4 || ptr_size == 8))
   6757 	    {
   6758 	      struct cieinfo *newp = alloca (sizeof (*newp));
   6759 	      newp->cie_offset = offset;
   6760 	      newp->augmentation = augmentation;
   6761 	      newp->fde_encoding = fde_encoding;
   6762 	      newp->lsda_encoding = lsda_encoding;
   6763 	      newp->address_size = ptr_size;
   6764 	      newp->code_alignment_factor = code_alignment_factor;
   6765 	      newp->data_alignment_factor = data_alignment_factor;
   6766 	      newp->next = cies;
   6767 	      cies = newp;
   6768 	    }
   6769 	}
   6770       else
   6771 	{
   6772 	  struct cieinfo *cie = cies;
   6773 	  while (cie != NULL)
   6774 	    if (is_eh_frame
   6775 		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
   6776 		: cie_id == (Dwarf_Off) cie->cie_offset)
   6777 	      break;
   6778 	    else
   6779 	      cie = cie->next;
   6780 	  if (unlikely (cie == NULL))
   6781 	    {
   6782 	      puts ("invalid CIE reference in FDE");
   6783 	      return;
   6784 	    }
   6785 
   6786 	  /* Initialize from CIE data.  */
   6787 	  fde_encoding = cie->fde_encoding;
   6788 	  lsda_encoding = cie->lsda_encoding;
   6789 	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
   6790 	  code_alignment_factor = cie->code_alignment_factor;
   6791 	  data_alignment_factor = cie->data_alignment_factor;
   6792 
   6793 	  const unsigned char *base = readp;
   6794 	  // XXX There are sometimes relocations for this value
   6795 	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
   6796 	  Dwarf_Word address_range
   6797 	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
   6798 
   6799 	  /* pcrel for an FDE address is relative to the runtime
   6800 	     address of the start_address field itself.  Sign extend
   6801 	     if necessary to make sure the calculation is done on the
   6802 	     full 64 bit address even when initial_location only holds
   6803 	     the lower 32 bits.  */
   6804 	  Dwarf_Addr pc_start = initial_location;
   6805 	  if (ptr_size == 4)
   6806 	    pc_start = (uint64_t) (int32_t) pc_start;
   6807 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
   6808 	    pc_start += ((uint64_t) shdr->sh_addr
   6809 			 + (base - (const unsigned char *) data->d_buf)
   6810 			 - bias);
   6811 
   6812 	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
   6813 		  "   CIE_pointer:              %" PRIu64 "\n"
   6814 		  "   initial_location:         ",
   6815 		  offset, (uint64_t) unit_length,
   6816 		  cie->cie_offset, (uint64_t) cie_id);
   6817 	  print_dwarf_addr (dwflmod, cie->address_size,
   6818 			    pc_start, initial_location);
   6819 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
   6820 	    {
   6821 	      vma_base = (((uint64_t) shdr->sh_offset
   6822 			   + (base - (const unsigned char *) data->d_buf)
   6823 			   + (uint64_t) initial_location)
   6824 			  & (ptr_size == 4
   6825 			     ? UINT64_C (0xffffffff)
   6826 			     : UINT64_C (0xffffffffffffffff)));
   6827 	      printf (gettext (" (offset: %#" PRIx64 ")"),
   6828 		      (uint64_t) vma_base);
   6829 	    }
   6830 
   6831 	  printf ("\n   address_range:            %#" PRIx64,
   6832 		  (uint64_t) address_range);
   6833 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
   6834 	    printf (gettext (" (end offset: %#" PRIx64 ")"),
   6835 		    ((uint64_t) vma_base + (uint64_t) address_range)
   6836 		    & (ptr_size == 4
   6837 		       ? UINT64_C (0xffffffff)
   6838 		       : UINT64_C (0xffffffffffffffff)));
   6839 	  putchar ('\n');
   6840 
   6841 	  if (cie->augmentation[0] == 'z')
   6842 	    {
   6843 	      unsigned int augmentationlen;
   6844 	      if (cieend - readp < 1)
   6845 		goto invalid_data;
   6846 	      get_uleb128 (augmentationlen, readp, cieend);
   6847 
   6848 	      if (augmentationlen > (size_t) (cieend - readp))
   6849 		{
   6850 		  error (0, 0, gettext ("invalid augmentation length"));
   6851 		  readp = cieend;
   6852 		  continue;
   6853 		}
   6854 
   6855 	      if (augmentationlen > 0)
   6856 		{
   6857 		  const char *hdr = "Augmentation data:";
   6858 		  const char *cp = cie->augmentation + 1;
   6859 		  unsigned int u = 0;
   6860 		  while (*cp != '\0'
   6861 			 && cp < cie->augmentation + augmentationlen + 1)
   6862 		    {
   6863 		      if (*cp == 'L')
   6864 			{
   6865 			  uint64_t lsda_pointer;
   6866 			  const unsigned char *p
   6867 			    = read_encoded (lsda_encoding, &readp[u],
   6868 					    &readp[augmentationlen],
   6869 					    &lsda_pointer, dbg);
   6870 			  u = p - readp;
   6871 			  printf (gettext ("\
   6872    %-26sLSDA pointer: %#" PRIx64 "\n"),
   6873 				  hdr, lsda_pointer);
   6874 			  hdr = "";
   6875 			}
   6876 		      ++cp;
   6877 		    }
   6878 
   6879 		  while (u < augmentationlen)
   6880 		    {
   6881 		      printf ("   %-26s%#x\n", hdr, readp[u++]);
   6882 		      hdr = "";
   6883 		    }
   6884 		}
   6885 
   6886 	      readp += augmentationlen;
   6887 	    }
   6888 	}
   6889 
   6890       /* Handle the initialization instructions.  */
   6891       if (ptr_size != 4 && ptr_size !=8)
   6892 	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
   6893       else
   6894 	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
   6895 			   data_alignment_factor, version, ptr_size,
   6896 			   fde_encoding, dwflmod, ebl, dbg);
   6897       readp = cieend;
   6898     }
   6899 }
   6900 
   6901 
   6902 /* Returns the signedness (or false if it cannot be determined) and
   6903    the byte size (or zero if it cannot be gotten) of the given DIE
   6904    DW_AT_type attribute.  Uses dwarf_peel_type and dwarf_aggregate_size.  */
   6905 static void
   6906 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
   6907 {
   6908   Dwarf_Attribute attr;
   6909   Dwarf_Die type;
   6910 
   6911   *bytes = 0;
   6912   *is_signed = false;
   6913 
   6914   if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
   6915 								DW_AT_type,
   6916 								&attr), &type),
   6917 		       &type) == 0)
   6918     {
   6919       Dwarf_Word val;
   6920       *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
   6921 						 &attr), &val) == 0
   6922 		    && (val == DW_ATE_signed || val == DW_ATE_signed_char));
   6923 
   6924       if (dwarf_aggregate_size (&type, &val) == 0)
   6925 	*bytes = val;
   6926     }
   6927 }
   6928 
   6929 struct attrcb_args
   6930 {
   6931   Dwfl_Module *dwflmod;
   6932   Dwarf *dbg;
   6933   Dwarf_Die *die;
   6934   int level;
   6935   bool silent;
   6936   bool is_split;
   6937   unsigned int version;
   6938   unsigned int addrsize;
   6939   unsigned int offset_size;
   6940   struct Dwarf_CU *cu;
   6941 };
   6942 
   6943 
   6944 static int
   6945 attr_callback (Dwarf_Attribute *attrp, void *arg)
   6946 {
   6947   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
   6948   const int level = cbargs->level;
   6949   Dwarf_Die *die = cbargs->die;
   6950   bool is_split = cbargs->is_split;
   6951 
   6952   unsigned int attr = dwarf_whatattr (attrp);
   6953   if (unlikely (attr == 0))
   6954     {
   6955       if (!cbargs->silent)
   6956 	error (0, 0, gettext ("DIE [%" PRIx64 "] "
   6957 			      "cannot get attribute code: %s"),
   6958 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
   6959       return DWARF_CB_ABORT;
   6960     }
   6961 
   6962   unsigned int form = dwarf_whatform (attrp);
   6963   if (unlikely (form == 0))
   6964     {
   6965       if (!cbargs->silent)
   6966 	error (0, 0, gettext ("DIE [%" PRIx64 "] "
   6967 			      "cannot get attribute form: %s"),
   6968 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
   6969       return DWARF_CB_ABORT;
   6970     }
   6971 
   6972   switch (form)
   6973     {
   6974     case DW_FORM_addr:
   6975     case DW_FORM_addrx:
   6976     case DW_FORM_addrx1:
   6977     case DW_FORM_addrx2:
   6978     case DW_FORM_addrx3:
   6979     case DW_FORM_addrx4:
   6980     case DW_FORM_GNU_addr_index:
   6981       if (!cbargs->silent)
   6982 	{
   6983 	  Dwarf_Addr addr;
   6984 	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
   6985 	    {
   6986 	    attrval_out:
   6987 	      if (!cbargs->silent)
   6988 		error (0, 0, gettext ("DIE [%" PRIx64 "] "
   6989 				      "cannot get attribute '%s' (%s) value: "
   6990 				      "%s"),
   6991 		       dwarf_dieoffset (die),
   6992 		       dwarf_attr_name (attr),
   6993 		       dwarf_form_name (form),
   6994 		       dwarf_errmsg (-1));
   6995 	      /* Don't ABORT, it might be other attributes can be resolved.  */
   6996 	      return DWARF_CB_OK;
   6997 	    }
   6998 	  if (form != DW_FORM_addr )
   6999 	    {
   7000 	      Dwarf_Word word;
   7001 	      if (dwarf_formudata (attrp, &word) != 0)
   7002 		goto attrval_out;
   7003 	      printf ("           %*s%-20s (%s) [%" PRIx64 "] ",
   7004 		      (int) (level * 2), "", dwarf_attr_name (attr),
   7005 		      dwarf_form_name (form), word);
   7006 	    }
   7007 	  else
   7008 	    printf ("           %*s%-20s (%s) ",
   7009 		    (int) (level * 2), "", dwarf_attr_name (attr),
   7010 		    dwarf_form_name (form));
   7011 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
   7012 	  printf ("\n");
   7013 	}
   7014       break;
   7015 
   7016     case DW_FORM_indirect:
   7017     case DW_FORM_strp:
   7018     case DW_FORM_line_strp:
   7019     case DW_FORM_strx:
   7020     case DW_FORM_strx1:
   7021     case DW_FORM_strx2:
   7022     case DW_FORM_strx3:
   7023     case DW_FORM_strx4:
   7024     case DW_FORM_string:
   7025     case DW_FORM_GNU_strp_alt:
   7026     case DW_FORM_GNU_str_index:
   7027       if (cbargs->silent)
   7028 	break;
   7029       const char *str = dwarf_formstring (attrp);
   7030       if (unlikely (str == NULL))
   7031 	goto attrval_out;
   7032       printf ("           %*s%-20s (%s) \"%s\"\n",
   7033 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7034 	      dwarf_form_name (form), str);
   7035       break;
   7036 
   7037     case DW_FORM_ref_addr:
   7038     case DW_FORM_ref_udata:
   7039     case DW_FORM_ref8:
   7040     case DW_FORM_ref4:
   7041     case DW_FORM_ref2:
   7042     case DW_FORM_ref1:
   7043     case DW_FORM_GNU_ref_alt:
   7044     case DW_FORM_ref_sup4:
   7045     case DW_FORM_ref_sup8:
   7046       if (cbargs->silent)
   7047 	break;
   7048       Dwarf_Die ref;
   7049       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
   7050 	goto attrval_out;
   7051 
   7052       printf ("           %*s%-20s (%s) ",
   7053 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7054 	      dwarf_form_name (form));
   7055       if (is_split)
   7056 	printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
   7057       else
   7058 	printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
   7059       break;
   7060 
   7061     case DW_FORM_ref_sig8:
   7062       if (cbargs->silent)
   7063 	break;
   7064       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
   7065 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7066 	      dwarf_form_name (form),
   7067 	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
   7068       break;
   7069 
   7070     case DW_FORM_sec_offset:
   7071     case DW_FORM_rnglistx:
   7072     case DW_FORM_loclistx:
   7073     case DW_FORM_implicit_const:
   7074     case DW_FORM_udata:
   7075     case DW_FORM_sdata:
   7076     case DW_FORM_data8: /* Note no data16 here, we see that as block. */
   7077     case DW_FORM_data4:
   7078     case DW_FORM_data2:
   7079     case DW_FORM_data1:;
   7080       Dwarf_Word num;
   7081       if (unlikely (dwarf_formudata (attrp, &num) != 0))
   7082 	goto attrval_out;
   7083 
   7084       const char *valuestr = NULL;
   7085       bool as_hex_id = false;
   7086       switch (attr)
   7087 	{
   7088 	  /* This case can take either a constant or a loclistptr.  */
   7089 	case DW_AT_data_member_location:
   7090 	  if (form != DW_FORM_sec_offset
   7091 	      && (cbargs->version >= 4
   7092 		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
   7093 	    {
   7094 	      if (!cbargs->silent)
   7095 		printf ("           %*s%-20s (%s) %" PRIxMAX "\n",
   7096 			(int) (level * 2), "", dwarf_attr_name (attr),
   7097 			dwarf_form_name (form), (uintmax_t) num);
   7098 	      return DWARF_CB_OK;
   7099 	    }
   7100 	  FALLTHROUGH;
   7101 
   7102 	/* These cases always take a loclist[ptr] and no constant. */
   7103 	case DW_AT_location:
   7104 	case DW_AT_data_location:
   7105 	case DW_AT_vtable_elem_location:
   7106 	case DW_AT_string_length:
   7107 	case DW_AT_use_location:
   7108 	case DW_AT_frame_base:
   7109 	case DW_AT_return_addr:
   7110 	case DW_AT_static_link:
   7111 	case DW_AT_segment:
   7112 	case DW_AT_GNU_call_site_value:
   7113 	case DW_AT_GNU_call_site_data_value:
   7114 	case DW_AT_GNU_call_site_target:
   7115 	case DW_AT_GNU_call_site_target_clobbered:
   7116 	case DW_AT_GNU_locviews:
   7117 	  {
   7118 	    bool nlpt;
   7119 	    if (cbargs->cu->version < 5)
   7120 	      {
   7121 		if (! cbargs->is_split)
   7122 		  {
   7123 		    nlpt = notice_listptr (section_loc, &known_locsptr,
   7124 					   cbargs->addrsize,
   7125 					   cbargs->offset_size,
   7126 					   cbargs->cu, num, attr);
   7127 		  }
   7128 		else
   7129 		  nlpt = true;
   7130 	      }
   7131 	    else
   7132 	      {
   7133 		/* Only register for a real section offset.  Otherwise
   7134 		   it is a DW_FORM_loclistx which is just an index
   7135 		   number and we should already have registered the
   7136 		   section offset for the index when we saw the
   7137 		   DW_AT_loclists_base CU attribute.  */
   7138 		if (form == DW_FORM_sec_offset)
   7139 		  nlpt = notice_listptr (section_loc, &known_loclistsptr,
   7140 					 cbargs->addrsize, cbargs->offset_size,
   7141 					 cbargs->cu, num, attr);
   7142 		else
   7143 		  nlpt = true;
   7144 
   7145 	      }
   7146 
   7147 	    if (!cbargs->silent)
   7148 	      {
   7149 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
   7150 		  printf ("           %*s%-20s (%s) location list [%6"
   7151 			  PRIxMAX "]%s\n",
   7152 			  (int) (level * 2), "", dwarf_attr_name (attr),
   7153 			  dwarf_form_name (form), (uintmax_t) num,
   7154 			  nlpt ? "" : " <WARNING offset too big>");
   7155 		else
   7156 		  printf ("           %*s%-20s (%s) location index [%6"
   7157 			  PRIxMAX "]\n",
   7158 			  (int) (level * 2), "", dwarf_attr_name (attr),
   7159 			  dwarf_form_name (form), (uintmax_t) num);
   7160 	      }
   7161 	  }
   7162 	  return DWARF_CB_OK;
   7163 
   7164 	case DW_AT_loclists_base:
   7165 	  {
   7166 	    bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
   7167                                         cbargs->addrsize, cbargs->offset_size,
   7168                                         cbargs->cu, num, attr);
   7169 
   7170 	    if (!cbargs->silent)
   7171 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
   7172 		      (int) (level * 2), "", dwarf_attr_name (attr),
   7173 		      dwarf_form_name (form), (uintmax_t) num,
   7174 		      nlpt ? "" : " <WARNING offset too big>");
   7175 	  }
   7176 	  return DWARF_CB_OK;
   7177 
   7178 	case DW_AT_ranges:
   7179 	case DW_AT_start_scope:
   7180 	  {
   7181 	    bool nlpt;
   7182 	    if (cbargs->cu->version < 5)
   7183 	      nlpt = notice_listptr (section_ranges, &known_rangelistptr,
   7184 				     cbargs->addrsize, cbargs->offset_size,
   7185 				     cbargs->cu, num, attr);
   7186 	    else
   7187 	      {
   7188 		/* Only register for a real section offset.  Otherwise
   7189 		   it is a DW_FORM_rangelistx which is just an index
   7190 		   number and we should already have registered the
   7191 		   section offset for the index when we saw the
   7192 		   DW_AT_rnglists_base CU attribute.  */
   7193 		if (form == DW_FORM_sec_offset)
   7194 		  nlpt = notice_listptr (section_ranges, &known_rnglistptr,
   7195 					 cbargs->addrsize, cbargs->offset_size,
   7196 					 cbargs->cu, num, attr);
   7197 		else
   7198 		  nlpt = true;
   7199 	      }
   7200 
   7201 	    if (!cbargs->silent)
   7202 	      {
   7203 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
   7204 		  printf ("           %*s%-20s (%s) range list [%6"
   7205 			  PRIxMAX "]%s\n",
   7206 			  (int) (level * 2), "", dwarf_attr_name (attr),
   7207 			  dwarf_form_name (form), (uintmax_t) num,
   7208 			  nlpt ? "" : " <WARNING offset too big>");
   7209 		else
   7210 		  printf ("           %*s%-20s (%s) range index [%6"
   7211 			  PRIxMAX "]\n",
   7212 			  (int) (level * 2), "", dwarf_attr_name (attr),
   7213 			  dwarf_form_name (form), (uintmax_t) num);
   7214 	      }
   7215 	  }
   7216 	  return DWARF_CB_OK;
   7217 
   7218 	case DW_AT_rnglists_base:
   7219 	  {
   7220 	    bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
   7221 					cbargs->addrsize, cbargs->offset_size,
   7222 					cbargs->cu, num, attr);
   7223 	    if (!cbargs->silent)
   7224 	      printf ("           %*s%-20s (%s) range list [%6"
   7225 		      PRIxMAX "]%s\n",
   7226 		      (int) (level * 2), "", dwarf_attr_name (attr),
   7227 		      dwarf_form_name (form), (uintmax_t) num,
   7228 		      nlpt ? "" : " <WARNING offset too big>");
   7229 	  }
   7230 	  return DWARF_CB_OK;
   7231 
   7232 	case DW_AT_addr_base:
   7233 	case DW_AT_GNU_addr_base:
   7234 	  {
   7235 	    bool addrbase = notice_listptr (section_addr, &known_addrbases,
   7236 					    cbargs->addrsize,
   7237 					    cbargs->offset_size,
   7238 					    cbargs->cu, num, attr);
   7239 	    if (!cbargs->silent)
   7240 	      printf ("           %*s%-20s (%s) address base [%6"
   7241 		      PRIxMAX "]%s\n",
   7242 		      (int) (level * 2), "", dwarf_attr_name (attr),
   7243 		      dwarf_form_name (form), (uintmax_t) num,
   7244 		      addrbase ? "" : " <WARNING offset too big>");
   7245 	  }
   7246 	  return DWARF_CB_OK;
   7247 
   7248 	case DW_AT_str_offsets_base:
   7249 	  {
   7250 	    bool stroffbase = notice_listptr (section_str, &known_stroffbases,
   7251 					      cbargs->addrsize,
   7252 					      cbargs->offset_size,
   7253 					      cbargs->cu, num, attr);
   7254 	    if (!cbargs->silent)
   7255 	      printf ("           %*s%-20s (%s) str offsets base [%6"
   7256 		      PRIxMAX "]%s\n",
   7257 		      (int) (level * 2), "", dwarf_attr_name (attr),
   7258 		      dwarf_form_name (form), (uintmax_t) num,
   7259 		      stroffbase ? "" : " <WARNING offset too big>");
   7260 	  }
   7261 	  return DWARF_CB_OK;
   7262 
   7263 	case DW_AT_language:
   7264 	  valuestr = dwarf_lang_name (num);
   7265 	  break;
   7266 	case DW_AT_encoding:
   7267 	  valuestr = dwarf_encoding_name (num);
   7268 	  break;
   7269 	case DW_AT_accessibility:
   7270 	  valuestr = dwarf_access_name (num);
   7271 	  break;
   7272 	case DW_AT_defaulted:
   7273 	  valuestr = dwarf_defaulted_name (num);
   7274 	  break;
   7275 	case DW_AT_visibility:
   7276 	  valuestr = dwarf_visibility_name (num);
   7277 	  break;
   7278 	case DW_AT_virtuality:
   7279 	  valuestr = dwarf_virtuality_name (num);
   7280 	  break;
   7281 	case DW_AT_identifier_case:
   7282 	  valuestr = dwarf_identifier_case_name (num);
   7283 	  break;
   7284 	case DW_AT_calling_convention:
   7285 	  valuestr = dwarf_calling_convention_name (num);
   7286 	  break;
   7287 	case DW_AT_inline:
   7288 	  valuestr = dwarf_inline_name (num);
   7289 	  break;
   7290 	case DW_AT_ordering:
   7291 	  valuestr = dwarf_ordering_name (num);
   7292 	  break;
   7293 	case DW_AT_discr_list:
   7294 	  valuestr = dwarf_discr_list_name (num);
   7295 	  break;
   7296 	case DW_AT_decl_file:
   7297 	case DW_AT_call_file:
   7298 	  {
   7299 	    if (cbargs->silent)
   7300 	      break;
   7301 
   7302 	    /* Try to get the actual file, the current interface only
   7303 	       gives us full paths, but we only want to show the file
   7304 	       name for now.  */
   7305 	    Dwarf_Die cudie;
   7306 	    if (dwarf_cu_die (cbargs->cu, &cudie,
   7307 			      NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
   7308 	      {
   7309 		Dwarf_Files *files;
   7310 		size_t nfiles;
   7311 		if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
   7312 		  {
   7313 		    valuestr = dwarf_filesrc (files, num, NULL, NULL);
   7314 		    if (valuestr != NULL)
   7315 		      {
   7316 			char *filename = strrchr (valuestr, '/');
   7317 			if (filename != NULL)
   7318 			  valuestr = filename + 1;
   7319 		      }
   7320 		    else
   7321 		      error (0, 0, gettext ("invalid file (%" PRId64 "): %s"),
   7322 			     num, dwarf_errmsg (-1));
   7323 		  }
   7324 		else
   7325 		  error (0, 0, gettext ("no srcfiles for CU [%" PRIx64 "]"),
   7326 			 dwarf_dieoffset (&cudie));
   7327 	      }
   7328 	    else
   7329 	     error (0, 0, gettext ("couldn't get DWARF CU: %s"),
   7330 		    dwarf_errmsg (-1));
   7331 	    if (valuestr == NULL)
   7332 	      valuestr = "???";
   7333 	  }
   7334 	  break;
   7335 	case DW_AT_GNU_dwo_id:
   7336 	  as_hex_id = true;
   7337 	  break;
   7338 
   7339 	default:
   7340 	  /* Nothing.  */
   7341 	  break;
   7342 	}
   7343 
   7344       if (cbargs->silent)
   7345 	break;
   7346 
   7347       /* When highpc is in constant form it is relative to lowpc.
   7348 	 In that case also show the address.  */
   7349       Dwarf_Addr highpc;
   7350       if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
   7351 	{
   7352 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (",
   7353 		  (int) (level * 2), "", dwarf_attr_name (attr),
   7354 		  dwarf_form_name (form), (uintmax_t) num);
   7355 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
   7356 	  printf (")\n");
   7357 	}
   7358       else
   7359 	{
   7360 	  if (as_hex_id)
   7361 	    {
   7362 	      printf ("           %*s%-20s (%s) 0x%.16" PRIx64 "\n",
   7363 		      (int) (level * 2), "", dwarf_attr_name (attr),
   7364 		      dwarf_form_name (form), num);
   7365 	    }
   7366 	  else
   7367 	    {
   7368 	      Dwarf_Sword snum = 0;
   7369 	      bool is_signed;
   7370 	      int bytes = 0;
   7371 	      if (attr == DW_AT_const_value)
   7372 		die_type_sign_bytes (cbargs->die, &is_signed, &bytes);
   7373 	      else
   7374 		is_signed = (form == DW_FORM_sdata
   7375 			     || form == DW_FORM_implicit_const);
   7376 
   7377 	      if (is_signed)
   7378 		if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
   7379 		  goto attrval_out;
   7380 
   7381 	      if (valuestr == NULL)
   7382 		{
   7383 		  printf ("           %*s%-20s (%s) ",
   7384 			  (int) (level * 2), "", dwarf_attr_name (attr),
   7385 			  dwarf_form_name (form));
   7386 		}
   7387 	      else
   7388 		{
   7389 		  printf ("           %*s%-20s (%s) %s (",
   7390 			  (int) (level * 2), "", dwarf_attr_name (attr),
   7391 			  dwarf_form_name (form), valuestr);
   7392 		}
   7393 
   7394 	      switch (bytes)
   7395 		{
   7396 		case 1:
   7397 		  if (is_signed)
   7398 		    printf ("%" PRId8, (int8_t) snum);
   7399 		  else
   7400 		    printf ("%" PRIu8, (uint8_t) num);
   7401 		  break;
   7402 
   7403 		case 2:
   7404 		  if (is_signed)
   7405 		    printf ("%" PRId16, (int16_t) snum);
   7406 		  else
   7407 		    printf ("%" PRIu16, (uint16_t) num);
   7408 		  break;
   7409 
   7410 		case 4:
   7411 		  if (is_signed)
   7412 		    printf ("%" PRId32, (int32_t) snum);
   7413 		  else
   7414 		    printf ("%" PRIu32, (uint32_t) num);
   7415 		  break;
   7416 
   7417 		case 8:
   7418 		  if (is_signed)
   7419 		    printf ("%" PRId64, (int64_t) snum);
   7420 		  else
   7421 		    printf ("%" PRIu64, (uint64_t) num);
   7422 		  break;
   7423 
   7424 		default:
   7425 		  if (is_signed)
   7426 		    printf ("%" PRIdMAX, (intmax_t) snum);
   7427 		  else
   7428 		    printf ("%" PRIuMAX, (uintmax_t) num);
   7429 		  break;
   7430 		}
   7431 
   7432 	      /* Make clear if we switched from a signed encoding to
   7433 		 an unsigned value.  */
   7434 	      if (attr == DW_AT_const_value
   7435 		  && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
   7436 		  && !is_signed)
   7437 		printf (" (%" PRIdMAX ")", (intmax_t) num);
   7438 
   7439 	      if (valuestr == NULL)
   7440 		printf ("\n");
   7441 	      else
   7442 		printf (")\n");
   7443 	    }
   7444 	}
   7445       break;
   7446 
   7447     case DW_FORM_flag:
   7448       if (cbargs->silent)
   7449 	break;
   7450       bool flag;
   7451       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
   7452 	goto attrval_out;
   7453 
   7454       printf ("           %*s%-20s (%s) %s\n",
   7455 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7456 	      dwarf_form_name (form), flag ? yes_str : no_str);
   7457       break;
   7458 
   7459     case DW_FORM_flag_present:
   7460       if (cbargs->silent)
   7461 	break;
   7462       printf ("           %*s%-20s (%s) %s\n",
   7463 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7464 	      dwarf_form_name (form), yes_str);
   7465       break;
   7466 
   7467     case DW_FORM_exprloc:
   7468     case DW_FORM_block4:
   7469     case DW_FORM_block2:
   7470     case DW_FORM_block1:
   7471     case DW_FORM_block:
   7472     case DW_FORM_data16: /* DWARF5 calls this a constant class.  */
   7473       if (cbargs->silent)
   7474 	break;
   7475       Dwarf_Block block;
   7476       if (unlikely (dwarf_formblock (attrp, &block) != 0))
   7477 	goto attrval_out;
   7478 
   7479       printf ("           %*s%-20s (%s) ",
   7480 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7481 	      dwarf_form_name (form));
   7482 
   7483       switch (attr)
   7484 	{
   7485 	default:
   7486 	  if (form != DW_FORM_exprloc)
   7487 	    {
   7488 	      print_block (block.length, block.data);
   7489 	      break;
   7490 	    }
   7491 	  FALLTHROUGH;
   7492 
   7493 	case DW_AT_location:
   7494 	case DW_AT_data_location:
   7495 	case DW_AT_data_member_location:
   7496 	case DW_AT_vtable_elem_location:
   7497 	case DW_AT_string_length:
   7498 	case DW_AT_use_location:
   7499 	case DW_AT_frame_base:
   7500 	case DW_AT_return_addr:
   7501 	case DW_AT_static_link:
   7502 	case DW_AT_allocated:
   7503 	case DW_AT_associated:
   7504 	case DW_AT_bit_size:
   7505 	case DW_AT_bit_offset:
   7506 	case DW_AT_bit_stride:
   7507 	case DW_AT_byte_size:
   7508 	case DW_AT_byte_stride:
   7509 	case DW_AT_count:
   7510 	case DW_AT_lower_bound:
   7511 	case DW_AT_upper_bound:
   7512 	case DW_AT_GNU_call_site_value:
   7513 	case DW_AT_GNU_call_site_data_value:
   7514 	case DW_AT_GNU_call_site_target:
   7515 	case DW_AT_GNU_call_site_target_clobbered:
   7516 	  if (form != DW_FORM_data16)
   7517 	    {
   7518 	      putchar ('\n');
   7519 	      print_ops (cbargs->dwflmod, cbargs->dbg,
   7520 			 12 + level * 2, 12 + level * 2,
   7521 			 cbargs->version, cbargs->addrsize, cbargs->offset_size,
   7522 			 attrp->cu, block.length, block.data);
   7523 	    }
   7524 	  else
   7525 	    print_block (block.length, block.data);
   7526 	  break;
   7527 	}
   7528       break;
   7529 
   7530     default:
   7531       if (cbargs->silent)
   7532 	break;
   7533       printf ("           %*s%-20s (%s) ???\n",
   7534 	      (int) (level * 2), "", dwarf_attr_name (attr),
   7535 	      dwarf_form_name (form));
   7536       break;
   7537     }
   7538 
   7539   return DWARF_CB_OK;
   7540 }
   7541 
   7542 static void
   7543 print_debug_units (Dwfl_Module *dwflmod,
   7544 		   Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
   7545 		   Elf_Scn *scn, GElf_Shdr *shdr,
   7546 		   Dwarf *dbg, bool debug_types)
   7547 {
   7548   const bool silent = !(print_debug_sections & section_info) && !debug_types;
   7549   const char *secname = section_name (ebl, shdr);
   7550 
   7551   if (!silent)
   7552     printf (gettext ("\
   7553 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
   7554 	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
   7555 
   7556   /* If the section is empty we don't have to do anything.  */
   7557   if (!silent && shdr->sh_size == 0)
   7558     return;
   7559 
   7560   int maxdies = 20;
   7561   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
   7562 
   7563   /* New compilation unit.  */
   7564   Dwarf_Half version;
   7565 
   7566   Dwarf_Die result;
   7567   Dwarf_Off abbroffset;
   7568   uint8_t addrsize;
   7569   uint8_t offsize;
   7570   uint64_t unit_id;
   7571   Dwarf_Off subdie_off;
   7572 
   7573   int unit_res;
   7574   Dwarf_CU *cu;
   7575   Dwarf_CU cu_mem;
   7576   uint8_t unit_type;
   7577   Dwarf_Die cudie;
   7578 
   7579   /* We cheat a little because we want to see only the CUs from .debug_info
   7580      or .debug_types.  We know the Dwarf_CU struct layout.  Set it up at
   7581      the end of .debug_info if we want .debug_types only.  Check the returned
   7582      Dwarf_CU is still in the expected section.  */
   7583   if (debug_types)
   7584     {
   7585       cu_mem.dbg = dbg;
   7586       cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
   7587       cu_mem.sec_idx = IDX_debug_info;
   7588       cu = &cu_mem;
   7589     }
   7590   else
   7591     cu = NULL;
   7592 
   7593  next_cu:
   7594   unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
   7595 			      &cudie, NULL);
   7596   if (unit_res == 1)
   7597     goto do_return;
   7598 
   7599   if (unit_res == -1)
   7600     {
   7601       if (!silent)
   7602 	error (0, 0, gettext ("cannot get next unit: %s"), dwarf_errmsg (-1));
   7603       goto do_return;
   7604     }
   7605 
   7606   if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
   7607     goto do_return;
   7608 
   7609   dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
   7610 		&unit_id, &subdie_off);
   7611 
   7612   if (!silent)
   7613     {
   7614       Dwarf_Off offset = cu->start;
   7615       if (debug_types && version < 5)
   7616 	{
   7617 	  Dwarf_Die typedie;
   7618 	  Dwarf_Off dieoffset;
   7619 	  dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
   7620 							   &typedie));
   7621 	  printf (gettext (" Type unit at offset %" PRIu64 ":\n"
   7622 			   " Version: %" PRIu16
   7623 			   ", Abbreviation section offset: %" PRIu64
   7624 			   ", Address size: %" PRIu8
   7625 			   ", Offset size: %" PRIu8
   7626 			   "\n Type signature: %#" PRIx64
   7627 			   ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
   7628 		  (uint64_t) offset, version, abbroffset, addrsize, offsize,
   7629 		  unit_id, (uint64_t) subdie_off, dieoffset);
   7630 	}
   7631       else
   7632 	{
   7633 	  printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
   7634 			   " Version: %" PRIu16
   7635 			   ", Abbreviation section offset: %" PRIu64
   7636 			   ", Address size: %" PRIu8
   7637 			   ", Offset size: %" PRIu8 "\n"),
   7638 		  (uint64_t) offset, version, abbroffset, addrsize, offsize);
   7639 
   7640 	  if (version >= 5 || (unit_type != DW_UT_compile
   7641 			       && unit_type != DW_UT_partial))
   7642 	    {
   7643 	      printf (gettext (" Unit type: %s (%" PRIu8 ")"),
   7644 			       dwarf_unit_name (unit_type), unit_type);
   7645 	      if (unit_type == DW_UT_type
   7646 		  || unit_type == DW_UT_skeleton
   7647 		  || unit_type == DW_UT_split_compile
   7648 		  || unit_type == DW_UT_split_type)
   7649 		printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
   7650 	      if (unit_type == DW_UT_type
   7651 		  || unit_type == DW_UT_split_type)
   7652 		{
   7653 		  Dwarf_Die typedie;
   7654 		  Dwarf_Off dieoffset;
   7655 		  dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
   7656 				 NULL, NULL, NULL);
   7657 		  dieoffset = dwarf_dieoffset (&typedie);
   7658 		  printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
   7659 			  subdie_off, dieoffset);
   7660 		}
   7661 	      printf ("\n");
   7662 	    }
   7663 	}
   7664     }
   7665 
   7666   if (version < 2 || version > 5
   7667       || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
   7668     {
   7669       if (!silent)
   7670 	error (0, 0, gettext ("unknown version (%d) or unit type (%d)"),
   7671 	       version, unit_type);
   7672       goto next_cu;
   7673     }
   7674 
   7675   struct attrcb_args args =
   7676     {
   7677       .dwflmod = dwflmod,
   7678       .silent = silent,
   7679       .version = version,
   7680       .addrsize = addrsize,
   7681       .offset_size = offsize
   7682     };
   7683 
   7684   bool is_split = false;
   7685   int level = 0;
   7686   dies[0] = cudie;
   7687   args.cu = dies[0].cu;
   7688   args.dbg = dbg;
   7689   args.is_split = is_split;
   7690 
   7691   /* We might return here again for the split CU subdie.  */
   7692   do_cu:
   7693   do
   7694     {
   7695       Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
   7696       if (unlikely (offset == (Dwarf_Off) -1))
   7697 	{
   7698 	  if (!silent)
   7699 	    error (0, 0, gettext ("cannot get DIE offset: %s"),
   7700 		   dwarf_errmsg (-1));
   7701 	  goto do_return;
   7702 	}
   7703 
   7704       int tag = dwarf_tag (&dies[level]);
   7705       if (unlikely (tag == DW_TAG_invalid))
   7706 	{
   7707 	  if (!silent)
   7708 	    error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
   7709 				  "] in section '%s': %s"),
   7710 		   (uint64_t) offset, secname, dwarf_errmsg (-1));
   7711 <