• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
main(int argc,char * argv[])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
parse_opt(int key,char * arg,struct argp_state * state)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
open_input_section(int fd)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
check_archive_index(int fd,const char * fname,bool only_one)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
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)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
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)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
find_no_debuginfo(Dwfl_Module * mod,void ** userdata,const char * modname,Dwarf_Addr base,const char * file_name,const char * debuglink_file,GElf_Word debuglink_crc,char ** debuginfo_file_name)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 *
create_dwfl(int fd,const char * fname)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
process_file(int fd,const char * fname,bool only_one)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
elf_contains_chdrs(Elf * elf)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
process_elf_file(Dwfl_Module * dwflmod,int fd)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
print_file_type(unsigned short int e_type)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
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)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 *
get_visibility_type(int value)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 *
elf_ch_type_name(unsigned int code)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
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)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
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)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 *
section_name(Ebl * ebl,GElf_Shdr * shdr)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
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)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
print_scngrp(Ebl * ebl)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
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)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
print_dt_flags(int class,GElf_Xword d_val)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
print_dt_flags_1(int class,GElf_Xword d_val)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
print_dt_feature_1(int class,GElf_Xword d_val)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
print_dt_posflag_1(int class,GElf_Xword d_val)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
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)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
print_dynamic(Ebl * ebl)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
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)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
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)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
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)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
print_symtab(Ebl * ebl,int type)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
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)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
print_verinfo(Ebl * ebl)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 *
get_ver_flags(unsigned int flags)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
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)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
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)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
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)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
print_hash_info(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx,uint_fast32_t maxlength,Elf32_Word nbucket,uint_fast32_t nsyms,uint32_t * lengths,const char * extrastr)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
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)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
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)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
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)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
handle_hash(Ebl * ebl)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
print_liblist(Ebl * ebl)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
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)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
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)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 *
dwarf_tag_string(unsigned int tag)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 *
dwarf_attr_string(unsigned int attrnum)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 *
dwarf_form_string(unsigned int form)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 *
dwarf_lang_string(unsigned int lang)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 *
dwarf_inline_string(unsigned int code)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 *
dwarf_encoding_string(unsigned int code)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 *
dwarf_access_string(unsigned int code)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 *
dwarf_defaulted_string(unsigned int code)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 *
dwarf_visibility_string(unsigned int code)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 *
dwarf_virtuality_string(unsigned int code)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 *
dwarf_identifier_case_string(unsigned int code)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 *
dwarf_calling_convention_string(unsigned int code)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 *
dwarf_ordering_string(unsigned int code)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 *
dwarf_discr_list_string(unsigned int code)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 *
dwarf_locexpr_opcode_string(unsigned int code)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 *
dwarf_unit_string(unsigned int type)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 *
dwarf_range_list_encoding_string(unsigned int kind)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 *
dwarf_loc_list_encoding_string(unsigned int kind)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 *
dwarf_line_content_description_string(unsigned int kind)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 *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)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 *
dwarf_tag_name(unsigned int tag)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 *
dwarf_attr_name(unsigned int attr)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 *
dwarf_form_name(unsigned int form)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 *
dwarf_lang_name(unsigned int lang)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 *
dwarf_inline_name(unsigned int code)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 *
dwarf_encoding_name(unsigned int code)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 *
dwarf_access_name(unsigned int code)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 *
dwarf_defaulted_name(unsigned int code)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 *
dwarf_visibility_name(unsigned int code)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 *
dwarf_virtuality_name(unsigned int code)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 *
dwarf_identifier_case_name(unsigned int code)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 *
dwarf_calling_convention_name(unsigned int code)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 *
dwarf_ordering_name(unsigned int code)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 *
dwarf_discr_list_name(unsigned int code)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 *
dwarf_unit_name(unsigned int type)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 *
dwarf_range_list_encoding_name(unsigned int kind)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 *
dwarf_loc_list_encoding_name(unsigned int kind)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 *
dwarf_line_content_description_name(unsigned int kind)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
print_block(size_t n,const void * block)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
print_bytes(size_t n,const unsigned char * bytes)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
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)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
print_ops(Dwfl_Module * dwflmod,Dwarf * dbg,int indent,int indentrest,unsigned int vers,unsigned int addrsize,unsigned int offset_size,struct Dwarf_CU * cu,Dwarf_Word len,const unsigned char * data)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
cudie_base(Dwarf_Die * cudie)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
listptr_base(struct listptr * p)4789 listptr_base (struct listptr *p)
4790 {
4791   Dwarf_Die cu = CUDIE (p->cu);
4792   return cudie_base (&cu);
4793 }
4794 
4795 static int
compare_listptr(const void * a,const void * b,void * arg)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
reset_listptr(struct listptr_table * table)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
notice_listptr(enum section_e section,struct listptr_table * table,uint_fast8_t address_size,uint_fast8_t offset_size,struct Dwarf_CU * cu,Dwarf_Off offset,unsigned int attr)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
sort_listptr(struct listptr_table * table,const char * name)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
skip_listptr_hole(struct listptr_table * table,size_t * idxp,uint_fast8_t * address_sizep,uint_fast8_t * offset_sizep,Dwarf_Addr * base,struct Dwarf_CU ** cu,ptrdiff_t offset,unsigned char ** readp,unsigned char * endp,unsigned int * attr)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
next_listptr_offset(struct listptr_table * table,size_t idx)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 *
get_listptr(struct listptr_table * table,size_t idx)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
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)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
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)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
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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 *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)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 *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)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
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)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
encoded_ptr_size(int encoding,unsigned int ptr_size)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
print_encoding(unsigned int val)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
print_relinfo(unsigned int val)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
print_encoding_base(const char * pfx,unsigned int fde_encoding)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
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)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
attr_callback(Dwarf_Attribute * attrp,void * arg)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
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)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
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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 *
print_form_data(Dwarf * dbg,int form,const unsigned char * readp,const unsigned char * readendp,unsigned int offset_len,Dwarf_Off str_offsets_base)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
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)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 				|| lineendp - linep < 1))
8708 		    goto invalid_unit;
8709 
8710 		  get_uleb128 (u128, linep, lineendp);
8711 		  printf (gettext (" set discriminator to %u\n"), u128);
8712 		  break;
8713 
8714 		default:
8715 		  /* Unknown, ignore it.  */
8716 		  puts (gettext (" unknown opcode"));
8717 		  linep += len - 1;
8718 		  break;
8719 		}
8720 	    }
8721 	  else if (opcode <= DW_LNS_set_isa)
8722 	    {
8723 	      /* This is a known standard opcode.  */
8724 	      switch (opcode)
8725 		{
8726 		case DW_LNS_copy:
8727 		  /* Takes no argument.  */
8728 		  puts (gettext (" copy"));
8729 		  break;
8730 
8731 		case DW_LNS_advance_pc:
8732 		  /* Takes one uleb128 parameter which is added to the
8733 		     address.  */
8734 		  if (lineendp - linep < 1)
8735 		    goto invalid_unit;
8736 		  get_uleb128 (u128, linep, lineendp);
8737 		  advance_pc (u128);
8738 		  {
8739 		    printf (gettext (" advance address by %u to "),
8740 			    op_addr_advance);
8741 		    print_dwarf_addr (dwflmod, 0, address, address);
8742 		    if (show_op_index)
8743 		      printf (gettext (", op_index to %u"), op_index);
8744 		    printf ("\n");
8745 		  }
8746 		  break;
8747 
8748 		case DW_LNS_advance_line:
8749 		  /* Takes one sleb128 parameter which is added to the
8750 		     line.  */
8751 		  if (lineendp - linep < 1)
8752 		    goto invalid_unit;
8753 		  get_sleb128 (s128, linep, lineendp);
8754 		  line += s128;
8755 		  printf (gettext ("\
8756  advance line by constant %d to %" PRId64 "\n"),
8757 			  s128, (int64_t) line);
8758 		  break;
8759 
8760 		case DW_LNS_set_file:
8761 		  /* Takes one uleb128 parameter which is stored in file.  */
8762 		  if (lineendp - linep < 1)
8763 		    goto invalid_unit;
8764 		  get_uleb128 (u128, linep, lineendp);
8765 		  printf (gettext (" set file to %" PRIu64 "\n"),
8766 			  (uint64_t) u128);
8767 		  break;
8768 
8769 		case DW_LNS_set_column:
8770 		  /* Takes one uleb128 parameter which is stored in column.  */
8771 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8772 				|| lineendp - linep < 1))
8773 		    goto invalid_unit;
8774 
8775 		  get_uleb128 (u128, linep, lineendp);
8776 		  printf (gettext (" set column to %" PRIu64 "\n"),
8777 			  (uint64_t) u128);
8778 		  break;
8779 
8780 		case DW_LNS_negate_stmt:
8781 		  /* Takes no argument.  */
8782 		  is_stmt = 1 - is_stmt;
8783 		  printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8784 			  "is_stmt", is_stmt);
8785 		  break;
8786 
8787 		case DW_LNS_set_basic_block:
8788 		  /* Takes no argument.  */
8789 		  puts (gettext (" set basic block flag"));
8790 		  break;
8791 
8792 		case DW_LNS_const_add_pc:
8793 		  /* Takes no argument.  */
8794 
8795 		  if (unlikely (line_range == 0))
8796 		    goto invalid_unit;
8797 
8798 		  advance_pc ((255 - opcode_base) / line_range);
8799 		  {
8800 		    printf (gettext (" advance address by constant %u to "),
8801 			    op_addr_advance);
8802 		    print_dwarf_addr (dwflmod, 0, address, address);
8803 		    if (show_op_index)
8804 		      printf (gettext (", op_index to %u"), op_index);
8805 		    printf ("\n");
8806 		  }
8807 		  break;
8808 
8809 		case DW_LNS_fixed_advance_pc:
8810 		  /* Takes one 16 bit parameter which is added to the
8811 		     address.  */
8812 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8813 				|| lineendp - linep < 2))
8814 		    goto invalid_unit;
8815 
8816 		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
8817 		  address += u128;
8818 		  op_index = 0;
8819 		  {
8820 		    printf (gettext ("\
8821  advance address by fixed value %u to \n"),
8822 			    u128);
8823 		    print_dwarf_addr (dwflmod, 0, address, address);
8824 		    printf ("\n");
8825 		  }
8826 		  break;
8827 
8828 		case DW_LNS_set_prologue_end:
8829 		  /* Takes no argument.  */
8830 		  puts (gettext (" set prologue end flag"));
8831 		  break;
8832 
8833 		case DW_LNS_set_epilogue_begin:
8834 		  /* Takes no argument.  */
8835 		  puts (gettext (" set epilogue begin flag"));
8836 		  break;
8837 
8838 		case DW_LNS_set_isa:
8839 		  /* Takes one uleb128 parameter which is stored in isa.  */
8840 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8841 				|| lineendp - linep < 1))
8842 		    goto invalid_unit;
8843 
8844 		  get_uleb128 (u128, linep, lineendp);
8845 		  printf (gettext (" set isa to %u\n"), u128);
8846 		  break;
8847 		}
8848 	    }
8849 	  else
8850 	    {
8851 	      /* This is a new opcode the generator but not we know about.
8852 		 Read the parameters associated with it but then discard
8853 		 everything.  Read all the parameters for this opcode.  */
8854 	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8855 				" unknown opcode with %" PRIu8 " parameters:",
8856 				standard_opcode_lengths[opcode]),
8857 		      standard_opcode_lengths[opcode]);
8858 	      for (int n = standard_opcode_lengths[opcode];
8859 		   n > 0 && linep < lineendp; --n)
8860 		{
8861 		  get_uleb128 (u128, linep, lineendp);
8862 		  if (n != standard_opcode_lengths[opcode])
8863 		    putc_unlocked (',', stdout);
8864 		  printf (" %u", u128);
8865 		}
8866 
8867 	      /* Next round, ignore this opcode.  */
8868 	      continue;
8869 	    }
8870 	}
8871     }
8872 
8873   /* There must only be one data block.  */
8874   assert (elf_getdata (scn, data) == NULL);
8875 }
8876 
8877 
8878 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8879 print_debug_loclists_section (Dwfl_Module *dwflmod,
8880 			      Ebl *ebl,
8881 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
8882 			      Elf_Scn *scn, GElf_Shdr *shdr,
8883 			      Dwarf *dbg)
8884 {
8885   printf (gettext ("\
8886 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8887 	  elf_ndxscn (scn), section_name (ebl, shdr),
8888 	  (uint64_t) shdr->sh_offset);
8889 
8890   Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
8891 		    ?: elf_rawdata (scn, NULL));
8892   if (unlikely (data == NULL))
8893     {
8894       error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
8895 	     elf_errmsg (-1));
8896       return;
8897     }
8898 
8899   /* For the listptr to get the base address/CU.  */
8900   sort_listptr (&known_loclistsptr, "loclistsptr");
8901   size_t listptr_idx = 0;
8902 
8903   const unsigned char *readp = data->d_buf;
8904   const unsigned char *const dataend = ((unsigned char *) data->d_buf
8905 					+ data->d_size);
8906   while (readp < dataend)
8907     {
8908       if (unlikely (readp > dataend - 4))
8909 	{
8910 	invalid_data:
8911 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8912 		 elf_ndxscn (scn), section_name (ebl, shdr));
8913 	  return;
8914 	}
8915 
8916       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
8917       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
8918 	      (uint64_t) offset);
8919 
8920       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
8921       unsigned int offset_size = 4;
8922       if (unlikely (unit_length == 0xffffffff))
8923 	{
8924 	  if (unlikely (readp > dataend - 8))
8925 	    goto invalid_data;
8926 
8927 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
8928 	  offset_size = 8;
8929 	}
8930       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
8931 
8932       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
8933 	 bytes to complete the header.  And this unit cannot go beyond
8934 	 the section data.  */
8935       if (readp > dataend - 8
8936 	  || unit_length < 8
8937 	  || unit_length > (uint64_t) (dataend - readp))
8938 	goto invalid_data;
8939 
8940       const unsigned char *nexthdr = readp + unit_length;
8941 
8942       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
8943       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
8944 
8945       if (version != 5)
8946 	{
8947 	  error (0, 0, gettext ("Unknown version"));
8948 	  goto next_table;
8949 	}
8950 
8951       uint8_t address_size = *readp++;
8952       printf (gettext (" Address size:   %8" PRIu64 "\n"),
8953 	      (uint64_t) address_size);
8954 
8955       if (address_size != 4 && address_size != 8)
8956 	{
8957 	  error (0, 0, gettext ("unsupported address size"));
8958 	  goto next_table;
8959 	}
8960 
8961       uint8_t segment_size = *readp++;
8962       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
8963 	      (uint64_t) segment_size);
8964 
8965       if (segment_size != 0)
8966         {
8967           error (0, 0, gettext ("unsupported segment size"));
8968           goto next_table;
8969         }
8970 
8971       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
8972       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
8973 	      (uint64_t) offset_entry_count);
8974 
8975       /* We need the CU that uses this unit to get the initial base address. */
8976       Dwarf_Addr cu_base = 0;
8977       struct Dwarf_CU *cu = NULL;
8978       if (listptr_cu (&known_loclistsptr, &listptr_idx,
8979 		      (Dwarf_Off) offset,
8980 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
8981 		      &cu_base, &cu)
8982 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
8983 	{
8984 	  Dwarf_Die cudie;
8985 	  if (dwarf_cu_die (cu, &cudie,
8986 			    NULL, NULL, NULL, NULL,
8987 			    NULL, NULL) == NULL)
8988 	    printf (gettext (" Unknown CU base: "));
8989 	  else
8990 	    printf (gettext (" CU [%6" PRIx64 "] base: "),
8991 		    dwarf_dieoffset (&cudie));
8992 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
8993 	  printf ("\n");
8994 	}
8995       else
8996 	printf (gettext (" Not associated with a CU.\n"));
8997 
8998       printf ("\n");
8999 
9000       const unsigned char *offset_array_start = readp;
9001       if (offset_entry_count > 0)
9002 	{
9003 	  uint64_t max_entries = (unit_length - 8) / offset_size;
9004 	  if (offset_entry_count > max_entries)
9005 	    {
9006 	      error (0, 0,
9007 		     gettext ("too many offset entries for unit length"));
9008 	      offset_entry_count = max_entries;
9009 	    }
9010 
9011 	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
9012 		  (uint64_t) (offset_array_start
9013 			      - (unsigned char *) data->d_buf));
9014 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9015 	    {
9016 	      printf ("   [%6" PRIu32 "] ", idx);
9017 	      if (offset_size == 4)
9018 		{
9019 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9020 		  printf ("0x%" PRIx32 "\n", off);
9021 		}
9022 	      else
9023 		{
9024 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9025 		  printf ("0x%" PRIx64 "\n", off);
9026 		}
9027 	    }
9028 	  printf ("\n");
9029 	}
9030 
9031       Dwarf_Addr base = cu_base;
9032       bool start_of_list = true;
9033       while (readp < nexthdr)
9034 	{
9035 	  uint8_t kind = *readp++;
9036 	  uint64_t op1, op2, len;
9037 
9038 	  /* Skip padding.  */
9039 	  if (start_of_list && kind == DW_LLE_end_of_list)
9040 	    continue;
9041 
9042 	  if (start_of_list)
9043 	    {
9044 	      base = cu_base;
9045 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9046 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9047 		      (uint64_t) (readp - offset_array_start - 1));
9048 	      start_of_list = false;
9049 	    }
9050 
9051 	  printf ("    %s", dwarf_loc_list_encoding_name (kind));
9052 	  switch (kind)
9053 	    {
9054 	    case DW_LLE_end_of_list:
9055 	      start_of_list = true;
9056 	      printf ("\n\n");
9057 	      break;
9058 
9059 	    case DW_LLE_base_addressx:
9060 	      if ((uint64_t) (nexthdr - readp) < 1)
9061 		{
9062 		invalid_entry:
9063 		  error (0, 0, gettext ("invalid loclists data"));
9064 		  goto next_table;
9065 		}
9066 	      get_uleb128 (op1, readp, nexthdr);
9067 	      printf (" %" PRIx64 "\n", op1);
9068 	      if (! print_unresolved_addresses)
9069 		{
9070 		  Dwarf_Addr addr;
9071 		  if (get_indexed_addr (cu, op1, &addr) != 0)
9072 		    printf ("      ???\n");
9073 		  else
9074 		    {
9075 		      printf ("      ");
9076 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
9077 		      printf ("\n");
9078 		    }
9079 		}
9080 	      break;
9081 
9082 	    case DW_LLE_startx_endx:
9083 	      if ((uint64_t) (nexthdr - readp) < 1)
9084 		goto invalid_entry;
9085 	      get_uleb128 (op1, readp, nexthdr);
9086 	      if ((uint64_t) (nexthdr - readp) < 1)
9087 		goto invalid_entry;
9088 	      get_uleb128 (op2, readp, nexthdr);
9089 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9090 	      if (! print_unresolved_addresses)
9091 		{
9092 		  Dwarf_Addr addr1;
9093 		  Dwarf_Addr addr2;
9094 		  if (get_indexed_addr (cu, op1, &addr1) != 0
9095 		      || get_indexed_addr (cu, op2, &addr2) != 0)
9096 		    {
9097 		      printf ("      ???..\n");
9098 		      printf ("      ???\n");
9099 		    }
9100 		  else
9101 		    {
9102 		      printf ("      ");
9103 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9104 		      printf ("..\n      ");
9105 		      print_dwarf_addr (dwflmod, address_size,
9106 					addr2 - 1, addr2);
9107 		      printf ("\n");
9108 		    }
9109 		}
9110 	      if ((uint64_t) (nexthdr - readp) < 1)
9111 		goto invalid_entry;
9112 	      get_uleb128 (len, readp, nexthdr);
9113 	      if ((uint64_t) (nexthdr - readp) < len)
9114 		goto invalid_entry;
9115 	      print_ops (dwflmod, dbg, 8, 8, version,
9116 			 address_size, offset_size, cu, len, readp);
9117 	      readp += len;
9118 	      break;
9119 
9120 	    case DW_LLE_startx_length:
9121 	      if ((uint64_t) (nexthdr - readp) < 1)
9122 		goto invalid_entry;
9123 	      get_uleb128 (op1, readp, nexthdr);
9124 	      if ((uint64_t) (nexthdr - readp) < 1)
9125 		goto invalid_entry;
9126 	      get_uleb128 (op2, readp, nexthdr);
9127 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9128 	      if (! print_unresolved_addresses)
9129 		{
9130 		  Dwarf_Addr addr1;
9131 		  Dwarf_Addr addr2;
9132 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
9133 		    {
9134 		      printf ("      ???..\n");
9135 		      printf ("      ???\n");
9136 		    }
9137 		  else
9138 		    {
9139 		      addr2 = addr1 + op2;
9140 		      printf ("      ");
9141 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9142 		      printf ("..\n      ");
9143 		      print_dwarf_addr (dwflmod, address_size,
9144 					addr2 - 1, addr2);
9145 		      printf ("\n");
9146 		    }
9147 		}
9148 	      if ((uint64_t) (nexthdr - readp) < 1)
9149 		goto invalid_entry;
9150 	      get_uleb128 (len, readp, nexthdr);
9151 	      if ((uint64_t) (nexthdr - readp) < len)
9152 		goto invalid_entry;
9153 	      print_ops (dwflmod, dbg, 8, 8, version,
9154 			 address_size, offset_size, cu, len, readp);
9155 	      readp += len;
9156 	      break;
9157 
9158 	    case DW_LLE_offset_pair:
9159 	      if ((uint64_t) (nexthdr - readp) < 1)
9160 		goto invalid_entry;
9161 	      get_uleb128 (op1, readp, nexthdr);
9162 	      if ((uint64_t) (nexthdr - readp) < 1)
9163 		goto invalid_entry;
9164 	      get_uleb128 (op2, readp, nexthdr);
9165 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9166 	      if (! print_unresolved_addresses)
9167 		{
9168 		  op1 += base;
9169 		  op2 += base;
9170 		  printf ("      ");
9171 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9172 		  printf ("..\n      ");
9173 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9174 		  printf ("\n");
9175 		}
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_default_location:
9187 	      if ((uint64_t) (nexthdr - readp) < 1)
9188 		goto invalid_entry;
9189 	      get_uleb128 (len, readp, nexthdr);
9190 	      if ((uint64_t) (nexthdr - readp) < len)
9191 		goto invalid_entry;
9192 	      print_ops (dwflmod, dbg, 8, 8, version,
9193 			 address_size, offset_size, cu, len, readp);
9194 	      readp += len;
9195 	      break;
9196 
9197 	    case DW_LLE_base_address:
9198 	      if (address_size == 4)
9199 		{
9200 		  if ((uint64_t) (nexthdr - readp) < 4)
9201 		    goto invalid_entry;
9202 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9203 		}
9204 	      else
9205 		{
9206 		  if ((uint64_t) (nexthdr - readp) < 8)
9207 		    goto invalid_entry;
9208 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9209 		}
9210 	      base = op1;
9211 	      printf (" 0x%" PRIx64 "\n", base);
9212 	      if (! print_unresolved_addresses)
9213 		{
9214 		  printf ("      ");
9215 		  print_dwarf_addr (dwflmod, address_size, base, base);
9216 		  printf ("\n");
9217 		}
9218 	      break;
9219 
9220 	    case DW_LLE_start_end:
9221 	      if (address_size == 4)
9222 		{
9223 		  if ((uint64_t) (nexthdr - readp) < 8)
9224 		    goto invalid_entry;
9225 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9226 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
9227 		}
9228 	      else
9229 		{
9230 		  if ((uint64_t) (nexthdr - readp) < 16)
9231 		    goto invalid_entry;
9232 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9233 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
9234 		}
9235 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9236 	      if (! print_unresolved_addresses)
9237 		{
9238 		  printf ("      ");
9239 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9240 		  printf ("..\n      ");
9241 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9242 		  printf ("\n");
9243 		}
9244 	      if ((uint64_t) (nexthdr - readp) < 1)
9245 		goto invalid_entry;
9246 	      get_uleb128 (len, readp, nexthdr);
9247 	      if ((uint64_t) (nexthdr - readp) < len)
9248 		goto invalid_entry;
9249 	      print_ops (dwflmod, dbg, 8, 8, version,
9250 			 address_size, offset_size, cu, len, readp);
9251 	      readp += len;
9252 	      break;
9253 
9254 	    case DW_LLE_start_length:
9255 	      if (address_size == 4)
9256 		{
9257 		  if ((uint64_t) (nexthdr - readp) < 4)
9258 		    goto invalid_entry;
9259 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9260 		}
9261 	      else
9262 		{
9263 		  if ((uint64_t) (nexthdr - readp) < 8)
9264 		    goto invalid_entry;
9265 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9266 		}
9267 	      if ((uint64_t) (nexthdr - readp) < 1)
9268 		goto invalid_entry;
9269 	      get_uleb128 (op2, readp, nexthdr);
9270 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9271 	      if (! print_unresolved_addresses)
9272 		{
9273 		  op2 = op1 + op2;
9274 		  printf ("      ");
9275 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9276 		  printf ("..\n      ");
9277 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9278 		  printf ("\n");
9279 		}
9280 	      if ((uint64_t) (nexthdr - readp) < 1)
9281 		goto invalid_entry;
9282 	      get_uleb128 (len, readp, nexthdr);
9283 	      if ((uint64_t) (nexthdr - readp) < len)
9284 		goto invalid_entry;
9285 	      print_ops (dwflmod, dbg, 8, 8, version,
9286 			 address_size, offset_size, cu, len, readp);
9287 	      readp += len;
9288 	      break;
9289 
9290 	    default:
9291 	      goto invalid_entry;
9292 	    }
9293 	}
9294 
9295     next_table:
9296       if (readp != nexthdr)
9297 	{
9298           size_t padding = nexthdr - readp;
9299           printf (gettext ("   %zu padding bytes\n\n"), padding);
9300 	  readp = nexthdr;
9301 	}
9302     }
9303 }
9304 
9305 
9306 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9307 print_debug_loc_section (Dwfl_Module *dwflmod,
9308 			 Ebl *ebl, GElf_Ehdr *ehdr,
9309 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9310 {
9311   Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9312 		    ?: elf_rawdata (scn, NULL));
9313 
9314   if (unlikely (data == NULL))
9315     {
9316       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9317 	     elf_errmsg (-1));
9318       return;
9319     }
9320 
9321   printf (gettext ("\
9322 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9323 	  elf_ndxscn (scn), section_name (ebl, shdr),
9324 	  (uint64_t) shdr->sh_offset);
9325 
9326   sort_listptr (&known_locsptr, "loclistptr");
9327   size_t listptr_idx = 0;
9328 
9329   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9330   uint_fast8_t offset_size = 4;
9331 
9332   bool first = true;
9333   Dwarf_Addr base = 0;
9334   unsigned char *readp = data->d_buf;
9335   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9336   Dwarf_CU *last_cu = NULL;
9337   while (readp < endp)
9338     {
9339       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9340       Dwarf_CU *cu = last_cu;
9341       unsigned int attr = 0;
9342 
9343       if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9344 				      &address_size, &offset_size, &base,
9345 				      &cu, offset, &readp, endp, &attr))
9346 	continue;
9347 
9348       if (last_cu != cu)
9349        {
9350 	Dwarf_Die cudie;
9351 	if (dwarf_cu_die (cu, &cudie,
9352 			  NULL, NULL, NULL, NULL,
9353 			  NULL, NULL) == NULL)
9354 	  printf (gettext ("\n Unknown CU base: "));
9355 	else
9356 	  printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9357 		  dwarf_dieoffset (&cudie));
9358 	print_dwarf_addr (dwflmod, address_size, base, base);
9359 	printf ("\n");
9360        }
9361       last_cu = cu;
9362 
9363       if (attr == DW_AT_GNU_locviews)
9364 	{
9365 	  Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9366 						    listptr_idx);
9367 	  const unsigned char *locp = readp;
9368 	  const unsigned char *locendp;
9369 	  if (next_off == 0
9370 	      || next_off > (size_t) (endp
9371 				      - (const unsigned char *) data->d_buf))
9372 	    locendp = endp;
9373 	  else
9374 	    locendp = (const unsigned char *) data->d_buf + next_off;
9375 
9376 	  while (locp < locendp)
9377 	    {
9378 	      uint64_t v1, v2;
9379 	      get_uleb128 (v1, locp, locendp);
9380 	      if (locp >= locendp)
9381 		{
9382 		  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9383 		  break;
9384 		}
9385 	      get_uleb128 (v2, locp, locendp);
9386 	      if (first)		/* First view pair in a list.  */
9387 		printf (" [%6tx] ", offset);
9388 	      else
9389 		printf ("          ");
9390 	      printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9391 	      first = false;
9392 	    }
9393 
9394 	  first = true;
9395 	  readp = (unsigned char *) locendp;
9396 	  continue;
9397 	}
9398 
9399       /* GNU DebugFission encoded addresses as addrx.  */
9400       bool is_debugfission = ((cu != NULL
9401 			       || split_dwarf_cu_base (dbg, &cu, &base))
9402 			      && (cu->version < 5
9403 				  && cu->unit_type == DW_UT_split_compile));
9404       if (!is_debugfission
9405 	  && unlikely (data->d_size - offset < (size_t) address_size * 2))
9406         {
9407 	invalid_data:
9408 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9409 	  break;
9410 	}
9411 
9412       Dwarf_Addr begin;
9413       Dwarf_Addr end;
9414       bool use_base = true;
9415       if (is_debugfission)
9416 	{
9417 	  const unsigned char *locp = readp;
9418 	  const unsigned char *locendp = readp + data->d_size;
9419 	  if (locp >= locendp)
9420 	    goto invalid_data;
9421 
9422 	  Dwarf_Word idx;
9423 	  unsigned char code = *locp++;
9424 	  switch (code)
9425 	    {
9426 	    case DW_LLE_GNU_end_of_list_entry:
9427 	      begin = 0;
9428 	      end = 0;
9429 	      break;
9430 
9431 	    case DW_LLE_GNU_base_address_selection_entry:
9432 	      if (locp >= locendp)
9433 		goto invalid_data;
9434 	      begin = (Dwarf_Addr) -1;
9435 	      get_uleb128 (idx, locp, locendp);
9436 	      if (get_indexed_addr (cu, idx, &end) != 0)
9437 		end = idx; /* ... */
9438 	      break;
9439 
9440 	    case DW_LLE_GNU_start_end_entry:
9441 	      if (locp >= locendp)
9442 		goto invalid_data;
9443 	      get_uleb128 (idx, locp, locendp);
9444 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9445 		begin = idx; /* ... */
9446 	      if (locp >= locendp)
9447 		goto invalid_data;
9448 	      get_uleb128 (idx, locp, locendp);
9449 	      if (get_indexed_addr (cu, idx, &end) != 0)
9450 		end = idx; /* ... */
9451 	      use_base = false;
9452 	      break;
9453 
9454 	    case DW_LLE_GNU_start_length_entry:
9455 	      if (locp >= locendp)
9456 		goto invalid_data;
9457 	      get_uleb128 (idx, locp, locendp);
9458 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9459 		begin = idx; /* ... */
9460 	      if (locendp - locp < 4)
9461 		goto invalid_data;
9462 	      end = read_4ubyte_unaligned_inc (dbg, locp);
9463 	      end += begin;
9464 	      use_base = false;
9465 	      break;
9466 
9467 	    default:
9468 		goto invalid_data;
9469 	    }
9470 
9471 	  readp = (unsigned char *) locp;
9472 	}
9473       else if (address_size == 8)
9474 	{
9475 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
9476 	  end = read_8ubyte_unaligned_inc (dbg, readp);
9477 	}
9478       else
9479 	{
9480 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
9481 	  end = read_4ubyte_unaligned_inc (dbg, readp);
9482 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
9483 	    begin = (Dwarf_Addr) -1l;
9484 	}
9485 
9486       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
9487 	{
9488 	  printf (gettext (" [%6tx] base address\n          "), offset);
9489 	  print_dwarf_addr (dwflmod, address_size, end, end);
9490 	  printf ("\n");
9491 	  base = end;
9492 	}
9493       else if (begin == 0 && end == 0) /* End of list entry.  */
9494 	{
9495 	  if (first)
9496 	    printf (gettext (" [%6tx] empty list\n"), offset);
9497 	  first = true;
9498 	}
9499       else
9500 	{
9501 	  /* We have a location expression entry.  */
9502 	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9503 
9504 	  if (first)		/* First entry in a list.  */
9505 	    printf (" [%6tx] ", offset);
9506 	  else
9507 	    printf ("          ");
9508 
9509 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9510 	  if (! print_unresolved_addresses)
9511 	    {
9512 	      Dwarf_Addr dab = use_base ? base + begin : begin;
9513 	      Dwarf_Addr dae = use_base ? base + end : end;
9514 	      printf ("          ");
9515 	      print_dwarf_addr (dwflmod, address_size, dab, dab);
9516 	      printf ("..\n          ");
9517 	      print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9518 	      printf ("\n");
9519 	    }
9520 
9521 	  if (endp - readp <= (ptrdiff_t) len)
9522 	    {
9523 	      fputs (gettext ("   <INVALID DATA>\n"), stdout);
9524 	      break;
9525 	    }
9526 
9527 	  print_ops (dwflmod, dbg, 11, 11,
9528 		     cu != NULL ? cu->version : 3,
9529 		     address_size, offset_size, cu, len, readp);
9530 
9531 	  first = false;
9532 	  readp += len;
9533 	}
9534     }
9535 }
9536 
9537 struct mac_culist
9538 {
9539   Dwarf_Die die;
9540   Dwarf_Off offset;
9541   Dwarf_Files *files;
9542   struct mac_culist *next;
9543 };
9544 
9545 
9546 static int
mac_compare(const void * p1,const void * p2)9547 mac_compare (const void *p1, const void *p2)
9548 {
9549   struct mac_culist *m1 = (struct mac_culist *) p1;
9550   struct mac_culist *m2 = (struct mac_culist *) p2;
9551 
9552   if (m1->offset < m2->offset)
9553     return -1;
9554   if (m1->offset > m2->offset)
9555     return 1;
9556   return 0;
9557 }
9558 
9559 
9560 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9561 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9562 			     Ebl *ebl,
9563 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
9564 			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9565 {
9566   printf (gettext ("\
9567 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9568 	  elf_ndxscn (scn), section_name (ebl, shdr),
9569 	  (uint64_t) shdr->sh_offset);
9570   putc_unlocked ('\n', stdout);
9571 
9572   /* There is no function in libdw to iterate over the raw content of
9573      the section but it is easy enough to do.  */
9574   Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9575 		    ?: elf_rawdata (scn, NULL));
9576   if (unlikely (data == NULL))
9577     {
9578       error (0, 0, gettext ("cannot get macro information section data: %s"),
9579 	     elf_errmsg (-1));
9580       return;
9581     }
9582 
9583   /* Get the source file information for all CUs.  */
9584   Dwarf_Off offset;
9585   Dwarf_Off ncu = 0;
9586   size_t hsize;
9587   struct mac_culist *culist = NULL;
9588   size_t nculist = 0;
9589   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9590     {
9591       Dwarf_Die cudie;
9592       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9593 	continue;
9594 
9595       Dwarf_Attribute attr;
9596       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9597 	continue;
9598 
9599       Dwarf_Word macoff;
9600       if (dwarf_formudata (&attr, &macoff) != 0)
9601 	continue;
9602 
9603       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9604       newp->die = cudie;
9605       newp->offset = macoff;
9606       newp->files = NULL;
9607       newp->next = culist;
9608       culist = newp;
9609       ++nculist;
9610     }
9611 
9612   /* Convert the list into an array for easier consumption.  */
9613   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9614 							 * sizeof (*cus));
9615   /* Add sentinel.  */
9616   cus[nculist].offset = data->d_size;
9617   cus[nculist].files = (Dwarf_Files *) -1l;
9618   if (nculist > 0)
9619     {
9620       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9621 	{
9622 	  assert (cnt < nculist);
9623 	  cus[cnt] = *culist;
9624 	  culist = culist->next;
9625 	}
9626 
9627       /* Sort the array according to the offset in the .debug_macinfo
9628 	 section.  Note we keep the sentinel at the end.  */
9629       qsort (cus, nculist, sizeof (*cus), mac_compare);
9630     }
9631 
9632   const unsigned char *readp = (const unsigned char *) data->d_buf;
9633   const unsigned char *readendp = readp + data->d_size;
9634   int level = 1;
9635 
9636   while (readp < readendp)
9637     {
9638       unsigned int opcode = *readp++;
9639       unsigned int u128;
9640       unsigned int u128_2;
9641       const unsigned char *endp;
9642 
9643       switch (opcode)
9644 	{
9645 	case DW_MACINFO_define:
9646 	case DW_MACINFO_undef:
9647 	case DW_MACINFO_vendor_ext:
9648 	  /*  For the first two opcodes the parameters are
9649 		line, string
9650 	      For the latter
9651 		number, string.
9652 	      We can treat these cases together.  */
9653 	  get_uleb128 (u128, readp, readendp);
9654 
9655 	  endp = memchr (readp, '\0', readendp - readp);
9656 	  if (unlikely (endp == NULL))
9657 	    {
9658 	      printf (gettext ("\
9659 %*s*** non-terminated string at end of section"),
9660 		      level, "");
9661 	      return;
9662 	    }
9663 
9664 	  if (opcode == DW_MACINFO_define)
9665 	    printf ("%*s#define %s, line %u\n",
9666 		    level, "", (char *) readp, u128);
9667 	  else if (opcode == DW_MACINFO_undef)
9668 	    printf ("%*s#undef %s, line %u\n",
9669 		    level, "", (char *) readp, u128);
9670 	  else
9671 	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9672 
9673 	  readp = endp + 1;
9674 	  break;
9675 
9676 	case DW_MACINFO_start_file:
9677 	  /* The two parameters are line and file index, in this order.  */
9678 	  get_uleb128 (u128, readp, readendp);
9679 	  if (readendp - readp < 1)
9680 	    {
9681 	      printf (gettext ("\
9682 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9683 		      level, "");
9684 	      return;
9685 	    }
9686 	  get_uleb128 (u128_2, readp, readendp);
9687 
9688 	  /* Find the CU DIE for this file.  */
9689 	  size_t macoff = readp - (const unsigned char *) data->d_buf;
9690 	  const char *fname = "???";
9691 	  if (macoff >= cus[0].offset)
9692 	    {
9693 	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9694 		++cus;
9695 
9696 	      if (cus[0].files == NULL
9697 		&& dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9698 		cus[0].files = (Dwarf_Files *) -1l;
9699 
9700 	      if (cus[0].files != (Dwarf_Files *) -1l)
9701 		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9702 			 ?: "???");
9703 	    }
9704 
9705 	  printf ("%*sstart_file %u, [%u] %s\n",
9706 		  level, "", u128, u128_2, fname);
9707 	  ++level;
9708 	  break;
9709 
9710 	case DW_MACINFO_end_file:
9711 	  --level;
9712 	  printf ("%*send_file\n", level, "");
9713 	  /* Nothing more to do.  */
9714 	  break;
9715 
9716 	default:
9717 	  // XXX gcc seems to generate files with a trailing zero.
9718 	  if (unlikely (opcode != 0 || readp != readendp))
9719 	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9720 	  break;
9721 	}
9722     }
9723 }
9724 
9725 
9726 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9727 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9728 			   Ebl *ebl,
9729 			   GElf_Ehdr *ehdr __attribute__ ((unused)),
9730 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9731 {
9732   printf (gettext ("\
9733 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9734 	  elf_ndxscn (scn), section_name (ebl, shdr),
9735 	  (uint64_t) shdr->sh_offset);
9736   putc_unlocked ('\n', stdout);
9737 
9738   Elf_Data *data =  elf_getdata (scn, NULL);
9739   if (unlikely (data == NULL))
9740     {
9741       error (0, 0, gettext ("cannot get macro information section data: %s"),
9742 	     elf_errmsg (-1));
9743       return;
9744     }
9745 
9746   /* Get the source file information for all CUs.  Uses same
9747      datastructure as macinfo.  But uses offset field to directly
9748      match .debug_line offset.  And just stored in a list.  */
9749   Dwarf_Off offset;
9750   Dwarf_Off ncu = 0;
9751   size_t hsize;
9752   struct mac_culist *culist = NULL;
9753   size_t nculist = 0;
9754   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9755     {
9756       Dwarf_Die cudie;
9757       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9758 	continue;
9759 
9760       Dwarf_Attribute attr;
9761       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9762 	continue;
9763 
9764       Dwarf_Word lineoff;
9765       if (dwarf_formudata (&attr, &lineoff) != 0)
9766 	continue;
9767 
9768       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9769       newp->die = cudie;
9770       newp->offset = lineoff;
9771       newp->files = NULL;
9772       newp->next = culist;
9773       culist = newp;
9774       ++nculist;
9775     }
9776 
9777   const unsigned char *readp = (const unsigned char *) data->d_buf;
9778   const unsigned char *readendp = readp + data->d_size;
9779 
9780   while (readp < readendp)
9781     {
9782       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
9783 	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
9784 
9785       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9786       // optional vendor extension macro entry table.
9787       if (readp + 2 > readendp)
9788 	{
9789 	invalid_data:
9790 	  error (0, 0, gettext ("invalid data"));
9791 	  return;
9792 	}
9793       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9794       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
9795 
9796       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
9797       // 5 when it gets standardized.
9798       if (vers != 4 && vers != 5)
9799 	{
9800 	  printf (gettext ("  unknown version, cannot parse section\n"));
9801 	  return;
9802 	}
9803 
9804       if (readp + 1 > readendp)
9805 	goto invalid_data;
9806       const unsigned char flag = *readp++;
9807       printf (gettext (" Flag:               0x%" PRIx8), flag);
9808       if (flag != 0)
9809 	{
9810 	  printf (" (");
9811 	  if ((flag & 0x01) != 0)
9812 	    {
9813 	      printf ("offset_size");
9814 	      if ((flag & 0xFE) !=  0)
9815 		printf (", ");
9816 	    }
9817 	  if ((flag & 0x02) != 0)
9818 	    {
9819 	      printf ("debug_line_offset");
9820 	      if ((flag & 0xFC) !=  0)
9821 		printf (", ");
9822 	    }
9823 	  if ((flag & 0x04) != 0)
9824 	    {
9825 	      printf ("operands_table");
9826 	      if ((flag & 0xF8) !=  0)
9827 		printf (", ");
9828 	    }
9829 	  if ((flag & 0xF8) != 0)
9830 	    printf ("unknown");
9831 	  printf (")");
9832 	}
9833       printf ("\n");
9834 
9835       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9836       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
9837       Dwarf_Off line_offset = -1;
9838       if (flag & 0x02)
9839 	{
9840 	  if (offset_len == 8)
9841 	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9842 	  else
9843 	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9844 	  printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9845 		  line_offset);
9846 	}
9847 
9848       struct mac_culist *cu = NULL;
9849       if (line_offset != (Dwarf_Off) -1)
9850 	{
9851 	  cu = culist;
9852 	  while (cu != NULL && line_offset != cu->offset)
9853 	    cu = cu->next;
9854 	}
9855 
9856       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9857 							       ? cu->die.cu
9858 							       : NULL));
9859 
9860       const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9861       memset (vendor, 0, sizeof vendor);
9862       if (flag & 0x04)
9863 	{
9864 	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
9865 	  // of arguments, for each argument 1 byte form code.
9866 	  if (readp + 1 > readendp)
9867 	    goto invalid_data;
9868 	  unsigned int tlen = *readp++;
9869 	  printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
9870 		  tlen);
9871 	  for (unsigned int i = 0; i < tlen; i++)
9872 	    {
9873 	      if (readp + 1 > readendp)
9874 		goto invalid_data;
9875 	      unsigned int opcode = *readp++;
9876 	      printf (gettext ("    [%" PRIx8 "]"), opcode);
9877 	      if (opcode < DW_MACRO_lo_user
9878 		  || opcode > DW_MACRO_hi_user)
9879 		goto invalid_data;
9880 	      // Record the start of description for this vendor opcode.
9881 	      // uleb128 nr args, 1 byte per arg form.
9882 	      vendor[opcode - DW_MACRO_lo_user] = readp;
9883 	      if (readp + 1 > readendp)
9884 		goto invalid_data;
9885 	      unsigned int args = *readp++;
9886 	      if (args > 0)
9887 		{
9888 		  printf (gettext (" %" PRIu8 " arguments:"), args);
9889 		  while (args > 0)
9890 		    {
9891 		      if (readp + 1 > readendp)
9892 			goto invalid_data;
9893 		      unsigned int form = *readp++;
9894 		      printf (" %s", dwarf_form_name (form));
9895 		      if (! libdw_valid_user_form (form))
9896 			goto invalid_data;
9897 		      args--;
9898 		      if (args > 0)
9899 			putchar_unlocked (',');
9900 		    }
9901 		}
9902 	      else
9903 		printf (gettext (" no arguments."));
9904 	      putchar_unlocked ('\n');
9905 	    }
9906 	}
9907       putchar_unlocked ('\n');
9908 
9909       int level = 1;
9910       if (readp + 1 > readendp)
9911 	goto invalid_data;
9912       unsigned int opcode = *readp++;
9913       while (opcode != 0)
9914 	{
9915 	  unsigned int u128;
9916 	  unsigned int u128_2;
9917 	  const unsigned char *endp;
9918 	  uint64_t off;
9919 
9920           switch (opcode)
9921             {
9922             case DW_MACRO_start_file:
9923 	      get_uleb128 (u128, readp, readendp);
9924 	      if (readp >= readendp)
9925 		goto invalid_data;
9926 	      get_uleb128 (u128_2, readp, readendp);
9927 
9928 	      /* Find the CU DIE that matches this line offset.  */
9929 	      const char *fname = "???";
9930 	      if (cu != NULL)
9931 		{
9932 		  if (cu->files == NULL
9933 		      && dwarf_getsrcfiles (&cu->die, &cu->files,
9934 					    NULL) != 0)
9935 		    cu->files = (Dwarf_Files *) -1l;
9936 
9937 		  if (cu->files != (Dwarf_Files *) -1l)
9938 		    fname = (dwarf_filesrc (cu->files, u128_2,
9939 					    NULL, NULL) ?: "???");
9940 		}
9941 	      printf ("%*sstart_file %u, [%u] %s\n",
9942 		      level, "", u128, u128_2, fname);
9943 	      ++level;
9944 	      break;
9945 
9946 	    case DW_MACRO_end_file:
9947 	      --level;
9948 	      printf ("%*send_file\n", level, "");
9949 	      break;
9950 
9951 	    case DW_MACRO_define:
9952 	      get_uleb128 (u128, readp, readendp);
9953 	      endp = memchr (readp, '\0', readendp - readp);
9954 	      if (endp == NULL)
9955 		goto invalid_data;
9956 	      printf ("%*s#define %s, line %u\n",
9957 		      level, "", readp, u128);
9958 	      readp = endp + 1;
9959 	      break;
9960 
9961 	    case DW_MACRO_undef:
9962 	      get_uleb128 (u128, readp, readendp);
9963 	      endp = memchr (readp, '\0', readendp - readp);
9964 	      if (endp == NULL)
9965 		goto invalid_data;
9966 	      printf ("%*s#undef %s, line %u\n",
9967 		      level, "", readp, u128);
9968 	      readp = endp + 1;
9969 	      break;
9970 
9971 	    case DW_MACRO_define_strp:
9972 	      get_uleb128 (u128, readp, readendp);
9973 	      if (readp + offset_len > readendp)
9974 		goto invalid_data;
9975 	      if (offset_len == 8)
9976 		off = read_8ubyte_unaligned_inc (dbg, readp);
9977 	      else
9978 		off = read_4ubyte_unaligned_inc (dbg, readp);
9979 	      printf ("%*s#define %s, line %u (indirect)\n",
9980 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
9981 	      break;
9982 
9983 	    case DW_MACRO_undef_strp:
9984 	      get_uleb128 (u128, readp, readendp);
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#undef %s, line %u (indirect)\n",
9992 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
9993 	      break;
9994 
9995 	    case DW_MACRO_import:
9996 	      if (readp + offset_len > readendp)
9997 		goto invalid_data;
9998 	      if (offset_len == 8)
9999 		off = read_8ubyte_unaligned_inc (dbg, readp);
10000 	      else
10001 		off = read_4ubyte_unaligned_inc (dbg, readp);
10002 	      printf ("%*s#include offset 0x%" PRIx64 "\n",
10003 		      level, "", off);
10004 	      break;
10005 
10006 	    case DW_MACRO_define_sup:
10007 	      get_uleb128 (u128, readp, readendp);
10008 	      if (readp + offset_len > readendp)
10009 		goto invalid_data;
10010 	      printf ("%*s#define ", 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_undef_sup:
10018 	      get_uleb128 (u128, readp, readendp);
10019 	      if (readp + offset_len > readendp)
10020 		goto invalid_data;
10021 	      printf ("%*s#undef ", level, "");
10022 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10023 					readp, readendp, offset_len,
10024 					str_offsets_base);
10025 	      printf (", line %u (sup)\n", u128);
10026 	      break;
10027 
10028 	    case DW_MACRO_import_sup:
10029 	      if (readp + offset_len > readendp)
10030 		goto invalid_data;
10031 	      if (offset_len == 8)
10032 		off = read_8ubyte_unaligned_inc (dbg, readp);
10033 	      else
10034 		off = read_4ubyte_unaligned_inc (dbg, readp);
10035 	      // XXX Needs support for reading from supplementary object file.
10036 	      printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10037 		      level, "", off);
10038 	      break;
10039 
10040 	    case DW_MACRO_define_strx:
10041 	      get_uleb128 (u128, readp, readendp);
10042 	      if (readp + offset_len > readendp)
10043 		goto invalid_data;
10044 	      printf ("%*s#define ", 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 	    case DW_MACRO_undef_strx:
10052 	      get_uleb128 (u128, readp, readendp);
10053 	      if (readp + offset_len > readendp)
10054 		goto invalid_data;
10055 	      printf ("%*s#undef ", level, "");
10056 	      readp =  print_form_data (dbg, DW_FORM_strx,
10057 					readp, readendp, offset_len,
10058 					str_offsets_base);
10059 	      printf (", line %u (strx)\n", u128);
10060 	      break;
10061 
10062 	    default:
10063 	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10064 	      if (opcode < DW_MACRO_lo_user
10065 		  || opcode > DW_MACRO_lo_user
10066 		  || vendor[opcode - DW_MACRO_lo_user] == NULL)
10067 		goto invalid_data;
10068 
10069 	      const unsigned char *op_desc;
10070 	      op_desc = vendor[opcode - DW_MACRO_lo_user];
10071 
10072 	      // Just skip the arguments, we cannot really interpret them,
10073 	      // but print as much as we can.
10074 	      unsigned int args = *op_desc++;
10075 	      while (args > 0 && readp < readendp)
10076 		{
10077 		  unsigned int form = *op_desc++;
10078 		  readp = print_form_data (dbg, form, readp, readendp,
10079 					   offset_len, str_offsets_base);
10080 		  args--;
10081 		  if (args > 0)
10082 		    printf (", ");
10083 		}
10084 	      putchar_unlocked ('\n');
10085 	    }
10086 
10087 	  if (readp + 1 > readendp)
10088 	    goto invalid_data;
10089 	  opcode = *readp++;
10090 	  if (opcode == 0)
10091 	    putchar_unlocked ('\n');
10092 	}
10093     }
10094 }
10095 
10096 
10097 /* Callback for printing global names.  */
10098 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10099 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10100 		void *arg)
10101 {
10102   int *np = (int *) arg;
10103 
10104   printf (gettext (" [%5d] DIE offset: %6" PRId64
10105 		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10106 	  (*np)++, global->die_offset, global->cu_offset, global->name);
10107 
10108   return 0;
10109 }
10110 
10111 
10112 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
10113 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10114 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10115 			      Ebl *ebl,
10116 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
10117 			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10118 {
10119   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10120 	  elf_ndxscn (scn), section_name (ebl, shdr),
10121 	  (uint64_t) shdr->sh_offset);
10122 
10123   int n = 0;
10124   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10125 }
10126 
10127 /* Print the content of the DWARF string section '.debug_str'.  */
10128 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10129 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10130 			 Ebl *ebl,
10131 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10132 			 Elf_Scn *scn, GElf_Shdr *shdr,
10133 			 Dwarf *dbg __attribute__ ((unused)))
10134 {
10135   Elf_Data *data = elf_rawdata (scn, NULL);
10136   const size_t sh_size = data ? data->d_size : 0;
10137 
10138   /* Compute floor(log16(shdr->sh_size)).  */
10139   GElf_Addr tmp = sh_size;
10140   int digits = 1;
10141   while (tmp >= 16)
10142     {
10143       ++digits;
10144       tmp >>= 4;
10145     }
10146   digits = MAX (4, digits);
10147 
10148   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10149 		   " %*s  String\n"),
10150 	  elf_ndxscn (scn),
10151 	  section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10152 	  /* TRANS: the debugstr| prefix makes the string unique.  */
10153 	  digits + 2, sgettext ("debugstr|Offset"));
10154 
10155   Dwarf_Off offset = 0;
10156   while (offset < sh_size)
10157     {
10158       size_t len;
10159       const char *str = (const char *) data->d_buf + offset;
10160       const char *endp = memchr (str, '\0', sh_size - offset);
10161       if (unlikely (endp == NULL))
10162 	{
10163 	  printf (gettext (" *** error, missing string terminator\n"));
10164 	  break;
10165 	}
10166 
10167       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
10168       len = endp - str;
10169       offset += len + 1;
10170     }
10171 }
10172 
10173 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10174 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10175 				 Ebl *ebl,
10176 				 GElf_Ehdr *ehdr __attribute__ ((unused)),
10177 				 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10178 {
10179   printf (gettext ("\
10180 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10181 	  elf_ndxscn (scn), section_name (ebl, shdr),
10182 	  (uint64_t) shdr->sh_offset);
10183 
10184   if (shdr->sh_size == 0)
10185     return;
10186 
10187   /* We like to get the section from libdw to make sure they are relocated.  */
10188   Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10189 		    ?: elf_rawdata (scn, NULL));
10190   if (unlikely (data == NULL))
10191     {
10192       error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10193 	     elf_errmsg (-1));
10194       return;
10195     }
10196 
10197   size_t idx = 0;
10198   sort_listptr (&known_stroffbases, "str_offsets");
10199 
10200   const unsigned char *start = (const unsigned char *) data->d_buf;
10201   const unsigned char *readp = start;
10202   const unsigned char *readendp = ((const unsigned char *) data->d_buf
10203 				   + data->d_size);
10204 
10205   while (readp < readendp)
10206     {
10207       /* Most string offset tables will have a header.  For split
10208 	 dwarf unit GNU DebugFission didn't add one.  But they were
10209 	 also only defined for split units (main or skeleton units
10210 	 didn't have indirect strings).  So if we don't have a
10211 	 DW_AT_str_offsets_base at all and this is offset zero, then
10212 	 just start printing offsets immediately, if this is a .dwo
10213 	 section.  */
10214       Dwarf_Off off = (Dwarf_Off) (readp
10215 				   - (const unsigned char *) data->d_buf);
10216 
10217       printf ("Table at offset %" PRIx64 " ", off);
10218 
10219       struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10220       const unsigned char *next_unitp = readendp;
10221       uint8_t offset_size;
10222       bool has_header;
10223       if (listptr == NULL)
10224 	{
10225 	  /* This can happen for .dwo files.  There is only an header
10226 	     in the case this is a version 5 split DWARF file.  */
10227 	  Dwarf_CU *cu;
10228 	  uint8_t unit_type;
10229 	  if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10230 			       NULL, NULL) != 0)
10231 	    {
10232 	      error (0, 0, "Warning: Cannot find any DWARF unit.");
10233 	      /* Just guess some values.  */
10234 	      has_header = false;
10235 	      offset_size = 4;
10236 	    }
10237 	  else if (off == 0
10238 		   && (unit_type == DW_UT_split_type
10239 		       || unit_type == DW_UT_split_compile))
10240 	    {
10241 	      has_header = cu->version > 4;
10242 	      offset_size = cu->offset_size;
10243 	    }
10244 	  else
10245 	    {
10246 	      error (0, 0,
10247 		     "Warning: No CU references .debug_str_offsets after %"
10248 		     PRIx64, off);
10249 	      has_header = cu->version > 4;
10250 	      offset_size = cu->offset_size;
10251 	    }
10252 	  printf ("\n");
10253 	}
10254       else
10255 	{
10256 	  /* This must be DWARF5, since GNU DebugFission didn't define
10257 	     DW_AT_str_offsets_base.  */
10258 	  has_header = true;
10259 
10260 	  Dwarf_Die cudie;
10261 	  if (dwarf_cu_die (listptr->cu, &cudie,
10262 			    NULL, NULL, NULL, NULL,
10263 			    NULL, NULL) == NULL)
10264 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10265 	  else
10266 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10267 	}
10268 
10269       if (has_header)
10270 	{
10271 	  uint64_t unit_length;
10272 	  uint16_t version;
10273 	  uint16_t padding;
10274 
10275 	  unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10276 	  if (unlikely (unit_length == 0xffffffff))
10277 	    {
10278 	      if (unlikely (readp > readendp - 8))
10279 		{
10280 		invalid_data:
10281 		  error (0, 0, "Invalid data");
10282 		  return;
10283 		}
10284 	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10285 	      offset_size = 8;
10286 	    }
10287 	  else
10288 	    offset_size = 4;
10289 
10290 	  printf ("\n");
10291 	  printf (gettext (" Length:        %8" PRIu64 "\n"),
10292 		  unit_length);
10293 	  printf (gettext (" Offset size:   %8" PRIu8 "\n"),
10294 		  offset_size);
10295 
10296 	  /* We need at least 2-bytes (version) + 2-bytes (padding) =
10297 	     4 bytes to complete the header.  And this unit cannot go
10298 	     beyond the section data.  */
10299 	  if (readp > readendp - 4
10300 	      || unit_length < 4
10301 	      || unit_length > (uint64_t) (readendp - readp))
10302 	    goto invalid_data;
10303 
10304 	  next_unitp = readp + unit_length;
10305 
10306 	  version = read_2ubyte_unaligned_inc (dbg, readp);
10307 	  printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10308 
10309 	  if (version != 5)
10310 	    {
10311 	      error (0, 0, gettext ("Unknown version"));
10312 	      goto next_unit;
10313 	    }
10314 
10315 	  padding = read_2ubyte_unaligned_inc (dbg, readp);
10316 	  printf (gettext (" Padding:       %8" PRIx16 "\n"), padding);
10317 
10318 	  if (listptr != NULL
10319 	      && listptr->offset != (Dwarf_Off) (readp - start))
10320 	    {
10321 	      error (0, 0, "String offsets index doesn't start after header");
10322 	      goto next_unit;
10323 	    }
10324 
10325 	  printf ("\n");
10326 	}
10327 
10328       int digits = 1;
10329       size_t offsets = (next_unitp - readp) / offset_size;
10330       while (offsets >= 10)
10331 	{
10332 	  ++digits;
10333 	  offsets /= 10;
10334 	}
10335 
10336       unsigned int uidx = 0;
10337       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
10338       printf (" Offsets start at 0x%zx:\n", index_offset);
10339       while (readp <= next_unitp - offset_size)
10340 	{
10341 	  Dwarf_Word offset;
10342 	  if (offset_size == 4)
10343 	    offset = read_4ubyte_unaligned_inc (dbg, readp);
10344 	  else
10345 	    offset = read_8ubyte_unaligned_inc (dbg, readp);
10346 	  const char *str = dwarf_getstring (dbg, offset, NULL);
10347 	  printf (" [%*u] [%*" PRIx64 "]  \"%s\"\n",
10348 		  digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10349 	}
10350       printf ("\n");
10351 
10352       if (readp != next_unitp)
10353 	error (0, 0, "extra %zd bytes at end of unit",
10354 	       (size_t) (next_unitp - readp));
10355 
10356     next_unit:
10357       readp = next_unitp;
10358     }
10359 }
10360 
10361 
10362 /* Print the content of the call frame search table section
10363    '.eh_frame_hdr'.  */
10364 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10365 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10366 			       Ebl *ebl __attribute__ ((unused)),
10367 			       GElf_Ehdr *ehdr __attribute__ ((unused)),
10368 			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10369 {
10370   printf (gettext ("\
10371 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10372 	  elf_ndxscn (scn));
10373 
10374   Elf_Data *data = elf_rawdata (scn, NULL);
10375 
10376   if (unlikely (data == NULL))
10377     {
10378       error (0, 0, gettext ("cannot get %s content: %s"),
10379 	     ".eh_frame_hdr", elf_errmsg (-1));
10380       return;
10381     }
10382 
10383   const unsigned char *readp = data->d_buf;
10384   const unsigned char *const dataend = ((unsigned char *) data->d_buf
10385 					+ data->d_size);
10386 
10387   if (unlikely (readp + 4 > dataend))
10388     {
10389     invalid_data:
10390       error (0, 0, gettext ("invalid data"));
10391       return;
10392     }
10393 
10394   unsigned int version = *readp++;
10395   unsigned int eh_frame_ptr_enc = *readp++;
10396   unsigned int fde_count_enc = *readp++;
10397   unsigned int table_enc = *readp++;
10398 
10399   printf (" version:          %u\n"
10400 	  " eh_frame_ptr_enc: %#x ",
10401 	  version, eh_frame_ptr_enc);
10402   print_encoding_base ("", eh_frame_ptr_enc);
10403   printf (" fde_count_enc:    %#x ", fde_count_enc);
10404   print_encoding_base ("", fde_count_enc);
10405   printf (" table_enc:        %#x ", table_enc);
10406   print_encoding_base ("", table_enc);
10407 
10408   uint64_t eh_frame_ptr = 0;
10409   if (eh_frame_ptr_enc != DW_EH_PE_omit)
10410     {
10411       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10412 			    dbg);
10413       if (unlikely (readp == NULL))
10414 	goto invalid_data;
10415 
10416       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
10417       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10418 	printf (" (offset: %#" PRIx64 ")",
10419 		/* +4 because of the 4 byte header of the section.  */
10420 		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10421 
10422       putchar_unlocked ('\n');
10423     }
10424 
10425   uint64_t fde_count = 0;
10426   if (fde_count_enc != DW_EH_PE_omit)
10427     {
10428       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10429       if (unlikely (readp == NULL))
10430 	goto invalid_data;
10431 
10432       printf (" fde_count:        %" PRIu64 "\n", fde_count);
10433     }
10434 
10435   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10436     return;
10437 
10438   puts (" Table:");
10439 
10440   /* Optimize for the most common case.  */
10441   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10442     while (fde_count > 0 && readp + 8 <= dataend)
10443       {
10444 	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10445 	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10446 				   + (int64_t) initial_location);
10447 	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10448 	// XXX Possibly print symbol name or section offset for initial_offset
10449 	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10450 		" fde=[%6" PRIx64 "]\n",
10451 		initial_location, initial_offset,
10452 		address, address - (eh_frame_ptr + 4));
10453       }
10454   else
10455     while (0 && readp < dataend)
10456       {
10457 
10458       }
10459 }
10460 
10461 
10462 /* Print the content of the exception handling table section
10463    '.eh_frame_hdr'.  */
10464 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10465 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10466 			     Ebl *ebl __attribute__ ((unused)),
10467 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
10468 			     Elf_Scn *scn,
10469 			     GElf_Shdr *shdr __attribute__ ((unused)),
10470 			     Dwarf *dbg __attribute__ ((unused)))
10471 {
10472   printf (gettext ("\
10473 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10474 	  elf_ndxscn (scn));
10475 
10476   Elf_Data *data = elf_rawdata (scn, NULL);
10477 
10478   if (unlikely (data == NULL))
10479     {
10480       error (0, 0, gettext ("cannot get %s content: %s"),
10481 	     ".gcc_except_table", elf_errmsg (-1));
10482       return;
10483     }
10484 
10485   const unsigned char *readp = data->d_buf;
10486   const unsigned char *const dataend = readp + data->d_size;
10487 
10488   if (unlikely (readp + 1 > dataend))
10489     {
10490     invalid_data:
10491       error (0, 0, gettext ("invalid data"));
10492       return;
10493     }
10494   unsigned int lpstart_encoding = *readp++;
10495   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
10496   print_encoding_base ("", lpstart_encoding);
10497   if (lpstart_encoding != DW_EH_PE_omit)
10498     {
10499       uint64_t lpstart;
10500       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10501       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
10502     }
10503 
10504   if (unlikely (readp + 1 > dataend))
10505     goto invalid_data;
10506   unsigned int ttype_encoding = *readp++;
10507   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
10508   print_encoding_base ("", ttype_encoding);
10509   const unsigned char *ttype_base = NULL;
10510   if (ttype_encoding != DW_EH_PE_omit)
10511     {
10512       unsigned int ttype_base_offset;
10513       get_uleb128 (ttype_base_offset, readp, dataend);
10514       printf (" TType base offset:   %#x\n", ttype_base_offset);
10515       if ((size_t) (dataend - readp) > ttype_base_offset)
10516         ttype_base = readp + ttype_base_offset;
10517     }
10518 
10519   if (unlikely (readp + 1 > dataend))
10520     goto invalid_data;
10521   unsigned int call_site_encoding = *readp++;
10522   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
10523   print_encoding_base ("", call_site_encoding);
10524   unsigned int call_site_table_len;
10525   get_uleb128 (call_site_table_len, readp, dataend);
10526 
10527   const unsigned char *const action_table = readp + call_site_table_len;
10528   if (unlikely (action_table > dataend))
10529     goto invalid_data;
10530   unsigned int u = 0;
10531   unsigned int max_action = 0;
10532   while (readp < action_table)
10533     {
10534       if (u == 0)
10535 	puts (gettext ("\n Call site table:"));
10536 
10537       uint64_t call_site_start;
10538       readp = read_encoded (call_site_encoding, readp, dataend,
10539 			    &call_site_start, dbg);
10540       uint64_t call_site_length;
10541       readp = read_encoded (call_site_encoding, readp, dataend,
10542 			    &call_site_length, dbg);
10543       uint64_t landing_pad;
10544       readp = read_encoded (call_site_encoding, readp, dataend,
10545 			    &landing_pad, dbg);
10546       unsigned int action;
10547       get_uleb128 (action, readp, dataend);
10548       max_action = MAX (action, max_action);
10549       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
10550 		       "        Call site length:  %" PRIu64 "\n"
10551 		       "        Landing pad:       %#" PRIx64 "\n"
10552 		       "        Action:            %u\n"),
10553 	      u++, call_site_start, call_site_length, landing_pad, action);
10554     }
10555   if (readp != action_table)
10556     goto invalid_data;
10557 
10558   unsigned int max_ar_filter = 0;
10559   if (max_action > 0)
10560     {
10561       puts ("\n Action table:");
10562 
10563       size_t maxdata = (size_t) (dataend - action_table);
10564       if (max_action > maxdata || maxdata - max_action < 1)
10565 	{
10566 	invalid_action_table:
10567 	  fputs (gettext ("   <INVALID DATA>\n"), stdout);
10568 	  return;
10569 	}
10570 
10571       const unsigned char *const action_table_end
10572 	= action_table + max_action + 1;
10573 
10574       u = 0;
10575       do
10576 	{
10577 	  int ar_filter;
10578 	  get_sleb128 (ar_filter, readp, action_table_end);
10579 	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10580 	    max_ar_filter = ar_filter;
10581 	  int ar_disp;
10582 	  if (readp >= action_table_end)
10583 	    goto invalid_action_table;
10584 	  get_sleb128 (ar_disp, readp, action_table_end);
10585 
10586 	  printf (" [%4u] ar_filter:  % d\n"
10587 		  "        ar_disp:    % -5d",
10588 		  u, ar_filter, ar_disp);
10589 	  if (abs (ar_disp) & 1)
10590 	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10591 	  else if (ar_disp != 0)
10592 	    puts (" -> ???");
10593 	  else
10594 	    putchar_unlocked ('\n');
10595 	  ++u;
10596 	}
10597       while (readp < action_table_end);
10598     }
10599 
10600   if (max_ar_filter > 0 && ttype_base != NULL)
10601     {
10602       unsigned char dsize;
10603       puts ("\n TType table:");
10604 
10605       // XXX Not *4, size of encoding;
10606       switch (ttype_encoding & 7)
10607 	{
10608 	case DW_EH_PE_udata2:
10609 	case DW_EH_PE_sdata2:
10610 	  dsize = 2;
10611 	  break;
10612 	case DW_EH_PE_udata4:
10613 	case DW_EH_PE_sdata4:
10614 	  dsize = 4;
10615 	  break;
10616 	case DW_EH_PE_udata8:
10617 	case DW_EH_PE_sdata8:
10618 	  dsize = 8;
10619 	  break;
10620 	default:
10621 	  dsize = 0;
10622 	  error (1, 0, gettext ("invalid TType encoding"));
10623 	}
10624 
10625       if (max_ar_filter
10626 	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10627 	goto invalid_data;
10628 
10629       readp = ttype_base - max_ar_filter * dsize;
10630       do
10631 	{
10632 	  uint64_t ttype;
10633 	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10634 				dbg);
10635 	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10636 	}
10637       while (readp < ttype_base);
10638     }
10639 }
10640 
10641 /* Print the content of the '.gdb_index' section.
10642    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10643 */
10644 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10645 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10646 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10647 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10648 {
10649   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10650 		   " contains %" PRId64 " bytes :\n"),
10651 	  elf_ndxscn (scn), section_name (ebl, shdr),
10652 	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10653 
10654   Elf_Data *data = elf_rawdata (scn, NULL);
10655 
10656   if (unlikely (data == NULL))
10657     {
10658       error (0, 0, gettext ("cannot get %s content: %s"),
10659 	     ".gdb_index", elf_errmsg (-1));
10660       return;
10661     }
10662 
10663   // .gdb_index is always in little endian.
10664   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10665   dbg = &dummy_dbg;
10666 
10667   const unsigned char *readp = data->d_buf;
10668   const unsigned char *const dataend = readp + data->d_size;
10669 
10670   if (unlikely (readp + 4 > dataend))
10671     {
10672     invalid_data:
10673       error (0, 0, gettext ("invalid data"));
10674       return;
10675     }
10676 
10677   int32_t vers = read_4ubyte_unaligned (dbg, readp);
10678   printf (gettext (" Version:         %" PRId32 "\n"), vers);
10679 
10680   // The only difference between version 4 and version 5 is the
10681   // hash used for generating the table.  Version 6 contains symbols
10682   // for inlined functions, older versions didn't.  Version 7 adds
10683   // symbol kinds.  Version 8 just indicates that it correctly includes
10684   // TUs for symbols.
10685   if (vers < 4 || vers > 8)
10686     {
10687       printf (gettext ("  unknown version, cannot parse section\n"));
10688       return;
10689     }
10690 
10691   readp += 4;
10692   if (unlikely (readp + 4 > dataend))
10693     goto invalid_data;
10694 
10695   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10696   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
10697 
10698   readp += 4;
10699   if (unlikely (readp + 4 > dataend))
10700     goto invalid_data;
10701 
10702   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10703   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
10704 
10705   readp += 4;
10706   if (unlikely (readp + 4 > dataend))
10707     goto invalid_data;
10708 
10709   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10710   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
10711 
10712   readp += 4;
10713   if (unlikely (readp + 4 > dataend))
10714     goto invalid_data;
10715 
10716   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10717   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
10718 
10719   readp += 4;
10720   if (unlikely (readp + 4 > dataend))
10721     goto invalid_data;
10722 
10723   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10724   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10725 
10726   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10727 		< const_off))
10728     goto invalid_data;
10729 
10730   readp = data->d_buf + cu_off;
10731 
10732   const unsigned char *nextp = data->d_buf + tu_off;
10733   if (tu_off >= data->d_size)
10734     goto invalid_data;
10735 
10736   size_t cu_nr = (nextp - readp) / 16;
10737 
10738   printf (gettext ("\n CU list at offset %#" PRIx32
10739 		   " contains %zu entries:\n"),
10740 	  cu_off, cu_nr);
10741 
10742   size_t n = 0;
10743   while (dataend - readp >= 16 && n < cu_nr)
10744     {
10745       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10746       readp += 8;
10747 
10748       uint64_t len = read_8ubyte_unaligned (dbg, readp);
10749       readp += 8;
10750 
10751       printf (" [%4zu] start: %0#8" PRIx64
10752 	      ", length: %5" PRIu64 "\n", n, off, len);
10753       n++;
10754     }
10755 
10756   readp = data->d_buf + tu_off;
10757   nextp = data->d_buf + addr_off;
10758   if (addr_off >= data->d_size)
10759     goto invalid_data;
10760 
10761   size_t tu_nr = (nextp - readp) / 24;
10762 
10763   printf (gettext ("\n TU list at offset %#" PRIx32
10764 		   " contains %zu entries:\n"),
10765 	  tu_off, tu_nr);
10766 
10767   n = 0;
10768   while (dataend - readp >= 24 && n < tu_nr)
10769     {
10770       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10771       readp += 8;
10772 
10773       uint64_t type = read_8ubyte_unaligned (dbg, readp);
10774       readp += 8;
10775 
10776       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10777       readp += 8;
10778 
10779       printf (" [%4zu] CU offset: %5" PRId64
10780 	      ", type offset: %5" PRId64
10781 	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10782       n++;
10783     }
10784 
10785   readp = data->d_buf + addr_off;
10786   nextp = data->d_buf + sym_off;
10787   if (sym_off >= data->d_size)
10788     goto invalid_data;
10789 
10790   size_t addr_nr = (nextp - readp) / 20;
10791 
10792   printf (gettext ("\n Address list at offset %#" PRIx32
10793 		   " contains %zu entries:\n"),
10794 	  addr_off, addr_nr);
10795 
10796   n = 0;
10797   while (dataend - readp >= 20 && n < addr_nr)
10798     {
10799       uint64_t low = read_8ubyte_unaligned (dbg, readp);
10800       readp += 8;
10801 
10802       uint64_t high = read_8ubyte_unaligned (dbg, readp);
10803       readp += 8;
10804 
10805       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10806       readp += 4;
10807 
10808       printf (" [%4zu] ", n);
10809       print_dwarf_addr (dwflmod, 8, low, low);
10810       printf ("..");
10811       print_dwarf_addr (dwflmod, 8, high - 1, high);
10812       printf (", CU index: %5" PRId32 "\n", idx);
10813       n++;
10814     }
10815 
10816   const unsigned char *const_start = data->d_buf + const_off;
10817   if (const_off >= data->d_size)
10818     goto invalid_data;
10819 
10820   readp = data->d_buf + sym_off;
10821   nextp = const_start;
10822   size_t sym_nr = (nextp - readp) / 8;
10823 
10824   printf (gettext ("\n Symbol table at offset %#" PRIx32
10825 		   " contains %zu slots:\n"),
10826 	  addr_off, sym_nr);
10827 
10828   n = 0;
10829   while (dataend - readp >= 8 && n < sym_nr)
10830     {
10831       uint32_t name = read_4ubyte_unaligned (dbg, readp);
10832       readp += 4;
10833 
10834       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10835       readp += 4;
10836 
10837       if (name != 0 || vector != 0)
10838 	{
10839 	  const unsigned char *sym = const_start + name;
10840 	  if (unlikely ((size_t) (dataend - const_start) < name
10841 			|| memchr (sym, '\0', dataend - sym) == NULL))
10842 	    goto invalid_data;
10843 
10844 	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10845 
10846 	  const unsigned char *readcus = const_start + vector;
10847 	  if (unlikely ((size_t) (dataend - const_start) < vector))
10848 	    goto invalid_data;
10849 	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10850 	  while (cus--)
10851 	    {
10852 	      uint32_t cu_kind, cu, kind;
10853 	      bool is_static;
10854 	      readcus += 4;
10855 	      if (unlikely (readcus + 4 > dataend))
10856 		goto invalid_data;
10857 	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
10858 	      cu = cu_kind & ((1 << 24) - 1);
10859 	      kind = (cu_kind >> 28) & 7;
10860 	      is_static = cu_kind & (1U << 31);
10861 	      if (cu > cu_nr - 1)
10862 		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10863 	      else
10864 		printf ("%" PRId32, cu);
10865 	      if (kind != 0)
10866 		{
10867 		  printf (" (");
10868 		  switch (kind)
10869 		    {
10870 		    case 1:
10871 		      printf ("type");
10872 		      break;
10873 		    case 2:
10874 		      printf ("var");
10875 		      break;
10876 		    case 3:
10877 		      printf ("func");
10878 		      break;
10879 		    case 4:
10880 		      printf ("other");
10881 		      break;
10882 		    default:
10883 		      printf ("unknown-0x%" PRIx32, kind);
10884 		      break;
10885 		    }
10886 		  printf (":%c)", (is_static ? 'S' : 'G'));
10887 		}
10888 	      if (cus > 0)
10889 		printf (", ");
10890 	    }
10891 	  printf ("\n");
10892 	}
10893       n++;
10894     }
10895 }
10896 
10897 /* Returns true and sets split DWARF CU id if there is a split compile
10898    unit in the given Dwarf, and no non-split units are found (before it).  */
10899 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)10900 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
10901 {
10902   Dwarf_CU *cu = NULL;
10903   while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
10904     {
10905       uint8_t unit_type;
10906       if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
10907 			 id, NULL, NULL) != 0)
10908 	return false;
10909 
10910       if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
10911 	return false;
10912 
10913       /* We really only care about the split compile unit, the types
10914 	 should be fine and self sufficient.  Also they don't have an
10915 	 id that we can match with a skeleton unit.  */
10916       if (unit_type == DW_UT_split_compile)
10917 	{
10918 	  *split_cu = cu;
10919 	  return true;
10920 	}
10921     }
10922 
10923   return false;
10924 }
10925 
10926 /* Check that there is one and only one Dwfl_Module, return in arg.  */
10927 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)10928 getone_dwflmod (Dwfl_Module *dwflmod,
10929 	       void **userdata __attribute__ ((unused)),
10930 	       const char *name __attribute__ ((unused)),
10931 	       Dwarf_Addr base __attribute__ ((unused)),
10932 	       void *arg)
10933 {
10934   Dwfl_Module **m = (Dwfl_Module **) arg;
10935   if (*m != NULL)
10936     return DWARF_CB_ABORT;
10937   *m = dwflmod;
10938   return DWARF_CB_OK;
10939 }
10940 
10941 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)10942 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
10943 {
10944   /* Used for skeleton file, if necessary for split DWARF.  */
10945   Dwfl *skel_dwfl = NULL;
10946   Dwfl_Module *skel_mod = NULL;
10947   char *skel_name = NULL;
10948   Dwarf *split_dbg = NULL;
10949   Dwarf_CU *split_cu = NULL;
10950 
10951   /* Before we start the real work get a debug context descriptor.  */
10952   Dwarf_Addr dwbias;
10953   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
10954   Dwarf dummy_dbg =
10955     {
10956       .elf = ebl->elf,
10957       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
10958     };
10959   if (dbg == NULL)
10960     {
10961       if ((print_debug_sections & ~section_exception) != 0)
10962 	error (0, 0, gettext ("cannot get debug context descriptor: %s"),
10963 	       dwfl_errmsg (-1));
10964       dbg = &dummy_dbg;
10965     }
10966   else
10967     {
10968       /* If we are asked about a split dwarf (.dwo) file, use the user
10969 	 provided, or find the corresponding skeleton file. If we got
10970 	 a skeleton file, replace the given dwflmod and dbg, with one
10971 	 derived from the skeleton file to provide enough context.  */
10972       uint64_t split_id;
10973       if (is_split_dwarf (dbg, &split_id, &split_cu))
10974 	{
10975 	  if (dwarf_skeleton != NULL)
10976 	    skel_name = strdup (dwarf_skeleton);
10977 	  else
10978 	    {
10979 	      /* Replace file.dwo with file.o and see if that matches. */
10980 	      const char *fname;
10981 	      dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
10982 				&fname, NULL);
10983 	      if (fname != NULL)
10984 		{
10985 		  size_t flen = strlen (fname);
10986 		  if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
10987 		    {
10988 		      skel_name = strdup (fname);
10989 		      if (skel_name != NULL)
10990 			{
10991 			  skel_name[flen - 3] = 'o';
10992 			  skel_name[flen - 2] = '\0';
10993 			}
10994 		    }
10995 		}
10996 	    }
10997 
10998 	  if (skel_name != NULL)
10999 	    {
11000 	      int skel_fd = open (skel_name, O_RDONLY);
11001 	      if (skel_fd == -1)
11002 		fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11003 			 " '%s'\n", skel_name);
11004 	      else
11005 		skel_dwfl = create_dwfl (skel_fd, skel_name);
11006 
11007 	      if (skel_dwfl != NULL)
11008 		{
11009 		  if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11010 				       &skel_mod, 0) != 0)
11011 		    {
11012 		      fprintf (stderr, "Warning: Bad DWARF skeleton,"
11013 			       " multiple modules '%s'\n", skel_name);
11014 		      dwfl_end (skel_dwfl);
11015 		      skel_mod = NULL;
11016 		    }
11017 		}
11018 	      else if (skel_fd != -1)
11019 		fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11020 			 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11021 
11022 	      if (skel_mod != NULL)
11023 		{
11024 		  Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11025 		  if (skel_dbg != NULL)
11026 		    {
11027 		      /* First check the skeleton CU DIE, only fetch
11028 			 the split DIE if we know the id matches to
11029 			 not unnecessary search for any split DIEs we
11030 			 don't need. */
11031 		      Dwarf_CU *cu = NULL;
11032 		      while (dwarf_get_units (skel_dbg, cu, &cu,
11033 					      NULL, NULL, NULL, NULL) == 0)
11034 			{
11035 			  uint8_t unit_type;
11036 			  uint64_t skel_id;
11037 			  if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11038 					     &skel_id, NULL, NULL) == 0
11039 			      && unit_type == DW_UT_skeleton
11040 			      && split_id == skel_id)
11041 			    {
11042 			      Dwarf_Die subdie;
11043 			      if (dwarf_cu_info (cu, NULL, NULL, NULL,
11044 						 &subdie,
11045 						 NULL, NULL, NULL) == 0
11046 				  && dwarf_tag (&subdie) != DW_TAG_invalid)
11047 				{
11048 				  split_dbg = dwarf_cu_getdwarf (subdie.cu);
11049 				  if (split_dbg == NULL)
11050 				    fprintf (stderr,
11051 					     "Warning: Couldn't get split_dbg:"
11052 					     " %s\n", dwarf_errmsg (-1));
11053 				  break;
11054 				}
11055 			      else
11056 				{
11057 				  /* Everything matches up, but not
11058 				     according to libdw. Which means
11059 				     the user knew better.  So...
11060 				     Terrible hack... We can never
11061 				     destroy the underlying dwfl
11062 				     because it would free the wrong
11063 				     Dwarfs... So we leak memory...*/
11064 				  if (cu->split == NULL
11065 				      && dwarf_skeleton != NULL)
11066 				    {
11067 				      do_not_close_dwfl = true;
11068 				      __libdw_link_skel_split (cu, split_cu);
11069 				      split_dbg = dwarf_cu_getdwarf (split_cu);
11070 				      break;
11071 				    }
11072 				  else
11073 				    fprintf (stderr, "Warning: Couldn't get"
11074 					     " skeleton subdie: %s\n",
11075 					     dwarf_errmsg (-1));
11076 				}
11077 			    }
11078 			}
11079 		      if (split_dbg == NULL)
11080 			fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11081 		    }
11082 		  else
11083 		    fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11084 			     " %s\n", dwfl_errmsg (-1));
11085 		}
11086 	    }
11087 
11088 	  if (split_dbg != NULL)
11089 	    {
11090 	      dbg = split_dbg;
11091 	      dwflmod = skel_mod;
11092 	    }
11093 	  else if (skel_name == NULL)
11094 	    fprintf (stderr,
11095 		     "Warning: split DWARF file, but no skeleton found.\n");
11096 	}
11097       else if (dwarf_skeleton != NULL)
11098 	fprintf (stderr, "Warning: DWARF skeleton given,"
11099 		 " but not a split DWARF file\n");
11100     }
11101 
11102   /* Get the section header string table index.  */
11103   size_t shstrndx;
11104   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11105     error (EXIT_FAILURE, 0,
11106 	   gettext ("cannot get section header string table index"));
11107 
11108   /* If the .debug_info section is listed as implicitly required then
11109      we must make sure to handle it before handling any other debug
11110      section.  Various other sections depend on the CU DIEs being
11111      scanned (silently) first.  */
11112   bool implicit_info = (implicit_debug_sections & section_info) != 0;
11113   bool explicit_info = (print_debug_sections & section_info) != 0;
11114   if (implicit_info)
11115     {
11116       Elf_Scn *scn = NULL;
11117       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11118 	{
11119 	  GElf_Shdr shdr_mem;
11120 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11121 
11122 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11123 	    {
11124 	      const char *name = elf_strptr (ebl->elf, shstrndx,
11125 					     shdr->sh_name);
11126 	      if (name == NULL)
11127 		continue;
11128 
11129 	      if (strcmp (name, ".debug_info") == 0
11130 		  || strcmp (name, ".debug_info.dwo") == 0
11131 		  || strcmp (name, ".zdebug_info") == 0
11132 		  || strcmp (name, ".zdebug_info.dwo") == 0)
11133 		{
11134 		  print_debug_info_section (dwflmod, ebl, ehdr,
11135 					    scn, shdr, dbg);
11136 		  break;
11137 		}
11138 	    }
11139 	}
11140       print_debug_sections &= ~section_info;
11141       implicit_debug_sections &= ~section_info;
11142     }
11143 
11144   /* Look through all the sections for the debugging sections to print.  */
11145   Elf_Scn *scn = NULL;
11146   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11147     {
11148       GElf_Shdr shdr_mem;
11149       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11150 
11151       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11152 	{
11153 	  static const struct
11154 	  {
11155 	    const char *name;
11156 	    enum section_e bitmask;
11157 	    void (*fp) (Dwfl_Module *, Ebl *,
11158 			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11159 	  } debug_sections[] =
11160 	    {
11161 #define NEW_SECTION(name) \
11162 	      { ".debug_" #name, section_##name, print_debug_##name##_section }
11163 	      NEW_SECTION (abbrev),
11164 	      NEW_SECTION (addr),
11165 	      NEW_SECTION (aranges),
11166 	      NEW_SECTION (frame),
11167 	      NEW_SECTION (info),
11168 	      NEW_SECTION (types),
11169 	      NEW_SECTION (line),
11170 	      NEW_SECTION (loc),
11171 	      /* loclists is loc for DWARF5.  */
11172 	      { ".debug_loclists", section_loc,
11173 		print_debug_loclists_section },
11174 	      NEW_SECTION (pubnames),
11175 	      NEW_SECTION (str),
11176 	      /* A DWARF5 specialised debug string section.  */
11177 	      { ".debug_line_str", section_str,
11178 		print_debug_str_section },
11179 	      /* DWARF5 string offsets table.  */
11180 	      { ".debug_str_offsets", section_str,
11181 		print_debug_str_offsets_section },
11182 	      NEW_SECTION (macinfo),
11183 	      NEW_SECTION (macro),
11184 	      NEW_SECTION (ranges),
11185 	      /* rnglists is ranges for DWARF5.  */
11186 	      { ".debug_rnglists", section_ranges,
11187 		print_debug_rnglists_section },
11188 	      { ".eh_frame", section_frame | section_exception,
11189 		print_debug_frame_section },
11190 	      { ".eh_frame_hdr", section_frame | section_exception,
11191 		print_debug_frame_hdr_section },
11192 	      { ".gcc_except_table", section_frame | section_exception,
11193 		print_debug_exception_table },
11194 	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
11195 	    };
11196 	  const int ndebug_sections = (sizeof (debug_sections)
11197 				       / sizeof (debug_sections[0]));
11198 	  const char *name = elf_strptr (ebl->elf, shstrndx,
11199 					 shdr->sh_name);
11200 	  if (name == NULL)
11201 	    continue;
11202 
11203 	  int n;
11204 	  for (n = 0; n < ndebug_sections; ++n)
11205 	    {
11206 	      size_t dbglen = strlen (debug_sections[n].name);
11207 	      size_t scnlen = strlen (name);
11208 	      if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11209 		   && (dbglen == scnlen
11210 		       || (scnlen == dbglen + 4
11211 			   && strstr (name, ".dwo") == name + dbglen)))
11212 		  || (name[0] == '.' && name[1] == 'z'
11213 		      && debug_sections[n].name[1] == 'd'
11214 		      && strncmp (&name[2], &debug_sections[n].name[1],
11215 				  dbglen - 1) == 0
11216 		      && (scnlen == dbglen + 1
11217 			  || (scnlen == dbglen + 5
11218 			      && strstr (name, ".dwo") == name + dbglen + 1))))
11219 		{
11220 		  if ((print_debug_sections | implicit_debug_sections)
11221 		      & debug_sections[n].bitmask)
11222 		    debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11223 		  break;
11224 		}
11225 	    }
11226 	}
11227     }
11228 
11229   dwfl_end (skel_dwfl);
11230   free (skel_name);
11231 
11232   /* Turn implicit and/or explicit back on in case we go over another file.  */
11233   if (implicit_info)
11234     implicit_debug_sections |= section_info;
11235   if (explicit_info)
11236     print_debug_sections |= section_info;
11237 
11238   reset_listptr (&known_locsptr);
11239   reset_listptr (&known_loclistsptr);
11240   reset_listptr (&known_rangelistptr);
11241   reset_listptr (&known_rnglistptr);
11242   reset_listptr (&known_addrbases);
11243   reset_listptr (&known_stroffbases);
11244 }
11245 
11246 
11247 #define ITEM_INDENT		4
11248 #define WRAP_COLUMN		75
11249 
11250 /* Print "NAME: FORMAT", wrapping when output text would make the line
11251    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
11252    but this function is also used for registers which should be printed
11253    aligned.  Fortunately registers output uses fixed fields width (such
11254    as %11d) for the alignment.
11255 
11256    Line breaks should not depend on the particular values although that
11257    may happen in some cases of the core items.  */
11258 
11259 static unsigned int
11260 __attribute__ ((format (printf, 6, 7)))
print_core_item(unsigned int colno,char sep,unsigned int wrap,size_t name_width,const char * name,const char * format,...)11261 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11262 		 size_t name_width, const char *name, const char *format, ...)
11263 {
11264   size_t len = strlen (name);
11265   if (name_width < len)
11266     name_width = len;
11267 
11268   char *out;
11269   va_list ap;
11270   va_start (ap, format);
11271   int out_len = vasprintf (&out, format, ap);
11272   va_end (ap);
11273   if (out_len == -1)
11274     error (EXIT_FAILURE, 0, _("memory exhausted"));
11275 
11276   size_t n = name_width + sizeof ": " - 1 + out_len;
11277 
11278   if (colno == 0)
11279     {
11280       printf ("%*s", ITEM_INDENT, "");
11281       colno = ITEM_INDENT + n;
11282     }
11283   else if (colno + 2 + n < wrap)
11284     {
11285       printf ("%c ", sep);
11286       colno += 2 + n;
11287     }
11288   else
11289     {
11290       printf ("\n%*s", ITEM_INDENT, "");
11291       colno = ITEM_INDENT + n;
11292     }
11293 
11294   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11295 
11296   free (out);
11297 
11298   return colno;
11299 }
11300 
11301 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11302 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11303 	 void *value, const void *data, size_t size)
11304 {
11305   Elf_Data valuedata =
11306     {
11307       .d_type = type,
11308       .d_buf = value,
11309       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11310       .d_version = EV_CURRENT,
11311     };
11312   Elf_Data indata =
11313     {
11314       .d_type = type,
11315       .d_buf = (void *) data,
11316       .d_size = valuedata.d_size,
11317       .d_version = EV_CURRENT,
11318     };
11319 
11320   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11321 		 ? elf32_xlatetom : elf64_xlatetom)
11322     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11323   if (d == NULL)
11324     error (EXIT_FAILURE, 0,
11325 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11326 
11327   return data + indata.d_size;
11328 }
11329 
11330 typedef uint8_t GElf_Byte;
11331 
11332 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11333 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11334 		  unsigned int colno, size_t *repeated_size)
11335 {
11336   uint_fast16_t count = item->count ?: 1;
11337   /* Ebl_Core_Item count is always a small number.
11338      Make sure the backend didn't put in some large bogus value.  */
11339   assert (count < 128);
11340 
11341 #define TYPES								      \
11342   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
11343   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
11344   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
11345   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
11346   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
11347   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11348 
11349 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11350   typedef union { TYPES; } value_t;
11351   void *data = alloca (count * sizeof (value_t));
11352 #undef DO_TYPE
11353 
11354 #define DO_TYPE(NAME, Name, hex, dec) \
11355     GElf_##Name *value_##Name __attribute__((unused)) = data
11356   TYPES;
11357 #undef DO_TYPE
11358 
11359   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11360   size_t convsize = size;
11361   if (repeated_size != NULL)
11362     {
11363       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11364 	{
11365 	  data = alloca (*repeated_size);
11366 	  count *= *repeated_size / size;
11367 	  convsize = count * size;
11368 	  *repeated_size -= convsize;
11369 	}
11370       else if (item->count != 0 || item->format != '\n')
11371 	*repeated_size -= size;
11372     }
11373 
11374   convert (core, item->type, count, data, desc + item->offset, convsize);
11375 
11376   Elf_Type type = item->type;
11377   if (type == ELF_T_ADDR)
11378     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11379 
11380   switch (item->format)
11381     {
11382     case 'd':
11383       assert (count == 1);
11384       switch (type)
11385 	{
11386 #define DO_TYPE(NAME, Name, hex, dec)					      \
11387 	  case ELF_T_##NAME:						      \
11388 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11389 				     0, item->name, dec, value_##Name[0]); \
11390 	    break
11391 	  TYPES;
11392 #undef DO_TYPE
11393 	default:
11394 	  abort ();
11395 	}
11396       break;
11397 
11398     case 'x':
11399       assert (count == 1);
11400       switch (type)
11401 	{
11402 #define DO_TYPE(NAME, Name, hex, dec)					      \
11403 	  case ELF_T_##NAME:						      \
11404 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11405 				     0, item->name, hex, value_##Name[0]);      \
11406 	    break
11407 	  TYPES;
11408 #undef DO_TYPE
11409 	default:
11410 	  abort ();
11411 	}
11412       break;
11413 
11414     case 'b':
11415     case 'B':
11416       assert (size % sizeof (unsigned int) == 0);
11417       unsigned int nbits = count * size * 8;
11418       unsigned int pop = 0;
11419       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11420 	pop += __builtin_popcount (*i);
11421       bool negate = pop > nbits / 2;
11422       const unsigned int bias = item->format == 'b';
11423 
11424       {
11425 	char printed[(negate ? nbits - pop : pop) * 16 + 1];
11426 	char *p = printed;
11427 	*p = '\0';
11428 
11429 	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11430 	  {
11431 	    assert (size == sizeof (unsigned int) * 2);
11432 	    for (unsigned int *i = data;
11433 		 (void *) i < data + count * size; i += 2)
11434 	      {
11435 		unsigned int w = i[1];
11436 		i[1] = i[0];
11437 		i[0] = w;
11438 	      }
11439 	  }
11440 
11441 	unsigned int lastbit = 0;
11442 	unsigned int run = 0;
11443 	for (const unsigned int *i = data;
11444 	     (void *) i < data + count * size; ++i)
11445 	  {
11446 	    unsigned int bit = ((void *) i - data) * 8;
11447 	    unsigned int w = negate ? ~*i : *i;
11448 	    while (w != 0)
11449 	      {
11450 		/* Note that a right shift equal to (or greater than)
11451 		   the number of bits of w is undefined behaviour.  In
11452 		   particular when the least significant bit is bit 32
11453 		   (w = 0x8000000) then w >>= n is undefined.  So
11454 		   explicitly handle that case separately.  */
11455 		unsigned int n = ffs (w);
11456 		if (n < sizeof (w) * 8)
11457 		  w >>= n;
11458 		else
11459 		  w = 0;
11460 		bit += n;
11461 
11462 		if (lastbit != 0 && lastbit + 1 == bit)
11463 		  ++run;
11464 		else
11465 		  {
11466 		    if (lastbit == 0)
11467 		      p += sprintf (p, "%u", bit - bias);
11468 		    else if (run == 0)
11469 		      p += sprintf (p, ",%u", bit - bias);
11470 		    else
11471 		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11472 		    run = 0;
11473 		  }
11474 
11475 		lastbit = bit;
11476 	      }
11477 	  }
11478 	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11479 	  p += sprintf (p, "-%u", lastbit - bias);
11480 
11481 	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11482 				 negate ? "~<%s>" : "<%s>", printed);
11483       }
11484       break;
11485 
11486     case 'T':
11487     case (char) ('T'|0x80):
11488       assert (count == 2);
11489       Dwarf_Word sec;
11490       Dwarf_Word usec;
11491       switch (type)
11492 	{
11493 #define DO_TYPE(NAME, Name, hex, dec)					      \
11494 	  case ELF_T_##NAME:						      \
11495 	    sec = value_##Name[0];					      \
11496 	    usec = value_##Name[1];					      \
11497 	    break
11498 	  TYPES;
11499 #undef DO_TYPE
11500 	default:
11501 	  abort ();
11502 	}
11503       if (unlikely (item->format == (char) ('T'|0x80)))
11504 	{
11505 	  /* This is a hack for an ill-considered 64-bit ABI where
11506 	     tv_usec is actually a 32-bit field with 32 bits of padding
11507 	     rounding out struct timeval.  We've already converted it as
11508 	     a 64-bit field.  For little-endian, this just means the
11509 	     high half is the padding; it's presumably zero, but should
11510 	     be ignored anyway.  For big-endian, it means the 32-bit
11511 	     field went into the high half of USEC.  */
11512 	  GElf_Ehdr ehdr_mem;
11513 	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11514 	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11515 	    usec >>= 32;
11516 	  else
11517 	    usec &= UINT32_MAX;
11518 	}
11519       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11520 			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
11521       break;
11522 
11523     case 'c':
11524       assert (count == 1);
11525       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11526 			       "%c", value_Byte[0]);
11527       break;
11528 
11529     case 's':
11530       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11531 			       "%.*s", (int) count, value_Byte);
11532       break;
11533 
11534     case '\n':
11535       /* This is a list of strings separated by '\n'.  */
11536       assert (item->count == 0);
11537       assert (repeated_size != NULL);
11538       assert (item->name == NULL);
11539       if (unlikely (item->offset >= *repeated_size))
11540 	break;
11541 
11542       const char *s = desc + item->offset;
11543       size = *repeated_size - item->offset;
11544       *repeated_size = 0;
11545       while (size > 0)
11546 	{
11547 	  const char *eol = memchr (s, '\n', size);
11548 	  int len = size;
11549 	  if (eol != NULL)
11550 	    len = eol - s;
11551 	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11552 	  if (eol == NULL)
11553 	    break;
11554 	  size -= eol + 1 - s;
11555 	  s = eol + 1;
11556 	}
11557 
11558       colno = WRAP_COLUMN;
11559       break;
11560 
11561     case 'h':
11562       break;
11563 
11564     default:
11565       error (0, 0, "XXX not handling format '%c' for %s",
11566 	     item->format, item->name);
11567       break;
11568     }
11569 
11570 #undef TYPES
11571 
11572   return colno;
11573 }
11574 
11575 
11576 /* Sort items by group, and by layout offset within each group.  */
11577 static int
compare_core_items(const void * a,const void * b)11578 compare_core_items (const void *a, const void *b)
11579 {
11580   const Ebl_Core_Item *const *p1 = a;
11581   const Ebl_Core_Item *const *p2 = b;
11582   const Ebl_Core_Item *item1 = *p1;
11583   const Ebl_Core_Item *item2 = *p2;
11584 
11585   return ((item1->group == item2->group ? 0
11586 	   : strcmp (item1->group, item2->group))
11587 	  ?: (int) item1->offset - (int) item2->offset);
11588 }
11589 
11590 /* Sort item groups by layout offset of the first item in the group.  */
11591 static int
compare_core_item_groups(const void * a,const void * b)11592 compare_core_item_groups (const void *a, const void *b)
11593 {
11594   const Ebl_Core_Item *const *const *p1 = a;
11595   const Ebl_Core_Item *const *const *p2 = b;
11596   const Ebl_Core_Item *const *group1 = *p1;
11597   const Ebl_Core_Item *const *group2 = *p2;
11598   const Ebl_Core_Item *item1 = *group1;
11599   const Ebl_Core_Item *item2 = *group2;
11600 
11601   return (int) item1->offset - (int) item2->offset;
11602 }
11603 
11604 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11605 handle_core_items (Elf *core, const void *desc, size_t descsz,
11606 		   const Ebl_Core_Item *items, size_t nitems)
11607 {
11608   if (nitems == 0)
11609     return 0;
11610   unsigned int colno = 0;
11611 
11612   /* FORMAT '\n' makes sense to be present only as a single item as it
11613      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
11614      if present as a single item but they can be also processed with other
11615      items below.  */
11616   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11617 		      || items[0].format == 'B'))
11618     {
11619       assert (items[0].offset == 0);
11620       size_t size = descsz;
11621       colno = handle_core_item (core, items, desc, colno, &size);
11622       /* If SIZE is not zero here there is some remaining data.  But we do not
11623 	 know how to process it anyway.  */
11624       return colno;
11625     }
11626   for (size_t i = 0; i < nitems; ++i)
11627     assert (items[i].format != '\n');
11628 
11629   /* Sort to collect the groups together.  */
11630   const Ebl_Core_Item *sorted_items[nitems];
11631   for (size_t i = 0; i < nitems; ++i)
11632     sorted_items[i] = &items[i];
11633   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11634 
11635   /* Collect the unique groups and sort them.  */
11636   const Ebl_Core_Item **groups[nitems];
11637   groups[0] = &sorted_items[0];
11638   size_t ngroups = 1;
11639   for (size_t i = 1; i < nitems; ++i)
11640     if (sorted_items[i]->group != sorted_items[i - 1]->group
11641 	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11642       groups[ngroups++] = &sorted_items[i];
11643   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11644 
11645   /* Write out all the groups.  */
11646   const void *last = desc;
11647   do
11648     {
11649       for (size_t i = 0; i < ngroups; ++i)
11650 	{
11651 	  for (const Ebl_Core_Item **item = groups[i];
11652 	       (item < &sorted_items[nitems]
11653 		&& ((*item)->group == groups[i][0]->group
11654 		    || !strcmp ((*item)->group, groups[i][0]->group)));
11655 	       ++item)
11656 	    colno = handle_core_item (core, *item, desc, colno, NULL);
11657 
11658 	  /* Force a line break at the end of the group.  */
11659 	  colno = WRAP_COLUMN;
11660 	}
11661 
11662       if (descsz == 0)
11663 	break;
11664 
11665       /* This set of items consumed a certain amount of the note's data.
11666 	 If there is more data there, we have another unit of the same size.
11667 	 Loop to print that out too.  */
11668       const Ebl_Core_Item *item = &items[nitems - 1];
11669       size_t eltsz = item->offset + gelf_fsize (core, item->type,
11670 						item->count ?: 1, EV_CURRENT);
11671 
11672       int reps = -1;
11673       do
11674 	{
11675 	  ++reps;
11676 	  desc += eltsz;
11677 	  descsz -= eltsz;
11678 	}
11679       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11680 
11681       if (reps == 1)
11682 	{
11683 	  /* For just one repeat, print it unabridged twice.  */
11684 	  desc -= eltsz;
11685 	  descsz += eltsz;
11686 	}
11687       else if (reps > 1)
11688 	printf (gettext ("\n%*s... <repeats %u more times> ..."),
11689 		ITEM_INDENT, "", reps);
11690 
11691       last = desc;
11692     }
11693   while (descsz > 0);
11694 
11695   return colno;
11696 }
11697 
11698 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11699 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11700 		      unsigned int colno)
11701 {
11702   desc += regloc->offset;
11703 
11704   abort ();			/* XXX */
11705   return colno;
11706 }
11707 
11708 
11709 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11710 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11711 		      const Ebl_Register_Location *regloc, const void *desc,
11712 		      unsigned int colno)
11713 {
11714   if (regloc->bits % 8 != 0)
11715     return handle_bit_registers (regloc, desc, colno);
11716 
11717   desc += regloc->offset;
11718 
11719   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11720     {
11721       char name[REGNAMESZ];
11722       int bits;
11723       int type;
11724       register_info (ebl, reg, regloc, name, &bits, &type);
11725 
11726 #define TYPES								      \
11727       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
11728       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
11729       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
11730       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
11731 
11732 #define BITS(bits, xtype, sfmt, ufmt)				\
11733       uint##bits##_t b##bits; int##bits##_t b##bits##s
11734       union { TYPES; uint64_t b128[2]; } value;
11735 #undef	BITS
11736 
11737       switch (type)
11738 	{
11739 	case DW_ATE_unsigned:
11740 	case DW_ATE_signed:
11741 	case DW_ATE_address:
11742 	  switch (bits)
11743 	    {
11744 #define BITS(bits, xtype, sfmt, ufmt)					      \
11745 	    case bits:							      \
11746 	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
11747 	      if (type == DW_ATE_signed)				      \
11748 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11749 					 maxregname, name,		      \
11750 					 sfmt, value.b##bits##s);	      \
11751 	      else							      \
11752 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11753 					 maxregname, name,		      \
11754 					 ufmt, value.b##bits);		      \
11755 	      break
11756 
11757 	    TYPES;
11758 
11759 	    case 128:
11760 	      assert (type == DW_ATE_unsigned);
11761 	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11762 	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11763 	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
11764 				       maxregname, name,
11765 				       "0x%.16" PRIx64 "%.16" PRIx64,
11766 				       value.b128[!be], value.b128[be]);
11767 	      break;
11768 
11769 	    default:
11770 	      abort ();
11771 #undef	BITS
11772 	    }
11773 	  break;
11774 
11775 	default:
11776 	  /* Print each byte in hex, the whole thing in native byte order.  */
11777 	  assert (bits % 8 == 0);
11778 	  const uint8_t *bytes = desc;
11779 	  desc += bits / 8;
11780 	  char hex[bits / 4 + 1];
11781 	  hex[bits / 4] = '\0';
11782 	  int incr = 1;
11783 	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11784 	    {
11785 	      bytes += bits / 8 - 1;
11786 	      incr = -1;
11787 	    }
11788 	  size_t idx = 0;
11789 	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11790 	    {
11791 	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11792 	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11793 	    }
11794 	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
11795 				   maxregname, name, "0x%s", hex);
11796 	  break;
11797 	}
11798       desc += regloc->pad;
11799 
11800 #undef TYPES
11801     }
11802 
11803   return colno;
11804 }
11805 
11806 
11807 struct register_info
11808 {
11809   const Ebl_Register_Location *regloc;
11810   const char *set;
11811   char name[REGNAMESZ];
11812   int regno;
11813   int bits;
11814   int type;
11815 };
11816 
11817 static int
register_bitpos(const struct register_info * r)11818 register_bitpos (const struct register_info *r)
11819 {
11820   return (r->regloc->offset * 8
11821 	  + ((r->regno - r->regloc->regno)
11822 	     * (r->regloc->bits + r->regloc->pad * 8)));
11823 }
11824 
11825 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)11826 compare_sets_by_info (const struct register_info *r1,
11827 		      const struct register_info *r2)
11828 {
11829   return ((int) r2->bits - (int) r1->bits
11830 	  ?: register_bitpos (r1) - register_bitpos (r2));
11831 }
11832 
11833 /* Sort registers by set, and by size and layout offset within each set.  */
11834 static int
compare_registers(const void * a,const void * b)11835 compare_registers (const void *a, const void *b)
11836 {
11837   const struct register_info *r1 = a;
11838   const struct register_info *r2 = b;
11839 
11840   /* Unused elements sort last.  */
11841   if (r1->regloc == NULL)
11842     return r2->regloc == NULL ? 0 : 1;
11843   if (r2->regloc == NULL)
11844     return -1;
11845 
11846   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11847 	  ?: compare_sets_by_info (r1, r2));
11848 }
11849 
11850 /* Sort register sets by layout offset of the first register in the set.  */
11851 static int
compare_register_sets(const void * a,const void * b)11852 compare_register_sets (const void *a, const void *b)
11853 {
11854   const struct register_info *const *p1 = a;
11855   const struct register_info *const *p2 = b;
11856   return compare_sets_by_info (*p1, *p2);
11857 }
11858 
11859 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)11860 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11861 		       const Ebl_Register_Location *reglocs, size_t nregloc)
11862 {
11863   if (nregloc == 0)
11864     return 0;
11865 
11866   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
11867   if (maxnreg <= 0)
11868     {
11869       for (size_t i = 0; i < nregloc; ++i)
11870 	if (maxnreg < reglocs[i].regno + reglocs[i].count)
11871 	  maxnreg = reglocs[i].regno + reglocs[i].count;
11872       assert (maxnreg > 0);
11873     }
11874 
11875   struct register_info regs[maxnreg];
11876   memset (regs, 0, sizeof regs);
11877 
11878   /* Sort to collect the sets together.  */
11879   int maxreg = 0;
11880   for (size_t i = 0; i < nregloc; ++i)
11881     for (int reg = reglocs[i].regno;
11882 	 reg < reglocs[i].regno + reglocs[i].count;
11883 	 ++reg)
11884       {
11885 	assert (reg < maxnreg);
11886 	if (reg > maxreg)
11887 	  maxreg = reg;
11888 	struct register_info *info = &regs[reg];
11889 	info->regloc = &reglocs[i];
11890 	info->regno = reg;
11891 	info->set = register_info (ebl, reg, &reglocs[i],
11892 				   info->name, &info->bits, &info->type);
11893       }
11894   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
11895 
11896   /* Collect the unique sets and sort them.  */
11897   inline bool same_set (const struct register_info *a,
11898 			const struct register_info *b)
11899   {
11900     return (a < &regs[maxnreg] && a->regloc != NULL
11901 	    && b < &regs[maxnreg] && b->regloc != NULL
11902 	    && a->bits == b->bits
11903 	    && (a->set == b->set || !strcmp (a->set, b->set)));
11904   }
11905   struct register_info *sets[maxreg + 1];
11906   sets[0] = &regs[0];
11907   size_t nsets = 1;
11908   for (int i = 1; i <= maxreg; ++i)
11909     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
11910       sets[nsets++] = &regs[i];
11911   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
11912 
11913   /* Write out all the sets.  */
11914   unsigned int colno = 0;
11915   for (size_t i = 0; i < nsets; ++i)
11916     {
11917       /* Find the longest name of a register in this set.  */
11918       size_t maxname = 0;
11919       const struct register_info *end;
11920       for (end = sets[i]; same_set (sets[i], end); ++end)
11921 	{
11922 	  size_t len = strlen (end->name);
11923 	  if (len > maxname)
11924 	    maxname = len;
11925 	}
11926 
11927       for (const struct register_info *reg = sets[i];
11928 	   reg < end;
11929 	   reg += reg->regloc->count ?: 1)
11930 	colno = handle_core_register (ebl, core, maxname,
11931 				      reg->regloc, desc, colno);
11932 
11933       /* Force a line break at the end of the group.  */
11934       colno = WRAP_COLUMN;
11935     }
11936 
11937   return colno;
11938 }
11939 
11940 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)11941 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
11942 {
11943   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
11944   if (data == NULL)
11945   elf_error:
11946     error (EXIT_FAILURE, 0,
11947 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11948 
11949   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
11950   for (size_t i = 0; i < nauxv; ++i)
11951     {
11952       GElf_auxv_t av_mem;
11953       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
11954       if (av == NULL)
11955 	goto elf_error;
11956 
11957       const char *name;
11958       const char *fmt;
11959       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
11960 	{
11961 	  /* Unknown type.  */
11962 	  if (av->a_un.a_val == 0)
11963 	    printf ("    %" PRIu64 "\n", av->a_type);
11964 	  else
11965 	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
11966 		    av->a_type, av->a_un.a_val);
11967 	}
11968       else
11969 	switch (fmt[0])
11970 	  {
11971 	  case '\0':		/* Normally zero.  */
11972 	    if (av->a_un.a_val == 0)
11973 	      {
11974 		printf ("    %s\n", name);
11975 		break;
11976 	      }
11977 	    FALLTHROUGH;
11978 	  case 'x':		/* hex */
11979 	  case 'p':		/* address */
11980 	  case 's':		/* address of string */
11981 	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
11982 	    break;
11983 	  case 'u':
11984 	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
11985 	    break;
11986 	  case 'd':
11987 	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
11988 	    break;
11989 
11990 	  case 'b':
11991 	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
11992 	    GElf_Xword bit = 1;
11993 	    const char *pfx = "<";
11994 	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
11995 	      {
11996 		if (av->a_un.a_val & bit)
11997 		  {
11998 		    printf ("%s%s", pfx, p);
11999 		    pfx = " ";
12000 		  }
12001 		bit <<= 1;
12002 	      }
12003 	    printf (">\n");
12004 	    break;
12005 
12006 	  default:
12007 	    abort ();
12008 	  }
12009     }
12010 }
12011 
12012 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12013 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12014 {
12015   return ptr < end && (size_t) (end - ptr) >= sz;
12016 }
12017 
12018 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12019 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12020 	      int *retp)
12021 {
12022   if (! buf_has_data (*ptrp, end, 4))
12023     return false;
12024 
12025   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12026   return true;
12027 }
12028 
12029 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12030 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12031 		uint64_t *retp)
12032 {
12033   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12034   if (! buf_has_data (*ptrp, end, sz))
12035     return false;
12036 
12037   union
12038   {
12039     uint64_t u64;
12040     uint32_t u32;
12041   } u;
12042 
12043   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12044 
12045   if (sz == 4)
12046     *retp = u.u32;
12047   else
12048     *retp = u.u64;
12049   return true;
12050 }
12051 
12052 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12053 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12054 {
12055   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12056   if (data == NULL)
12057     error (EXIT_FAILURE, 0,
12058 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12059 
12060   unsigned char const *ptr = data->d_buf;
12061   unsigned char const *const end = data->d_buf + data->d_size;
12062 
12063   /* Siginfo head is three ints: signal number, error number, origin
12064      code.  */
12065   int si_signo, si_errno, si_code;
12066   if (! buf_read_int (core, &ptr, end, &si_signo)
12067       || ! buf_read_int (core, &ptr, end, &si_errno)
12068       || ! buf_read_int (core, &ptr, end, &si_code))
12069     {
12070     fail:
12071       printf ("    Not enough data in NT_SIGINFO note.\n");
12072       return;
12073     }
12074 
12075   /* Next is a pointer-aligned union of structures.  On 64-bit
12076      machines, that implies a word of padding.  */
12077   if (gelf_getclass (core) == ELFCLASS64)
12078     ptr += 4;
12079 
12080   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
12081 	  si_signo, si_errno, si_code);
12082 
12083   if (si_code > 0)
12084     switch (si_signo)
12085       {
12086       case CORE_SIGILL:
12087       case CORE_SIGFPE:
12088       case CORE_SIGSEGV:
12089       case CORE_SIGBUS:
12090 	{
12091 	  uint64_t addr;
12092 	  if (! buf_read_ulong (core, &ptr, end, &addr))
12093 	    goto fail;
12094 	  printf ("    fault address: %#" PRIx64 "\n", addr);
12095 	  break;
12096 	}
12097       default:
12098 	;
12099       }
12100   else if (si_code == CORE_SI_USER)
12101     {
12102       int pid, uid;
12103       if (! buf_read_int (core, &ptr, end, &pid)
12104 	  || ! buf_read_int (core, &ptr, end, &uid))
12105 	goto fail;
12106       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
12107     }
12108 }
12109 
12110 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12111 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12112 {
12113   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12114   if (data == NULL)
12115     error (EXIT_FAILURE, 0,
12116 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12117 
12118   unsigned char const *ptr = data->d_buf;
12119   unsigned char const *const end = data->d_buf + data->d_size;
12120 
12121   uint64_t count, page_size;
12122   if (! buf_read_ulong (core, &ptr, end, &count)
12123       || ! buf_read_ulong (core, &ptr, end, &page_size))
12124     {
12125     fail:
12126       printf ("    Not enough data in NT_FILE note.\n");
12127       return;
12128     }
12129 
12130   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12131   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12132   if (count > maxcount)
12133     goto fail;
12134 
12135   /* Where file names are stored.  */
12136   unsigned char const *const fstart = ptr + 3 * count * addrsize;
12137   char const *fptr = (char *) fstart;
12138 
12139   printf ("    %" PRId64 " files:\n", count);
12140   for (uint64_t i = 0; i < count; ++i)
12141     {
12142       uint64_t mstart, mend, moffset;
12143       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12144 	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
12145 	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12146 	goto fail;
12147 
12148       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12149       if (fnext == NULL)
12150 	goto fail;
12151 
12152       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
12153 		       " %08" PRIx64 " %" PRId64,
12154 		       mstart, mend, moffset * page_size, mend - mstart);
12155       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12156 
12157       fptr = fnext + 1;
12158     }
12159 }
12160 
12161 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12162 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12163 		  const char *name, const void *desc)
12164 {
12165   GElf_Word regs_offset;
12166   size_t nregloc;
12167   const Ebl_Register_Location *reglocs;
12168   size_t nitems;
12169   const Ebl_Core_Item *items;
12170 
12171   if (! ebl_core_note (ebl, nhdr, name, desc,
12172 		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
12173     return;
12174 
12175   /* Pass 0 for DESCSZ when there are registers in the note,
12176      so that the ITEMS array does not describe the whole thing.
12177      For non-register notes, the actual descsz might be a multiple
12178      of the unit size, not just exactly the unit size.  */
12179   unsigned int colno = handle_core_items (ebl->elf, desc,
12180 					  nregloc == 0 ? nhdr->n_descsz : 0,
12181 					  items, nitems);
12182   if (colno != 0)
12183     putchar_unlocked ('\n');
12184 
12185   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12186 				 reglocs, nregloc);
12187   if (colno != 0)
12188     putchar_unlocked ('\n');
12189 }
12190 
12191 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12192 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12193 		   GElf_Off start, Elf_Data *data)
12194 {
12195   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
12196 
12197   if (data == NULL)
12198     goto bad_note;
12199 
12200   size_t offset = 0;
12201   GElf_Nhdr nhdr;
12202   size_t name_offset;
12203   size_t desc_offset;
12204   while (offset < data->d_size
12205 	 && (offset = gelf_getnote (data, offset,
12206 				    &nhdr, &name_offset, &desc_offset)) > 0)
12207     {
12208       const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12209       const char *desc = data->d_buf + desc_offset;
12210 
12211       /* GNU Build Attributes are weird, they store most of their data
12212 	 into the owner name field.  Extract just the owner name
12213 	 prefix here, then use the rest later as data.  */
12214       bool is_gnu_build_attr
12215 	= strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12216 		   strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12217       const char *print_name = (is_gnu_build_attr
12218 				? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12219       size_t print_namesz = (is_gnu_build_attr
12220 			     ? strlen (print_name) : nhdr.n_namesz);
12221 
12222       char buf[100];
12223       char buf2[100];
12224       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
12225 	      (int) print_namesz, print_name, nhdr.n_descsz,
12226 	      ehdr->e_type == ET_CORE
12227 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
12228 					 buf, sizeof (buf))
12229 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12230 					   nhdr.n_descsz,
12231 					   buf2, sizeof (buf2)));
12232 
12233       /* Filter out invalid entries.  */
12234       if (memchr (name, '\0', nhdr.n_namesz) != NULL
12235 	  /* XXX For now help broken Linux kernels.  */
12236 	  || 1)
12237 	{
12238 	  if (ehdr->e_type == ET_CORE)
12239 	    {
12240 	      if (nhdr.n_type == NT_AUXV
12241 		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
12242 		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
12243 		  && !memcmp (name, "CORE", 4))
12244 		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12245 				  start + desc_offset);
12246 	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12247 		switch (nhdr.n_type)
12248 		  {
12249 		  case NT_SIGINFO:
12250 		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12251 					 start + desc_offset);
12252 		    break;
12253 
12254 		  case NT_FILE:
12255 		    handle_file_note (ebl->elf, nhdr.n_descsz,
12256 				      start + desc_offset);
12257 		    break;
12258 
12259 		  default:
12260 		    handle_core_note (ebl, &nhdr, name, desc);
12261 		  }
12262 	      else
12263 		handle_core_note (ebl, &nhdr, name, desc);
12264 	    }
12265 	  else
12266 	    ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12267 			     nhdr.n_descsz, desc);
12268 	}
12269     }
12270 
12271   if (offset == data->d_size)
12272     return;
12273 
12274  bad_note:
12275   error (0, 0,
12276 	 gettext ("cannot get content of note: %s"),
12277 	 data != NULL ? "garbage data" : elf_errmsg (-1));
12278 }
12279 
12280 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12281 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12282 {
12283   /* If we have section headers, just look for SHT_NOTE sections.
12284      In a debuginfo file, the program headers are not reliable.  */
12285   if (shnum != 0)
12286     {
12287       /* Get the section header string table index.  */
12288       size_t shstrndx;
12289       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12290 	error (EXIT_FAILURE, 0,
12291 	       gettext ("cannot get section header string table index"));
12292 
12293       Elf_Scn *scn = NULL;
12294       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12295 	{
12296 	  GElf_Shdr shdr_mem;
12297 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12298 
12299 	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12300 	    /* Not what we are looking for.  */
12301 	    continue;
12302 
12303 	  printf (gettext ("\
12304 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12305 		  elf_ndxscn (scn),
12306 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12307 		  shdr->sh_size, shdr->sh_offset);
12308 
12309 	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
12310 			     elf_getdata (scn, NULL));
12311 	}
12312       return;
12313     }
12314 
12315   /* We have to look through the program header to find the note
12316      sections.  There can be more than one.  */
12317   for (size_t cnt = 0; cnt < phnum; ++cnt)
12318     {
12319       GElf_Phdr mem;
12320       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12321 
12322       if (phdr == NULL || phdr->p_type != PT_NOTE)
12323 	/* Not what we are looking for.  */
12324 	continue;
12325 
12326       printf (gettext ("\
12327 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12328 	      phdr->p_filesz, phdr->p_offset);
12329 
12330       handle_notes_data (ebl, ehdr, phdr->p_offset,
12331 			 elf_getdata_rawchunk (ebl->elf,
12332 					       phdr->p_offset, phdr->p_filesz,
12333 					       (phdr->p_align == 8
12334 						? ELF_T_NHDR8 : ELF_T_NHDR)));
12335     }
12336 }
12337 
12338 
12339 static void
hex_dump(const uint8_t * data,size_t len)12340 hex_dump (const uint8_t *data, size_t len)
12341 {
12342   size_t pos = 0;
12343   while (pos < len)
12344     {
12345       printf ("  0x%08zx ", pos);
12346 
12347       const size_t chunk = MIN (len - pos, 16);
12348 
12349       for (size_t i = 0; i < chunk; ++i)
12350 	if (i % 4 == 3)
12351 	  printf ("%02x ", data[pos + i]);
12352 	else
12353 	  printf ("%02x", data[pos + i]);
12354 
12355       if (chunk < 16)
12356 	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12357 
12358       for (size_t i = 0; i < chunk; ++i)
12359 	{
12360 	  unsigned char b = data[pos + i];
12361 	  printf ("%c", isprint (b) ? b : '.');
12362 	}
12363 
12364       putchar ('\n');
12365       pos += chunk;
12366     }
12367 }
12368 
12369 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12370 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12371 {
12372   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12373     printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12374 	    elf_ndxscn (scn), name);
12375   else
12376     {
12377       if (print_decompress)
12378 	{
12379 	  /* We try to decompress the section, but keep the old shdr around
12380 	     so we can show both the original shdr size and the uncompressed
12381 	     data size.   */
12382 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12383 	    {
12384 	      if (elf_compress (scn, 0, 0) < 0)
12385 		printf ("WARNING: %s [%zd]\n",
12386 			gettext ("Couldn't uncompress section"),
12387 			elf_ndxscn (scn));
12388 	    }
12389 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12390 	    {
12391 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12392 		printf ("WARNING: %s [%zd]\n",
12393 			gettext ("Couldn't uncompress section"),
12394 			elf_ndxscn (scn));
12395 	    }
12396 	}
12397 
12398       Elf_Data *data = elf_rawdata (scn, NULL);
12399       if (data == NULL)
12400 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12401 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12402       else
12403 	{
12404 	  if (data->d_size == shdr->sh_size)
12405 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12406 			     " bytes at offset %#0" PRIx64 ":\n"),
12407 		    elf_ndxscn (scn), name,
12408 		    shdr->sh_size, shdr->sh_offset);
12409 	  else
12410 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12411 			     " bytes (%zd uncompressed) at offset %#0"
12412 			     PRIx64 ":\n"),
12413 		    elf_ndxscn (scn), name,
12414 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12415 	  hex_dump (data->d_buf, data->d_size);
12416 	}
12417     }
12418 }
12419 
12420 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12421 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12422 {
12423   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12424     printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12425 	    elf_ndxscn (scn), name);
12426   else
12427     {
12428       if (print_decompress)
12429 	{
12430 	  /* We try to decompress the section, but keep the old shdr around
12431 	     so we can show both the original shdr size and the uncompressed
12432 	     data size.  */
12433 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12434 	    {
12435 	      if (elf_compress (scn, 0, 0) < 0)
12436 		printf ("WARNING: %s [%zd]\n",
12437 			gettext ("Couldn't uncompress section"),
12438 			elf_ndxscn (scn));
12439 	    }
12440 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12441 	    {
12442 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12443 		printf ("WARNING: %s [%zd]\n",
12444 			gettext ("Couldn't uncompress section"),
12445 			elf_ndxscn (scn));
12446 	    }
12447 	}
12448 
12449       Elf_Data *data = elf_rawdata (scn, NULL);
12450       if (data == NULL)
12451 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12452 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12453       else
12454 	{
12455 	  if (data->d_size == shdr->sh_size)
12456 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12457 			     " bytes at offset %#0" PRIx64 ":\n"),
12458 		    elf_ndxscn (scn), name,
12459 		    shdr->sh_size, shdr->sh_offset);
12460 	  else
12461 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12462 			     " bytes (%zd uncompressed) at offset %#0"
12463 			     PRIx64 ":\n"),
12464 		    elf_ndxscn (scn), name,
12465 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12466 
12467 	  const char *start = data->d_buf;
12468 	  const char *const limit = start + data->d_size;
12469 	  do
12470 	    {
12471 	      const char *end = memchr (start, '\0', limit - start);
12472 	      const size_t pos = start - (const char *) data->d_buf;
12473 	      if (unlikely (end == NULL))
12474 		{
12475 		  printf ("  [%6zx]- %.*s\n",
12476 			  pos, (int) (limit - start), start);
12477 		  break;
12478 		}
12479 	      printf ("  [%6zx]  %s\n", pos, start);
12480 	      start = end + 1;
12481 	    } while (start < limit);
12482 	}
12483     }
12484 }
12485 
12486 static void
for_each_section_argument(Elf * elf,const struct section_argument * list,void (* dump)(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name))12487 for_each_section_argument (Elf *elf, const struct section_argument *list,
12488 			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12489 					 const char *name))
12490 {
12491   /* Get the section header string table index.  */
12492   size_t shstrndx;
12493   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12494     error (EXIT_FAILURE, 0,
12495 	   gettext ("cannot get section header string table index"));
12496 
12497   for (const struct section_argument *a = list; a != NULL; a = a->next)
12498     {
12499       Elf_Scn *scn;
12500       GElf_Shdr shdr_mem;
12501       const char *name = NULL;
12502 
12503       char *endp = NULL;
12504       unsigned long int shndx = strtoul (a->arg, &endp, 0);
12505       if (endp != a->arg && *endp == '\0')
12506 	{
12507 	  scn = elf_getscn (elf, shndx);
12508 	  if (scn == NULL)
12509 	    {
12510 	      error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12511 	      continue;
12512 	    }
12513 
12514 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
12515 	    error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12516 		   elf_errmsg (-1));
12517 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12518 	}
12519       else
12520 	{
12521 	  /* Need to look up the section by name.  */
12522 	  scn = NULL;
12523 	  bool found = false;
12524 	  while ((scn = elf_nextscn (elf, scn)) != NULL)
12525 	    {
12526 	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
12527 		continue;
12528 	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12529 	      if (name == NULL)
12530 		continue;
12531 	      if (!strcmp (name, a->arg))
12532 		{
12533 		  found = true;
12534 		  (*dump) (scn, &shdr_mem, name);
12535 		}
12536 	    }
12537 
12538 	  if (unlikely (!found) && !a->implicit)
12539 	    error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12540 	}
12541     }
12542 }
12543 
12544 static void
dump_data(Ebl * ebl)12545 dump_data (Ebl *ebl)
12546 {
12547   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12548 }
12549 
12550 static void
dump_strings(Ebl * ebl)12551 dump_strings (Ebl *ebl)
12552 {
12553   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12554 }
12555 
12556 static void
print_strings(Ebl * ebl)12557 print_strings (Ebl *ebl)
12558 {
12559   /* Get the section header string table index.  */
12560   size_t shstrndx;
12561   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12562     error (EXIT_FAILURE, 0,
12563 	   gettext ("cannot get section header string table index"));
12564 
12565   Elf_Scn *scn;
12566   GElf_Shdr shdr_mem;
12567   const char *name;
12568   scn = NULL;
12569   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12570     {
12571       if (gelf_getshdr (scn, &shdr_mem) == NULL)
12572 	continue;
12573 
12574       if (shdr_mem.sh_type != SHT_PROGBITS
12575 	  || !(shdr_mem.sh_flags & SHF_STRINGS))
12576 	continue;
12577 
12578       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12579       if (name == NULL)
12580 	continue;
12581 
12582       print_string_section (scn, &shdr_mem, name);
12583     }
12584 }
12585 
12586 static void
dump_archive_index(Elf * elf,const char * fname)12587 dump_archive_index (Elf *elf, const char *fname)
12588 {
12589   size_t narsym;
12590   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12591   if (arsym == NULL)
12592     {
12593       int result = elf_errno ();
12594       if (unlikely (result != ELF_E_NO_INDEX))
12595 	error (EXIT_FAILURE, 0,
12596 	       gettext ("cannot get symbol index of archive '%s': %s"),
12597 	       fname, elf_errmsg (result));
12598       else
12599 	printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12600       return;
12601     }
12602 
12603   printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12604 	  fname, narsym);
12605 
12606   size_t as_off = 0;
12607   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12608     {
12609       if (s->as_off != as_off)
12610 	{
12611 	  as_off = s->as_off;
12612 
12613 	  Elf *subelf = NULL;
12614 	  if (unlikely (elf_rand (elf, as_off) == 0)
12615 	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12616 			   == NULL))
12617 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12618 	    while (1)
12619 #endif
12620 	      error (EXIT_FAILURE, 0,
12621 		     gettext ("cannot extract member at offset %zu in '%s': %s"),
12622 		     as_off, fname, elf_errmsg (-1));
12623 
12624 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
12625 
12626 	  printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12627 
12628 	  elf_end (subelf);
12629 	}
12630 
12631       printf ("\t%s\n", s->as_name);
12632     }
12633 }
12634 
12635 #include "debugpred.h"
12636