libdw: Check terminating NUL byte in dwarf_getsrclines for dir/file table.
[platform/upstream/elfutils.git] / src / readelf.c
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           goto do_return;
7712         }
7713
7714       if (!silent)
7715         {
7716           unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7717           if (is_split)
7718             printf (" {%6" PRIx64 "}  ", (uint64_t) offset);
7719           else
7720             printf (" [%6" PRIx64 "]  ", (uint64_t) offset);
7721           printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7722                   dwarf_tag_name (tag), code);
7723         }
7724
7725       /* Print the attribute values.  */
7726       args.level = level;
7727       args.die = &dies[level];
7728       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7729
7730       /* Make room for the next level's DIE.  */
7731       if (level + 1 == maxdies)
7732         dies = (Dwarf_Die *) xrealloc (dies,
7733                                        (maxdies += 10)
7734                                        * sizeof (Dwarf_Die));
7735
7736       int res = dwarf_child (&dies[level], &dies[level + 1]);
7737       if (res > 0)
7738         {
7739           while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7740             if (level-- == 0)
7741               break;
7742
7743           if (unlikely (res == -1))
7744             {
7745               if (!silent)
7746                 error (0, 0, gettext ("cannot get next DIE: %s\n"),
7747                        dwarf_errmsg (-1));
7748               goto do_return;
7749             }
7750         }
7751       else if (unlikely (res < 0))
7752         {
7753           if (!silent)
7754             error (0, 0, gettext ("cannot get next DIE: %s"),
7755                    dwarf_errmsg (-1));
7756           goto do_return;
7757         }
7758       else
7759         ++level;
7760     }
7761   while (level >= 0);
7762
7763   /* We might want to show the split compile unit if this was a skeleton.
7764      We need to scan it if we are requesting printing .debug_ranges for
7765      DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7766      section.  */
7767   if (unit_type == DW_UT_skeleton
7768       && ((!silent && show_split_units)
7769           || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7770     {
7771       Dwarf_Die subdie;
7772       if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7773           || dwarf_tag (&subdie) == DW_TAG_invalid)
7774         {
7775           if (!silent)
7776             {
7777               Dwarf_Attribute dwo_at;
7778               const char *dwo_name =
7779                 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7780                                                &dwo_at))
7781                  ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7782                                                    &dwo_at))
7783                      ?: "<unknown>"));
7784               fprintf (stderr,
7785                        "Could not find split unit '%s', id: %" PRIx64 "\n",
7786                        dwo_name, unit_id);
7787             }
7788         }
7789       else
7790         {
7791           Dwarf_CU *split_cu = subdie.cu;
7792           dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7793                         &addrsize, &offsize, &unit_id, &subdie_off);
7794           Dwarf_Off offset = cu->start;
7795
7796           if (!silent)
7797             {
7798               printf (gettext (" Split compilation unit at offset %"
7799                                PRIu64 ":\n"
7800                                " Version: %" PRIu16
7801                                ", Abbreviation section offset: %" PRIu64
7802                                ", Address size: %" PRIu8
7803                                ", Offset size: %" PRIu8 "\n"),
7804                       (uint64_t) offset, version, abbroffset,
7805                       addrsize, offsize);
7806               printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7807                       dwarf_unit_name (unit_type), unit_type);
7808               printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7809               printf ("\n");
7810             }
7811
7812           unit_type = DW_UT_split_compile;
7813           is_split = true;
7814           level = 0;
7815           dies[0] = subdie;
7816           args.cu = dies[0].cu;
7817           args.dbg = split_cu->dbg;
7818           args.is_split = is_split;
7819           goto do_cu;
7820         }
7821     }
7822
7823   /* And again... */
7824   goto next_cu;
7825
7826  do_return:
7827   free (dies);
7828 }
7829
7830 static void
7831 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7832                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7833 {
7834   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
7835 }
7836
7837 static void
7838 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7839                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7840 {
7841   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
7842 }
7843
7844
7845 static void
7846 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
7847                             GElf_Ehdr *ehdr __attribute__ ((unused)),
7848                             Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7849 {
7850   printf (gettext ("\
7851 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
7852           elf_ndxscn (scn), section_name (ebl, shdr),
7853           (uint64_t) shdr->sh_offset);
7854
7855   size_t address_size
7856     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7857
7858   Dwarf_Lines *lines;
7859   size_t nlines;
7860   Dwarf_Off off, next_off = 0;
7861   Dwarf_CU *cu = NULL;
7862   while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
7863                            &lines, &nlines) == 0)
7864     {
7865       Dwarf_Die cudie;
7866       if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
7867                                        NULL, NULL, NULL, NULL) == 0)
7868         printf (" CU [%" PRIx64 "] %s\n",
7869                 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
7870       else
7871         {
7872           /* DWARF5 lines can be independent of any CU, but they probably
7873              are used by some CU.  Determine the CU this block is for.  */
7874           Dwarf_Off cuoffset;
7875           Dwarf_Off ncuoffset = 0;
7876           size_t hsize;
7877           while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
7878                                NULL, NULL, NULL) == 0)
7879             {
7880               if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
7881                 continue;
7882               Dwarf_Attribute stmt_list;
7883               if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
7884                 continue;
7885               Dwarf_Word lineoff;
7886               if (dwarf_formudata (&stmt_list, &lineoff) != 0)
7887                 continue;
7888               if (lineoff == off)
7889                 {
7890                   /* Found the CU.  */
7891                   cu = cudie.cu;
7892                   break;
7893                 }
7894             }
7895
7896           if (cu != NULL)
7897             printf (" CU [%" PRIx64 "] %s\n",
7898                     dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
7899           else
7900             printf (" No CU\n");
7901         }
7902
7903       printf ("  line:col SBPE* disc isa op address"
7904               " (Statement Block Prologue Epilogue *End)\n");
7905       const char *last_file = "";
7906       for (size_t n = 0; n < nlines; n++)
7907         {
7908           Dwarf_Line *line = dwarf_onesrcline (lines, n);
7909           if (line == NULL)
7910             {
7911               printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
7912               continue;
7913             }
7914           Dwarf_Word mtime, length;
7915           const char *file = dwarf_linesrc (line, &mtime, &length);
7916           if (file == NULL)
7917             {
7918               printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
7919               last_file = "";
7920             }
7921           else if (strcmp (last_file, file) != 0)
7922             {
7923               printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
7924                       file, mtime, length);
7925               last_file = file;
7926             }
7927
7928           int lineno, colno;
7929           bool statement, endseq, block, prologue_end, epilogue_begin;
7930           unsigned int lineop, isa, disc;
7931           Dwarf_Addr address;
7932           dwarf_lineaddr (line, &address);
7933           dwarf_lineno (line, &lineno);
7934           dwarf_linecol (line, &colno);
7935           dwarf_lineop_index (line, &lineop);
7936           dwarf_linebeginstatement (line, &statement);
7937           dwarf_lineendsequence (line, &endseq);
7938           dwarf_lineblock (line, &block);
7939           dwarf_lineprologueend (line, &prologue_end);
7940           dwarf_lineepiloguebegin (line, &epilogue_begin);
7941           dwarf_lineisa (line, &isa);
7942           dwarf_linediscriminator (line, &disc);
7943
7944           /* End sequence is special, it is one byte past.  */
7945           printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
7946                   lineno, colno,
7947                   (statement ? 'S' : ' '),
7948                   (block ? 'B' : ' '),
7949                   (prologue_end ? 'P' : ' '),
7950                   (epilogue_begin ? 'E' : ' '),
7951                   (endseq ? '*' : ' '),
7952                   disc, isa, lineop);
7953           print_dwarf_addr (dwflmod, address_size,
7954                             address - (endseq ? 1 : 0), address);
7955           printf ("\n");
7956
7957           if (endseq)
7958             printf("\n");
7959         }
7960     }
7961 }
7962
7963
7964 /* Print the value of a form.
7965    Returns new value of readp, or readendp on failure.  */
7966 static const unsigned char *
7967 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
7968                  const unsigned char *readendp, unsigned int offset_len,
7969                  Dwarf_Off str_offsets_base)
7970 {
7971   Dwarf_Word val;
7972   unsigned char *endp;
7973   Elf_Data *data;
7974   char *str;
7975   switch (form)
7976     {
7977     case DW_FORM_data1:
7978       if (readendp - readp < 1)
7979         {
7980         invalid_data:
7981           error (0, 0, "invalid data");
7982           return readendp;
7983         }
7984       val = *readp++;
7985       printf (" %" PRIx8, (unsigned int) val);
7986       break;
7987
7988     case DW_FORM_data2:
7989       if (readendp - readp < 2)
7990         goto invalid_data;
7991       val = read_2ubyte_unaligned_inc (dbg, readp);
7992       printf(" %" PRIx16, (unsigned int) val);
7993       break;
7994
7995     case DW_FORM_data4:
7996       if (readendp - readp < 4)
7997         goto invalid_data;
7998       val = read_4ubyte_unaligned_inc (dbg, readp);
7999       printf (" %" PRIx32, (unsigned int) val);
8000       break;
8001
8002     case DW_FORM_data8:
8003       if (readendp - readp < 8)
8004         goto invalid_data;
8005       val = read_8ubyte_unaligned_inc (dbg, readp);
8006       printf (" %" PRIx64, val);
8007       break;
8008
8009     case DW_FORM_sdata:
8010       if (readendp - readp < 1)
8011         goto invalid_data;
8012       get_sleb128 (val, readp, readendp);
8013       printf (" %" PRIx64, val);
8014       break;
8015
8016     case DW_FORM_udata:
8017       if (readendp - readp < 1)
8018         goto invalid_data;
8019       get_uleb128 (val, readp, readendp);
8020       printf (" %" PRIx64, val);
8021       break;
8022
8023     case DW_FORM_block:
8024       if (readendp - readp < 1)
8025         goto invalid_data;
8026       get_uleb128 (val, readp, readendp);
8027       if ((size_t) (readendp - readp) < val)
8028         goto invalid_data;
8029       print_bytes (val, readp);
8030       readp += val;
8031       break;
8032
8033     case DW_FORM_block1:
8034       if (readendp - readp < 1)
8035         goto invalid_data;
8036       val = *readp++;
8037       if ((size_t) (readendp - readp) < val)
8038         goto invalid_data;
8039       print_bytes (val, readp);
8040       readp += val;
8041       break;
8042
8043     case DW_FORM_block2:
8044       if (readendp - readp < 2)
8045         goto invalid_data;
8046       val = read_2ubyte_unaligned_inc (dbg, readp);
8047       if ((size_t) (readendp - readp) < val)
8048         goto invalid_data;
8049       print_bytes (val, readp);
8050       readp += val;
8051       break;
8052
8053     case DW_FORM_block4:
8054       if (readendp - readp < 4)
8055         goto invalid_data;
8056       val = read_4ubyte_unaligned_inc (dbg, readp);
8057       if ((size_t) (readendp - readp) < val)
8058         goto invalid_data;
8059       print_bytes (val, readp);
8060       readp += val;
8061       break;
8062
8063     case DW_FORM_data16:
8064       if (readendp - readp < 16)
8065         goto invalid_data;
8066       print_bytes (16, readp);
8067       readp += 16;
8068       break;
8069
8070     case DW_FORM_flag:
8071       if (readendp - readp < 1)
8072         goto invalid_data;
8073       val = *readp++;
8074       printf ("%s", val != 0 ? yes_str : no_str);
8075       break;
8076
8077     case DW_FORM_string:
8078       endp = memchr (readp, '\0', readendp - readp);
8079       if (endp == NULL)
8080         goto invalid_data;
8081       printf ("%s", readp);
8082       readp = endp + 1;
8083       break;
8084
8085     case DW_FORM_strp:
8086     case DW_FORM_line_strp:
8087     case DW_FORM_strp_sup:
8088       if ((size_t) (readendp - readp) < offset_len)
8089         goto invalid_data;
8090       if (offset_len == 8)
8091         val = read_8ubyte_unaligned_inc (dbg, readp);
8092       else
8093         val = read_4ubyte_unaligned_inc (dbg, readp);
8094       if (form == DW_FORM_strp)
8095         data = dbg->sectiondata[IDX_debug_str];
8096       else if (form == DW_FORM_line_strp)
8097         data = dbg->sectiondata[IDX_debug_line_str];
8098       else /* form == DW_FORM_strp_sup */
8099         {
8100           Dwarf *alt = dwarf_getalt (dbg);
8101           data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8102         }
8103       if (data == NULL || val >= data->d_size
8104           || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8105         str = "???";
8106       else
8107         str = (char *) data->d_buf + val;
8108       printf ("%s (%" PRIu64 ")", str, val);
8109       break;
8110
8111     case DW_FORM_sec_offset:
8112       if ((size_t) (readendp - readp) < offset_len)
8113         goto invalid_data;
8114       if (offset_len == 8)
8115         val = read_8ubyte_unaligned_inc (dbg, readp);
8116       else
8117         val = read_4ubyte_unaligned_inc (dbg, readp);
8118       printf ("[%" PRIx64 "]", val);
8119       break;
8120
8121     case DW_FORM_strx:
8122     case DW_FORM_GNU_str_index:
8123       if (readendp - readp < 1)
8124         goto invalid_data;
8125       get_uleb128 (val, readp, readendp);
8126     strx_val:
8127       data = dbg->sectiondata[IDX_debug_str_offsets];
8128       if (data == NULL
8129           || data->d_size - str_offsets_base < val)
8130         str = "???";
8131       else
8132         {
8133           const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8134           const unsigned char *strreadendp = data->d_buf + data->d_size;
8135           if ((size_t) (strreadendp - strreadp) < offset_len)
8136             str = "???";
8137           else
8138             {
8139               Dwarf_Off idx;
8140               if (offset_len == 8)
8141                 idx = read_8ubyte_unaligned (dbg, strreadp);
8142               else
8143                 idx = read_4ubyte_unaligned (dbg, strreadp);
8144
8145               data = dbg->sectiondata[IDX_debug_str];
8146               if (data == NULL || idx >= data->d_size
8147                   || memchr (data->d_buf + idx, '\0',
8148                              data->d_size - idx) == NULL)
8149                 str = "???";
8150               else
8151                 str = (char *) data->d_buf + idx;
8152             }
8153         }
8154       printf ("%s (%" PRIu64 ")", str, val);
8155       break;
8156
8157     case DW_FORM_strx1:
8158       if (readendp - readp < 1)
8159         goto invalid_data;
8160       val = *readp++;
8161       goto strx_val;
8162
8163     case DW_FORM_strx2:
8164       if (readendp - readp < 2)
8165         goto invalid_data;
8166       val = read_2ubyte_unaligned_inc (dbg, readp);
8167       goto strx_val;
8168
8169     case DW_FORM_strx3:
8170       if (readendp - readp < 3)
8171         goto invalid_data;
8172       val = read_3ubyte_unaligned_inc (dbg, readp);
8173       goto strx_val;
8174
8175     case DW_FORM_strx4:
8176       if (readendp - readp < 4)
8177         goto invalid_data;
8178       val = read_4ubyte_unaligned_inc (dbg, readp);
8179       goto strx_val;
8180
8181     default:
8182       error (0, 0, gettext ("unknown form: %s"), dwarf_form_name (form));
8183       return readendp;
8184     }
8185
8186   return readp;
8187 }
8188
8189 static void
8190 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8191                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8192 {
8193   if (decodedline)
8194     {
8195       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8196       return;
8197     }
8198
8199   printf (gettext ("\
8200 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8201           elf_ndxscn (scn), section_name (ebl, shdr),
8202           (uint64_t) shdr->sh_offset);
8203
8204   if (shdr->sh_size == 0)
8205     return;
8206
8207   /* There is no functionality in libdw to read the information in the
8208      way it is represented here.  Hardcode the decoder.  */
8209   Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8210                     ?: elf_rawdata (scn, NULL));
8211   if (unlikely (data == NULL))
8212     {
8213       error (0, 0, gettext ("cannot get line data section data: %s"),
8214              elf_errmsg (-1));
8215       return;
8216     }
8217
8218   const unsigned char *linep = (const unsigned char *) data->d_buf;
8219   const unsigned char *lineendp;
8220
8221   while (linep
8222          < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8223     {
8224       size_t start_offset = linep - (const unsigned char *) data->d_buf;
8225
8226       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
8227
8228       if (unlikely (linep + 4 > lineendp))
8229         goto invalid_data;
8230       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8231       unsigned int length = 4;
8232       if (unlikely (unit_length == 0xffffffff))
8233         {
8234           if (unlikely (linep + 8 > lineendp))
8235             {
8236             invalid_data:
8237               error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8238                      elf_ndxscn (scn), section_name (ebl, shdr));
8239               return;
8240             }
8241           unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8242           length = 8;
8243         }
8244
8245       /* Check whether we have enough room in the section.  */
8246       if (unlikely (unit_length > (size_t) (lineendp - linep)))
8247         goto invalid_data;
8248       lineendp = linep + unit_length;
8249
8250       /* The next element of the header is the version identifier.  */
8251       if ((size_t) (lineendp - linep) < 2)
8252         goto invalid_data;
8253       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8254
8255       size_t address_size
8256         = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8257       unsigned char segment_selector_size = 0;
8258       if (version > 4)
8259         {
8260           if ((size_t) (lineendp - linep) < 2)
8261             goto invalid_data;
8262           address_size = *linep++;
8263           segment_selector_size = *linep++;
8264         }
8265
8266       /* Next comes the header length.  */
8267       Dwarf_Word header_length;
8268       if (length == 4)
8269         {
8270           if ((size_t) (lineendp - linep) < 4)
8271             goto invalid_data;
8272           header_length = read_4ubyte_unaligned_inc (dbg, linep);
8273         }
8274       else
8275         {
8276           if ((size_t) (lineendp - linep) < 8)
8277             goto invalid_data;
8278           header_length = read_8ubyte_unaligned_inc (dbg, linep);
8279         }
8280
8281       /* Next the minimum instruction length.  */
8282       if ((size_t) (lineendp - linep) < 1)
8283         goto invalid_data;
8284       uint_fast8_t minimum_instr_len = *linep++;
8285
8286       /* Next the maximum operations per instruction, in version 4 format.  */
8287       uint_fast8_t max_ops_per_instr;
8288       if (version < 4)
8289         max_ops_per_instr = 1;
8290       else
8291         {
8292           if ((size_t) (lineendp - linep) < 1)
8293             goto invalid_data;
8294           max_ops_per_instr = *linep++;
8295         }
8296
8297       /* We need at least 4 more bytes.  */
8298       if ((size_t) (lineendp - linep) < 4)
8299         goto invalid_data;
8300
8301       /* Then the flag determining the default value of the is_stmt
8302          register.  */
8303       uint_fast8_t default_is_stmt = *linep++;
8304
8305       /* Now the line base.  */
8306       int_fast8_t line_base = *linep++;
8307
8308       /* And the line range.  */
8309       uint_fast8_t line_range = *linep++;
8310
8311       /* The opcode base.  */
8312       uint_fast8_t opcode_base = *linep++;
8313
8314       /* Print what we got so far.  */
8315       printf (gettext ("\n"
8316                        " Length:                         %" PRIu64 "\n"
8317                        " DWARF version:                  %" PRIuFAST16 "\n"
8318                        " Prologue length:                %" PRIu64 "\n"
8319                        " Address size:                   %zd\n"
8320                        " Segment selector size:          %zd\n"
8321                        " Min instruction length:         %" PRIuFAST8 "\n"
8322                        " Max operations per instruction: %" PRIuFAST8 "\n"
8323                        " Initial value if 'is_stmt':     %" PRIuFAST8 "\n"
8324                        " Line base:                      %" PRIdFAST8 "\n"
8325                        " Line range:                     %" PRIuFAST8 "\n"
8326                        " Opcode base:                    %" PRIuFAST8 "\n"
8327                        "\n"
8328                        "Opcodes:\n"),
8329               (uint64_t) unit_length, version, (uint64_t) header_length,
8330               address_size, (size_t) segment_selector_size,
8331               minimum_instr_len, max_ops_per_instr,
8332               default_is_stmt, line_base,
8333               line_range, opcode_base);
8334
8335       if (version < 2 || version > 5)
8336         {
8337           error (0, 0, gettext ("cannot handle .debug_line version: %u\n"),
8338                  (unsigned int) version);
8339           linep = lineendp;
8340           continue;
8341         }
8342
8343       if (address_size != 4 && address_size != 8)
8344         {
8345           error (0, 0, gettext ("cannot handle address size: %u\n"),
8346                  (unsigned int) address_size);
8347           linep = lineendp;
8348           continue;
8349         }
8350
8351       if (segment_selector_size != 0)
8352         {
8353           error (0, 0, gettext ("cannot handle segment selector size: %u\n"),
8354                  (unsigned int) segment_selector_size);
8355           linep = lineendp;
8356           continue;
8357         }
8358
8359       if (unlikely (linep + opcode_base - 1 >= lineendp))
8360         {
8361         invalid_unit:
8362           error (0, 0,
8363                  gettext ("invalid data at offset %tu in section [%zu] '%s'"),
8364                  linep - (const unsigned char *) data->d_buf,
8365                  elf_ndxscn (scn), section_name (ebl, shdr));
8366           linep = lineendp;
8367           continue;
8368         }
8369       int opcode_base_l10 = 1;
8370       unsigned int tmp = opcode_base;
8371       while (tmp > 10)
8372         {
8373           tmp /= 10;
8374           ++opcode_base_l10;
8375         }
8376       const uint8_t *standard_opcode_lengths = linep - 1;
8377       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8378         printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
8379                           "  [%*" PRIuFAST8 "]  %hhu arguments\n",
8380                           (int) linep[cnt - 1]),
8381                 opcode_base_l10, cnt, linep[cnt - 1]);
8382       linep += opcode_base - 1;
8383
8384       if (unlikely (linep >= lineendp))
8385         goto invalid_unit;
8386
8387       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8388
8389       puts (gettext ("\nDirectory table:"));
8390       if (version > 4)
8391         {
8392           struct encpair { uint16_t desc; uint16_t form; };
8393           struct encpair enc[256];
8394
8395           printf (gettext ("      ["));
8396           if ((size_t) (lineendp - linep) < 1)
8397             goto invalid_data;
8398           unsigned char directory_entry_format_count = *linep++;
8399           for (int i = 0; i < directory_entry_format_count; i++)
8400             {
8401               uint16_t desc, form;
8402               if ((size_t) (lineendp - linep) < 1)
8403                 goto invalid_data;
8404               get_uleb128 (desc, linep, lineendp);
8405               if ((size_t) (lineendp - linep) < 1)
8406                 goto invalid_data;
8407               get_uleb128 (form, linep, lineendp);
8408
8409               enc[i].desc = desc;
8410               enc[i].form = form;
8411
8412               printf ("%s(%s)",
8413                       dwarf_line_content_description_name (desc),
8414                       dwarf_form_name (form));
8415               if (i + 1 < directory_entry_format_count)
8416                 printf (", ");
8417             }
8418           printf ("]\n");
8419
8420           uint64_t directories_count;
8421           if ((size_t) (lineendp - linep) < 1)
8422             goto invalid_data;
8423           get_uleb128 (directories_count, linep, lineendp);
8424
8425           if (directory_entry_format_count == 0
8426               && directories_count != 0)
8427             goto invalid_data;
8428
8429           for (uint64_t i = 0; i < directories_count; i++)
8430             {
8431               printf (" %-5" PRIu64 " ", i);
8432               for (int j = 0; j < directory_entry_format_count; j++)
8433                 {
8434                   linep = print_form_data (dbg, enc[j].form,
8435                                            linep, lineendp, length,
8436                                            str_offsets_base);
8437                   if (j + 1 < directory_entry_format_count)
8438                     printf (", ");
8439                 }
8440               printf ("\n");
8441               if (linep >= lineendp)
8442                 goto invalid_unit;
8443             }
8444         }
8445       else
8446         {
8447           while (linep < lineendp && *linep != 0)
8448             {
8449               unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8450               if (unlikely (endp == NULL))
8451                 goto invalid_unit;
8452
8453               printf (" %s\n", (char *) linep);
8454
8455               linep = endp + 1;
8456             }
8457           if (linep >= lineendp || *linep != 0)
8458             goto invalid_unit;
8459           /* Skip the final NUL byte.  */
8460           ++linep;
8461         }
8462
8463       if (unlikely (linep >= lineendp))
8464         goto invalid_unit;
8465
8466       puts (gettext ("\nFile name table:"));
8467       if (version > 4)
8468         {
8469           struct encpair { uint16_t desc; uint16_t form; };
8470           struct encpair enc[256];
8471
8472           printf (gettext ("      ["));
8473           if ((size_t) (lineendp - linep) < 1)
8474             goto invalid_data;
8475           unsigned char file_name_format_count = *linep++;
8476           for (int i = 0; i < file_name_format_count; i++)
8477             {
8478               uint64_t desc, form;
8479               if ((size_t) (lineendp - linep) < 1)
8480                 goto invalid_data;
8481               get_uleb128 (desc, linep, lineendp);
8482               if ((size_t) (lineendp - linep) < 1)
8483                 goto invalid_data;
8484               get_uleb128 (form, linep, lineendp);
8485
8486               if (! libdw_valid_user_form (form))
8487                 goto invalid_data;
8488
8489               enc[i].desc = desc;
8490               enc[i].form = form;
8491
8492               printf ("%s(%s)",
8493                       dwarf_line_content_description_name (desc),
8494                       dwarf_form_name (form));
8495               if (i + 1 < file_name_format_count)
8496                 printf (", ");
8497             }
8498           printf ("]\n");
8499
8500           uint64_t file_name_count;
8501           if ((size_t) (lineendp - linep) < 1)
8502             goto invalid_data;
8503           get_uleb128 (file_name_count, linep, lineendp);
8504
8505           if (file_name_format_count == 0
8506               && file_name_count != 0)
8507             goto invalid_data;
8508
8509           for (uint64_t i = 0; i < file_name_count; i++)
8510             {
8511               printf (" %-5" PRIu64 " ", i);
8512               for (int j = 0; j < file_name_format_count; j++)
8513                 {
8514                   linep = print_form_data (dbg, enc[j].form,
8515                                            linep, lineendp, length,
8516                                            str_offsets_base);
8517                   if (j + 1 < file_name_format_count)
8518                     printf (", ");
8519                 }
8520               printf ("\n");
8521               if (linep >= lineendp)
8522                 goto invalid_unit;
8523             }
8524         }
8525       else
8526         {
8527           puts (gettext (" Entry Dir   Time      Size      Name"));
8528           for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8529             {
8530               /* First comes the file name.  */
8531               char *fname = (char *) linep;
8532               unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8533               if (unlikely (endp == NULL))
8534                 goto invalid_unit;
8535               linep = endp + 1;
8536
8537               /* Then the index.  */
8538               unsigned int diridx;
8539               if (lineendp - linep < 1)
8540                 goto invalid_unit;
8541               get_uleb128 (diridx, linep, lineendp);
8542
8543               /* Next comes the modification time.  */
8544               unsigned int mtime;
8545               if (lineendp - linep < 1)
8546                 goto invalid_unit;
8547               get_uleb128 (mtime, linep, lineendp);
8548
8549               /* Finally the length of the file.  */
8550               unsigned int fsize;
8551               if (lineendp - linep < 1)
8552                 goto invalid_unit;
8553               get_uleb128 (fsize, linep, lineendp);
8554
8555               printf (" %-5u %-5u %-9u %-9u %s\n",
8556                       cnt, diridx, mtime, fsize, fname);
8557             }
8558           if (linep >= lineendp || *linep != '\0')
8559             goto invalid_unit;
8560           /* Skip the final NUL byte.  */
8561           ++linep;
8562         }
8563
8564       puts (gettext ("\nLine number statements:"));
8565       Dwarf_Word address = 0;
8566       unsigned int op_index = 0;
8567       size_t line = 1;
8568       uint_fast8_t is_stmt = default_is_stmt;
8569
8570       /* Apply the "operation advance" from a special opcode
8571          or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
8572       unsigned int op_addr_advance;
8573       bool show_op_index;
8574       inline void advance_pc (unsigned int op_advance)
8575       {
8576         op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8577                                                / max_ops_per_instr);
8578         address += op_addr_advance;
8579         show_op_index = (op_index > 0 ||
8580                          (op_index + op_advance) % max_ops_per_instr > 0);
8581         op_index = (op_index + op_advance) % max_ops_per_instr;
8582       }
8583
8584       if (max_ops_per_instr == 0)
8585         {
8586           error (0, 0,
8587                  gettext ("invalid maximum operations per instruction is zero"));
8588           linep = lineendp;
8589           continue;
8590         }
8591
8592       while (linep < lineendp)
8593         {
8594           size_t offset = linep - (const unsigned char *) data->d_buf;
8595           unsigned int u128;
8596           int s128;
8597
8598           /* Read the opcode.  */
8599           unsigned int opcode = *linep++;
8600
8601           printf (" [%6" PRIx64 "]", (uint64_t)offset);
8602           /* Is this a special opcode?  */
8603           if (likely (opcode >= opcode_base))
8604             {
8605               if (unlikely (line_range == 0))
8606                 goto invalid_unit;
8607
8608               /* Yes.  Handling this is quite easy since the opcode value
8609                  is computed with
8610
8611                  opcode = (desired line increment - line_base)
8612                            + (line_range * address advance) + opcode_base
8613               */
8614               int line_increment = (line_base
8615                                     + (opcode - opcode_base) % line_range);
8616
8617               /* Perform the increments.  */
8618               line += line_increment;
8619               advance_pc ((opcode - opcode_base) / line_range);
8620
8621               printf (gettext (" special opcode %u: address+%u = "),
8622                       opcode, op_addr_advance);
8623               print_dwarf_addr (dwflmod, 0, address, address);
8624               if (show_op_index)
8625                 printf (gettext (", op_index = %u, line%+d = %zu\n"),
8626                         op_index, line_increment, line);
8627               else
8628                 printf (gettext (", line%+d = %zu\n"),
8629                         line_increment, line);
8630             }
8631           else if (opcode == 0)
8632             {
8633               /* This an extended opcode.  */
8634               if (unlikely (linep + 2 > lineendp))
8635                 goto invalid_unit;
8636
8637               /* The length.  */
8638               unsigned int len = *linep++;
8639
8640               if (unlikely (linep + len > lineendp))
8641                 goto invalid_unit;
8642
8643               /* The sub-opcode.  */
8644               opcode = *linep++;
8645
8646               printf (gettext (" extended opcode %u: "), opcode);
8647
8648               switch (opcode)
8649                 {
8650                 case DW_LNE_end_sequence:
8651                   puts (gettext (" end of sequence"));
8652
8653                   /* Reset the registers we care about.  */
8654                   address = 0;
8655                   op_index = 0;
8656                   line = 1;
8657                   is_stmt = default_is_stmt;
8658                   break;
8659
8660                 case DW_LNE_set_address:
8661                   op_index = 0;
8662                   if (unlikely ((size_t) (lineendp - linep) < address_size))
8663                     goto invalid_unit;
8664                   if (address_size == 4)
8665                     address = read_4ubyte_unaligned_inc (dbg, linep);
8666                   else
8667                     address = read_8ubyte_unaligned_inc (dbg, linep);
8668                   {
8669                     printf (gettext (" set address to "));
8670                     print_dwarf_addr (dwflmod, 0, address, address);
8671                     printf ("\n");
8672                   }
8673                   break;
8674
8675                 case DW_LNE_define_file:
8676                   {
8677                     char *fname = (char *) linep;
8678                     unsigned char *endp = memchr (linep, '\0',
8679                                                   lineendp - linep);
8680                     if (unlikely (endp == NULL))
8681                       goto invalid_unit;
8682                     linep = endp + 1;
8683
8684                     unsigned int diridx;
8685                     if (lineendp - linep < 1)
8686                       goto invalid_unit;
8687                     get_uleb128 (diridx, linep, lineendp);
8688                     Dwarf_Word mtime;
8689                     if (lineendp - linep < 1)
8690                       goto invalid_unit;
8691                     get_uleb128 (mtime, linep, lineendp);
8692                     Dwarf_Word filelength;
8693                     if (lineendp - linep < 1)
8694                       goto invalid_unit;
8695                     get_uleb128 (filelength, linep, lineendp);
8696
8697                     printf (gettext ("\
8698  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8699                             diridx, (uint64_t) mtime, (uint64_t) filelength,
8700                             fname);
8701                   }
8702                   break;
8703
8704                 case DW_LNE_set_discriminator:
8705                   /* Takes one ULEB128 parameter, the discriminator.  */
8706                   if (unlikely (standard_opcode_lengths[opcode] != 1))
8707                     goto invalid_unit;
8708
8709                   get_uleb128 (u128, linep, lineendp);
8710                   printf (gettext (" set discriminator to %u\n"), u128);
8711                   break;
8712
8713                 default:
8714                   /* Unknown, ignore it.  */
8715                   puts (gettext (" unknown opcode"));
8716                   linep += len - 1;
8717                   break;
8718                 }
8719             }
8720           else if (opcode <= DW_LNS_set_isa)
8721             {
8722               /* This is a known standard opcode.  */
8723               switch (opcode)
8724                 {
8725                 case DW_LNS_copy:
8726                   /* Takes no argument.  */
8727                   puts (gettext (" copy"));
8728                   break;
8729
8730                 case DW_LNS_advance_pc:
8731                   /* Takes one uleb128 parameter which is added to the
8732                      address.  */
8733                   get_uleb128 (u128, linep, lineendp);
8734                   advance_pc (u128);
8735                   {
8736                     printf (gettext (" advance address by %u to "),
8737                             op_addr_advance);
8738                     print_dwarf_addr (dwflmod, 0, address, address);
8739                     if (show_op_index)
8740                       printf (gettext (", op_index to %u"), op_index);
8741                     printf ("\n");
8742                   }
8743                   break;
8744
8745                 case DW_LNS_advance_line:
8746                   /* Takes one sleb128 parameter which is added to the
8747                      line.  */
8748                   get_sleb128 (s128, linep, lineendp);
8749                   line += s128;
8750                   printf (gettext ("\
8751  advance line by constant %d to %" PRId64 "\n"),
8752                           s128, (int64_t) line);
8753                   break;
8754
8755                 case DW_LNS_set_file:
8756                   /* Takes one uleb128 parameter which is stored in file.  */
8757                   get_uleb128 (u128, linep, lineendp);
8758                   printf (gettext (" set file to %" PRIu64 "\n"),
8759                           (uint64_t) u128);
8760                   break;
8761
8762                 case DW_LNS_set_column:
8763                   /* Takes one uleb128 parameter which is stored in column.  */
8764                   if (unlikely (standard_opcode_lengths[opcode] != 1))
8765                     goto invalid_unit;
8766
8767                   get_uleb128 (u128, linep, lineendp);
8768                   printf (gettext (" set column to %" PRIu64 "\n"),
8769                           (uint64_t) u128);
8770                   break;
8771
8772                 case DW_LNS_negate_stmt:
8773                   /* Takes no argument.  */
8774                   is_stmt = 1 - is_stmt;
8775                   printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8776                           "is_stmt", is_stmt);
8777                   break;
8778
8779                 case DW_LNS_set_basic_block:
8780                   /* Takes no argument.  */
8781                   puts (gettext (" set basic block flag"));
8782                   break;
8783
8784                 case DW_LNS_const_add_pc:
8785                   /* Takes no argument.  */
8786
8787                   if (unlikely (line_range == 0))
8788                     goto invalid_unit;
8789
8790                   advance_pc ((255 - opcode_base) / line_range);
8791                   {
8792                     printf (gettext (" advance address by constant %u to "),
8793                             op_addr_advance);
8794                     print_dwarf_addr (dwflmod, 0, address, address);
8795                     if (show_op_index)
8796                       printf (gettext (", op_index to %u"), op_index);
8797                     printf ("\n");
8798                   }
8799                   break;
8800
8801                 case DW_LNS_fixed_advance_pc:
8802                   /* Takes one 16 bit parameter which is added to the
8803                      address.  */
8804                   if (unlikely (standard_opcode_lengths[opcode] != 1))
8805                     goto invalid_unit;
8806
8807                   u128 = read_2ubyte_unaligned_inc (dbg, linep);
8808                   address += u128;
8809                   op_index = 0;
8810                   {
8811                     printf (gettext ("\
8812  advance address by fixed value %u to \n"),
8813                             u128);
8814                     print_dwarf_addr (dwflmod, 0, address, address);
8815                     printf ("\n");
8816                   }
8817                   break;
8818
8819                 case DW_LNS_set_prologue_end:
8820                   /* Takes no argument.  */
8821                   puts (gettext (" set prologue end flag"));
8822                   break;
8823
8824                 case DW_LNS_set_epilogue_begin:
8825                   /* Takes no argument.  */
8826                   puts (gettext (" set epilogue begin flag"));
8827                   break;
8828
8829                 case DW_LNS_set_isa:
8830                   /* Takes one uleb128 parameter which is stored in isa.  */
8831                   if (unlikely (standard_opcode_lengths[opcode] != 1))
8832                     goto invalid_unit;
8833
8834                   get_uleb128 (u128, linep, lineendp);
8835                   printf (gettext (" set isa to %u\n"), u128);
8836                   break;
8837                 }
8838             }
8839           else
8840             {
8841               /* This is a new opcode the generator but not we know about.
8842                  Read the parameters associated with it but then discard
8843                  everything.  Read all the parameters for this opcode.  */
8844               printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8845                                 " unknown opcode with %" PRIu8 " parameters:",
8846                                 standard_opcode_lengths[opcode]),
8847                       standard_opcode_lengths[opcode]);
8848               for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
8849                 {
8850                   get_uleb128 (u128, linep, lineendp);
8851                   if (n != standard_opcode_lengths[opcode])
8852                     putc_unlocked (',', stdout);
8853                   printf (" %u", u128);
8854                 }
8855
8856               /* Next round, ignore this opcode.  */
8857               continue;
8858             }
8859         }
8860     }
8861
8862   /* There must only be one data block.  */
8863   assert (elf_getdata (scn, data) == NULL);
8864 }
8865
8866
8867 static void
8868 print_debug_loclists_section (Dwfl_Module *dwflmod,
8869                               Ebl *ebl,
8870                               GElf_Ehdr *ehdr __attribute__ ((unused)),
8871                               Elf_Scn *scn, GElf_Shdr *shdr,
8872                               Dwarf *dbg)
8873 {
8874   printf (gettext ("\
8875 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8876           elf_ndxscn (scn), section_name (ebl, shdr),
8877           (uint64_t) shdr->sh_offset);
8878
8879   Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
8880                     ?: elf_rawdata (scn, NULL));
8881   if (unlikely (data == NULL))
8882     {
8883       error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
8884              elf_errmsg (-1));
8885       return;
8886     }
8887
8888   /* For the listptr to get the base address/CU.  */
8889   sort_listptr (&known_loclistsptr, "loclistsptr");
8890   size_t listptr_idx = 0;
8891
8892   const unsigned char *readp = data->d_buf;
8893   const unsigned char *const dataend = ((unsigned char *) data->d_buf
8894                                         + data->d_size);
8895   while (readp < dataend)
8896     {
8897       if (unlikely (readp > dataend - 4))
8898         {
8899         invalid_data:
8900           error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8901                  elf_ndxscn (scn), section_name (ebl, shdr));
8902           return;
8903         }
8904
8905       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
8906       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
8907               (uint64_t) offset);
8908
8909       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
8910       unsigned int offset_size = 4;
8911       if (unlikely (unit_length == 0xffffffff))
8912         {
8913           if (unlikely (readp > dataend - 8))
8914             goto invalid_data;
8915
8916           unit_length = read_8ubyte_unaligned_inc (dbg, readp);
8917           offset_size = 8;
8918         }
8919       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
8920
8921       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
8922          bytes to complete the header.  And this unit cannot go beyond
8923          the section data.  */
8924       if (readp > dataend - 8
8925           || unit_length < 8
8926           || unit_length > (uint64_t) (dataend - readp))
8927         goto invalid_data;
8928
8929       const unsigned char *nexthdr = readp + unit_length;
8930
8931       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
8932       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
8933
8934       if (version != 5)
8935         {
8936           error (0, 0, gettext ("Unknown version"));
8937           goto next_table;
8938         }
8939
8940       uint8_t address_size = *readp++;
8941       printf (gettext (" Address size:   %8" PRIu64 "\n"),
8942               (uint64_t) address_size);
8943
8944       if (address_size != 4 && address_size != 8)
8945         {
8946           error (0, 0, gettext ("unsupported address size"));
8947           goto next_table;
8948         }
8949
8950       uint8_t segment_size = *readp++;
8951       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
8952               (uint64_t) segment_size);
8953
8954       if (segment_size != 0)
8955         {
8956           error (0, 0, gettext ("unsupported segment size"));
8957           goto next_table;
8958         }
8959
8960       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
8961       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
8962               (uint64_t) offset_entry_count);
8963
8964       /* We need the CU that uses this unit to get the initial base address. */
8965       Dwarf_Addr cu_base = 0;
8966       struct Dwarf_CU *cu = NULL;
8967       if (listptr_cu (&known_loclistsptr, &listptr_idx,
8968                       (Dwarf_Off) offset,
8969                       (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
8970                       &cu_base, &cu)
8971           || split_dwarf_cu_base (dbg, &cu, &cu_base))
8972         {
8973           Dwarf_Die cudie;
8974           if (dwarf_cu_die (cu, &cudie,
8975                             NULL, NULL, NULL, NULL,
8976                             NULL, NULL) == NULL)
8977             printf (gettext (" Unknown CU base: "));
8978           else
8979             printf (gettext (" CU [%6" PRIx64 "] base: "),
8980                     dwarf_dieoffset (&cudie));
8981           print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
8982           printf ("\n");
8983         }
8984       else
8985         printf (gettext (" Not associated with a CU.\n"));
8986
8987       printf ("\n");
8988
8989       const unsigned char *offset_array_start = readp;
8990       if (offset_entry_count > 0)
8991         {
8992           uint64_t max_entries = (unit_length - 8) / offset_size;
8993           if (offset_entry_count > max_entries)
8994             {
8995               error (0, 0,
8996                      gettext ("too many offset entries for unit length"));
8997               offset_entry_count = max_entries;
8998             }
8999
9000           printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
9001                   (uint64_t) (offset_array_start
9002                               - (unsigned char *) data->d_buf));
9003           for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9004             {
9005               printf ("   [%6" PRIu32 "] ", idx);
9006               if (offset_size == 4)
9007                 {
9008                   uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9009                   printf ("0x%" PRIx32 "\n", off);
9010                 }
9011               else
9012                 {
9013                   uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9014                   printf ("0x%" PRIx64 "\n", off);
9015                 }
9016             }
9017           printf ("\n");
9018         }
9019
9020       Dwarf_Addr base = cu_base;
9021       bool start_of_list = true;
9022       while (readp < nexthdr)
9023         {
9024           uint8_t kind = *readp++;
9025           uint64_t op1, op2, len;
9026
9027           /* Skip padding.  */
9028           if (start_of_list && kind == DW_LLE_end_of_list)
9029             continue;
9030
9031           if (start_of_list)
9032             {
9033               base = cu_base;
9034               printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9035                       (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9036                       (uint64_t) (readp - offset_array_start - 1));
9037               start_of_list = false;
9038             }
9039
9040           printf ("    %s", dwarf_loc_list_encoding_name (kind));
9041           switch (kind)
9042             {
9043             case DW_LLE_end_of_list:
9044               start_of_list = true;
9045               printf ("\n\n");
9046               break;
9047
9048             case DW_LLE_base_addressx:
9049               if ((uint64_t) (nexthdr - readp) < 1)
9050                 {
9051                 invalid_entry:
9052                   error (0, 0, gettext ("invalid loclists data"));
9053                   goto next_table;
9054                 }
9055               get_uleb128 (op1, readp, nexthdr);
9056               printf (" %" PRIx64 "\n", op1);
9057               if (! print_unresolved_addresses)
9058                 {
9059                   Dwarf_Addr addr;
9060                   if (get_indexed_addr (cu, op1, &addr) != 0)
9061                     printf ("      ???\n");
9062                   else
9063                     {
9064                       printf ("      ");
9065                       print_dwarf_addr (dwflmod, address_size, addr, addr);
9066                       printf ("\n");
9067                     }
9068                 }
9069               break;
9070
9071             case DW_LLE_startx_endx:
9072               if ((uint64_t) (nexthdr - readp) < 1)
9073                 goto invalid_entry;
9074               get_uleb128 (op1, readp, nexthdr);
9075               if ((uint64_t) (nexthdr - readp) < 1)
9076                 goto invalid_entry;
9077               get_uleb128 (op2, readp, nexthdr);
9078               printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9079               if (! print_unresolved_addresses)
9080                 {
9081                   Dwarf_Addr addr1;
9082                   Dwarf_Addr addr2;
9083                   if (get_indexed_addr (cu, op1, &addr1) != 0
9084                       || get_indexed_addr (cu, op2, &addr2) != 0)
9085                     {
9086                       printf ("      ???..\n");
9087                       printf ("      ???\n");
9088                     }
9089                   else
9090                     {
9091                       printf ("      ");
9092                       print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9093                       printf ("..\n      ");
9094                       print_dwarf_addr (dwflmod, address_size,
9095                                         addr2 - 1, addr2);
9096                       printf ("\n");
9097                     }
9098                 }
9099               if ((uint64_t) (nexthdr - readp) < 1)
9100                 goto invalid_entry;
9101               get_uleb128 (len, readp, nexthdr);
9102               if ((uint64_t) (nexthdr - readp) < len)
9103                 goto invalid_entry;
9104               print_ops (dwflmod, dbg, 8, 8, version,
9105                          address_size, offset_size, cu, len, readp);
9106               readp += len;
9107               break;
9108
9109             case DW_LLE_startx_length:
9110               if ((uint64_t) (nexthdr - readp) < 1)
9111                 goto invalid_entry;
9112               get_uleb128 (op1, readp, nexthdr);
9113               if ((uint64_t) (nexthdr - readp) < 1)
9114                 goto invalid_entry;
9115               get_uleb128 (op2, readp, nexthdr);
9116               printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9117               if (! print_unresolved_addresses)
9118                 {
9119                   Dwarf_Addr addr1;
9120                   Dwarf_Addr addr2;
9121                   if (get_indexed_addr (cu, op1, &addr1) != 0)
9122                     {
9123                       printf ("      ???..\n");
9124                       printf ("      ???\n");
9125                     }
9126                   else
9127                     {
9128                       addr2 = addr1 + op2;
9129                       printf ("      ");
9130                       print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9131                       printf ("..\n      ");
9132                       print_dwarf_addr (dwflmod, address_size,
9133                                         addr2 - 1, addr2);
9134                       printf ("\n");
9135                     }
9136                 }
9137               if ((uint64_t) (nexthdr - readp) < 1)
9138                 goto invalid_entry;
9139               get_uleb128 (len, readp, nexthdr);
9140               if ((uint64_t) (nexthdr - readp) < len)
9141                 goto invalid_entry;
9142               print_ops (dwflmod, dbg, 8, 8, version,
9143                          address_size, offset_size, cu, len, readp);
9144               readp += len;
9145               break;
9146
9147             case DW_LLE_offset_pair:
9148               if ((uint64_t) (nexthdr - readp) < 1)
9149                 goto invalid_entry;
9150               get_uleb128 (op1, readp, nexthdr);
9151               if ((uint64_t) (nexthdr - readp) < 1)
9152                 goto invalid_entry;
9153               get_uleb128 (op2, readp, nexthdr);
9154               printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9155               if (! print_unresolved_addresses)
9156                 {
9157                   op1 += base;
9158                   op2 += base;
9159                   printf ("      ");
9160                   print_dwarf_addr (dwflmod, address_size, op1, op1);
9161                   printf ("..\n      ");
9162                   print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9163                   printf ("\n");
9164                 }
9165               if ((uint64_t) (nexthdr - readp) < 1)
9166                 goto invalid_entry;
9167               get_uleb128 (len, readp, nexthdr);
9168               if ((uint64_t) (nexthdr - readp) < len)
9169                 goto invalid_entry;
9170               print_ops (dwflmod, dbg, 8, 8, version,
9171                          address_size, offset_size, cu, len, readp);
9172               readp += len;
9173               break;
9174
9175             case DW_LLE_default_location:
9176               if ((uint64_t) (nexthdr - readp) < 1)
9177                 goto invalid_entry;
9178               get_uleb128 (len, readp, nexthdr);
9179               if ((uint64_t) (nexthdr - readp) < len)
9180                 goto invalid_entry;
9181               print_ops (dwflmod, dbg, 8, 8, version,
9182                          address_size, offset_size, cu, len, readp);
9183               readp += len;
9184               break;
9185
9186             case DW_LLE_base_address:
9187               if (address_size == 4)
9188                 {
9189                   if ((uint64_t) (nexthdr - readp) < 4)
9190                     goto invalid_entry;
9191                   op1 = read_4ubyte_unaligned_inc (dbg, readp);
9192                 }
9193               else
9194                 {
9195                   if ((uint64_t) (nexthdr - readp) < 8)
9196                     goto invalid_entry;
9197                   op1 = read_8ubyte_unaligned_inc (dbg, readp);
9198                 }
9199               base = op1;
9200               printf (" 0x%" PRIx64 "\n", base);
9201               if (! print_unresolved_addresses)
9202                 {
9203                   printf ("      ");
9204                   print_dwarf_addr (dwflmod, address_size, base, base);
9205                   printf ("\n");
9206                 }
9207               break;
9208
9209             case DW_LLE_start_end:
9210               if (address_size == 4)
9211                 {
9212                   if ((uint64_t) (nexthdr - readp) < 8)
9213                     goto invalid_entry;
9214                   op1 = read_4ubyte_unaligned_inc (dbg, readp);
9215                   op2 = read_4ubyte_unaligned_inc (dbg, readp);
9216                 }
9217               else
9218                 {
9219                   if ((uint64_t) (nexthdr - readp) < 16)
9220                     goto invalid_entry;
9221                   op1 = read_8ubyte_unaligned_inc (dbg, readp);
9222                   op2 = read_8ubyte_unaligned_inc (dbg, readp);
9223                 }
9224               printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9225               if (! print_unresolved_addresses)
9226                 {
9227                   printf ("      ");
9228                   print_dwarf_addr (dwflmod, address_size, op1, op1);
9229                   printf ("..\n      ");
9230                   print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9231                   printf ("\n");
9232                 }
9233               if ((uint64_t) (nexthdr - readp) < 1)
9234                 goto invalid_entry;
9235               get_uleb128 (len, readp, nexthdr);
9236               if ((uint64_t) (nexthdr - readp) < len)
9237                 goto invalid_entry;
9238               print_ops (dwflmod, dbg, 8, 8, version,
9239                          address_size, offset_size, cu, len, readp);
9240               readp += len;
9241               break;
9242
9243             case DW_LLE_start_length:
9244               if (address_size == 4)
9245                 {
9246                   if ((uint64_t) (nexthdr - readp) < 4)
9247                     goto invalid_entry;
9248                   op1 = read_4ubyte_unaligned_inc (dbg, readp);
9249                 }
9250               else
9251                 {
9252                   if ((uint64_t) (nexthdr - readp) < 8)
9253                     goto invalid_entry;
9254                   op1 = read_8ubyte_unaligned_inc (dbg, readp);
9255                 }
9256               if ((uint64_t) (nexthdr - readp) < 1)
9257                 goto invalid_entry;
9258               get_uleb128 (op2, readp, nexthdr);
9259               printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9260               if (! print_unresolved_addresses)
9261                 {
9262                   op2 = op1 + op2;
9263                   printf ("      ");
9264                   print_dwarf_addr (dwflmod, address_size, op1, op1);
9265                   printf ("..\n      ");
9266                   print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9267                   printf ("\n");
9268                 }
9269               if ((uint64_t) (nexthdr - readp) < 1)
9270                 goto invalid_entry;
9271               get_uleb128 (len, readp, nexthdr);
9272               if ((uint64_t) (nexthdr - readp) < len)
9273                 goto invalid_entry;
9274               print_ops (dwflmod, dbg, 8, 8, version,
9275                          address_size, offset_size, cu, len, readp);
9276               readp += len;
9277               break;
9278
9279             default:
9280               goto invalid_entry;
9281             }
9282         }
9283
9284     next_table:
9285       if (readp != nexthdr)
9286         {
9287           size_t padding = nexthdr - readp;
9288           printf (gettext ("   %zu padding bytes\n\n"), padding);
9289           readp = nexthdr;
9290         }
9291     }
9292 }
9293
9294
9295 static void
9296 print_debug_loc_section (Dwfl_Module *dwflmod,
9297                          Ebl *ebl, GElf_Ehdr *ehdr,
9298                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9299 {
9300   Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9301                     ?: elf_rawdata (scn, NULL));
9302
9303   if (unlikely (data == NULL))
9304     {
9305       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9306              elf_errmsg (-1));
9307       return;
9308     }
9309
9310   printf (gettext ("\
9311 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9312           elf_ndxscn (scn), section_name (ebl, shdr),
9313           (uint64_t) shdr->sh_offset);
9314
9315   sort_listptr (&known_locsptr, "loclistptr");
9316   size_t listptr_idx = 0;
9317
9318   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9319   uint_fast8_t offset_size = 4;
9320
9321   bool first = true;
9322   Dwarf_Addr base = 0;
9323   unsigned char *readp = data->d_buf;
9324   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9325   Dwarf_CU *last_cu = NULL;
9326   while (readp < endp)
9327     {
9328       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9329       Dwarf_CU *cu = last_cu;
9330       unsigned int attr = 0;
9331
9332       if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9333                                       &address_size, &offset_size, &base,
9334                                       &cu, offset, &readp, endp, &attr))
9335         continue;
9336
9337       if (last_cu != cu)
9338        {
9339         Dwarf_Die cudie;
9340         if (dwarf_cu_die (cu, &cudie,
9341                           NULL, NULL, NULL, NULL,
9342                           NULL, NULL) == NULL)
9343           printf (gettext ("\n Unknown CU base: "));
9344         else
9345           printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9346                   dwarf_dieoffset (&cudie));
9347         print_dwarf_addr (dwflmod, address_size, base, base);
9348         printf ("\n");
9349        }
9350       last_cu = cu;
9351
9352       if (attr == DW_AT_GNU_locviews)
9353         {
9354           Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9355                                                     listptr_idx);
9356           const unsigned char *locp = readp;
9357           const unsigned char *locendp;
9358           if (next_off == 0
9359               || next_off > (size_t) (endp
9360                                       - (const unsigned char *) data->d_buf))
9361             locendp = endp;
9362           else
9363             locendp = (const unsigned char *) data->d_buf + next_off;
9364
9365           while (locp < locendp)
9366             {
9367               uint64_t v1, v2;
9368               get_uleb128 (v1, locp, locendp);
9369               if (locp >= locendp)
9370                 {
9371                   printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9372                   break;
9373                 }
9374               get_uleb128 (v2, locp, locendp);
9375               if (first)                /* First view pair in a list.  */
9376                 printf (" [%6tx] ", offset);
9377               else
9378                 printf ("          ");
9379               printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9380               first = false;
9381             }
9382
9383           first = true;
9384           readp = (unsigned char *) locendp;
9385           continue;
9386         }
9387
9388       /* GNU DebugFission encoded addresses as addrx.  */
9389       bool is_debugfission = ((cu != NULL
9390                                || split_dwarf_cu_base (dbg, &cu, &base))
9391                               && (cu->version < 5
9392                                   && cu->unit_type == DW_UT_split_compile));
9393       if (!is_debugfission
9394           && unlikely (data->d_size - offset < (size_t) address_size * 2))
9395         {
9396         invalid_data:
9397           printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9398           break;
9399         }
9400
9401       Dwarf_Addr begin;
9402       Dwarf_Addr end;
9403       bool use_base = true;
9404       if (is_debugfission)
9405         {
9406           const unsigned char *locp = readp;
9407           const unsigned char *locendp = readp + data->d_size;
9408           if (locp >= locendp)
9409             goto invalid_data;
9410
9411           Dwarf_Word idx;
9412           unsigned char code = *locp++;
9413           switch (code)
9414             {
9415             case DW_LLE_GNU_end_of_list_entry:
9416               begin = 0;
9417               end = 0;
9418               break;
9419
9420             case DW_LLE_GNU_base_address_selection_entry:
9421               if (locp >= locendp)
9422                 goto invalid_data;
9423               begin = (Dwarf_Addr) -1;
9424               get_uleb128 (idx, locp, locendp);
9425               if (get_indexed_addr (cu, idx, &end) != 0)
9426                 end = idx; /* ... */
9427               break;
9428
9429             case DW_LLE_GNU_start_end_entry:
9430               if (locp >= locendp)
9431                 goto invalid_data;
9432               get_uleb128 (idx, locp, locendp);
9433               if (get_indexed_addr (cu, idx, &begin) != 0)
9434                 begin = idx; /* ... */
9435               if (locp >= locendp)
9436                 goto invalid_data;
9437               get_uleb128 (idx, locp, locendp);
9438               if (get_indexed_addr (cu, idx, &end) != 0)
9439                 end = idx; /* ... */
9440               use_base = false;
9441               break;
9442
9443             case DW_LLE_GNU_start_length_entry:
9444               if (locp >= locendp)
9445                 goto invalid_data;
9446               get_uleb128 (idx, locp, locendp);
9447               if (get_indexed_addr (cu, idx, &begin) != 0)
9448                 begin = idx; /* ... */
9449               if (locendp - locp < 4)
9450                 goto invalid_data;
9451               end = read_4ubyte_unaligned_inc (dbg, locp);
9452               end += begin;
9453               use_base = false;
9454               break;
9455
9456             default:
9457                 goto invalid_data;
9458             }
9459
9460           readp = (unsigned char *) locp;
9461         }
9462       else if (address_size == 8)
9463         {
9464           begin = read_8ubyte_unaligned_inc (dbg, readp);
9465           end = read_8ubyte_unaligned_inc (dbg, readp);
9466         }
9467       else
9468         {
9469           begin = read_4ubyte_unaligned_inc (dbg, readp);
9470           end = read_4ubyte_unaligned_inc (dbg, readp);
9471           if (begin == (Dwarf_Addr) (uint32_t) -1)
9472             begin = (Dwarf_Addr) -1l;
9473         }
9474
9475       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
9476         {
9477           printf (gettext (" [%6tx] base address\n          "), offset);
9478           print_dwarf_addr (dwflmod, address_size, end, end);
9479           printf ("\n");
9480           base = end;
9481         }
9482       else if (begin == 0 && end == 0) /* End of list entry.  */
9483         {
9484           if (first)
9485             printf (gettext (" [%6tx] empty list\n"), offset);
9486           first = true;
9487         }
9488       else
9489         {
9490           /* We have a location expression entry.  */
9491           uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9492
9493           if (first)            /* First entry in a list.  */
9494             printf (" [%6tx] ", offset);
9495           else
9496             printf ("          ");
9497
9498           printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9499           if (! print_unresolved_addresses)
9500             {
9501               Dwarf_Addr dab = use_base ? base + begin : begin;
9502               Dwarf_Addr dae = use_base ? base + end : end;
9503               printf ("          ");
9504               print_dwarf_addr (dwflmod, address_size, dab, dab);
9505               printf ("..\n          ");
9506               print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9507               printf ("\n");
9508             }
9509
9510           if (endp - readp <= (ptrdiff_t) len)
9511             {
9512               fputs (gettext ("   <INVALID DATA>\n"), stdout);
9513               break;
9514             }
9515
9516           print_ops (dwflmod, dbg, 11, 11,
9517                      cu != NULL ? cu->version : 3,
9518                      address_size, offset_size, cu, len, readp);
9519
9520           first = false;
9521           readp += len;
9522         }
9523     }
9524 }
9525
9526 struct mac_culist
9527 {
9528   Dwarf_Die die;
9529   Dwarf_Off offset;
9530   Dwarf_Files *files;
9531   struct mac_culist *next;
9532 };
9533
9534
9535 static int
9536 mac_compare (const void *p1, const void *p2)
9537 {
9538   struct mac_culist *m1 = (struct mac_culist *) p1;
9539   struct mac_culist *m2 = (struct mac_culist *) p2;
9540
9541   if (m1->offset < m2->offset)
9542     return -1;
9543   if (m1->offset > m2->offset)
9544     return 1;
9545   return 0;
9546 }
9547
9548
9549 static void
9550 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9551                              Ebl *ebl,
9552                              GElf_Ehdr *ehdr __attribute__ ((unused)),
9553                              Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9554 {
9555   printf (gettext ("\
9556 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9557           elf_ndxscn (scn), section_name (ebl, shdr),
9558           (uint64_t) shdr->sh_offset);
9559   putc_unlocked ('\n', stdout);
9560
9561   /* There is no function in libdw to iterate over the raw content of
9562      the section but it is easy enough to do.  */
9563   Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9564                     ?: elf_rawdata (scn, NULL));
9565   if (unlikely (data == NULL))
9566     {
9567       error (0, 0, gettext ("cannot get macro information section data: %s"),
9568              elf_errmsg (-1));
9569       return;
9570     }
9571
9572   /* Get the source file information for all CUs.  */
9573   Dwarf_Off offset;
9574   Dwarf_Off ncu = 0;
9575   size_t hsize;
9576   struct mac_culist *culist = NULL;
9577   size_t nculist = 0;
9578   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9579     {
9580       Dwarf_Die cudie;
9581       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9582         continue;
9583
9584       Dwarf_Attribute attr;
9585       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9586         continue;
9587
9588       Dwarf_Word macoff;
9589       if (dwarf_formudata (&attr, &macoff) != 0)
9590         continue;
9591
9592       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9593       newp->die = cudie;
9594       newp->offset = macoff;
9595       newp->files = NULL;
9596       newp->next = culist;
9597       culist = newp;
9598       ++nculist;
9599     }
9600
9601   /* Convert the list into an array for easier consumption.  */
9602   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9603                                                          * sizeof (*cus));
9604   /* Add sentinel.  */
9605   cus[nculist].offset = data->d_size;
9606   cus[nculist].files = (Dwarf_Files *) -1l;
9607   if (nculist > 0)
9608     {
9609       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9610         {
9611           assert (cnt < nculist);
9612           cus[cnt] = *culist;
9613           culist = culist->next;
9614         }
9615
9616       /* Sort the array according to the offset in the .debug_macinfo
9617          section.  Note we keep the sentinel at the end.  */
9618       qsort (cus, nculist, sizeof (*cus), mac_compare);
9619     }
9620
9621   const unsigned char *readp = (const unsigned char *) data->d_buf;
9622   const unsigned char *readendp = readp + data->d_size;
9623   int level = 1;
9624
9625   while (readp < readendp)
9626     {
9627       unsigned int opcode = *readp++;
9628       unsigned int u128;
9629       unsigned int u128_2;
9630       const unsigned char *endp;
9631
9632       switch (opcode)
9633         {
9634         case DW_MACINFO_define:
9635         case DW_MACINFO_undef:
9636         case DW_MACINFO_vendor_ext:
9637           /*  For the first two opcodes the parameters are
9638                 line, string
9639               For the latter
9640                 number, string.
9641               We can treat these cases together.  */
9642           get_uleb128 (u128, readp, readendp);
9643
9644           endp = memchr (readp, '\0', readendp - readp);
9645           if (unlikely (endp == NULL))
9646             {
9647               printf (gettext ("\
9648 %*s*** non-terminated string at end of section"),
9649                       level, "");
9650               return;
9651             }
9652
9653           if (opcode == DW_MACINFO_define)
9654             printf ("%*s#define %s, line %u\n",
9655                     level, "", (char *) readp, u128);
9656           else if (opcode == DW_MACINFO_undef)
9657             printf ("%*s#undef %s, line %u\n",
9658                     level, "", (char *) readp, u128);
9659           else
9660             printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9661
9662           readp = endp + 1;
9663           break;
9664
9665         case DW_MACINFO_start_file:
9666           /* The two parameters are line and file index, in this order.  */
9667           get_uleb128 (u128, readp, readendp);
9668           if (readendp - readp < 1)
9669             {
9670               printf (gettext ("\
9671 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9672                       level, "");
9673               return;
9674             }
9675           get_uleb128 (u128_2, readp, readendp);
9676
9677           /* Find the CU DIE for this file.  */
9678           size_t macoff = readp - (const unsigned char *) data->d_buf;
9679           const char *fname = "???";
9680           if (macoff >= cus[0].offset)
9681             {
9682               while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9683                 ++cus;
9684
9685               if (cus[0].files == NULL
9686                 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9687                 cus[0].files = (Dwarf_Files *) -1l;
9688
9689               if (cus[0].files != (Dwarf_Files *) -1l)
9690                 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9691                          ?: "???");
9692             }
9693
9694           printf ("%*sstart_file %u, [%u] %s\n",
9695                   level, "", u128, u128_2, fname);
9696           ++level;
9697           break;
9698
9699         case DW_MACINFO_end_file:
9700           --level;
9701           printf ("%*send_file\n", level, "");
9702           /* Nothing more to do.  */
9703           break;
9704
9705         default:
9706           // XXX gcc seems to generate files with a trailing zero.
9707           if (unlikely (opcode != 0 || readp != readendp))
9708             printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9709           break;
9710         }
9711     }
9712 }
9713
9714
9715 static void
9716 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9717                            Ebl *ebl,
9718                            GElf_Ehdr *ehdr __attribute__ ((unused)),
9719                            Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9720 {
9721   printf (gettext ("\
9722 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9723           elf_ndxscn (scn), section_name (ebl, shdr),
9724           (uint64_t) shdr->sh_offset);
9725   putc_unlocked ('\n', stdout);
9726
9727   Elf_Data *data =  elf_getdata (scn, NULL);
9728   if (unlikely (data == NULL))
9729     {
9730       error (0, 0, gettext ("cannot get macro information section data: %s"),
9731              elf_errmsg (-1));
9732       return;
9733     }
9734
9735   /* Get the source file information for all CUs.  Uses same
9736      datastructure as macinfo.  But uses offset field to directly
9737      match .debug_line offset.  And just stored in a list.  */
9738   Dwarf_Off offset;
9739   Dwarf_Off ncu = 0;
9740   size_t hsize;
9741   struct mac_culist *culist = NULL;
9742   size_t nculist = 0;
9743   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9744     {
9745       Dwarf_Die cudie;
9746       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9747         continue;
9748
9749       Dwarf_Attribute attr;
9750       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9751         continue;
9752
9753       Dwarf_Word lineoff;
9754       if (dwarf_formudata (&attr, &lineoff) != 0)
9755         continue;
9756
9757       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9758       newp->die = cudie;
9759       newp->offset = lineoff;
9760       newp->files = NULL;
9761       newp->next = culist;
9762       culist = newp;
9763       ++nculist;
9764     }
9765
9766   const unsigned char *readp = (const unsigned char *) data->d_buf;
9767   const unsigned char *readendp = readp + data->d_size;
9768
9769   while (readp < readendp)
9770     {
9771       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
9772               (uint64_t) (readp - (const unsigned char *) data->d_buf));
9773
9774       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9775       // optional vendor extension macro entry table.
9776       if (readp + 2 > readendp)
9777         {
9778         invalid_data:
9779           error (0, 0, gettext ("invalid data"));
9780           return;
9781         }
9782       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9783       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
9784
9785       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
9786       // 5 when it gets standardized.
9787       if (vers != 4 && vers != 5)
9788         {
9789           printf (gettext ("  unknown version, cannot parse section\n"));
9790           return;
9791         }
9792
9793       if (readp + 1 > readendp)
9794         goto invalid_data;
9795       const unsigned char flag = *readp++;
9796       printf (gettext (" Flag:               0x%" PRIx8), flag);
9797       if (flag != 0)
9798         {
9799           printf (" (");
9800           if ((flag & 0x01) != 0)
9801             {
9802               printf ("offset_size");
9803               if ((flag & 0xFE) !=  0)
9804                 printf (", ");
9805             }
9806           if ((flag & 0x02) != 0)
9807             {
9808               printf ("debug_line_offset");
9809               if ((flag & 0xFC) !=  0)
9810                 printf (", ");
9811             }
9812           if ((flag & 0x04) != 0)
9813             {
9814               printf ("operands_table");
9815               if ((flag & 0xF8) !=  0)
9816                 printf (", ");
9817             }
9818           if ((flag & 0xF8) != 0)
9819             printf ("unknown");
9820           printf (")");
9821         }
9822       printf ("\n");
9823
9824       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9825       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
9826       Dwarf_Off line_offset = -1;
9827       if (flag & 0x02)
9828         {
9829           if (offset_len == 8)
9830             line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9831           else
9832             line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9833           printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9834                   line_offset);
9835         }
9836
9837       struct mac_culist *cu = NULL;
9838       if (line_offset != (Dwarf_Off) -1)
9839         {
9840           cu = culist;
9841           while (cu != NULL && line_offset != cu->offset)
9842             cu = cu->next;
9843         }
9844
9845       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9846                                                                ? cu->die.cu
9847                                                                : NULL));
9848
9849       const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9850       memset (vendor, 0, sizeof vendor);
9851       if (flag & 0x04)
9852         {
9853           // 1 byte length, for each item, 1 byte opcode, uleb128 number
9854           // of arguments, for each argument 1 byte form code.
9855           if (readp + 1 > readendp)
9856             goto invalid_data;
9857           unsigned int tlen = *readp++;
9858           printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
9859                   tlen);
9860           for (unsigned int i = 0; i < tlen; i++)
9861             {
9862               if (readp + 1 > readendp)
9863                 goto invalid_data;
9864               unsigned int opcode = *readp++;
9865               printf (gettext ("    [%" PRIx8 "]"), opcode);
9866               if (opcode < DW_MACRO_lo_user
9867                   || opcode > DW_MACRO_hi_user)
9868                 goto invalid_data;
9869               // Record the start of description for this vendor opcode.
9870               // uleb128 nr args, 1 byte per arg form.
9871               vendor[opcode - DW_MACRO_lo_user] = readp;
9872               if (readp + 1 > readendp)
9873                 goto invalid_data;
9874               unsigned int args = *readp++;
9875               if (args > 0)
9876                 {
9877                   printf (gettext (" %" PRIu8 " arguments:"), args);
9878                   while (args > 0)
9879                     {
9880                       if (readp + 1 > readendp)
9881                         goto invalid_data;
9882                       unsigned int form = *readp++;
9883                       printf (" %s", dwarf_form_name (form));
9884                       if (! libdw_valid_user_form (form))
9885                         goto invalid_data;
9886                       args--;
9887                       if (args > 0)
9888                         putchar_unlocked (',');
9889                     }
9890                 }
9891               else
9892                 printf (gettext (" no arguments."));
9893               putchar_unlocked ('\n');
9894             }
9895         }
9896       putchar_unlocked ('\n');
9897
9898       int level = 1;
9899       if (readp + 1 > readendp)
9900         goto invalid_data;
9901       unsigned int opcode = *readp++;
9902       while (opcode != 0)
9903         {
9904           unsigned int u128;
9905           unsigned int u128_2;
9906           const unsigned char *endp;
9907           uint64_t off;
9908
9909           switch (opcode)
9910             {
9911             case DW_MACRO_start_file:
9912               get_uleb128 (u128, readp, readendp);
9913               if (readp >= readendp)
9914                 goto invalid_data;
9915               get_uleb128 (u128_2, readp, readendp);
9916
9917               /* Find the CU DIE that matches this line offset.  */
9918               const char *fname = "???";
9919               if (cu != NULL)
9920                 {
9921                   if (cu->files == NULL
9922                       && dwarf_getsrcfiles (&cu->die, &cu->files,
9923                                             NULL) != 0)
9924                     cu->files = (Dwarf_Files *) -1l;
9925
9926                   if (cu->files != (Dwarf_Files *) -1l)
9927                     fname = (dwarf_filesrc (cu->files, u128_2,
9928                                             NULL, NULL) ?: "???");
9929                 }
9930               printf ("%*sstart_file %u, [%u] %s\n",
9931                       level, "", u128, u128_2, fname);
9932               ++level;
9933               break;
9934
9935             case DW_MACRO_end_file:
9936               --level;
9937               printf ("%*send_file\n", level, "");
9938               break;
9939
9940             case DW_MACRO_define:
9941               get_uleb128 (u128, readp, readendp);
9942               endp = memchr (readp, '\0', readendp - readp);
9943               if (endp == NULL)
9944                 goto invalid_data;
9945               printf ("%*s#define %s, line %u\n",
9946                       level, "", readp, u128);
9947               readp = endp + 1;
9948               break;
9949
9950             case DW_MACRO_undef:
9951               get_uleb128 (u128, readp, readendp);
9952               endp = memchr (readp, '\0', readendp - readp);
9953               if (endp == NULL)
9954                 goto invalid_data;
9955               printf ("%*s#undef %s, line %u\n",
9956                       level, "", readp, u128);
9957               readp = endp + 1;
9958               break;
9959
9960             case DW_MACRO_define_strp:
9961               get_uleb128 (u128, readp, readendp);
9962               if (readp + offset_len > readendp)
9963                 goto invalid_data;
9964               if (offset_len == 8)
9965                 off = read_8ubyte_unaligned_inc (dbg, readp);
9966               else
9967                 off = read_4ubyte_unaligned_inc (dbg, readp);
9968               printf ("%*s#define %s, line %u (indirect)\n",
9969                       level, "", dwarf_getstring (dbg, off, NULL), u128);
9970               break;
9971
9972             case DW_MACRO_undef_strp:
9973               get_uleb128 (u128, readp, readendp);
9974               if (readp + offset_len > readendp)
9975                 goto invalid_data;
9976               if (offset_len == 8)
9977                 off = read_8ubyte_unaligned_inc (dbg, readp);
9978               else
9979                 off = read_4ubyte_unaligned_inc (dbg, readp);
9980               printf ("%*s#undef %s, line %u (indirect)\n",
9981                       level, "", dwarf_getstring (dbg, off, NULL), u128);
9982               break;
9983
9984             case DW_MACRO_import:
9985               if (readp + offset_len > readendp)
9986                 goto invalid_data;
9987               if (offset_len == 8)
9988                 off = read_8ubyte_unaligned_inc (dbg, readp);
9989               else
9990                 off = read_4ubyte_unaligned_inc (dbg, readp);
9991               printf ("%*s#include offset 0x%" PRIx64 "\n",
9992                       level, "", off);
9993               break;
9994
9995             case DW_MACRO_define_sup:
9996               get_uleb128 (u128, readp, readendp);
9997               if (readp + offset_len > readendp)
9998                 goto invalid_data;
9999               printf ("%*s#define ", level, "");
10000               readp =  print_form_data (dbg, DW_FORM_strp_sup,
10001                                         readp, readendp, offset_len,
10002                                         str_offsets_base);
10003               printf (", line %u (sup)\n", u128);
10004               break;
10005
10006             case DW_MACRO_undef_sup:
10007               get_uleb128 (u128, readp, readendp);
10008               if (readp + offset_len > readendp)
10009                 goto invalid_data;
10010               printf ("%*s#undef ", level, "");
10011               readp =  print_form_data (dbg, DW_FORM_strp_sup,
10012                                         readp, readendp, offset_len,
10013                                         str_offsets_base);
10014               printf (", line %u (sup)\n", u128);
10015               break;
10016
10017             case DW_MACRO_import_sup:
10018               if (readp + offset_len > readendp)
10019                 goto invalid_data;
10020               if (offset_len == 8)
10021                 off = read_8ubyte_unaligned_inc (dbg, readp);
10022               else
10023                 off = read_4ubyte_unaligned_inc (dbg, readp);
10024               // XXX Needs support for reading from supplementary object file.
10025               printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10026                       level, "", off);
10027               break;
10028
10029             case DW_MACRO_define_strx:
10030               get_uleb128 (u128, readp, readendp);
10031               if (readp + offset_len > readendp)
10032                 goto invalid_data;
10033               printf ("%*s#define ", level, "");
10034               readp =  print_form_data (dbg, DW_FORM_strx,
10035                                         readp, readendp, offset_len,
10036                                         str_offsets_base);
10037               printf (", line %u (strx)\n", u128);
10038               break;
10039
10040             case DW_MACRO_undef_strx:
10041               get_uleb128 (u128, readp, readendp);
10042               if (readp + offset_len > readendp)
10043                 goto invalid_data;
10044               printf ("%*s#undef ", level, "");
10045               readp =  print_form_data (dbg, DW_FORM_strx,
10046                                         readp, readendp, offset_len,
10047                                         str_offsets_base);
10048               printf (", line %u (strx)\n", u128);
10049               break;
10050
10051             default:
10052               printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10053               if (opcode < DW_MACRO_lo_user
10054                   || opcode > DW_MACRO_lo_user
10055                   || vendor[opcode - DW_MACRO_lo_user] == NULL)
10056                 goto invalid_data;
10057
10058               const unsigned char *op_desc;
10059               op_desc = vendor[opcode - DW_MACRO_lo_user];
10060
10061               // Just skip the arguments, we cannot really interpret them,
10062               // but print as much as we can.
10063               unsigned int args = *op_desc++;
10064               while (args > 0 && readp < readendp)
10065                 {
10066                   unsigned int form = *op_desc++;
10067                   readp = print_form_data (dbg, form, readp, readendp,
10068                                            offset_len, str_offsets_base);
10069                   args--;
10070                   if (args > 0)
10071                     printf (", ");
10072                 }
10073               putchar_unlocked ('\n');
10074             }
10075
10076           if (readp + 1 > readendp)
10077             goto invalid_data;
10078           opcode = *readp++;
10079           if (opcode == 0)
10080             putchar_unlocked ('\n');
10081         }
10082     }
10083 }
10084
10085
10086 /* Callback for printing global names.  */
10087 static int
10088 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10089                 void *arg)
10090 {
10091   int *np = (int *) arg;
10092
10093   printf (gettext (" [%5d] DIE offset: %6" PRId64
10094                    ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10095           (*np)++, global->die_offset, global->cu_offset, global->name);
10096
10097   return 0;
10098 }
10099
10100
10101 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
10102 static void
10103 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10104                               Ebl *ebl,
10105                               GElf_Ehdr *ehdr __attribute__ ((unused)),
10106                               Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10107 {
10108   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10109           elf_ndxscn (scn), section_name (ebl, shdr),
10110           (uint64_t) shdr->sh_offset);
10111
10112   int n = 0;
10113   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10114 }
10115
10116 /* Print the content of the DWARF string section '.debug_str'.  */
10117 static void
10118 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10119                          Ebl *ebl,
10120                          GElf_Ehdr *ehdr __attribute__ ((unused)),
10121                          Elf_Scn *scn, GElf_Shdr *shdr,
10122                          Dwarf *dbg __attribute__ ((unused)))
10123 {
10124   Elf_Data *data = elf_rawdata (scn, NULL);
10125   const size_t sh_size = data ? data->d_size : 0;
10126
10127   /* Compute floor(log16(shdr->sh_size)).  */
10128   GElf_Addr tmp = sh_size;
10129   int digits = 1;
10130   while (tmp >= 16)
10131     {
10132       ++digits;
10133       tmp >>= 4;
10134     }
10135   digits = MAX (4, digits);
10136
10137   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10138                    " %*s  String\n"),
10139           elf_ndxscn (scn),
10140           section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10141           /* TRANS: the debugstr| prefix makes the string unique.  */
10142           digits + 2, sgettext ("debugstr|Offset"));
10143
10144   Dwarf_Off offset = 0;
10145   while (offset < sh_size)
10146     {
10147       size_t len;
10148       const char *str = (const char *) data->d_buf + offset;
10149       const char *endp = memchr (str, '\0', sh_size - offset);
10150       if (unlikely (endp == NULL))
10151         {
10152           printf (gettext (" *** error, missing string terminator\n"));
10153           break;
10154         }
10155
10156       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
10157       len = endp - str;
10158       offset += len + 1;
10159     }
10160 }
10161
10162 static void
10163 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10164                                  Ebl *ebl,
10165                                  GElf_Ehdr *ehdr __attribute__ ((unused)),
10166                                  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10167 {
10168   printf (gettext ("\
10169 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10170           elf_ndxscn (scn), section_name (ebl, shdr),
10171           (uint64_t) shdr->sh_offset);
10172
10173   if (shdr->sh_size == 0)
10174     return;
10175
10176   /* We like to get the section from libdw to make sure they are relocated.  */
10177   Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10178                     ?: elf_rawdata (scn, NULL));
10179   if (unlikely (data == NULL))
10180     {
10181       error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10182              elf_errmsg (-1));
10183       return;
10184     }
10185
10186   size_t idx = 0;
10187   sort_listptr (&known_stroffbases, "str_offsets");
10188
10189   const unsigned char *start = (const unsigned char *) data->d_buf;
10190   const unsigned char *readp = start;
10191   const unsigned char *readendp = ((const unsigned char *) data->d_buf
10192                                    + data->d_size);
10193
10194   while (readp < readendp)
10195     {
10196       /* Most string offset tables will have a header.  For split
10197          dwarf unit GNU DebugFission didn't add one.  But they were
10198          also only defined for split units (main or skeleton units
10199          didn't have indirect strings).  So if we don't have a
10200          DW_AT_str_offsets_base at all and this is offset zero, then
10201          just start printing offsets immediately, if this is a .dwo
10202          section.  */
10203       Dwarf_Off off = (Dwarf_Off) (readp
10204                                    - (const unsigned char *) data->d_buf);
10205
10206       printf ("Table at offset %" PRIx64 " ", off);
10207
10208       struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10209       const unsigned char *next_unitp = readendp;
10210       uint8_t offset_size;
10211       bool has_header;
10212       if (listptr == NULL)
10213         {
10214           /* This can happen for .dwo files.  There is only an header
10215              in the case this is a version 5 split DWARF file.  */
10216           Dwarf_CU *cu;
10217           uint8_t unit_type;
10218           if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10219                                NULL, NULL) != 0)
10220             {
10221               error (0, 0, "Warning: Cannot find any DWARF unit.");
10222               /* Just guess some values.  */
10223               has_header = false;
10224               offset_size = 4;
10225             }
10226           else if (off == 0
10227                    && (unit_type == DW_UT_split_type
10228                        || unit_type == DW_UT_split_compile))
10229             {
10230               has_header = cu->version > 4;
10231               offset_size = cu->offset_size;
10232             }
10233           else
10234             {
10235               error (0, 0,
10236                      "Warning: No CU references .debug_str_offsets after %"
10237                      PRIx64, off);
10238               has_header = cu->version > 4;
10239               offset_size = cu->offset_size;
10240             }
10241           printf ("\n");
10242         }
10243       else
10244         {
10245           /* This must be DWARF5, since GNU DebugFission didn't define
10246              DW_AT_str_offsets_base.  */
10247           has_header = true;
10248
10249           Dwarf_Die cudie;
10250           if (dwarf_cu_die (listptr->cu, &cudie,
10251                             NULL, NULL, NULL, NULL,
10252                             NULL, NULL) == NULL)
10253             printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10254           else
10255             printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10256         }
10257
10258       if (has_header)
10259         {
10260           uint64_t unit_length;
10261           uint16_t version;
10262           uint16_t padding;
10263
10264           unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10265           if (unlikely (unit_length == 0xffffffff))
10266             {
10267               if (unlikely (readp > readendp - 8))
10268                 {
10269                 invalid_data:
10270                   error (0, 0, "Invalid data");
10271                   return;
10272                 }
10273               unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10274               offset_size = 8;
10275             }
10276           else
10277             offset_size = 4;
10278
10279           printf ("\n");
10280           printf (gettext (" Length:        %8" PRIu64 "\n"),
10281                   unit_length);
10282           printf (gettext (" Offset size:   %8" PRIu8 "\n"),
10283                   offset_size);
10284
10285           /* We need at least 2-bytes (version) + 2-bytes (padding) =
10286              4 bytes to complete the header.  And this unit cannot go
10287              beyond the section data.  */
10288           if (readp > readendp - 4
10289               || unit_length < 4
10290               || unit_length > (uint64_t) (readendp - readp))
10291             goto invalid_data;
10292
10293           next_unitp = readp + unit_length;
10294
10295           version = read_2ubyte_unaligned_inc (dbg, readp);
10296           printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10297
10298           if (version != 5)
10299             {
10300               error (0, 0, gettext ("Unknown version"));
10301               goto next_unit;
10302             }
10303
10304           padding = read_2ubyte_unaligned_inc (dbg, readp);
10305           printf (gettext (" Padding:       %8" PRIx16 "\n"), padding);
10306
10307           if (listptr != NULL
10308               && listptr->offset != (Dwarf_Off) (readp - start))
10309             {
10310               error (0, 0, "String offsets index doesn't start after header");
10311               goto next_unit;
10312             }
10313
10314           printf ("\n");
10315         }
10316
10317       int digits = 1;
10318       size_t offsets = (next_unitp - readp) / offset_size;
10319       while (offsets >= 10)
10320         {
10321           ++digits;
10322           offsets /= 10;
10323         }
10324
10325       unsigned int uidx = 0;
10326       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
10327       printf (" Offsets start at 0x%zx:\n", index_offset);
10328       while (readp <= next_unitp - offset_size)
10329         {
10330           Dwarf_Word offset;
10331           if (offset_size == 4)
10332             offset = read_4ubyte_unaligned_inc (dbg, readp);
10333           else
10334             offset = read_8ubyte_unaligned_inc (dbg, readp);
10335           const char *str = dwarf_getstring (dbg, offset, NULL);
10336           printf (" [%*u] [%*" PRIx64 "]  \"%s\"\n",
10337                   digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10338         }
10339       printf ("\n");
10340
10341       if (readp != next_unitp)
10342         error (0, 0, "extra %zd bytes at end of unit",
10343                (size_t) (next_unitp - readp));
10344
10345     next_unit:
10346       readp = next_unitp;
10347     }
10348 }
10349
10350
10351 /* Print the content of the call frame search table section
10352    '.eh_frame_hdr'.  */
10353 static void
10354 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10355                                Ebl *ebl __attribute__ ((unused)),
10356                                GElf_Ehdr *ehdr __attribute__ ((unused)),
10357                                Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10358 {
10359   printf (gettext ("\
10360 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10361           elf_ndxscn (scn));
10362
10363   Elf_Data *data = elf_rawdata (scn, NULL);
10364
10365   if (unlikely (data == NULL))
10366     {
10367       error (0, 0, gettext ("cannot get %s content: %s"),
10368              ".eh_frame_hdr", elf_errmsg (-1));
10369       return;
10370     }
10371
10372   const unsigned char *readp = data->d_buf;
10373   const unsigned char *const dataend = ((unsigned char *) data->d_buf
10374                                         + data->d_size);
10375
10376   if (unlikely (readp + 4 > dataend))
10377     {
10378     invalid_data:
10379       error (0, 0, gettext ("invalid data"));
10380       return;
10381     }
10382
10383   unsigned int version = *readp++;
10384   unsigned int eh_frame_ptr_enc = *readp++;
10385   unsigned int fde_count_enc = *readp++;
10386   unsigned int table_enc = *readp++;
10387
10388   printf (" version:          %u\n"
10389           " eh_frame_ptr_enc: %#x ",
10390           version, eh_frame_ptr_enc);
10391   print_encoding_base ("", eh_frame_ptr_enc);
10392   printf (" fde_count_enc:    %#x ", fde_count_enc);
10393   print_encoding_base ("", fde_count_enc);
10394   printf (" table_enc:        %#x ", table_enc);
10395   print_encoding_base ("", table_enc);
10396
10397   uint64_t eh_frame_ptr = 0;
10398   if (eh_frame_ptr_enc != DW_EH_PE_omit)
10399     {
10400       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10401                             dbg);
10402       if (unlikely (readp == NULL))
10403         goto invalid_data;
10404
10405       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
10406       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10407         printf (" (offset: %#" PRIx64 ")",
10408                 /* +4 because of the 4 byte header of the section.  */
10409                 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10410
10411       putchar_unlocked ('\n');
10412     }
10413
10414   uint64_t fde_count = 0;
10415   if (fde_count_enc != DW_EH_PE_omit)
10416     {
10417       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10418       if (unlikely (readp == NULL))
10419         goto invalid_data;
10420
10421       printf (" fde_count:        %" PRIu64 "\n", fde_count);
10422     }
10423
10424   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10425     return;
10426
10427   puts (" Table:");
10428
10429   /* Optimize for the most common case.  */
10430   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10431     while (fde_count > 0 && readp + 8 <= dataend)
10432       {
10433         int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10434         uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10435                                    + (int64_t) initial_location);
10436         int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10437         // XXX Possibly print symbol name or section offset for initial_offset
10438         printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10439                 " fde=[%6" PRIx64 "]\n",
10440                 initial_location, initial_offset,
10441                 address, address - (eh_frame_ptr + 4));
10442       }
10443   else
10444     while (0 && readp < dataend)
10445       {
10446
10447       }
10448 }
10449
10450
10451 /* Print the content of the exception handling table section
10452    '.eh_frame_hdr'.  */
10453 static void
10454 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10455                              Ebl *ebl __attribute__ ((unused)),
10456                              GElf_Ehdr *ehdr __attribute__ ((unused)),
10457                              Elf_Scn *scn,
10458                              GElf_Shdr *shdr __attribute__ ((unused)),
10459                              Dwarf *dbg __attribute__ ((unused)))
10460 {
10461   printf (gettext ("\
10462 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10463           elf_ndxscn (scn));
10464
10465   Elf_Data *data = elf_rawdata (scn, NULL);
10466
10467   if (unlikely (data == NULL))
10468     {
10469       error (0, 0, gettext ("cannot get %s content: %s"),
10470              ".gcc_except_table", elf_errmsg (-1));
10471       return;
10472     }
10473
10474   const unsigned char *readp = data->d_buf;
10475   const unsigned char *const dataend = readp + data->d_size;
10476
10477   if (unlikely (readp + 1 > dataend))
10478     {
10479     invalid_data:
10480       error (0, 0, gettext ("invalid data"));
10481       return;
10482     }
10483   unsigned int lpstart_encoding = *readp++;
10484   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
10485   print_encoding_base ("", lpstart_encoding);
10486   if (lpstart_encoding != DW_EH_PE_omit)
10487     {
10488       uint64_t lpstart;
10489       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10490       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
10491     }
10492
10493   if (unlikely (readp + 1 > dataend))
10494     goto invalid_data;
10495   unsigned int ttype_encoding = *readp++;
10496   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
10497   print_encoding_base ("", ttype_encoding);
10498   const unsigned char *ttype_base = NULL;
10499   if (ttype_encoding != DW_EH_PE_omit)
10500     {
10501       unsigned int ttype_base_offset;
10502       get_uleb128 (ttype_base_offset, readp, dataend);
10503       printf (" TType base offset:   %#x\n", ttype_base_offset);
10504       if ((size_t) (dataend - readp) > ttype_base_offset)
10505         ttype_base = readp + ttype_base_offset;
10506     }
10507
10508   if (unlikely (readp + 1 > dataend))
10509     goto invalid_data;
10510   unsigned int call_site_encoding = *readp++;
10511   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
10512   print_encoding_base ("", call_site_encoding);
10513   unsigned int call_site_table_len;
10514   get_uleb128 (call_site_table_len, readp, dataend);
10515
10516   const unsigned char *const action_table = readp + call_site_table_len;
10517   if (unlikely (action_table > dataend))
10518     goto invalid_data;
10519   unsigned int u = 0;
10520   unsigned int max_action = 0;
10521   while (readp < action_table)
10522     {
10523       if (u == 0)
10524         puts (gettext ("\n Call site table:"));
10525
10526       uint64_t call_site_start;
10527       readp = read_encoded (call_site_encoding, readp, dataend,
10528                             &call_site_start, dbg);
10529       uint64_t call_site_length;
10530       readp = read_encoded (call_site_encoding, readp, dataend,
10531                             &call_site_length, dbg);
10532       uint64_t landing_pad;
10533       readp = read_encoded (call_site_encoding, readp, dataend,
10534                             &landing_pad, dbg);
10535       unsigned int action;
10536       get_uleb128 (action, readp, dataend);
10537       max_action = MAX (action, max_action);
10538       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
10539                        "        Call site length:  %" PRIu64 "\n"
10540                        "        Landing pad:       %#" PRIx64 "\n"
10541                        "        Action:            %u\n"),
10542               u++, call_site_start, call_site_length, landing_pad, action);
10543     }
10544   if (readp != action_table)
10545     goto invalid_data;
10546
10547   unsigned int max_ar_filter = 0;
10548   if (max_action > 0)
10549     {
10550       puts ("\n Action table:");
10551
10552       size_t maxdata = (size_t) (dataend - action_table);
10553       if (max_action > maxdata || maxdata - max_action < 1)
10554         {
10555         invalid_action_table:
10556           fputs (gettext ("   <INVALID DATA>\n"), stdout);
10557           return;
10558         }
10559
10560       const unsigned char *const action_table_end
10561         = action_table + max_action + 1;
10562
10563       u = 0;
10564       do
10565         {
10566           int ar_filter;
10567           get_sleb128 (ar_filter, readp, action_table_end);
10568           if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10569             max_ar_filter = ar_filter;
10570           int ar_disp;
10571           if (readp >= action_table_end)
10572             goto invalid_action_table;
10573           get_sleb128 (ar_disp, readp, action_table_end);
10574
10575           printf (" [%4u] ar_filter:  % d\n"
10576                   "        ar_disp:    % -5d",
10577                   u, ar_filter, ar_disp);
10578           if (abs (ar_disp) & 1)
10579             printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10580           else if (ar_disp != 0)
10581             puts (" -> ???");
10582           else
10583             putchar_unlocked ('\n');
10584           ++u;
10585         }
10586       while (readp < action_table_end);
10587     }
10588
10589   if (max_ar_filter > 0 && ttype_base != NULL)
10590     {
10591       unsigned char dsize;
10592       puts ("\n TType table:");
10593
10594       // XXX Not *4, size of encoding;
10595       switch (ttype_encoding & 7)
10596         {
10597         case DW_EH_PE_udata2:
10598         case DW_EH_PE_sdata2:
10599           dsize = 2;
10600           break;
10601         case DW_EH_PE_udata4:
10602         case DW_EH_PE_sdata4:
10603           dsize = 4;
10604           break;
10605         case DW_EH_PE_udata8:
10606         case DW_EH_PE_sdata8:
10607           dsize = 8;
10608           break;
10609         default:
10610           dsize = 0;
10611           error (1, 0, gettext ("invalid TType encoding"));
10612         }
10613
10614       if (max_ar_filter
10615           > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10616         goto invalid_data;
10617
10618       readp = ttype_base - max_ar_filter * dsize;
10619       do
10620         {
10621           uint64_t ttype;
10622           readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10623                                 dbg);
10624           printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10625         }
10626       while (readp < ttype_base);
10627     }
10628 }
10629
10630 /* Print the content of the '.gdb_index' section.
10631    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10632 */
10633 static void
10634 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10635                          GElf_Ehdr *ehdr __attribute__ ((unused)),
10636                          Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10637 {
10638   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10639                    " contains %" PRId64 " bytes :\n"),
10640           elf_ndxscn (scn), section_name (ebl, shdr),
10641           (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10642
10643   Elf_Data *data = elf_rawdata (scn, NULL);
10644
10645   if (unlikely (data == NULL))
10646     {
10647       error (0, 0, gettext ("cannot get %s content: %s"),
10648              ".gdb_index", elf_errmsg (-1));
10649       return;
10650     }
10651
10652   // .gdb_index is always in little endian.
10653   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10654   dbg = &dummy_dbg;
10655
10656   const unsigned char *readp = data->d_buf;
10657   const unsigned char *const dataend = readp + data->d_size;
10658
10659   if (unlikely (readp + 4 > dataend))
10660     {
10661     invalid_data:
10662       error (0, 0, gettext ("invalid data"));
10663       return;
10664     }
10665
10666   int32_t vers = read_4ubyte_unaligned (dbg, readp);
10667   printf (gettext (" Version:         %" PRId32 "\n"), vers);
10668
10669   // The only difference between version 4 and version 5 is the
10670   // hash used for generating the table.  Version 6 contains symbols
10671   // for inlined functions, older versions didn't.  Version 7 adds
10672   // symbol kinds.  Version 8 just indicates that it correctly includes
10673   // TUs for symbols.
10674   if (vers < 4 || vers > 8)
10675     {
10676       printf (gettext ("  unknown version, cannot parse section\n"));
10677       return;
10678     }
10679
10680   readp += 4;
10681   if (unlikely (readp + 4 > dataend))
10682     goto invalid_data;
10683
10684   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10685   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
10686
10687   readp += 4;
10688   if (unlikely (readp + 4 > dataend))
10689     goto invalid_data;
10690
10691   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10692   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
10693
10694   readp += 4;
10695   if (unlikely (readp + 4 > dataend))
10696     goto invalid_data;
10697
10698   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10699   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
10700
10701   readp += 4;
10702   if (unlikely (readp + 4 > dataend))
10703     goto invalid_data;
10704
10705   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10706   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
10707
10708   readp += 4;
10709   if (unlikely (readp + 4 > dataend))
10710     goto invalid_data;
10711
10712   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10713   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10714
10715   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10716                 < const_off))
10717     goto invalid_data;
10718
10719   readp = data->d_buf + cu_off;
10720
10721   const unsigned char *nextp = data->d_buf + tu_off;
10722   if (tu_off >= data->d_size)
10723     goto invalid_data;
10724
10725   size_t cu_nr = (nextp - readp) / 16;
10726
10727   printf (gettext ("\n CU list at offset %#" PRIx32
10728                    " contains %zu entries:\n"),
10729           cu_off, cu_nr);
10730
10731   size_t n = 0;
10732   while (dataend - readp >= 16 && n < cu_nr)
10733     {
10734       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10735       readp += 8;
10736
10737       uint64_t len = read_8ubyte_unaligned (dbg, readp);
10738       readp += 8;
10739
10740       printf (" [%4zu] start: %0#8" PRIx64
10741               ", length: %5" PRIu64 "\n", n, off, len);
10742       n++;
10743     }
10744
10745   readp = data->d_buf + tu_off;
10746   nextp = data->d_buf + addr_off;
10747   if (addr_off >= data->d_size)
10748     goto invalid_data;
10749
10750   size_t tu_nr = (nextp - readp) / 24;
10751
10752   printf (gettext ("\n TU list at offset %#" PRIx32
10753                    " contains %zu entries:\n"),
10754           tu_off, tu_nr);
10755
10756   n = 0;
10757   while (dataend - readp >= 24 && n < tu_nr)
10758     {
10759       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10760       readp += 8;
10761
10762       uint64_t type = read_8ubyte_unaligned (dbg, readp);
10763       readp += 8;
10764
10765       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10766       readp += 8;
10767
10768       printf (" [%4zu] CU offset: %5" PRId64
10769               ", type offset: %5" PRId64
10770               ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10771       n++;
10772     }
10773
10774   readp = data->d_buf + addr_off;
10775   nextp = data->d_buf + sym_off;
10776   if (sym_off >= data->d_size)
10777     goto invalid_data;
10778
10779   size_t addr_nr = (nextp - readp) / 20;
10780
10781   printf (gettext ("\n Address list at offset %#" PRIx32
10782                    " contains %zu entries:\n"),
10783           addr_off, addr_nr);
10784
10785   n = 0;
10786   while (dataend - readp >= 20 && n < addr_nr)
10787     {
10788       uint64_t low = read_8ubyte_unaligned (dbg, readp);
10789       readp += 8;
10790
10791       uint64_t high = read_8ubyte_unaligned (dbg, readp);
10792       readp += 8;
10793
10794       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10795       readp += 4;
10796
10797       printf (" [%4zu] ", n);
10798       print_dwarf_addr (dwflmod, 8, low, low);
10799       printf ("..");
10800       print_dwarf_addr (dwflmod, 8, high - 1, high);
10801       printf (", CU index: %5" PRId32 "\n", idx);
10802       n++;
10803     }
10804
10805   const unsigned char *const_start = data->d_buf + const_off;
10806   if (const_off >= data->d_size)
10807     goto invalid_data;
10808
10809   readp = data->d_buf + sym_off;
10810   nextp = const_start;
10811   size_t sym_nr = (nextp - readp) / 8;
10812
10813   printf (gettext ("\n Symbol table at offset %#" PRIx32
10814                    " contains %zu slots:\n"),
10815           addr_off, sym_nr);
10816
10817   n = 0;
10818   while (dataend - readp >= 8 && n < sym_nr)
10819     {
10820       uint32_t name = read_4ubyte_unaligned (dbg, readp);
10821       readp += 4;
10822
10823       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10824       readp += 4;
10825
10826       if (name != 0 || vector != 0)
10827         {
10828           const unsigned char *sym = const_start + name;
10829           if (unlikely ((size_t) (dataend - const_start) < name
10830                         || memchr (sym, '\0', dataend - sym) == NULL))
10831             goto invalid_data;
10832
10833           printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10834
10835           const unsigned char *readcus = const_start + vector;
10836           if (unlikely ((size_t) (dataend - const_start) < vector))
10837             goto invalid_data;
10838           uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10839           while (cus--)
10840             {
10841               uint32_t cu_kind, cu, kind;
10842               bool is_static;
10843               readcus += 4;
10844               if (unlikely (readcus + 4 > dataend))
10845                 goto invalid_data;
10846               cu_kind = read_4ubyte_unaligned (dbg, readcus);
10847               cu = cu_kind & ((1 << 24) - 1);
10848               kind = (cu_kind >> 28) & 7;
10849               is_static = cu_kind & (1U << 31);
10850               if (cu > cu_nr - 1)
10851                 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10852               else
10853                 printf ("%" PRId32, cu);
10854               if (kind != 0)
10855                 {
10856                   printf (" (");
10857                   switch (kind)
10858                     {
10859                     case 1:
10860                       printf ("type");
10861                       break;
10862                     case 2:
10863                       printf ("var");
10864                       break;
10865                     case 3:
10866                       printf ("func");
10867                       break;
10868                     case 4:
10869                       printf ("other");
10870                       break;
10871                     default:
10872                       printf ("unknown-0x%" PRIx32, kind);
10873                       break;
10874                     }
10875                   printf (":%c)", (is_static ? 'S' : 'G'));
10876                 }
10877               if (cus > 0)
10878                 printf (", ");
10879             }
10880           printf ("\n");
10881         }
10882       n++;
10883     }
10884 }
10885
10886 /* Returns true and sets split DWARF CU id if there is a split compile
10887    unit in the given Dwarf, and no non-split units are found (before it).  */
10888 static bool
10889 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
10890 {
10891   Dwarf_CU *cu = NULL;
10892   while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
10893     {
10894       uint8_t unit_type;
10895       if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
10896                          id, NULL, NULL) != 0)
10897         return false;
10898
10899       if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
10900         return false;
10901
10902       /* We really only care about the split compile unit, the types
10903          should be fine and self sufficient.  Also they don't have an
10904          id that we can match with a skeleton unit.  */
10905       if (unit_type == DW_UT_split_compile)
10906         {
10907           *split_cu = cu;
10908           return true;
10909         }
10910     }
10911
10912   return false;
10913 }
10914
10915 /* Check that there is one and only one Dwfl_Module, return in arg.  */
10916 static int
10917 getone_dwflmod (Dwfl_Module *dwflmod,
10918                void **userdata __attribute__ ((unused)),
10919                const char *name __attribute__ ((unused)),
10920                Dwarf_Addr base __attribute__ ((unused)),
10921                void *arg)
10922 {
10923   Dwfl_Module **m = (Dwfl_Module **) arg;
10924   if (*m != NULL)
10925     return DWARF_CB_ABORT;
10926   *m = dwflmod;
10927   return DWARF_CB_OK;
10928 }
10929
10930 static void
10931 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
10932 {
10933   /* Used for skeleton file, if necessary for split DWARF.  */
10934   Dwfl *skel_dwfl = NULL;
10935   Dwfl_Module *skel_mod = NULL;
10936   char *skel_name = NULL;
10937   Dwarf *split_dbg = NULL;
10938   Dwarf_CU *split_cu = NULL;
10939
10940   /* Before we start the real work get a debug context descriptor.  */
10941   Dwarf_Addr dwbias;
10942   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
10943   Dwarf dummy_dbg =
10944     {
10945       .elf = ebl->elf,
10946       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
10947     };
10948   if (dbg == NULL)
10949     {
10950       if ((print_debug_sections & ~section_exception) != 0)
10951         error (0, 0, gettext ("cannot get debug context descriptor: %s"),
10952                dwfl_errmsg (-1));
10953       dbg = &dummy_dbg;
10954     }
10955   else
10956     {
10957       /* If we are asked about a split dwarf (.dwo) file, use the user
10958          provided, or find the corresponding skeleton file. If we got
10959          a skeleton file, replace the given dwflmod and dbg, with one
10960          derived from the skeleton file to provide enough context.  */
10961       uint64_t split_id;
10962       if (is_split_dwarf (dbg, &split_id, &split_cu))
10963         {
10964           if (dwarf_skeleton != NULL)
10965             skel_name = strdup (dwarf_skeleton);
10966           else
10967             {
10968               /* Replace file.dwo with file.o and see if that matches. */
10969               const char *fname;
10970               dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
10971                                 &fname, NULL);
10972               if (fname != NULL)
10973                 {
10974                   size_t flen = strlen (fname);
10975                   if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
10976                     {
10977                       skel_name = strdup (fname);
10978                       if (skel_name != NULL)
10979                         {
10980                           skel_name[flen - 3] = 'o';
10981                           skel_name[flen - 2] = '\0';
10982                         }
10983                     }
10984                 }
10985             }
10986
10987           if (skel_name != NULL)
10988             {
10989               int skel_fd = open (skel_name, O_RDONLY);
10990               if (skel_fd == -1)
10991                 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
10992                          " '%s'\n", skel_name);
10993               else
10994                 skel_dwfl = create_dwfl (skel_fd, skel_name);
10995
10996               if (skel_dwfl != NULL)
10997                 {
10998                   if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
10999                                        &skel_mod, 0) != 0)
11000                     {
11001                       fprintf (stderr, "Warning: Bad DWARF skeleton,"
11002                                " multiple modules '%s'\n", skel_name);
11003                       dwfl_end (skel_dwfl);
11004                       skel_mod = NULL;
11005                     }
11006                 }
11007               else if (skel_fd != -1)
11008                 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11009                          " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11010
11011               if (skel_mod != NULL)
11012                 {
11013                   Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11014                   if (skel_dbg != NULL)
11015                     {
11016                       /* First check the skeleton CU DIE, only fetch
11017                          the split DIE if we know the id matches to
11018                          not unnecessary search for any split DIEs we
11019                          don't need. */
11020                       Dwarf_CU *cu = NULL;
11021                       while (dwarf_get_units (skel_dbg, cu, &cu,
11022                                               NULL, NULL, NULL, NULL) == 0)
11023                         {
11024                           uint8_t unit_type;
11025                           uint64_t skel_id;
11026                           if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11027                                              &skel_id, NULL, NULL) == 0
11028                               && unit_type == DW_UT_skeleton
11029                               && split_id == skel_id)
11030                             {
11031                               Dwarf_Die subdie;
11032                               if (dwarf_cu_info (cu, NULL, NULL, NULL,
11033                                                  &subdie,
11034                                                  NULL, NULL, NULL) == 0
11035                                   && dwarf_tag (&subdie) != DW_TAG_invalid)
11036                                 {
11037                                   split_dbg = dwarf_cu_getdwarf (subdie.cu);
11038                                   if (split_dbg == NULL)
11039                                     fprintf (stderr,
11040                                              "Warning: Couldn't get split_dbg:"
11041                                              " %s\n", dwarf_errmsg (-1));
11042                                   break;
11043                                 }
11044                               else
11045                                 {
11046                                   /* Everything matches up, but not
11047                                      according to libdw. Which means
11048                                      the user knew better.  So...
11049                                      Terrible hack... We can never
11050                                      destroy the underlying dwfl
11051                                      because it would free the wrong
11052                                      Dwarfs... So we leak memory...*/
11053                                   if (cu->split == NULL
11054                                       && dwarf_skeleton != NULL)
11055                                     {
11056                                       do_not_close_dwfl = true;
11057                                       __libdw_link_skel_split (cu, split_cu);
11058                                       split_dbg = dwarf_cu_getdwarf (split_cu);
11059                                       break;
11060                                     }
11061                                   else
11062                                     fprintf (stderr, "Warning: Couldn't get"
11063                                              " skeleton subdie: %s\n",
11064                                              dwarf_errmsg (-1));
11065                                 }
11066                             }
11067                         }
11068                       if (split_dbg == NULL)
11069                         fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11070                     }
11071                   else
11072                     fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11073                              " %s\n", dwfl_errmsg (-1));
11074                 }
11075             }
11076
11077           if (split_dbg != NULL)
11078             {
11079               dbg = split_dbg;
11080               dwflmod = skel_mod;
11081             }
11082           else if (skel_name == NULL)
11083             fprintf (stderr,
11084                      "Warning: split DWARF file, but no skeleton found.\n");
11085         }
11086       else if (dwarf_skeleton != NULL)
11087         fprintf (stderr, "Warning: DWARF skeleton given,"
11088                  " but not a split DWARF file\n");
11089     }
11090
11091   /* Get the section header string table index.  */
11092   size_t shstrndx;
11093   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11094     error (EXIT_FAILURE, 0,
11095            gettext ("cannot get section header string table index"));
11096
11097   /* If the .debug_info section is listed as implicitly required then
11098      we must make sure to handle it before handling any other debug
11099      section.  Various other sections depend on the CU DIEs being
11100      scanned (silently) first.  */
11101   bool implicit_info = (implicit_debug_sections & section_info) != 0;
11102   bool explicit_info = (print_debug_sections & section_info) != 0;
11103   if (implicit_info)
11104     {
11105       Elf_Scn *scn = NULL;
11106       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11107         {
11108           GElf_Shdr shdr_mem;
11109           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11110
11111           if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11112             {
11113               const char *name = elf_strptr (ebl->elf, shstrndx,
11114                                              shdr->sh_name);
11115               if (name == NULL)
11116                 continue;
11117
11118               if (strcmp (name, ".debug_info") == 0
11119                   || strcmp (name, ".debug_info.dwo") == 0
11120                   || strcmp (name, ".zdebug_info") == 0
11121                   || strcmp (name, ".zdebug_info.dwo") == 0)
11122                 {
11123                   print_debug_info_section (dwflmod, ebl, ehdr,
11124                                             scn, shdr, dbg);
11125                   break;
11126                 }
11127             }
11128         }
11129       print_debug_sections &= ~section_info;
11130       implicit_debug_sections &= ~section_info;
11131     }
11132
11133   /* Look through all the sections for the debugging sections to print.  */
11134   Elf_Scn *scn = NULL;
11135   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11136     {
11137       GElf_Shdr shdr_mem;
11138       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11139
11140       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11141         {
11142           static const struct
11143           {
11144             const char *name;
11145             enum section_e bitmask;
11146             void (*fp) (Dwfl_Module *, Ebl *,
11147                         GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11148           } debug_sections[] =
11149             {
11150 #define NEW_SECTION(name) \
11151               { ".debug_" #name, section_##name, print_debug_##name##_section }
11152               NEW_SECTION (abbrev),
11153               NEW_SECTION (addr),
11154               NEW_SECTION (aranges),
11155               NEW_SECTION (frame),
11156               NEW_SECTION (info),
11157               NEW_SECTION (types),
11158               NEW_SECTION (line),
11159               NEW_SECTION (loc),
11160               /* loclists is loc for DWARF5.  */
11161               { ".debug_loclists", section_loc,
11162                 print_debug_loclists_section },
11163               NEW_SECTION (pubnames),
11164               NEW_SECTION (str),
11165               /* A DWARF5 specialised debug string section.  */
11166               { ".debug_line_str", section_str,
11167                 print_debug_str_section },
11168               /* DWARF5 string offsets table.  */
11169               { ".debug_str_offsets", section_str,
11170                 print_debug_str_offsets_section },
11171               NEW_SECTION (macinfo),
11172               NEW_SECTION (macro),
11173               NEW_SECTION (ranges),
11174               /* rnglists is ranges for DWARF5.  */
11175               { ".debug_rnglists", section_ranges,
11176                 print_debug_rnglists_section },
11177               { ".eh_frame", section_frame | section_exception,
11178                 print_debug_frame_section },
11179               { ".eh_frame_hdr", section_frame | section_exception,
11180                 print_debug_frame_hdr_section },
11181               { ".gcc_except_table", section_frame | section_exception,
11182                 print_debug_exception_table },
11183               { ".gdb_index", section_gdb_index, print_gdb_index_section }
11184             };
11185           const int ndebug_sections = (sizeof (debug_sections)
11186                                        / sizeof (debug_sections[0]));
11187           const char *name = elf_strptr (ebl->elf, shstrndx,
11188                                          shdr->sh_name);
11189           if (name == NULL)
11190             continue;
11191
11192           int n;
11193           for (n = 0; n < ndebug_sections; ++n)
11194             {
11195               size_t dbglen = strlen (debug_sections[n].name);
11196               size_t scnlen = strlen (name);
11197               if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11198                    && (dbglen == scnlen
11199                        || (scnlen == dbglen + 4
11200                            && strstr (name, ".dwo") == name + dbglen)))
11201                   || (name[0] == '.' && name[1] == 'z'
11202                       && debug_sections[n].name[1] == 'd'
11203                       && strncmp (&name[2], &debug_sections[n].name[1],
11204                                   dbglen - 1) == 0
11205                       && (scnlen == dbglen + 1
11206                           || (scnlen == dbglen + 5
11207                               && strstr (name, ".dwo") == name + dbglen + 1))))
11208                 {
11209                   if ((print_debug_sections | implicit_debug_sections)
11210                       & debug_sections[n].bitmask)
11211                     debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11212                   break;
11213                 }
11214             }
11215         }
11216     }
11217
11218   dwfl_end (skel_dwfl);
11219   free (skel_name);
11220
11221   /* Turn implicit and/or explicit back on in case we go over another file.  */
11222   if (implicit_info)
11223     implicit_debug_sections |= section_info;
11224   if (explicit_info)
11225     print_debug_sections |= section_info;
11226
11227   reset_listptr (&known_locsptr);
11228   reset_listptr (&known_loclistsptr);
11229   reset_listptr (&known_rangelistptr);
11230   reset_listptr (&known_rnglistptr);
11231   reset_listptr (&known_addrbases);
11232   reset_listptr (&known_stroffbases);
11233 }
11234
11235
11236 #define ITEM_INDENT             4
11237 #define WRAP_COLUMN             75
11238
11239 /* Print "NAME: FORMAT", wrapping when output text would make the line
11240    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
11241    but this function is also used for registers which should be printed
11242    aligned.  Fortunately registers output uses fixed fields width (such
11243    as %11d) for the alignment.
11244
11245    Line breaks should not depend on the particular values although that
11246    may happen in some cases of the core items.  */
11247
11248 static unsigned int
11249 __attribute__ ((format (printf, 6, 7)))
11250 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11251                  size_t name_width, const char *name, const char *format, ...)
11252 {
11253   size_t len = strlen (name);
11254   if (name_width < len)
11255     name_width = len;
11256
11257   char *out;
11258   va_list ap;
11259   va_start (ap, format);
11260   int out_len = vasprintf (&out, format, ap);
11261   va_end (ap);
11262   if (out_len == -1)
11263     error (EXIT_FAILURE, 0, _("memory exhausted"));
11264
11265   size_t n = name_width + sizeof ": " - 1 + out_len;
11266
11267   if (colno == 0)
11268     {
11269       printf ("%*s", ITEM_INDENT, "");
11270       colno = ITEM_INDENT + n;
11271     }
11272   else if (colno + 2 + n < wrap)
11273     {
11274       printf ("%c ", sep);
11275       colno += 2 + n;
11276     }
11277   else
11278     {
11279       printf ("\n%*s", ITEM_INDENT, "");
11280       colno = ITEM_INDENT + n;
11281     }
11282
11283   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11284
11285   free (out);
11286
11287   return colno;
11288 }
11289
11290 static const void *
11291 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11292          void *value, const void *data, size_t size)
11293 {
11294   Elf_Data valuedata =
11295     {
11296       .d_type = type,
11297       .d_buf = value,
11298       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11299       .d_version = EV_CURRENT,
11300     };
11301   Elf_Data indata =
11302     {
11303       .d_type = type,
11304       .d_buf = (void *) data,
11305       .d_size = valuedata.d_size,
11306       .d_version = EV_CURRENT,
11307     };
11308
11309   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11310                  ? elf32_xlatetom : elf64_xlatetom)
11311     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11312   if (d == NULL)
11313     error (EXIT_FAILURE, 0,
11314            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11315
11316   return data + indata.d_size;
11317 }
11318
11319 typedef uint8_t GElf_Byte;
11320
11321 static unsigned int
11322 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11323                   unsigned int colno, size_t *repeated_size)
11324 {
11325   uint_fast16_t count = item->count ?: 1;
11326   /* Ebl_Core_Item count is always a small number.
11327      Make sure the backend didn't put in some large bogus value.  */
11328   assert (count < 128);
11329
11330 #define TYPES                                                                 \
11331   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);                             \
11332   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);                           \
11333   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);                           \
11334   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);                             \
11335   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);                        \
11336   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11337
11338 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11339   typedef union { TYPES; } value_t;
11340   void *data = alloca (count * sizeof (value_t));
11341 #undef DO_TYPE
11342
11343 #define DO_TYPE(NAME, Name, hex, dec) \
11344     GElf_##Name *value_##Name __attribute__((unused)) = data
11345   TYPES;
11346 #undef DO_TYPE
11347
11348   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11349   size_t convsize = size;
11350   if (repeated_size != NULL)
11351     {
11352       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11353         {
11354           data = alloca (*repeated_size);
11355           count *= *repeated_size / size;
11356           convsize = count * size;
11357           *repeated_size -= convsize;
11358         }
11359       else if (item->count != 0 || item->format != '\n')
11360         *repeated_size -= size;
11361     }
11362
11363   convert (core, item->type, count, data, desc + item->offset, convsize);
11364
11365   Elf_Type type = item->type;
11366   if (type == ELF_T_ADDR)
11367     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11368
11369   switch (item->format)
11370     {
11371     case 'd':
11372       assert (count == 1);
11373       switch (type)
11374         {
11375 #define DO_TYPE(NAME, Name, hex, dec)                                         \
11376           case ELF_T_##NAME:                                                  \
11377             colno = print_core_item (colno, ',', WRAP_COLUMN,                 \
11378                                      0, item->name, dec, value_##Name[0]); \
11379             break
11380           TYPES;
11381 #undef DO_TYPE
11382         default:
11383           abort ();
11384         }
11385       break;
11386
11387     case 'x':
11388       assert (count == 1);
11389       switch (type)
11390         {
11391 #define DO_TYPE(NAME, Name, hex, dec)                                         \
11392           case ELF_T_##NAME:                                                  \
11393             colno = print_core_item (colno, ',', WRAP_COLUMN,                 \
11394                                      0, item->name, hex, value_##Name[0]);      \
11395             break
11396           TYPES;
11397 #undef DO_TYPE
11398         default:
11399           abort ();
11400         }
11401       break;
11402
11403     case 'b':
11404     case 'B':
11405       assert (size % sizeof (unsigned int) == 0);
11406       unsigned int nbits = count * size * 8;
11407       unsigned int pop = 0;
11408       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11409         pop += __builtin_popcount (*i);
11410       bool negate = pop > nbits / 2;
11411       const unsigned int bias = item->format == 'b';
11412
11413       {
11414         char printed[(negate ? nbits - pop : pop) * 16 + 1];
11415         char *p = printed;
11416         *p = '\0';
11417
11418         if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11419           {
11420             assert (size == sizeof (unsigned int) * 2);
11421             for (unsigned int *i = data;
11422                  (void *) i < data + count * size; i += 2)
11423               {
11424                 unsigned int w = i[1];
11425                 i[1] = i[0];
11426                 i[0] = w;
11427               }
11428           }
11429
11430         unsigned int lastbit = 0;
11431         unsigned int run = 0;
11432         for (const unsigned int *i = data;
11433              (void *) i < data + count * size; ++i)
11434           {
11435             unsigned int bit = ((void *) i - data) * 8;
11436             unsigned int w = negate ? ~*i : *i;
11437             while (w != 0)
11438               {
11439                 /* Note that a right shift equal to (or greater than)
11440                    the number of bits of w is undefined behaviour.  In
11441                    particular when the least significant bit is bit 32
11442                    (w = 0x8000000) then w >>= n is undefined.  So
11443                    explicitly handle that case separately.  */
11444                 unsigned int n = ffs (w);
11445                 if (n < sizeof (w) * 8)
11446                   w >>= n;
11447                 else
11448                   w = 0;
11449                 bit += n;
11450
11451                 if (lastbit != 0 && lastbit + 1 == bit)
11452                   ++run;
11453                 else
11454                   {
11455                     if (lastbit == 0)
11456                       p += sprintf (p, "%u", bit - bias);
11457                     else if (run == 0)
11458                       p += sprintf (p, ",%u", bit - bias);
11459                     else
11460                       p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11461                     run = 0;
11462                   }
11463
11464                 lastbit = bit;
11465               }
11466           }
11467         if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11468           p += sprintf (p, "-%u", lastbit - bias);
11469
11470         colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11471                                  negate ? "~<%s>" : "<%s>", printed);
11472       }
11473       break;
11474
11475     case 'T':
11476     case (char) ('T'|0x80):
11477       assert (count == 2);
11478       Dwarf_Word sec;
11479       Dwarf_Word usec;
11480       switch (type)
11481         {
11482 #define DO_TYPE(NAME, Name, hex, dec)                                         \
11483           case ELF_T_##NAME:                                                  \
11484             sec = value_##Name[0];                                            \
11485             usec = value_##Name[1];                                           \
11486             break
11487           TYPES;
11488 #undef DO_TYPE
11489         default:
11490           abort ();
11491         }
11492       if (unlikely (item->format == (char) ('T'|0x80)))
11493         {
11494           /* This is a hack for an ill-considered 64-bit ABI where
11495              tv_usec is actually a 32-bit field with 32 bits of padding
11496              rounding out struct timeval.  We've already converted it as
11497              a 64-bit field.  For little-endian, this just means the
11498              high half is the padding; it's presumably zero, but should
11499              be ignored anyway.  For big-endian, it means the 32-bit
11500              field went into the high half of USEC.  */
11501           GElf_Ehdr ehdr_mem;
11502           GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11503           if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11504             usec >>= 32;
11505           else
11506             usec &= UINT32_MAX;
11507         }
11508       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11509                                "%" PRIu64 ".%.6" PRIu64, sec, usec);
11510       break;
11511
11512     case 'c':
11513       assert (count == 1);
11514       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11515                                "%c", value_Byte[0]);
11516       break;
11517
11518     case 's':
11519       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11520                                "%.*s", (int) count, value_Byte);
11521       break;
11522
11523     case '\n':
11524       /* This is a list of strings separated by '\n'.  */
11525       assert (item->count == 0);
11526       assert (repeated_size != NULL);
11527       assert (item->name == NULL);
11528       if (unlikely (item->offset >= *repeated_size))
11529         break;
11530
11531       const char *s = desc + item->offset;
11532       size = *repeated_size - item->offset;
11533       *repeated_size = 0;
11534       while (size > 0)
11535         {
11536           const char *eol = memchr (s, '\n', size);
11537           int len = size;
11538           if (eol != NULL)
11539             len = eol - s;
11540           printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11541           if (eol == NULL)
11542             break;
11543           size -= eol + 1 - s;
11544           s = eol + 1;
11545         }
11546
11547       colno = WRAP_COLUMN;
11548       break;
11549
11550     case 'h':
11551       break;
11552
11553     default:
11554       error (0, 0, "XXX not handling format '%c' for %s",
11555              item->format, item->name);
11556       break;
11557     }
11558
11559 #undef TYPES
11560
11561   return colno;
11562 }
11563
11564
11565 /* Sort items by group, and by layout offset within each group.  */
11566 static int
11567 compare_core_items (const void *a, const void *b)
11568 {
11569   const Ebl_Core_Item *const *p1 = a;
11570   const Ebl_Core_Item *const *p2 = b;
11571   const Ebl_Core_Item *item1 = *p1;
11572   const Ebl_Core_Item *item2 = *p2;
11573
11574   return ((item1->group == item2->group ? 0
11575            : strcmp (item1->group, item2->group))
11576           ?: (int) item1->offset - (int) item2->offset);
11577 }
11578
11579 /* Sort item groups by layout offset of the first item in the group.  */
11580 static int
11581 compare_core_item_groups (const void *a, const void *b)
11582 {
11583   const Ebl_Core_Item *const *const *p1 = a;
11584   const Ebl_Core_Item *const *const *p2 = b;
11585   const Ebl_Core_Item *const *group1 = *p1;
11586   const Ebl_Core_Item *const *group2 = *p2;
11587   const Ebl_Core_Item *item1 = *group1;
11588   const Ebl_Core_Item *item2 = *group2;
11589
11590   return (int) item1->offset - (int) item2->offset;
11591 }
11592
11593 static unsigned int
11594 handle_core_items (Elf *core, const void *desc, size_t descsz,
11595                    const Ebl_Core_Item *items, size_t nitems)
11596 {
11597   if (nitems == 0)
11598     return 0;
11599   unsigned int colno = 0;
11600
11601   /* FORMAT '\n' makes sense to be present only as a single item as it
11602      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
11603      if present as a single item but they can be also processed with other
11604      items below.  */
11605   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11606                       || items[0].format == 'B'))
11607     {
11608       assert (items[0].offset == 0);
11609       size_t size = descsz;
11610       colno = handle_core_item (core, items, desc, colno, &size);
11611       /* If SIZE is not zero here there is some remaining data.  But we do not
11612          know how to process it anyway.  */
11613       return colno;
11614     }
11615   for (size_t i = 0; i < nitems; ++i)
11616     assert (items[i].format != '\n');
11617
11618   /* Sort to collect the groups together.  */
11619   const Ebl_Core_Item *sorted_items[nitems];
11620   for (size_t i = 0; i < nitems; ++i)
11621     sorted_items[i] = &items[i];
11622   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11623
11624   /* Collect the unique groups and sort them.  */
11625   const Ebl_Core_Item **groups[nitems];
11626   groups[0] = &sorted_items[0];
11627   size_t ngroups = 1;
11628   for (size_t i = 1; i < nitems; ++i)
11629     if (sorted_items[i]->group != sorted_items[i - 1]->group
11630         && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11631       groups[ngroups++] = &sorted_items[i];
11632   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11633
11634   /* Write out all the groups.  */
11635   const void *last = desc;
11636   do
11637     {
11638       for (size_t i = 0; i < ngroups; ++i)
11639         {
11640           for (const Ebl_Core_Item **item = groups[i];
11641                (item < &sorted_items[nitems]
11642                 && ((*item)->group == groups[i][0]->group
11643                     || !strcmp ((*item)->group, groups[i][0]->group)));
11644                ++item)
11645             colno = handle_core_item (core, *item, desc, colno, NULL);
11646
11647           /* Force a line break at the end of the group.  */
11648           colno = WRAP_COLUMN;
11649         }
11650
11651       if (descsz == 0)
11652         break;
11653
11654       /* This set of items consumed a certain amount of the note's data.
11655          If there is more data there, we have another unit of the same size.
11656          Loop to print that out too.  */
11657       const Ebl_Core_Item *item = &items[nitems - 1];
11658       size_t eltsz = item->offset + gelf_fsize (core, item->type,
11659                                                 item->count ?: 1, EV_CURRENT);
11660
11661       int reps = -1;
11662       do
11663         {
11664           ++reps;
11665           desc += eltsz;
11666           descsz -= eltsz;
11667         }
11668       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11669
11670       if (reps == 1)
11671         {
11672           /* For just one repeat, print it unabridged twice.  */
11673           desc -= eltsz;
11674           descsz += eltsz;
11675         }
11676       else if (reps > 1)
11677         printf (gettext ("\n%*s... <repeats %u more times> ..."),
11678                 ITEM_INDENT, "", reps);
11679
11680       last = desc;
11681     }
11682   while (descsz > 0);
11683
11684   return colno;
11685 }
11686
11687 static unsigned int
11688 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11689                       unsigned int colno)
11690 {
11691   desc += regloc->offset;
11692
11693   abort ();                     /* XXX */
11694   return colno;
11695 }
11696
11697
11698 static unsigned int
11699 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11700                       const Ebl_Register_Location *regloc, const void *desc,
11701                       unsigned int colno)
11702 {
11703   if (regloc->bits % 8 != 0)
11704     return handle_bit_registers (regloc, desc, colno);
11705
11706   desc += regloc->offset;
11707
11708   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11709     {
11710       char name[REGNAMESZ];
11711       int bits;
11712       int type;
11713       register_info (ebl, reg, regloc, name, &bits, &type);
11714
11715 #define TYPES                                                                 \
11716       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);                              \
11717       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);                           \
11718       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);                         \
11719       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
11720
11721 #define BITS(bits, xtype, sfmt, ufmt)                           \
11722       uint##bits##_t b##bits; int##bits##_t b##bits##s
11723       union { TYPES; uint64_t b128[2]; } value;
11724 #undef  BITS
11725
11726       switch (type)
11727         {
11728         case DW_ATE_unsigned:
11729         case DW_ATE_signed:
11730         case DW_ATE_address:
11731           switch (bits)
11732             {
11733 #define BITS(bits, xtype, sfmt, ufmt)                                         \
11734             case bits:                                                        \
11735               desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);       \
11736               if (type == DW_ATE_signed)                                      \
11737                 colno = print_core_item (colno, ' ', WRAP_COLUMN,             \
11738                                          maxregname, name,                    \
11739                                          sfmt, value.b##bits##s);             \
11740               else                                                            \
11741                 colno = print_core_item (colno, ' ', WRAP_COLUMN,             \
11742                                          maxregname, name,                    \
11743                                          ufmt, value.b##bits);                \
11744               break
11745
11746             TYPES;
11747
11748             case 128:
11749               assert (type == DW_ATE_unsigned);
11750               desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11751               int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11752               colno = print_core_item (colno, ' ', WRAP_COLUMN,
11753                                        maxregname, name,
11754                                        "0x%.16" PRIx64 "%.16" PRIx64,
11755                                        value.b128[!be], value.b128[be]);
11756               break;
11757
11758             default:
11759               abort ();
11760 #undef  BITS
11761             }
11762           break;
11763
11764         default:
11765           /* Print each byte in hex, the whole thing in native byte order.  */
11766           assert (bits % 8 == 0);
11767           const uint8_t *bytes = desc;
11768           desc += bits / 8;
11769           char hex[bits / 4 + 1];
11770           hex[bits / 4] = '\0';
11771           int incr = 1;
11772           if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11773             {
11774               bytes += bits / 8 - 1;
11775               incr = -1;
11776             }
11777           size_t idx = 0;
11778           for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11779             {
11780               *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11781               *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11782             }
11783           colno = print_core_item (colno, ' ', WRAP_COLUMN,
11784                                    maxregname, name, "0x%s", hex);
11785           break;
11786         }
11787       desc += regloc->pad;
11788
11789 #undef TYPES
11790     }
11791
11792   return colno;
11793 }
11794
11795
11796 struct register_info
11797 {
11798   const Ebl_Register_Location *regloc;
11799   const char *set;
11800   char name[REGNAMESZ];
11801   int regno;
11802   int bits;
11803   int type;
11804 };
11805
11806 static int
11807 register_bitpos (const struct register_info *r)
11808 {
11809   return (r->regloc->offset * 8
11810           + ((r->regno - r->regloc->regno)
11811              * (r->regloc->bits + r->regloc->pad * 8)));
11812 }
11813
11814 static int
11815 compare_sets_by_info (const struct register_info *r1,
11816                       const struct register_info *r2)
11817 {
11818   return ((int) r2->bits - (int) r1->bits
11819           ?: register_bitpos (r1) - register_bitpos (r2));
11820 }
11821
11822 /* Sort registers by set, and by size and layout offset within each set.  */
11823 static int
11824 compare_registers (const void *a, const void *b)
11825 {
11826   const struct register_info *r1 = a;
11827   const struct register_info *r2 = b;
11828
11829   /* Unused elements sort last.  */
11830   if (r1->regloc == NULL)
11831     return r2->regloc == NULL ? 0 : 1;
11832   if (r2->regloc == NULL)
11833     return -1;
11834
11835   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11836           ?: compare_sets_by_info (r1, r2));
11837 }
11838
11839 /* Sort register sets by layout offset of the first register in the set.  */
11840 static int
11841 compare_register_sets (const void *a, const void *b)
11842 {
11843   const struct register_info *const *p1 = a;
11844   const struct register_info *const *p2 = b;
11845   return compare_sets_by_info (*p1, *p2);
11846 }
11847
11848 static unsigned int
11849 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11850                        const Ebl_Register_Location *reglocs, size_t nregloc)
11851 {
11852   if (nregloc == 0)
11853     return 0;
11854
11855   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
11856   if (maxnreg <= 0)
11857     {
11858       for (size_t i = 0; i < nregloc; ++i)
11859         if (maxnreg < reglocs[i].regno + reglocs[i].count)
11860           maxnreg = reglocs[i].regno + reglocs[i].count;
11861       assert (maxnreg > 0);
11862     }
11863
11864   struct register_info regs[maxnreg];
11865   memset (regs, 0, sizeof regs);
11866
11867   /* Sort to collect the sets together.  */
11868   int maxreg = 0;
11869   for (size_t i = 0; i < nregloc; ++i)
11870     for (int reg = reglocs[i].regno;
11871          reg < reglocs[i].regno + reglocs[i].count;
11872          ++reg)
11873       {
11874         assert (reg < maxnreg);
11875         if (reg > maxreg)
11876           maxreg = reg;
11877         struct register_info *info = &regs[reg];
11878         info->regloc = &reglocs[i];
11879         info->regno = reg;
11880         info->set = register_info (ebl, reg, &reglocs[i],
11881                                    info->name, &info->bits, &info->type);
11882       }
11883   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
11884
11885   /* Collect the unique sets and sort them.  */
11886   inline bool same_set (const struct register_info *a,
11887                         const struct register_info *b)
11888   {
11889     return (a < &regs[maxnreg] && a->regloc != NULL
11890             && b < &regs[maxnreg] && b->regloc != NULL
11891             && a->bits == b->bits
11892             && (a->set == b->set || !strcmp (a->set, b->set)));
11893   }
11894   struct register_info *sets[maxreg + 1];
11895   sets[0] = &regs[0];
11896   size_t nsets = 1;
11897   for (int i = 1; i <= maxreg; ++i)
11898     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
11899       sets[nsets++] = &regs[i];
11900   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
11901
11902   /* Write out all the sets.  */
11903   unsigned int colno = 0;
11904   for (size_t i = 0; i < nsets; ++i)
11905     {
11906       /* Find the longest name of a register in this set.  */
11907       size_t maxname = 0;
11908       const struct register_info *end;
11909       for (end = sets[i]; same_set (sets[i], end); ++end)
11910         {
11911           size_t len = strlen (end->name);
11912           if (len > maxname)
11913             maxname = len;
11914         }
11915
11916       for (const struct register_info *reg = sets[i];
11917            reg < end;
11918            reg += reg->regloc->count ?: 1)
11919         colno = handle_core_register (ebl, core, maxname,
11920                                       reg->regloc, desc, colno);
11921
11922       /* Force a line break at the end of the group.  */
11923       colno = WRAP_COLUMN;
11924     }
11925
11926   return colno;
11927 }
11928
11929 static void
11930 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
11931 {
11932   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
11933   if (data == NULL)
11934   elf_error:
11935     error (EXIT_FAILURE, 0,
11936            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11937
11938   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
11939   for (size_t i = 0; i < nauxv; ++i)
11940     {
11941       GElf_auxv_t av_mem;
11942       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
11943       if (av == NULL)
11944         goto elf_error;
11945
11946       const char *name;
11947       const char *fmt;
11948       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
11949         {
11950           /* Unknown type.  */
11951           if (av->a_un.a_val == 0)
11952             printf ("    %" PRIu64 "\n", av->a_type);
11953           else
11954             printf ("    %" PRIu64 ": %#" PRIx64 "\n",
11955                     av->a_type, av->a_un.a_val);
11956         }
11957       else
11958         switch (fmt[0])
11959           {
11960           case '\0':            /* Normally zero.  */
11961             if (av->a_un.a_val == 0)
11962               {
11963                 printf ("    %s\n", name);
11964                 break;
11965               }
11966             FALLTHROUGH;
11967           case 'x':             /* hex */
11968           case 'p':             /* address */
11969           case 's':             /* address of string */
11970             printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
11971             break;
11972           case 'u':
11973             printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
11974             break;
11975           case 'd':
11976             printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
11977             break;
11978
11979           case 'b':
11980             printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
11981             GElf_Xword bit = 1;
11982             const char *pfx = "<";
11983             for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
11984               {
11985                 if (av->a_un.a_val & bit)
11986                   {
11987                     printf ("%s%s", pfx, p);
11988                     pfx = " ";
11989                   }
11990                 bit <<= 1;
11991               }
11992             printf (">\n");
11993             break;
11994
11995           default:
11996             abort ();
11997           }
11998     }
11999 }
12000
12001 static bool
12002 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12003 {
12004   return ptr < end && (size_t) (end - ptr) >= sz;
12005 }
12006
12007 static bool
12008 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12009               int *retp)
12010 {
12011   if (! buf_has_data (*ptrp, end, 4))
12012     return false;
12013
12014   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12015   return true;
12016 }
12017
12018 static bool
12019 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12020                 uint64_t *retp)
12021 {
12022   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12023   if (! buf_has_data (*ptrp, end, sz))
12024     return false;
12025
12026   union
12027   {
12028     uint64_t u64;
12029     uint32_t u32;
12030   } u;
12031
12032   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12033
12034   if (sz == 4)
12035     *retp = u.u32;
12036   else
12037     *retp = u.u64;
12038   return true;
12039 }
12040
12041 static void
12042 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12043 {
12044   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12045   if (data == NULL)
12046     error (EXIT_FAILURE, 0,
12047            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12048
12049   unsigned char const *ptr = data->d_buf;
12050   unsigned char const *const end = data->d_buf + data->d_size;
12051
12052   /* Siginfo head is three ints: signal number, error number, origin
12053      code.  */
12054   int si_signo, si_errno, si_code;
12055   if (! buf_read_int (core, &ptr, end, &si_signo)
12056       || ! buf_read_int (core, &ptr, end, &si_errno)
12057       || ! buf_read_int (core, &ptr, end, &si_code))
12058     {
12059     fail:
12060       printf ("    Not enough data in NT_SIGINFO note.\n");
12061       return;
12062     }
12063
12064   /* Next is a pointer-aligned union of structures.  On 64-bit
12065      machines, that implies a word of padding.  */
12066   if (gelf_getclass (core) == ELFCLASS64)
12067     ptr += 4;
12068
12069   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
12070           si_signo, si_errno, si_code);
12071
12072   if (si_code > 0)
12073     switch (si_signo)
12074       {
12075       case CORE_SIGILL:
12076       case CORE_SIGFPE:
12077       case CORE_SIGSEGV:
12078       case CORE_SIGBUS:
12079         {
12080           uint64_t addr;
12081           if (! buf_read_ulong (core, &ptr, end, &addr))
12082             goto fail;
12083           printf ("    fault address: %#" PRIx64 "\n", addr);
12084           break;
12085         }
12086       default:
12087         ;
12088       }
12089   else if (si_code == CORE_SI_USER)
12090     {
12091       int pid, uid;
12092       if (! buf_read_int (core, &ptr, end, &pid)
12093           || ! buf_read_int (core, &ptr, end, &uid))
12094         goto fail;
12095       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
12096     }
12097 }
12098
12099 static void
12100 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12101 {
12102   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12103   if (data == NULL)
12104     error (EXIT_FAILURE, 0,
12105            gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12106
12107   unsigned char const *ptr = data->d_buf;
12108   unsigned char const *const end = data->d_buf + data->d_size;
12109
12110   uint64_t count, page_size;
12111   if (! buf_read_ulong (core, &ptr, end, &count)
12112       || ! buf_read_ulong (core, &ptr, end, &page_size))
12113     {
12114     fail:
12115       printf ("    Not enough data in NT_FILE note.\n");
12116       return;
12117     }
12118
12119   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12120   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12121   if (count > maxcount)
12122     goto fail;
12123
12124   /* Where file names are stored.  */
12125   unsigned char const *const fstart = ptr + 3 * count * addrsize;
12126   char const *fptr = (char *) fstart;
12127
12128   printf ("    %" PRId64 " files:\n", count);
12129   for (uint64_t i = 0; i < count; ++i)
12130     {
12131       uint64_t mstart, mend, moffset;
12132       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12133           || ! buf_read_ulong (core, &ptr, fstart, &mend)
12134           || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12135         goto fail;
12136
12137       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12138       if (fnext == NULL)
12139         goto fail;
12140
12141       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
12142                        " %08" PRIx64 " %" PRId64,
12143                        mstart, mend, moffset * page_size, mend - mstart);
12144       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12145
12146       fptr = fnext + 1;
12147     }
12148 }
12149
12150 static void
12151 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12152                   const char *name, const void *desc)
12153 {
12154   GElf_Word regs_offset;
12155   size_t nregloc;
12156   const Ebl_Register_Location *reglocs;
12157   size_t nitems;
12158   const Ebl_Core_Item *items;
12159
12160   if (! ebl_core_note (ebl, nhdr, name, desc,
12161                        &regs_offset, &nregloc, &reglocs, &nitems, &items))
12162     return;
12163
12164   /* Pass 0 for DESCSZ when there are registers in the note,
12165      so that the ITEMS array does not describe the whole thing.
12166      For non-register notes, the actual descsz might be a multiple
12167      of the unit size, not just exactly the unit size.  */
12168   unsigned int colno = handle_core_items (ebl->elf, desc,
12169                                           nregloc == 0 ? nhdr->n_descsz : 0,
12170                                           items, nitems);
12171   if (colno != 0)
12172     putchar_unlocked ('\n');
12173
12174   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12175                                  reglocs, nregloc);
12176   if (colno != 0)
12177     putchar_unlocked ('\n');
12178 }
12179
12180 static void
12181 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12182                    GElf_Off start, Elf_Data *data)
12183 {
12184   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
12185
12186   if (data == NULL)
12187     goto bad_note;
12188
12189   size_t offset = 0;
12190   GElf_Nhdr nhdr;
12191   size_t name_offset;
12192   size_t desc_offset;
12193   while (offset < data->d_size
12194          && (offset = gelf_getnote (data, offset,
12195                                     &nhdr, &name_offset, &desc_offset)) > 0)
12196     {
12197       const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12198       const char *desc = data->d_buf + desc_offset;
12199
12200       /* GNU Build Attributes are weird, they store most of their data
12201          into the owner name field.  Extract just the owner name
12202          prefix here, then use the rest later as data.  */
12203       bool is_gnu_build_attr
12204         = strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12205                    strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12206       const char *print_name = (is_gnu_build_attr
12207                                 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12208       size_t print_namesz = (is_gnu_build_attr
12209                              ? strlen (print_name) : nhdr.n_namesz);
12210
12211       char buf[100];
12212       char buf2[100];
12213       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
12214               (int) print_namesz, print_name, nhdr.n_descsz,
12215               ehdr->e_type == ET_CORE
12216               ? ebl_core_note_type_name (ebl, nhdr.n_type,
12217                                          buf, sizeof (buf))
12218               : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12219                                            nhdr.n_descsz,
12220                                            buf2, sizeof (buf2)));
12221
12222       /* Filter out invalid entries.  */
12223       if (memchr (name, '\0', nhdr.n_namesz) != NULL
12224           /* XXX For now help broken Linux kernels.  */
12225           || 1)
12226         {
12227           if (ehdr->e_type == ET_CORE)
12228             {
12229               if (nhdr.n_type == NT_AUXV
12230                   && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
12231                       || (nhdr.n_namesz == 5 && name[4] == '\0'))
12232                   && !memcmp (name, "CORE", 4))
12233                 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12234                                   start + desc_offset);
12235               else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12236                 switch (nhdr.n_type)
12237                   {
12238                   case NT_SIGINFO:
12239                     handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12240                                          start + desc_offset);
12241                     break;
12242
12243                   case NT_FILE:
12244                     handle_file_note (ebl->elf, nhdr.n_descsz,
12245                                       start + desc_offset);
12246                     break;
12247
12248                   default:
12249                     handle_core_note (ebl, &nhdr, name, desc);
12250                   }
12251               else
12252                 handle_core_note (ebl, &nhdr, name, desc);
12253             }
12254           else
12255             ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12256                              nhdr.n_descsz, desc);
12257         }
12258     }
12259
12260   if (offset == data->d_size)
12261     return;
12262
12263  bad_note:
12264   error (0, 0,
12265          gettext ("cannot get content of note: %s"),
12266          data != NULL ? "garbage data" : elf_errmsg (-1));
12267 }
12268
12269 static void
12270 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12271 {
12272   /* If we have section headers, just look for SHT_NOTE sections.
12273      In a debuginfo file, the program headers are not reliable.  */
12274   if (shnum != 0)
12275     {
12276       /* Get the section header string table index.  */
12277       size_t shstrndx;
12278       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12279         error (EXIT_FAILURE, 0,
12280                gettext ("cannot get section header string table index"));
12281
12282       Elf_Scn *scn = NULL;
12283       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12284         {
12285           GElf_Shdr shdr_mem;
12286           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12287
12288           if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12289             /* Not what we are looking for.  */
12290             continue;
12291
12292           printf (gettext ("\
12293 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12294                   elf_ndxscn (scn),
12295                   elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12296                   shdr->sh_size, shdr->sh_offset);
12297
12298           handle_notes_data (ebl, ehdr, shdr->sh_offset,
12299                              elf_getdata (scn, NULL));
12300         }
12301       return;
12302     }
12303
12304   /* We have to look through the program header to find the note
12305      sections.  There can be more than one.  */
12306   for (size_t cnt = 0; cnt < phnum; ++cnt)
12307     {
12308       GElf_Phdr mem;
12309       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12310
12311       if (phdr == NULL || phdr->p_type != PT_NOTE)
12312         /* Not what we are looking for.  */
12313         continue;
12314
12315       printf (gettext ("\
12316 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12317               phdr->p_filesz, phdr->p_offset);
12318
12319       handle_notes_data (ebl, ehdr, phdr->p_offset,
12320                          elf_getdata_rawchunk (ebl->elf,
12321                                                phdr->p_offset, phdr->p_filesz,
12322                                                (phdr->p_align == 8
12323                                                 ? ELF_T_NHDR8 : ELF_T_NHDR)));
12324     }
12325 }
12326
12327
12328 static void
12329 hex_dump (const uint8_t *data, size_t len)
12330 {
12331   size_t pos = 0;
12332   while (pos < len)
12333     {
12334       printf ("  0x%08zx ", pos);
12335
12336       const size_t chunk = MIN (len - pos, 16);
12337
12338       for (size_t i = 0; i < chunk; ++i)
12339         if (i % 4 == 3)
12340           printf ("%02x ", data[pos + i]);
12341         else
12342           printf ("%02x", data[pos + i]);
12343
12344       if (chunk < 16)
12345         printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12346
12347       for (size_t i = 0; i < chunk; ++i)
12348         {
12349           unsigned char b = data[pos + i];
12350           printf ("%c", isprint (b) ? b : '.');
12351         }
12352
12353       putchar ('\n');
12354       pos += chunk;
12355     }
12356 }
12357
12358 static void
12359 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12360 {
12361   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12362     printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12363             elf_ndxscn (scn), name);
12364   else
12365     {
12366       if (print_decompress)
12367         {
12368           /* We try to decompress the section, but keep the old shdr around
12369              so we can show both the original shdr size and the uncompressed
12370              data size.   */
12371           if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12372             {
12373               if (elf_compress (scn, 0, 0) < 0)
12374                 printf ("WARNING: %s [%zd]\n",
12375                         gettext ("Couldn't uncompress section"),
12376                         elf_ndxscn (scn));
12377             }
12378           else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12379             {
12380               if (elf_compress_gnu (scn, 0, 0) < 0)
12381                 printf ("WARNING: %s [%zd]\n",
12382                         gettext ("Couldn't uncompress section"),
12383                         elf_ndxscn (scn));
12384             }
12385         }
12386
12387       Elf_Data *data = elf_rawdata (scn, NULL);
12388       if (data == NULL)
12389         error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12390                elf_ndxscn (scn), name, elf_errmsg (-1));
12391       else
12392         {
12393           if (data->d_size == shdr->sh_size)
12394             printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12395                              " bytes at offset %#0" PRIx64 ":\n"),
12396                     elf_ndxscn (scn), name,
12397                     shdr->sh_size, shdr->sh_offset);
12398           else
12399             printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12400                              " bytes (%zd uncompressed) at offset %#0"
12401                              PRIx64 ":\n"),
12402                     elf_ndxscn (scn), name,
12403                     shdr->sh_size, data->d_size, shdr->sh_offset);
12404           hex_dump (data->d_buf, data->d_size);
12405         }
12406     }
12407 }
12408
12409 static void
12410 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12411 {
12412   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12413     printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12414             elf_ndxscn (scn), name);
12415   else
12416     {
12417       if (print_decompress)
12418         {
12419           /* We try to decompress the section, but keep the old shdr around
12420              so we can show both the original shdr size and the uncompressed
12421              data size.  */
12422           if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12423             {
12424               if (elf_compress (scn, 0, 0) < 0)
12425                 printf ("WARNING: %s [%zd]\n",
12426                         gettext ("Couldn't uncompress section"),
12427                         elf_ndxscn (scn));
12428             }
12429           else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12430             {
12431               if (elf_compress_gnu (scn, 0, 0) < 0)
12432                 printf ("WARNING: %s [%zd]\n",
12433                         gettext ("Couldn't uncompress section"),
12434                         elf_ndxscn (scn));
12435             }
12436         }
12437
12438       Elf_Data *data = elf_rawdata (scn, NULL);
12439       if (data == NULL)
12440         error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12441                elf_ndxscn (scn), name, elf_errmsg (-1));
12442       else
12443         {
12444           if (data->d_size == shdr->sh_size)
12445             printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12446                              " bytes at offset %#0" PRIx64 ":\n"),
12447                     elf_ndxscn (scn), name,
12448                     shdr->sh_size, shdr->sh_offset);
12449           else
12450             printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12451                              " bytes (%zd uncompressed) at offset %#0"
12452                              PRIx64 ":\n"),
12453                     elf_ndxscn (scn), name,
12454                     shdr->sh_size, data->d_size, shdr->sh_offset);
12455
12456           const char *start = data->d_buf;
12457           const char *const limit = start + data->d_size;
12458           do
12459             {
12460               const char *end = memchr (start, '\0', limit - start);
12461               const size_t pos = start - (const char *) data->d_buf;
12462               if (unlikely (end == NULL))
12463                 {
12464                   printf ("  [%6zx]- %.*s\n",
12465                           pos, (int) (limit - start), start);
12466                   break;
12467                 }
12468               printf ("  [%6zx]  %s\n", pos, start);
12469               start = end + 1;
12470             } while (start < limit);
12471         }
12472     }
12473 }
12474
12475 static void
12476 for_each_section_argument (Elf *elf, const struct section_argument *list,
12477                            void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12478                                          const char *name))
12479 {
12480   /* Get the section header string table index.  */
12481   size_t shstrndx;
12482   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12483     error (EXIT_FAILURE, 0,
12484            gettext ("cannot get section header string table index"));
12485
12486   for (const struct section_argument *a = list; a != NULL; a = a->next)
12487     {
12488       Elf_Scn *scn;
12489       GElf_Shdr shdr_mem;
12490       const char *name = NULL;
12491
12492       char *endp = NULL;
12493       unsigned long int shndx = strtoul (a->arg, &endp, 0);
12494       if (endp != a->arg && *endp == '\0')
12495         {
12496           scn = elf_getscn (elf, shndx);
12497           if (scn == NULL)
12498             {
12499               error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12500               continue;
12501             }
12502
12503           if (gelf_getshdr (scn, &shdr_mem) == NULL)
12504             error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12505                    elf_errmsg (-1));
12506           name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12507         }
12508       else
12509         {
12510           /* Need to look up the section by name.  */
12511           scn = NULL;
12512           bool found = false;
12513           while ((scn = elf_nextscn (elf, scn)) != NULL)
12514             {
12515               if (gelf_getshdr (scn, &shdr_mem) == NULL)
12516                 continue;
12517               name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12518               if (name == NULL)
12519                 continue;
12520               if (!strcmp (name, a->arg))
12521                 {
12522                   found = true;
12523                   (*dump) (scn, &shdr_mem, name);
12524                 }
12525             }
12526
12527           if (unlikely (!found) && !a->implicit)
12528             error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12529         }
12530     }
12531 }
12532
12533 static void
12534 dump_data (Ebl *ebl)
12535 {
12536   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12537 }
12538
12539 static void
12540 dump_strings (Ebl *ebl)
12541 {
12542   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12543 }
12544
12545 static void
12546 print_strings (Ebl *ebl)
12547 {
12548   /* Get the section header string table index.  */
12549   size_t shstrndx;
12550   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12551     error (EXIT_FAILURE, 0,
12552            gettext ("cannot get section header string table index"));
12553
12554   Elf_Scn *scn;
12555   GElf_Shdr shdr_mem;
12556   const char *name;
12557   scn = NULL;
12558   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12559     {
12560       if (gelf_getshdr (scn, &shdr_mem) == NULL)
12561         continue;
12562
12563       if (shdr_mem.sh_type != SHT_PROGBITS
12564           || !(shdr_mem.sh_flags & SHF_STRINGS))
12565         continue;
12566
12567       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12568       if (name == NULL)
12569         continue;
12570
12571       print_string_section (scn, &shdr_mem, name);
12572     }
12573 }
12574
12575 static void
12576 dump_archive_index (Elf *elf, const char *fname)
12577 {
12578   size_t narsym;
12579   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12580   if (arsym == NULL)
12581     {
12582       int result = elf_errno ();
12583       if (unlikely (result != ELF_E_NO_INDEX))
12584         error (EXIT_FAILURE, 0,
12585                gettext ("cannot get symbol index of archive '%s': %s"),
12586                fname, elf_errmsg (result));
12587       else
12588         printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12589       return;
12590     }
12591
12592   printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12593           fname, narsym);
12594
12595   size_t as_off = 0;
12596   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12597     {
12598       if (s->as_off != as_off)
12599         {
12600           as_off = s->as_off;
12601
12602           Elf *subelf = NULL;
12603           if (unlikely (elf_rand (elf, as_off) == 0)
12604               || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12605                            == NULL))
12606 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12607             while (1)
12608 #endif
12609               error (EXIT_FAILURE, 0,
12610                      gettext ("cannot extract member at offset %zu in '%s': %s"),
12611                      as_off, fname, elf_errmsg (-1));
12612
12613           const Elf_Arhdr *h = elf_getarhdr (subelf);
12614
12615           printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12616
12617           elf_end (subelf);
12618         }
12619
12620       printf ("\t%s\n", s->as_name);
12621     }
12622 }
12623
12624 #include "debugpred.h"