• 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 /* argp key value for --dyn-syms, non-ascii.  */
88 #define PRINT_DYNSYM_TABLE 258
89 
90 /* Terrible hack for hooking unrelated skeleton/split compile units,
91    see __libdw_link_skel_split in print_debug.  */
92 static bool do_not_close_dwfl = false;
93 
94 /* Definitions of arguments for argp functions.  */
95 static const struct argp_option options[] =
96 {
97   { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
98   { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
99     N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
100        "input data"), 0 },
101   { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
102     N_("Used with -w to find the skeleton Compile Units in FILE associated "
103        "with the Split Compile units in a .dwo input file"), 0 },
104   { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
105   { "all", 'a', NULL, 0,
106     N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
107   { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
108   { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
109   { "histogram", 'I', NULL, 0,
110     N_("Display histogram of bucket list lengths"), 0 },
111   { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
112   { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
113   { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
114   { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
115   { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
116   { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
117   { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
118     N_("Display the symbol table sections"), 0 },
119   { "dyn-syms", PRINT_DYNSYM_TABLE, NULL, 0,
120     N_("Display (only) the dynamic symbol table"), 0 },
121   { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
122   { "notes", 'n', "SECTION", OPTION_ARG_OPTIONAL, N_("Display the ELF notes"), 0 },
123   { "arch-specific", 'A', NULL, 0,
124     N_("Display architecture specific information, if any"), 0 },
125   { "exception", 'e', NULL, 0,
126     N_("Display sections for exception handling"), 0 },
127 
128   { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
129   { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
130     N_("Display DWARF section content.  SECTION can be one of abbrev, addr, "
131        "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
132        "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
133   { "hex-dump", 'x', "SECTION", 0,
134     N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
135   { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
136     N_("Print string contents of sections"), 0 },
137   { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
138   { "archive-index", 'c', NULL, 0,
139     N_("Display the symbol index of an archive"), 0 },
140 
141   { NULL, 0, NULL, 0, N_("Output control:"), 0 },
142   { "numeric-addresses", 'N', NULL, 0,
143     N_("Do not find symbol names for addresses in DWARF data"), 0 },
144   { "unresolved-address-offsets", 'U', NULL, 0,
145     N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
146   { "wide", 'W', NULL, 0,
147     N_("Ignored for compatibility (lines always wide)"), 0 },
148   { "decompress", 'z', NULL, 0,
149     N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
150   { NULL, 0, NULL, 0, NULL, 0 }
151 };
152 
153 /* Short description of program.  */
154 static const char doc[] = N_("\
155 Print information from ELF file in human-readable form.");
156 
157 /* Strings for arguments in help texts.  */
158 static const char args_doc[] = N_("FILE...");
159 
160 /* Prototype for option handler.  */
161 static error_t parse_opt (int key, char *arg, struct argp_state *state);
162 
163 /* Data structure to communicate with argp functions.  */
164 static struct argp argp =
165 {
166   options, parse_opt, args_doc, doc, NULL, NULL, NULL
167 };
168 
169 /* If non-null, the section from which we should read to (compressed) ELF.  */
170 static const char *elf_input_section = NULL;
171 
172 /* If non-null, the file that contains the skeleton CUs.  */
173 static const char *dwarf_skeleton = NULL;
174 
175 /* Flags set by the option controlling the output.  */
176 
177 /* True if dynamic segment should be printed.  */
178 static bool print_dynamic_table;
179 
180 /* True if the file header should be printed.  */
181 static bool print_file_header;
182 
183 /* True if the program headers should be printed.  */
184 static bool print_program_header;
185 
186 /* True if relocations should be printed.  */
187 static bool print_relocations;
188 
189 /* True if the section headers should be printed.  */
190 static bool print_section_header;
191 
192 /* True if the symbol table should be printed.  */
193 static bool print_symbol_table;
194 
195 /* True if (only) the dynsym table should be printed.  */
196 static bool print_dynsym_table;
197 
198 /* A specific section name, or NULL to print all symbol tables.  */
199 static char *symbol_table_section;
200 
201 /* A specific section name, or NULL to print all ELF notes.  */
202 static char *notes_section;
203 
204 /* True if the version information should be printed.  */
205 static bool print_version_info;
206 
207 /* True if section groups should be printed.  */
208 static bool print_section_groups;
209 
210 /* True if bucket list length histogram should be printed.  */
211 static bool print_histogram;
212 
213 /* True if the architecture specific data should be printed.  */
214 static bool print_arch;
215 
216 /* True if note section content should be printed.  */
217 static bool print_notes;
218 
219 /* True if SHF_STRINGS section content should be printed.  */
220 static bool print_string_sections;
221 
222 /* True if archive index should be printed.  */
223 static bool print_archive_index;
224 
225 /* True if any of the control options except print_archive_index is set.  */
226 static bool any_control_option;
227 
228 /* True if we should print addresses from DWARF in symbolic form.  */
229 static bool print_address_names = true;
230 
231 /* True if we should print raw values instead of relativized addresses.  */
232 static bool print_unresolved_addresses = false;
233 
234 /* True if we should print the .debug_aranges section using libdw.  */
235 static bool decodedaranges = false;
236 
237 /* True if we should print the .debug_aranges section using libdw.  */
238 static bool decodedline = false;
239 
240 /* True if we want to show more information about compressed sections.  */
241 static bool print_decompress = false;
242 
243 /* True if we want to show split compile units for debug_info skeletons.  */
244 static bool show_split_units = false;
245 
246 /* Select printing of debugging sections.  */
247 static enum section_e
248 {
249   section_abbrev = 1,		/* .debug_abbrev  */
250   section_aranges = 2,		/* .debug_aranges  */
251   section_frame = 4,		/* .debug_frame or .eh_frame & al.  */
252   section_info = 8,		/* .debug_info, (implies .debug_types)  */
253   section_line = 16,		/* .debug_line  */
254   section_loc = 32,		/* .debug_loc  */
255   section_pubnames = 64,	/* .debug_pubnames  */
256   section_str = 128,		/* .debug_str  */
257   section_macinfo = 256,	/* .debug_macinfo  */
258   section_ranges = 512, 	/* .debug_ranges  */
259   section_exception = 1024,	/* .eh_frame & al.  */
260   section_gdb_index = 2048,	/* .gdb_index  */
261   section_macro = 4096,		/* .debug_macro  */
262   section_addr = 8192,		/* .debug_addr  */
263   section_types = 16384,	/* .debug_types (implied by .debug_info)  */
264   section_all = (section_abbrev | section_aranges | section_frame
265 		 | section_info | section_line | section_loc
266 		 | section_pubnames | section_str | section_macinfo
267 		 | section_ranges | section_exception | section_gdb_index
268 		 | section_macro | section_addr | section_types)
269 } print_debug_sections, implicit_debug_sections;
270 
271 /* Select hex dumping of sections.  */
272 static struct section_argument *dump_data_sections;
273 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
274 
275 /* Select string dumping of sections.  */
276 static struct section_argument *string_sections;
277 static struct section_argument **string_sections_tail = &string_sections;
278 
279 struct section_argument
280 {
281   struct section_argument *next;
282   const char *arg;
283   bool implicit;
284 };
285 
286 /* Numbers of sections and program headers in the file.  */
287 static size_t shnum;
288 static size_t phnum;
289 
290 
291 /* Declarations of local functions.  */
292 static void process_file (int fd, const char *fname, bool only_one);
293 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
294 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
295 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
296 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
297 static void print_scngrp (Ebl *ebl);
298 static void print_dynamic (Ebl *ebl);
299 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
300 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
301 			       GElf_Shdr *shdr);
302 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
303 				GElf_Shdr *shdr);
304 static void print_symtab (Ebl *ebl, int type);
305 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
306 static void print_verinfo (Ebl *ebl);
307 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
308 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
309 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
310 			   GElf_Shdr *shdr);
311 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
312 static void handle_hash (Ebl *ebl);
313 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
314 static void print_liblist (Ebl *ebl);
315 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
316 static void dump_data (Ebl *ebl);
317 static void dump_strings (Ebl *ebl);
318 static void print_strings (Ebl *ebl);
319 static void dump_archive_index (Elf *, const char *);
320 
321 
322 /* Looked up once with gettext in main.  */
323 static char *yes_str;
324 static char *no_str;
325 
326 static void
cleanup_list(struct section_argument * list)327 cleanup_list (struct section_argument *list)
328 {
329   while (list != NULL)
330     {
331       struct section_argument *a = list;
332       list = a->next;
333       free (a);
334     }
335 }
336 
337 int
main(int argc,char * argv[])338 main (int argc, char *argv[])
339 {
340   /* We use no threads here which can interfere with handling a stream.  */
341   (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
342 
343   /* Set locale.  */
344   setlocale (LC_ALL, "");
345 
346   /* Initialize the message catalog.  */
347   textdomain (PACKAGE_TARNAME);
348 
349   /* Look up once.  */
350   yes_str = _("yes");
351   no_str = _("no");
352 
353   /* Parse and process arguments.  */
354   int remaining;
355   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
356 
357   /* Before we start tell the ELF library which version we are using.  */
358   elf_version (EV_CURRENT);
359 
360   /* Now process all the files given at the command line.  */
361   bool only_one = remaining + 1 == argc;
362   do
363     {
364       /* Open the file.  */
365       int fd = open (argv[remaining], O_RDONLY);
366       if (fd == -1)
367 	{
368 	  error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
369 	  continue;
370 	}
371 
372       process_file (fd, argv[remaining], only_one);
373 
374       close (fd);
375     }
376   while (++remaining < argc);
377 
378   cleanup_list (dump_data_sections);
379   cleanup_list (string_sections);
380 
381   return error_message_count != 0;
382 }
383 
384 static void
add_dump_section(const char * name,int key,bool implicit)385 add_dump_section (const char *name,
386 		  int key,
387 		  bool implicit)
388 {
389   struct section_argument *a = xmalloc (sizeof *a);
390   a->arg = name;
391   a->next = NULL;
392   a->implicit = implicit;
393   struct section_argument ***tailp
394     = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
395   **tailp = a;
396   *tailp = &a->next;
397 }
398 
399 /* Handle program arguments.  */
400 static error_t
parse_opt(int key,char * arg,struct argp_state * state)401 parse_opt (int key, char *arg,
402 	   struct argp_state *state __attribute__ ((unused)))
403 {
404   switch (key)
405     {
406     case 'a':
407       print_file_header = true;
408       print_program_header = true;
409       print_relocations = true;
410       print_section_header = true;
411       print_symbol_table = true;
412       print_version_info = true;
413       print_dynamic_table = true;
414       print_section_groups = true;
415       print_histogram = true;
416       print_arch = true;
417       print_notes = true;
418       implicit_debug_sections |= section_exception;
419       add_dump_section (".strtab", key, true);
420       add_dump_section (".dynstr", key, true);
421       add_dump_section (".comment", key, true);
422       any_control_option = true;
423       break;
424     case 'A':
425       print_arch = true;
426       any_control_option = true;
427       break;
428     case 'd':
429       print_dynamic_table = true;
430       any_control_option = true;
431       break;
432     case 'e':
433       print_debug_sections |= section_exception;
434       any_control_option = true;
435       break;
436     case 'g':
437       print_section_groups = true;
438       any_control_option = true;
439       break;
440     case 'h':
441       print_file_header = true;
442       any_control_option = true;
443       break;
444     case 'I':
445       print_histogram = true;
446       any_control_option = true;
447       break;
448     case 'l':
449       print_program_header = true;
450       any_control_option = true;
451       break;
452     case 'n':
453       print_notes = true;
454       any_control_option = true;
455       notes_section = arg;
456       break;
457     case 'r':
458       print_relocations = true;
459       any_control_option = true;
460      break;
461     case 'S':
462       print_section_header = true;
463       any_control_option = true;
464       break;
465     case 's':
466       print_symbol_table = true;
467       any_control_option = true;
468       symbol_table_section = arg;
469       break;
470     case PRINT_DYNSYM_TABLE:
471       print_dynsym_table = true;
472       any_control_option = true;
473       break;
474     case 'V':
475       print_version_info = true;
476       any_control_option = true;
477       break;
478     case 'c':
479       print_archive_index = true;
480       break;
481     case 'w':
482       if (arg == NULL)
483 	{
484 	  print_debug_sections = section_all;
485 	  implicit_debug_sections = section_info;
486 	  show_split_units = true;
487 	}
488       else if (strcmp (arg, "abbrev") == 0)
489 	print_debug_sections |= section_abbrev;
490       else if (strcmp (arg, "addr") == 0)
491 	{
492 	  print_debug_sections |= section_addr;
493 	  implicit_debug_sections |= section_info;
494 	}
495       else if (strcmp (arg, "aranges") == 0)
496 	print_debug_sections |= section_aranges;
497       else if (strcmp (arg, "decodedaranges") == 0)
498 	{
499 	  print_debug_sections |= section_aranges;
500 	  decodedaranges = true;
501 	}
502       else if (strcmp (arg, "ranges") == 0)
503 	{
504 	  print_debug_sections |= section_ranges;
505 	  implicit_debug_sections |= section_info;
506 	}
507       else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
508 	print_debug_sections |= section_frame;
509       else if (strcmp (arg, "info") == 0)
510 	{
511 	  print_debug_sections |= section_info;
512 	  print_debug_sections |= section_types;
513 	}
514       else if (strcmp (arg, "info+") == 0)
515 	{
516 	  print_debug_sections |= section_info;
517 	  print_debug_sections |= section_types;
518 	  show_split_units = true;
519 	}
520       else if (strcmp (arg, "loc") == 0)
521 	{
522 	  print_debug_sections |= section_loc;
523 	  implicit_debug_sections |= section_info;
524 	}
525       else if (strcmp (arg, "line") == 0)
526 	print_debug_sections |= section_line;
527       else if (strcmp (arg, "decodedline") == 0)
528 	{
529 	  print_debug_sections |= section_line;
530 	  decodedline = true;
531 	}
532       else if (strcmp (arg, "pubnames") == 0)
533 	print_debug_sections |= section_pubnames;
534       else if (strcmp (arg, "str") == 0)
535 	{
536 	  print_debug_sections |= section_str;
537 	  /* For mapping string offset tables to CUs.  */
538 	  implicit_debug_sections |= section_info;
539 	}
540       else if (strcmp (arg, "macinfo") == 0)
541 	print_debug_sections |= section_macinfo;
542       else if (strcmp (arg, "macro") == 0)
543 	print_debug_sections |= section_macro;
544       else if (strcmp (arg, "exception") == 0)
545 	print_debug_sections |= section_exception;
546       else if (strcmp (arg, "gdb_index") == 0)
547 	print_debug_sections |= section_gdb_index;
548       else
549 	{
550 	  fprintf (stderr, _("Unknown DWARF debug section `%s'.\n"),
551 		   arg);
552 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
553 		     program_invocation_short_name);
554 	  exit (1);
555 	}
556       any_control_option = true;
557       break;
558     case 'p':
559       any_control_option = true;
560       if (arg == NULL)
561 	{
562 	  print_string_sections = true;
563 	  break;
564 	}
565       FALLTHROUGH;
566     case 'x':
567       add_dump_section (arg, key, false);
568       any_control_option = true;
569       break;
570     case 'N':
571       print_address_names = false;
572       break;
573     case 'U':
574       print_unresolved_addresses = true;
575       break;
576     case ARGP_KEY_NO_ARGS:
577       fputs (_("Missing file name.\n"), stderr);
578       goto do_argp_help;
579     case ARGP_KEY_FINI:
580       if (! any_control_option && ! print_archive_index)
581 	{
582 	  fputs (_("No operation specified.\n"), stderr);
583 	do_argp_help:
584 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
585 		     program_invocation_short_name);
586 	  exit (EXIT_FAILURE);
587 	}
588       break;
589     case 'W':			/* Ignored.  */
590       break;
591     case 'z':
592       print_decompress = true;
593       break;
594     case ELF_INPUT_SECTION:
595       if (arg == NULL)
596 	elf_input_section = ".gnu_debugdata";
597       else
598 	elf_input_section = arg;
599       break;
600     case DWARF_SKELETON:
601       dwarf_skeleton = arg;
602       break;
603     default:
604       return ARGP_ERR_UNKNOWN;
605     }
606   return 0;
607 }
608 
609 
610 /* Create a file descriptor to read the data from the
611    elf_input_section given a file descriptor to an ELF file.  */
612 static int
open_input_section(int fd)613 open_input_section (int fd)
614 {
615   size_t shnums;
616   size_t cnt;
617   size_t shstrndx;
618   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
619   if (elf == NULL)
620     {
621       error (0, 0, _("cannot generate Elf descriptor: %s"),
622 	     elf_errmsg (-1));
623       return -1;
624     }
625 
626   if (elf_getshdrnum (elf, &shnums) < 0)
627     {
628       error (0, 0, _("cannot determine number of sections: %s"),
629 	     elf_errmsg (-1));
630     open_error:
631       elf_end (elf);
632       return -1;
633     }
634 
635   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
636     {
637       error (0, 0, _("cannot get section header string table index"));
638       goto open_error;
639     }
640 
641   for (cnt = 0; cnt < shnums; ++cnt)
642     {
643       Elf_Scn *scn = elf_getscn (elf, cnt);
644       if (scn == NULL)
645 	{
646 	  error (0, 0, _("cannot get section: %s"),
647 		 elf_errmsg (-1));
648 	  goto open_error;
649 	}
650 
651       GElf_Shdr shdr_mem;
652       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
653       if (unlikely (shdr == NULL))
654 	{
655 	  error (0, 0, _("cannot get section header: %s"),
656 		 elf_errmsg (-1));
657 	  goto open_error;
658 	}
659 
660       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
661       if (sname == NULL)
662 	{
663 	  error (0, 0, _("cannot get section name"));
664 	  goto open_error;
665 	}
666 
667       if (strcmp (sname, elf_input_section) == 0)
668 	{
669 	  Elf_Data *data = elf_rawdata (scn, NULL);
670 	  if (data == NULL)
671 	    {
672 	      error (0, 0, _("cannot get %s content: %s"),
673 		     sname, elf_errmsg (-1));
674 	      goto open_error;
675 	    }
676 
677 	  /* Create (and immediately unlink) a temporary file to store
678 	     section data in to create a file descriptor for it.  */
679 	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
680 	  static const char suffix[] = "/readelfXXXXXX";
681 	  int tmplen = strlen (tmpdir) + sizeof (suffix);
682 	  char *tempname = alloca (tmplen);
683 	  sprintf (tempname, "%s%s", tmpdir, suffix);
684 
685 	  int sfd = mkstemp (tempname);
686 	  if (sfd == -1)
687 	    {
688 	      error (0, 0, _("cannot create temp file '%s'"),
689 		     tempname);
690 	      goto open_error;
691 	    }
692 	  unlink (tempname);
693 
694 	  ssize_t size = data->d_size;
695 	  if (write_retry (sfd, data->d_buf, size) != size)
696 	    {
697 	      error (0, 0, _("cannot write section data"));
698 	      goto open_error;
699 	    }
700 
701 	  if (elf_end (elf) != 0)
702 	    {
703 	      error (0, 0, _("error while closing Elf descriptor: %s"),
704 		     elf_errmsg (-1));
705 	      return -1;
706 	    }
707 
708 	  if (lseek (sfd, 0, SEEK_SET) == -1)
709 	    {
710 	      error (0, 0, _("error while rewinding file descriptor"));
711 	      return -1;
712 	    }
713 
714 	  return sfd;
715 	}
716     }
717 
718   /* Named section not found.  */
719   if (elf_end (elf) != 0)
720     error (0, 0, _("error while closing Elf descriptor: %s"),
721 	   elf_errmsg (-1));
722   return -1;
723 }
724 
725 /* Check if the file is an archive, and if so dump its index.  */
726 static void
check_archive_index(int fd,const char * fname,bool only_one)727 check_archive_index (int fd, const char *fname, bool only_one)
728 {
729   /* Create an `Elf' descriptor.  */
730   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
731   if (elf == NULL)
732     error (0, 0, _("cannot generate Elf descriptor: %s"),
733 	   elf_errmsg (-1));
734   else
735     {
736       if (elf_kind (elf) == ELF_K_AR)
737 	{
738 	  if (!only_one)
739 	    printf ("\n%s:\n\n", fname);
740 	  dump_archive_index (elf, fname);
741 	}
742       else
743 	error (0, 0,
744 	       _("'%s' is not an archive, cannot print archive index"),
745 	       fname);
746 
747       /* Now we can close the descriptor.  */
748       if (elf_end (elf) != 0)
749 	error (0, 0, _("error while closing Elf descriptor: %s"),
750 	       elf_errmsg (-1));
751     }
752 }
753 
754 /* Trivial callback used for checking if we opened an archive.  */
755 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)756 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
757 	       void **userdata __attribute__ ((unused)),
758 	       const char *name __attribute__ ((unused)),
759 	       Dwarf_Addr base __attribute__ ((unused)),
760 	       void *arg)
761 {
762   if (*(bool *) arg)
763     return DWARF_CB_ABORT;
764   *(bool *) arg = true;
765   return DWARF_CB_OK;
766 }
767 
768 struct process_dwflmod_args
769 {
770   int fd;
771   bool only_one;
772 };
773 
774 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)775 process_dwflmod (Dwfl_Module *dwflmod,
776 		 void **userdata __attribute__ ((unused)),
777 		 const char *name __attribute__ ((unused)),
778 		 Dwarf_Addr base __attribute__ ((unused)),
779 		 void *arg)
780 {
781   const struct process_dwflmod_args *a = arg;
782 
783   /* Print the file name.  */
784   if (!a->only_one)
785     {
786       const char *fname;
787       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
788 
789       printf ("\n%s:\n\n", fname);
790     }
791 
792   process_elf_file (dwflmod, a->fd);
793 
794   return DWARF_CB_OK;
795 }
796 
797 /* Stub libdwfl callback, only the ELF handle already open is ever used.
798    Only used for finding the alternate debug file if the Dwarf comes from
799    the main file.  We are not interested in separate debuginfo.  */
800 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)801 find_no_debuginfo (Dwfl_Module *mod,
802 		   void **userdata,
803 		   const char *modname,
804 		   Dwarf_Addr base,
805 		   const char *file_name,
806 		   const char *debuglink_file,
807 		   GElf_Word debuglink_crc,
808 		   char **debuginfo_file_name)
809 {
810   Dwarf_Addr dwbias;
811   dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
812 
813   /* We are only interested if the Dwarf has been setup on the main
814      elf file but is only missing the alternate debug link.  If dwbias
815      hasn't even been setup, this is searching for separate debuginfo
816      for the main elf.  We don't care in that case.  */
817   if (dwbias == (Dwarf_Addr) -1)
818     return -1;
819 
820   return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
821 				       file_name, debuglink_file,
822 				       debuglink_crc, debuginfo_file_name);
823 }
824 
825 static Dwfl *
create_dwfl(int fd,const char * fname)826 create_dwfl (int fd, const char *fname)
827 {
828   /* Duplicate an fd for dwfl_report_offline to swallow.  */
829   int dwfl_fd = dup (fd);
830   if (unlikely (dwfl_fd < 0))
831     error (EXIT_FAILURE, errno, "dup");
832 
833   /* Use libdwfl in a trivial way to open the libdw handle for us.
834      This takes care of applying relocations to DWARF data in ET_REL files.  */
835   static const Dwfl_Callbacks callbacks =
836     {
837       .section_address = dwfl_offline_section_address,
838       .find_debuginfo = find_no_debuginfo
839     };
840   Dwfl *dwfl = dwfl_begin (&callbacks);
841   if (likely (dwfl != NULL))
842     /* Let 0 be the logical address of the file (or first in archive).  */
843     dwfl->offline_next_address = 0;
844   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
845     {
846       struct stat st;
847       if (fstat (dwfl_fd, &st) != 0)
848 	error (0, errno, _("cannot stat input file"));
849       else if (unlikely (st.st_size == 0))
850 	error (0, 0, _("input file is empty"));
851       else
852 	error (0, 0, _("failed reading '%s': %s"),
853 	       fname, dwfl_errmsg (-1));
854       close (dwfl_fd);		/* Consumed on success, not on failure.  */
855       dwfl = NULL;
856     }
857   else
858     dwfl_report_end (dwfl, NULL, NULL);
859 
860   return dwfl;
861 }
862 
863 /* Process one input file.  */
864 static void
process_file(int fd,const char * fname,bool only_one)865 process_file (int fd, const char *fname, bool only_one)
866 {
867   if (print_archive_index)
868     check_archive_index (fd, fname, only_one);
869 
870   if (!any_control_option)
871     return;
872 
873   if (elf_input_section != NULL)
874     {
875       /* Replace fname and fd with section content. */
876       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
877       sprintf (fnname, "%s:%s", fname, elf_input_section);
878       fd = open_input_section (fd);
879       if (fd == -1)
880         {
881           error (0, 0, _("No such section '%s' in '%s'"),
882 		 elf_input_section, fname);
883           return;
884         }
885       fname = fnname;
886     }
887 
888   Dwfl *dwfl = create_dwfl (fd, fname);
889   if (dwfl != NULL)
890     {
891       if (only_one)
892 	{
893 	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
894 	  bool seen = false;
895 	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
896 	}
897 
898       /* Process the one or more modules gleaned from this file.  */
899       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
900       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
901     }
902   /* Terrible hack for hooking unrelated skeleton/split compile units,
903      see __libdw_link_skel_split in print_debug.  */
904   if (! do_not_close_dwfl)
905     dwfl_end (dwfl);
906 
907   /* Need to close the replaced fd if we created it.  Caller takes
908      care of original.  */
909   if (elf_input_section != NULL)
910     close (fd);
911 }
912 
913 /* Check whether there are any compressed sections in the ELF file.  */
914 static bool
elf_contains_chdrs(Elf * elf)915 elf_contains_chdrs (Elf *elf)
916 {
917   Elf_Scn *scn = NULL;
918   while ((scn = elf_nextscn (elf, scn)) != NULL)
919     {
920       GElf_Shdr shdr_mem;
921       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
922       if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
923 	return true;
924     }
925   return false;
926 }
927 
928 /* Process one ELF file.  */
929 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)930 process_elf_file (Dwfl_Module *dwflmod, int fd)
931 {
932   GElf_Addr dwflbias;
933   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
934 
935   GElf_Ehdr ehdr_mem;
936   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
937 
938   if (ehdr == NULL)
939     {
940       error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1));
941       return;
942     }
943 
944   Ebl *ebl = ebl_openbackend (elf);
945   if (unlikely (ebl == NULL))
946     {
947     ebl_error:
948       error (0, errno, _("cannot create EBL handle"));
949       return;
950     }
951 
952   /* Determine the number of sections.  */
953   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
954     error (EXIT_FAILURE, 0,
955 	   _("cannot determine number of sections: %s"),
956 	   elf_errmsg (-1));
957 
958   /* Determine the number of phdrs.  */
959   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
960     error (EXIT_FAILURE, 0,
961 	   _("cannot determine number of program headers: %s"),
962 	   elf_errmsg (-1));
963 
964   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
965      may have applied relocation to some sections.  If there are any
966      compressed sections, any pass (or libdw/libdwfl) might have
967      uncompressed them.  So we need to get a fresh Elf handle on the
968      file to display those.  */
969   bool print_unchanged = ((print_section_header
970 			   || print_relocations
971 			   || dump_data_sections != NULL
972 			   || print_notes)
973 			  && (ehdr->e_type == ET_REL
974 			      || elf_contains_chdrs (ebl->elf)));
975 
976   Elf *pure_elf = NULL;
977   Ebl *pure_ebl = ebl;
978   if (print_unchanged)
979     {
980       /* Read the file afresh.  */
981       off_t aroff = elf_getaroff (elf);
982       pure_elf = dwelf_elf_begin (fd);
983       if (aroff > 0)
984 	{
985 	  /* Archive member.  */
986 	  (void) elf_rand (pure_elf, aroff);
987 	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
988 	  elf_end (pure_elf);
989 	  pure_elf = armem;
990 	}
991       if (pure_elf == NULL)
992 	{
993 	  error (0, 0, _("cannot read ELF: %s"), elf_errmsg (-1));
994 	  return;
995 	}
996       pure_ebl = ebl_openbackend (pure_elf);
997       if (pure_ebl == NULL)
998 	goto ebl_error;
999     }
1000 
1001   if (print_file_header)
1002     print_ehdr (ebl, ehdr);
1003   if (print_section_header)
1004     print_shdr (pure_ebl, ehdr);
1005   if (print_program_header)
1006     print_phdr (ebl, ehdr);
1007   if (print_section_groups)
1008     print_scngrp (ebl);
1009   if (print_dynamic_table)
1010     print_dynamic (ebl);
1011   if (print_relocations)
1012     print_relocs (pure_ebl, ehdr);
1013   if (print_histogram)
1014     handle_hash (ebl);
1015   if (print_symbol_table || print_dynsym_table)
1016     print_symtab (ebl, SHT_DYNSYM);
1017   if (print_version_info)
1018     print_verinfo (ebl);
1019   if (print_symbol_table)
1020     print_symtab (ebl, SHT_SYMTAB);
1021   if (print_arch)
1022     print_liblist (ebl);
1023   if (print_arch)
1024     print_attributes (ebl, ehdr);
1025   if (dump_data_sections != NULL)
1026     dump_data (pure_ebl);
1027   if (string_sections != NULL)
1028     dump_strings (ebl);
1029   if ((print_debug_sections | implicit_debug_sections) != 0)
1030     print_debug (dwflmod, ebl, ehdr);
1031   if (print_notes)
1032     handle_notes (pure_ebl, ehdr);
1033   if (print_string_sections)
1034     print_strings (ebl);
1035 
1036   ebl_closebackend (ebl);
1037 
1038   if (pure_ebl != ebl)
1039     {
1040       ebl_closebackend (pure_ebl);
1041       elf_end (pure_elf);
1042     }
1043 }
1044 
1045 
1046 /* Print file type.  */
1047 static void
print_file_type(unsigned short int e_type)1048 print_file_type (unsigned short int e_type)
1049 {
1050   if (likely (e_type <= ET_CORE))
1051     {
1052       static const char *const knowntypes[] =
1053       {
1054 	N_("NONE (None)"),
1055 	N_("REL (Relocatable file)"),
1056 	N_("EXEC (Executable file)"),
1057 	N_("DYN (Shared object file)"),
1058 	N_("CORE (Core file)")
1059       };
1060       puts (_(knowntypes[e_type]));
1061     }
1062   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1063     printf (_("OS Specific: (%x)\n"),  e_type);
1064   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1065     printf (_("Processor Specific: (%x)\n"),  e_type);
1066   else
1067     puts ("???");
1068 }
1069 
1070 
1071 /* Print ELF header.  */
1072 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1073 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1074 {
1075   fputs_unlocked (_("ELF Header:\n  Magic:  "), stdout);
1076   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1077     printf (" %02hhx", ehdr->e_ident[cnt]);
1078 
1079   printf (_("\n  Class:                             %s\n"),
1080 	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1081 	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1082 	  : "\?\?\?");
1083 
1084   printf (_("  Data:                              %s\n"),
1085 	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1086 	  ? "2's complement, little endian"
1087 	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1088 	  ? "2's complement, big endian" : "\?\?\?");
1089 
1090   printf (_("  Ident Version:                     %hhd %s\n"),
1091 	  ehdr->e_ident[EI_VERSION],
1092 	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)")
1093 	  : "(\?\?\?)");
1094 
1095   char buf[512];
1096   printf (_("  OS/ABI:                            %s\n"),
1097 	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1098 
1099   printf (_("  ABI Version:                       %hhd\n"),
1100 	  ehdr->e_ident[EI_ABIVERSION]);
1101 
1102   fputs_unlocked (_("  Type:                              "), stdout);
1103   print_file_type (ehdr->e_type);
1104 
1105   const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1106   if (machine != NULL)
1107     printf (_("  Machine:                           %s\n"), machine);
1108   else
1109     printf (_("  Machine:                           <unknown>: 0x%x\n"),
1110 	    ehdr->e_machine);
1111 
1112   printf (_("  Version:                           %d %s\n"),
1113 	  ehdr->e_version,
1114 	  ehdr->e_version  == EV_CURRENT ? _("(current)") : "(\?\?\?)");
1115 
1116   printf (_("  Entry point address:               %#" PRIx64 "\n"),
1117 	  ehdr->e_entry);
1118 
1119   printf (_("  Start of program headers:          %" PRId64 " %s\n"),
1120 	  ehdr->e_phoff, _("(bytes into file)"));
1121 
1122   printf (_("  Start of section headers:          %" PRId64 " %s\n"),
1123 	  ehdr->e_shoff, _("(bytes into file)"));
1124 
1125   printf (_("  Flags:                             %s\n"),
1126 	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1127 
1128   printf (_("  Size of this header:               %" PRId16 " %s\n"),
1129 	  ehdr->e_ehsize, _("(bytes)"));
1130 
1131   printf (_("  Size of program header entries:    %" PRId16 " %s\n"),
1132 	  ehdr->e_phentsize, _("(bytes)"));
1133 
1134   printf (_("  Number of program headers entries: %" PRId16),
1135 	  ehdr->e_phnum);
1136   if (ehdr->e_phnum == PN_XNUM)
1137     {
1138       GElf_Shdr shdr_mem;
1139       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1140       if (shdr != NULL)
1141 	printf (_(" (%" PRIu32 " in [0].sh_info)"),
1142 		(uint32_t) shdr->sh_info);
1143       else
1144 	fputs_unlocked (_(" ([0] not available)"), stdout);
1145     }
1146   fputc_unlocked ('\n', stdout);
1147 
1148   printf (_("  Size of section header entries:    %" PRId16 " %s\n"),
1149 	  ehdr->e_shentsize, _("(bytes)"));
1150 
1151   printf (_("  Number of section headers entries: %" PRId16),
1152 	  ehdr->e_shnum);
1153   if (ehdr->e_shnum == 0)
1154     {
1155       GElf_Shdr shdr_mem;
1156       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1157       if (shdr != NULL)
1158 	printf (_(" (%" PRIu32 " in [0].sh_size)"),
1159 		(uint32_t) shdr->sh_size);
1160       else
1161 	fputs_unlocked (_(" ([0] not available)"), stdout);
1162     }
1163   fputc_unlocked ('\n', stdout);
1164 
1165   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1166     {
1167       GElf_Shdr shdr_mem;
1168       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1169       if (shdr != NULL)
1170 	/* We managed to get the zeroth section.  */
1171 	snprintf (buf, sizeof (buf), _(" (%" PRIu32 " in [0].sh_link)"),
1172 		  (uint32_t) shdr->sh_link);
1173       else
1174 	{
1175 	  strncpy (buf, _(" ([0] not available)"), sizeof (buf));
1176 	  buf[sizeof (buf) - 1] = '\0';
1177 	}
1178 
1179       printf (_("  Section header string table index: XINDEX%s\n\n"),
1180 	      buf);
1181     }
1182   else
1183     printf (_("  Section header string table index: %" PRId16 "\n\n"),
1184 	    ehdr->e_shstrndx);
1185 }
1186 
1187 
1188 static const char *
get_visibility_type(int value)1189 get_visibility_type (int value)
1190 {
1191   switch (value)
1192     {
1193     case STV_DEFAULT:
1194       return "DEFAULT";
1195     case STV_INTERNAL:
1196       return "INTERNAL";
1197     case STV_HIDDEN:
1198       return "HIDDEN";
1199     case STV_PROTECTED:
1200       return "PROTECTED";
1201     default:
1202       return "???";
1203     }
1204 }
1205 
1206 static const char *
elf_ch_type_name(unsigned int code)1207 elf_ch_type_name (unsigned int code)
1208 {
1209   if (code == 0)
1210     return "NONE";
1211 
1212   if (code == ELFCOMPRESS_ZLIB)
1213     return "ZLIB";
1214 
1215   return "UNKNOWN";
1216 }
1217 
1218 /* Print the section headers.  */
1219 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1220 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1221 {
1222   size_t cnt;
1223   size_t shstrndx;
1224 
1225   if (! print_file_header)
1226     {
1227       size_t sections;
1228       if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
1229 	error (EXIT_FAILURE, 0,
1230 	       _("cannot get number of sections: %s"),
1231 	       elf_errmsg (-1));
1232 
1233       printf (_("\
1234 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1235 \n"),
1236 	      sections, ehdr->e_shoff);
1237     }
1238 
1239   /* Get the section header string table index.  */
1240   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1241     error (EXIT_FAILURE, 0,
1242 	   _("cannot get section header string table index: %s"),
1243 	   elf_errmsg (-1));
1244 
1245   puts (_("Section Headers:"));
1246 
1247   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1248     puts (_("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
1249   else
1250     puts (_("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
1251 
1252   if (print_decompress)
1253     {
1254       if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1255 	puts (_("     [Compression  Size   Al]"));
1256       else
1257 	puts (_("     [Compression  Size     Al]"));
1258     }
1259 
1260   for (cnt = 0; cnt < shnum; ++cnt)
1261     {
1262       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1263 
1264       if (unlikely (scn == NULL))
1265 	error (EXIT_FAILURE, 0, _("cannot get section: %s"),
1266 	       elf_errmsg (-1));
1267 
1268       /* Get the section header.  */
1269       GElf_Shdr shdr_mem;
1270       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1271       if (unlikely (shdr == NULL))
1272 	error (EXIT_FAILURE, 0, _("cannot get section header: %s"),
1273 	       elf_errmsg (-1));
1274 
1275       char flagbuf[20];
1276       char *cp = flagbuf;
1277       if (shdr->sh_flags & SHF_WRITE)
1278 	*cp++ = 'W';
1279       if (shdr->sh_flags & SHF_ALLOC)
1280 	*cp++ = 'A';
1281       if (shdr->sh_flags & SHF_EXECINSTR)
1282 	*cp++ = 'X';
1283       if (shdr->sh_flags & SHF_MERGE)
1284 	*cp++ = 'M';
1285       if (shdr->sh_flags & SHF_STRINGS)
1286 	*cp++ = 'S';
1287       if (shdr->sh_flags & SHF_INFO_LINK)
1288 	*cp++ = 'I';
1289       if (shdr->sh_flags & SHF_LINK_ORDER)
1290 	*cp++ = 'L';
1291       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1292 	*cp++ = 'N';
1293       if (shdr->sh_flags & SHF_GROUP)
1294 	*cp++ = 'G';
1295       if (shdr->sh_flags & SHF_TLS)
1296 	*cp++ = 'T';
1297       if (shdr->sh_flags & SHF_COMPRESSED)
1298 	*cp++ = 'C';
1299       if (shdr->sh_flags & SHF_ORDERED)
1300 	*cp++ = 'O';
1301       if (shdr->sh_flags & SHF_EXCLUDE)
1302 	*cp++ = 'E';
1303       if (shdr->sh_flags & SHF_GNU_RETAIN)
1304 	*cp++ = 'R';
1305       *cp = '\0';
1306 
1307       const char *sname;
1308       char buf[128];
1309       sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1310       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1311 	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1312 	      " %2" PRId64 "\n",
1313 	      cnt, sname,
1314 	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1315 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1316 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1317 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1318 	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1319 	      shdr->sh_addralign);
1320 
1321       if (print_decompress)
1322 	{
1323 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1324 	    {
1325 	      GElf_Chdr chdr;
1326 	      if (gelf_getchdr (scn, &chdr) != NULL)
1327 		printf ("     [ELF %s (%" PRId32 ") %0*" PRIx64
1328 			" %2" PRId64 "]\n",
1329 			elf_ch_type_name (chdr.ch_type),
1330 			chdr.ch_type,
1331 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1332 			chdr.ch_size, chdr.ch_addralign);
1333 	      else
1334 		error (0, 0,
1335 		       _("bad compression header for section %zd: %s"),
1336 		       elf_ndxscn (scn), elf_errmsg (-1));
1337 	    }
1338 	  else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1339 	    {
1340 	      ssize_t size;
1341 	      if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1342 		printf ("     [GNU ZLIB     %0*zx   ]\n",
1343 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1344 	      else
1345 		error (0, 0,
1346 		       _("bad gnu compressed size for section %zd: %s"),
1347 		       elf_ndxscn (scn), elf_errmsg (-1));
1348 	    }
1349 	}
1350     }
1351 
1352   fputc_unlocked ('\n', stdout);
1353 }
1354 
1355 
1356 /* Print the program header.  */
1357 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1358 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1359 {
1360   if (phnum == 0)
1361     /* No program header, this is OK in relocatable objects.  */
1362     return;
1363 
1364   puts (_("Program Headers:"));
1365   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1366     puts (_("\
1367   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
1368   else
1369     puts (_("\
1370   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
1371 
1372   /* Process all program headers.  */
1373   bool has_relro = false;
1374   GElf_Addr relro_from = 0;
1375   GElf_Addr relro_to = 0;
1376   for (size_t cnt = 0; cnt < phnum; ++cnt)
1377     {
1378       char buf[128];
1379       GElf_Phdr mem;
1380       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1381 
1382       /* If for some reason the header cannot be returned show this.  */
1383       if (unlikely (phdr == NULL))
1384 	{
1385 	  puts ("  ???");
1386 	  continue;
1387 	}
1388 
1389       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1390 	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1391 	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1392 	      phdr->p_offset,
1393 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1394 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1395 	      phdr->p_filesz,
1396 	      phdr->p_memsz,
1397 	      phdr->p_flags & PF_R ? 'R' : ' ',
1398 	      phdr->p_flags & PF_W ? 'W' : ' ',
1399 	      phdr->p_flags & PF_X ? 'E' : ' ',
1400 	      phdr->p_align);
1401 
1402       if (phdr->p_type == PT_INTERP)
1403 	{
1404 	  /* If we are sure the file offset is valid then we can show
1405 	     the user the name of the interpreter.  We check whether
1406 	     there is a section at the file offset.  Normally there
1407 	     would be a section called ".interp".  But in separate
1408 	     .debug files it is a NOBITS section (and so doesn't match
1409 	     with gelf_offscn).  Which probably means the offset is
1410 	     not valid another reason could be because the ELF file
1411 	     just doesn't contain any section headers, in that case
1412 	     just play it safe and don't display anything.  */
1413 
1414 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1415 	  GElf_Shdr shdr_mem;
1416 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1417 
1418 	  size_t maxsize;
1419 	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
1420 
1421 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1422 	      && filedata != NULL && phdr->p_offset < maxsize
1423 	      && phdr->p_filesz <= maxsize - phdr->p_offset
1424 	      && memchr (filedata + phdr->p_offset, '\0',
1425 			 phdr->p_filesz) != NULL)
1426 	    printf (_("\t[Requesting program interpreter: %s]\n"),
1427 		    filedata + phdr->p_offset);
1428 	}
1429       else if (phdr->p_type == PT_GNU_RELRO)
1430 	{
1431 	  has_relro = true;
1432 	  relro_from = phdr->p_vaddr;
1433 	  relro_to = relro_from + phdr->p_memsz;
1434 	}
1435     }
1436 
1437   size_t sections;
1438   if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
1439     error (EXIT_FAILURE, 0,
1440            _("cannot get number of sections: %s"),
1441            elf_errmsg (-1));
1442 
1443   if (sections == 0)
1444     /* No sections in the file.  Punt.  */
1445     return;
1446 
1447   /* Get the section header string table index.  */
1448   size_t shstrndx;
1449   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1450     error (EXIT_FAILURE, 0,
1451 	   _("cannot get section header string table index"));
1452 
1453   puts (_("\n Section to Segment mapping:\n  Segment Sections..."));
1454 
1455   for (size_t cnt = 0; cnt < phnum; ++cnt)
1456     {
1457       /* Print the segment number.  */
1458       printf ("   %2.2zu     ", cnt);
1459 
1460       GElf_Phdr phdr_mem;
1461       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1462       /* This must not happen.  */
1463       if (unlikely (phdr == NULL))
1464 	error (EXIT_FAILURE, 0, _("cannot get program header: %s"),
1465 	       elf_errmsg (-1));
1466 
1467       /* Iterate over the sections.  */
1468       bool in_relro = false;
1469       bool in_ro = false;
1470       for (size_t inner = 1; inner < shnum; ++inner)
1471 	{
1472 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1473 	  /* This should not happen.  */
1474 	  if (unlikely (scn == NULL))
1475 	    error (EXIT_FAILURE, 0, _("cannot get section: %s"),
1476 		   elf_errmsg (-1));
1477 
1478 	  /* Get the section header.  */
1479 	  GElf_Shdr shdr_mem;
1480 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1481 	  if (unlikely (shdr == NULL))
1482 	    error (EXIT_FAILURE, 0,
1483 		   _("cannot get section header: %s"),
1484 		   elf_errmsg (-1));
1485 
1486 	  if (shdr->sh_size > 0
1487 	      /* Compare allocated sections by VMA, unallocated
1488 		 sections by file offset.  */
1489 	      && (shdr->sh_flags & SHF_ALLOC
1490 		  ? (shdr->sh_addr >= phdr->p_vaddr
1491 		     && (shdr->sh_addr + shdr->sh_size
1492 			 <= phdr->p_vaddr + phdr->p_memsz))
1493 		  : (shdr->sh_offset >= phdr->p_offset
1494 		     && (shdr->sh_offset + shdr->sh_size
1495 			 <= phdr->p_offset + phdr->p_filesz))))
1496 	    {
1497 	      if (has_relro && !in_relro
1498 		  && shdr->sh_addr >= relro_from
1499 		  && shdr->sh_addr + shdr->sh_size <= relro_to)
1500 		{
1501 		  fputs_unlocked (" [RELRO:", stdout);
1502 		  in_relro = true;
1503 		}
1504 	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1505 		{
1506 		  fputs_unlocked ("]", stdout);
1507 		  in_relro =  false;
1508 		}
1509 	      else if (has_relro && in_relro
1510 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1511 		fputs_unlocked ("] <RELRO:", stdout);
1512 	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1513 		{
1514 		  if (!in_ro)
1515 		    {
1516 		      fputs_unlocked (" [RO:", stdout);
1517 		      in_ro = true;
1518 		    }
1519 		}
1520 	      else
1521 		{
1522 		  /* Determine the segment this section is part of.  */
1523 		  size_t cnt2;
1524 		  GElf_Phdr phdr2_mem;
1525 		  GElf_Phdr *phdr2 = NULL;
1526 		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1527 		    {
1528 		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1529 
1530 		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1531 			  && shdr->sh_addr >= phdr2->p_vaddr
1532 			  && (shdr->sh_addr + shdr->sh_size
1533 			      <= phdr2->p_vaddr + phdr2->p_memsz))
1534 			break;
1535 		    }
1536 
1537 		  if (cnt2 < phnum)
1538 		    {
1539 		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1540 			{
1541 			  fputs_unlocked (" [RO:", stdout);
1542 			  in_ro = true;
1543 			}
1544 		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1545 			{
1546 			  fputs_unlocked ("]", stdout);
1547 			  in_ro = false;
1548 			}
1549 		    }
1550 		}
1551 
1552 	      printf (" %s",
1553 		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1554 
1555 	      /* Signal that this section is only partially covered.  */
1556 	      if (has_relro && in_relro
1557 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1558 		{
1559 		  fputs_unlocked (">", stdout);
1560 		  in_relro =  false;
1561 		}
1562 	    }
1563 	}
1564       if (in_relro || in_ro)
1565 	fputs_unlocked ("]", stdout);
1566 
1567       /* Finish the line.  */
1568       fputc_unlocked ('\n', stdout);
1569     }
1570 }
1571 
1572 
1573 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1574 section_name (Ebl *ebl, GElf_Shdr *shdr)
1575 {
1576   size_t shstrndx;
1577   if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1578     return "???";
1579   return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1580 }
1581 
1582 
1583 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1584 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1585 {
1586   /* Get the data of the section.  */
1587   Elf_Data *data = elf_getdata (scn, NULL);
1588 
1589   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1590   GElf_Shdr symshdr_mem;
1591   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1592   Elf_Data *symdata = elf_getdata (symscn, NULL);
1593 
1594   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1595       || symdata == NULL)
1596     return;
1597 
1598   /* Get the section header string table index.  */
1599   size_t shstrndx;
1600   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1601     error (EXIT_FAILURE, 0,
1602 	   _("cannot get section header string table index"));
1603 
1604   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1605 
1606   GElf_Sym sym_mem;
1607   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1608 
1609   printf ((grpref[0] & GRP_COMDAT)
1610 	  ? ngettext ("\
1611 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1612 		      "\
1613 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1614 		      data->d_size / sizeof (Elf32_Word) - 1)
1615 	  : ngettext ("\
1616 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1617 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1618 		      data->d_size / sizeof (Elf32_Word) - 1),
1619 	  elf_ndxscn (scn),
1620 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1621 	  (sym == NULL ? NULL
1622 	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1623 	  ?: _("<INVALID SYMBOL>"),
1624 	  data->d_size / sizeof (Elf32_Word) - 1);
1625 
1626   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1627     {
1628       GElf_Shdr grpshdr_mem;
1629       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1630 					 &grpshdr_mem);
1631 
1632       const char *str;
1633       printf ("  [%2u] %s\n",
1634 	      grpref[cnt],
1635 	      grpshdr != NULL
1636 	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1637 	      ? str : _("<INVALID SECTION>"));
1638     }
1639 }
1640 
1641 
1642 static void
print_scngrp(Ebl * ebl)1643 print_scngrp (Ebl *ebl)
1644 {
1645   /* Find all relocation sections and handle them.  */
1646   Elf_Scn *scn = NULL;
1647 
1648   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1649     {
1650        /* Handle the section if it is a symbol table.  */
1651       GElf_Shdr shdr_mem;
1652       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1653 
1654       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1655 	{
1656 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1657 	    {
1658 	      if (elf_compress (scn, 0, 0) < 0)
1659 		printf ("WARNING: %s [%zd]\n",
1660 			_("Couldn't uncompress section"),
1661 			elf_ndxscn (scn));
1662 	      shdr = gelf_getshdr (scn, &shdr_mem);
1663 	      if (unlikely (shdr == NULL))
1664 		error (EXIT_FAILURE, 0,
1665 		       _("cannot get section [%zd] header: %s"),
1666 		       elf_ndxscn (scn),
1667 		       elf_errmsg (-1));
1668 	    }
1669 	  handle_scngrp (ebl, scn, shdr);
1670 	}
1671     }
1672 }
1673 
1674 
1675 static const struct flags
1676 {
1677   int mask;
1678   const char *str;
1679 } dt_flags[] =
1680   {
1681     { DF_ORIGIN, "ORIGIN" },
1682     { DF_SYMBOLIC, "SYMBOLIC" },
1683     { DF_TEXTREL, "TEXTREL" },
1684     { DF_BIND_NOW, "BIND_NOW" },
1685     { DF_STATIC_TLS, "STATIC_TLS" }
1686   };
1687 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1688 
1689 static const struct flags dt_flags_1[] =
1690   {
1691     { DF_1_NOW, "NOW" },
1692     { DF_1_GLOBAL, "GLOBAL" },
1693     { DF_1_GROUP, "GROUP" },
1694     { DF_1_NODELETE, "NODELETE" },
1695     { DF_1_LOADFLTR, "LOADFLTR" },
1696     { DF_1_INITFIRST, "INITFIRST" },
1697     { DF_1_NOOPEN, "NOOPEN" },
1698     { DF_1_ORIGIN, "ORIGIN" },
1699     { DF_1_DIRECT, "DIRECT" },
1700     { DF_1_TRANS, "TRANS" },
1701     { DF_1_INTERPOSE, "INTERPOSE" },
1702     { DF_1_NODEFLIB, "NODEFLIB" },
1703     { DF_1_NODUMP, "NODUMP" },
1704     { DF_1_CONFALT, "CONFALT" },
1705     { DF_1_ENDFILTEE, "ENDFILTEE" },
1706     { DF_1_DISPRELDNE, "DISPRELDNE" },
1707     { DF_1_DISPRELPND, "DISPRELPND" },
1708   };
1709 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1710 
1711 static const struct flags dt_feature_1[] =
1712   {
1713     { DTF_1_PARINIT, "PARINIT" },
1714     { DTF_1_CONFEXP, "CONFEXP" }
1715   };
1716 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1717 				  / sizeof (dt_feature_1[0]));
1718 
1719 static const struct flags dt_posflag_1[] =
1720   {
1721     { DF_P1_LAZYLOAD, "LAZYLOAD" },
1722     { DF_P1_GROUPPERM, "GROUPPERM" }
1723   };
1724 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1725 				  / sizeof (dt_posflag_1[0]));
1726 
1727 
1728 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1729 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1730 		int nflags)
1731 {
1732   bool first = true;
1733   int cnt;
1734 
1735   for (cnt = 0; cnt < nflags; ++cnt)
1736     if (d_val & flags[cnt].mask)
1737       {
1738 	if (!first)
1739 	  putchar_unlocked (' ');
1740 	fputs_unlocked (flags[cnt].str, stdout);
1741 	d_val &= ~flags[cnt].mask;
1742 	first = false;
1743       }
1744 
1745   if (d_val != 0)
1746     {
1747       if (!first)
1748 	putchar_unlocked (' ');
1749       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1750     }
1751 
1752   putchar_unlocked ('\n');
1753 }
1754 
1755 
1756 static void
print_dt_flags(int class,GElf_Xword d_val)1757 print_dt_flags (int class, GElf_Xword d_val)
1758 {
1759   print_flags (class, d_val, dt_flags, ndt_flags);
1760 }
1761 
1762 
1763 static void
print_dt_flags_1(int class,GElf_Xword d_val)1764 print_dt_flags_1 (int class, GElf_Xword d_val)
1765 {
1766   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1767 }
1768 
1769 
1770 static void
print_dt_feature_1(int class,GElf_Xword d_val)1771 print_dt_feature_1 (int class, GElf_Xword d_val)
1772 {
1773   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1774 }
1775 
1776 
1777 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1778 print_dt_posflag_1 (int class, GElf_Xword d_val)
1779 {
1780   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1781 }
1782 
1783 
1784 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1785 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1786 {
1787   int class = gelf_getclass (ebl->elf);
1788   GElf_Shdr glink_mem;
1789   GElf_Shdr *glink;
1790   Elf_Data *data;
1791   size_t cnt;
1792   size_t shstrndx;
1793   size_t sh_entsize;
1794 
1795   /* Get the data of the section.  */
1796   data = elf_getdata (scn, NULL);
1797   if (data == NULL)
1798     return;
1799 
1800   /* Get the section header string table index.  */
1801   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1802     error (EXIT_FAILURE, 0,
1803 	   _("cannot get section header string table index"));
1804 
1805   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1806 
1807   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1808   if (glink == NULL)
1809     error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
1810 	   elf_ndxscn (scn));
1811 
1812   printf (ngettext ("\
1813 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1814 		    "\
1815 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1816 		    shdr->sh_size / sh_entsize),
1817 	  (unsigned long int) (shdr->sh_size / sh_entsize),
1818 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1819 	  shdr->sh_offset,
1820 	  (int) shdr->sh_link,
1821 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1822   fputs_unlocked (_("  Type              Value\n"), stdout);
1823 
1824   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1825     {
1826       GElf_Dyn dynmem;
1827       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1828       if (dyn == NULL)
1829 	break;
1830 
1831       char buf[64];
1832       printf ("  %-17s ",
1833 	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1834 
1835       switch (dyn->d_tag)
1836 	{
1837 	case DT_NULL:
1838 	case DT_DEBUG:
1839 	case DT_BIND_NOW:
1840 	case DT_TEXTREL:
1841 	  /* No further output.  */
1842 	  fputc_unlocked ('\n', stdout);
1843 	  break;
1844 
1845 	case DT_NEEDED:
1846 	  printf (_("Shared library: [%s]\n"),
1847 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1848 	  break;
1849 
1850 	case DT_SONAME:
1851 	  printf (_("Library soname: [%s]\n"),
1852 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1853 	  break;
1854 
1855 	case DT_RPATH:
1856 	  printf (_("Library rpath: [%s]\n"),
1857 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1858 	  break;
1859 
1860 	case DT_RUNPATH:
1861 	  printf (_("Library runpath: [%s]\n"),
1862 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1863 	  break;
1864 
1865 	case DT_PLTRELSZ:
1866 	case DT_RELASZ:
1867 	case DT_STRSZ:
1868 	case DT_RELSZ:
1869 	case DT_RELAENT:
1870 	case DT_SYMENT:
1871 	case DT_RELENT:
1872 	case DT_PLTPADSZ:
1873 	case DT_MOVEENT:
1874 	case DT_MOVESZ:
1875 	case DT_INIT_ARRAYSZ:
1876 	case DT_FINI_ARRAYSZ:
1877 	case DT_SYMINSZ:
1878 	case DT_SYMINENT:
1879 	case DT_GNU_CONFLICTSZ:
1880 	case DT_GNU_LIBLISTSZ:
1881 	  printf (_("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1882 	  break;
1883 
1884 	case DT_VERDEFNUM:
1885 	case DT_VERNEEDNUM:
1886 	case DT_RELACOUNT:
1887 	case DT_RELCOUNT:
1888 	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
1889 	  break;
1890 
1891 	case DT_PLTREL:;
1892 	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1893 						      NULL, 0);
1894 	  puts (tagname ?: "???");
1895 	  break;
1896 
1897 	case DT_FLAGS:
1898 	  print_dt_flags (class, dyn->d_un.d_val);
1899 	  break;
1900 
1901 	case DT_FLAGS_1:
1902 	  print_dt_flags_1 (class, dyn->d_un.d_val);
1903 	  break;
1904 
1905 	case DT_FEATURE_1:
1906 	  print_dt_feature_1 (class, dyn->d_un.d_val);
1907 	  break;
1908 
1909 	case DT_POSFLAG_1:
1910 	  print_dt_posflag_1 (class, dyn->d_un.d_val);
1911 	  break;
1912 
1913 	default:
1914 	  printf ("%#0*" PRIx64 "\n",
1915 		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1916 	  break;
1917 	}
1918     }
1919 }
1920 
1921 
1922 /* Print the dynamic segment.  */
1923 static void
print_dynamic(Ebl * ebl)1924 print_dynamic (Ebl *ebl)
1925 {
1926   for (size_t i = 0; i < phnum; ++i)
1927     {
1928       GElf_Phdr phdr_mem;
1929       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1930 
1931       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1932 	{
1933 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1934 	  GElf_Shdr shdr_mem;
1935 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1936 	  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1937 	    handle_dynamic (ebl, scn, shdr);
1938 	  break;
1939 	}
1940     }
1941 }
1942 
1943 
1944 /* Print relocations.  */
1945 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1946 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1947 {
1948   /* Find all relocation sections and handle them.  */
1949   Elf_Scn *scn = NULL;
1950 
1951   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1952     {
1953        /* Handle the section if it is a symbol table.  */
1954       GElf_Shdr shdr_mem;
1955       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1956 
1957       if (likely (shdr != NULL))
1958 	{
1959 	  if (shdr->sh_type == SHT_REL)
1960 	    handle_relocs_rel (ebl, ehdr, scn, shdr);
1961 	  else if (shdr->sh_type == SHT_RELA)
1962 	    handle_relocs_rela (ebl, ehdr, scn, shdr);
1963 	}
1964     }
1965 }
1966 
1967 
1968 /* Handle a relocation section.  */
1969 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1970 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1971 {
1972   int class = gelf_getclass (ebl->elf);
1973   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1974   int nentries = shdr->sh_size / sh_entsize;
1975 
1976   /* Get the data of the section.  */
1977   Elf_Data *data = elf_getdata (scn, NULL);
1978   if (data == NULL)
1979     return;
1980 
1981   /* Get the symbol table information.  */
1982   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1983   GElf_Shdr symshdr_mem;
1984   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1985   Elf_Data *symdata = elf_getdata (symscn, NULL);
1986 
1987   /* Get the section header of the section the relocations are for.  */
1988   GElf_Shdr destshdr_mem;
1989   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1990 				      &destshdr_mem);
1991 
1992   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1993     {
1994       printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1995 	      shdr->sh_offset);
1996       return;
1997     }
1998 
1999   /* Search for the optional extended section index table.  */
2000   Elf_Data *xndxdata = NULL;
2001   int xndxscnidx = elf_scnshndx (scn);
2002   if (unlikely (xndxscnidx > 0))
2003     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2004 
2005   /* Get the section header string table index.  */
2006   size_t shstrndx;
2007   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2008     error (EXIT_FAILURE, 0,
2009 	   _("cannot get section header string table index"));
2010 
2011   if (shdr->sh_info != 0)
2012     printf (ngettext ("\
2013 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2014 		    "\
2015 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2016 		      nentries),
2017 	    elf_ndxscn (scn),
2018 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2019 	    (unsigned int) shdr->sh_info,
2020 	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2021 	    shdr->sh_offset,
2022 	    nentries);
2023   else
2024     /* The .rel.dyn section does not refer to a specific section but
2025        instead of section index zero.  Do not try to print a section
2026        name.  */
2027     printf (ngettext ("\
2028 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2029 		    "\
2030 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2031 		      nentries),
2032 	    (unsigned int) elf_ndxscn (scn),
2033 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2034 	    shdr->sh_offset,
2035 	    nentries);
2036   fputs_unlocked (class == ELFCLASS32
2037 		  ? _("\
2038   Offset      Type                 Value       Name\n")
2039 		  : _("\
2040   Offset              Type                 Value               Name\n"),
2041 	 stdout);
2042 
2043   int is_statically_linked = 0;
2044   for (int cnt = 0; cnt < nentries; ++cnt)
2045     {
2046       GElf_Rel relmem;
2047       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2048       if (likely (rel != NULL))
2049 	{
2050 	  char buf[128];
2051 	  GElf_Sym symmem;
2052 	  Elf32_Word xndx;
2053 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2054 					    GELF_R_SYM (rel->r_info),
2055 					    &symmem, &xndx);
2056 	  if (unlikely (sym == NULL))
2057 	    {
2058 	      /* As a special case we have to handle relocations in static
2059 		 executables.  This only happens for IRELATIVE relocations
2060 		 (so far).  There is no symbol table.  */
2061 	      if (is_statically_linked == 0)
2062 		{
2063 		  /* Find the program header and look for a PT_INTERP entry. */
2064 		  is_statically_linked = -1;
2065 		  if (ehdr->e_type == ET_EXEC)
2066 		    {
2067 		      is_statically_linked = 1;
2068 
2069 		      for (size_t inner = 0; inner < phnum; ++inner)
2070 			{
2071 			  GElf_Phdr phdr_mem;
2072 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2073 							  &phdr_mem);
2074 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2075 			    {
2076 			      is_statically_linked = -1;
2077 			      break;
2078 			    }
2079 			}
2080 		    }
2081 		}
2082 
2083 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2084 		printf ("\
2085   %#0*" PRIx64 "  %-20s %*s  %s\n",
2086 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2087 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2088 			/* Avoid the leading R_ which isn't carrying any
2089 			   information.  */
2090 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2091 					       buf, sizeof (buf)) + 2
2092 			: _("<INVALID RELOC>"),
2093 			class == ELFCLASS32 ? 10 : 18, "",
2094 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2095 	      else
2096 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
2097 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2098 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2099 			/* Avoid the leading R_ which isn't carrying any
2100 			   information.  */
2101 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2102 					       buf, sizeof (buf)) + 2
2103 			: _("<INVALID RELOC>"),
2104 			_("INVALID SYMBOL"),
2105 			(long int) GELF_R_SYM (rel->r_info));
2106 	    }
2107 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2108 	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2109 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2110 		    likely (ebl_reloc_type_check (ebl,
2111 						  GELF_R_TYPE (rel->r_info)))
2112 		    /* Avoid the leading R_ which isn't carrying any
2113 		       information.  */
2114 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2115 					   buf, sizeof (buf)) + 2
2116 		    : _("<INVALID RELOC>"),
2117 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2118 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2119 	  else
2120 	    {
2121 	      /* This is a relocation against a STT_SECTION symbol.  */
2122 	      GElf_Shdr secshdr_mem;
2123 	      GElf_Shdr *secshdr;
2124 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2125 						  sym->st_shndx == SHN_XINDEX
2126 						  ? xndx : sym->st_shndx),
2127 				      &secshdr_mem);
2128 
2129 	      if (unlikely (secshdr == NULL))
2130 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
2131 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2132 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2133 			/* Avoid the leading R_ which isn't carrying any
2134 			   information.  */
2135 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2136 					       buf, sizeof (buf)) + 2
2137 			: _("<INVALID RELOC>"),
2138 			_("INVALID SECTION"),
2139 			(long int) (sym->st_shndx == SHN_XINDEX
2140 				    ? xndx : sym->st_shndx));
2141 	      else
2142 		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2143 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2144 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2145 			/* Avoid the leading R_ which isn't carrying any
2146 			   information.  */
2147 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2148 					       buf, sizeof (buf)) + 2
2149 			: _("<INVALID RELOC>"),
2150 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2151 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2152 	    }
2153 	}
2154     }
2155 }
2156 
2157 
2158 /* Handle a relocation section.  */
2159 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2160 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2161 {
2162   int class = gelf_getclass (ebl->elf);
2163   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2164   int nentries = shdr->sh_size / sh_entsize;
2165 
2166   /* Get the data of the section.  */
2167   Elf_Data *data = elf_getdata (scn, NULL);
2168   if (data == NULL)
2169     return;
2170 
2171   /* Get the symbol table information.  */
2172   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2173   GElf_Shdr symshdr_mem;
2174   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2175   Elf_Data *symdata = elf_getdata (symscn, NULL);
2176 
2177   /* Get the section header of the section the relocations are for.  */
2178   GElf_Shdr destshdr_mem;
2179   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2180 				      &destshdr_mem);
2181 
2182   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2183     {
2184       printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2185 	      shdr->sh_offset);
2186       return;
2187     }
2188 
2189   /* Search for the optional extended section index table.  */
2190   Elf_Data *xndxdata = NULL;
2191   int xndxscnidx = elf_scnshndx (scn);
2192   if (unlikely (xndxscnidx > 0))
2193     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2194 
2195   /* Get the section header string table index.  */
2196   size_t shstrndx;
2197   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2198     error (EXIT_FAILURE, 0,
2199 	   _("cannot get section header string table index"));
2200 
2201   if (shdr->sh_info != 0)
2202     printf (ngettext ("\
2203 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2204 		    "\
2205 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2206 		    nentries),
2207 	  elf_ndxscn (scn),
2208 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2209 	  (unsigned int) shdr->sh_info,
2210 	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2211 	  shdr->sh_offset,
2212 	  nentries);
2213   else
2214     /* The .rela.dyn section does not refer to a specific section but
2215        instead of section index zero.  Do not try to print a section
2216        name.  */
2217     printf (ngettext ("\
2218 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2219 		    "\
2220 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2221 		      nentries),
2222 	    (unsigned int) elf_ndxscn (scn),
2223 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2224 	    shdr->sh_offset,
2225 	    nentries);
2226   fputs_unlocked (class == ELFCLASS32
2227 		  ? _("\
2228   Offset      Type            Value       Addend Name\n")
2229 		  : _("\
2230   Offset              Type            Value               Addend Name\n"),
2231 		  stdout);
2232 
2233   int is_statically_linked = 0;
2234   for (int cnt = 0; cnt < nentries; ++cnt)
2235     {
2236       GElf_Rela relmem;
2237       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2238       if (likely (rel != NULL))
2239 	{
2240 	  char buf[64];
2241 	  GElf_Sym symmem;
2242 	  Elf32_Word xndx;
2243 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2244 					    GELF_R_SYM (rel->r_info),
2245 					    &symmem, &xndx);
2246 
2247 	  if (unlikely (sym == NULL))
2248 	    {
2249 	      /* As a special case we have to handle relocations in static
2250 		 executables.  This only happens for IRELATIVE relocations
2251 		 (so far).  There is no symbol table.  */
2252 	      if (is_statically_linked == 0)
2253 		{
2254 		  /* Find the program header and look for a PT_INTERP entry. */
2255 		  is_statically_linked = -1;
2256 		  if (ehdr->e_type == ET_EXEC)
2257 		    {
2258 		      is_statically_linked = 1;
2259 
2260 		      for (size_t inner = 0; inner < phnum; ++inner)
2261 			{
2262 			  GElf_Phdr phdr_mem;
2263 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2264 							  &phdr_mem);
2265 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2266 			    {
2267 			      is_statically_linked = -1;
2268 			      break;
2269 			    }
2270 			}
2271 		    }
2272 		}
2273 
2274 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2275 		printf ("\
2276   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
2277 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2278 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2279 			/* Avoid the leading R_ which isn't carrying any
2280 			   information.  */
2281 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2282 					       buf, sizeof (buf)) + 2
2283 			: _("<INVALID RELOC>"),
2284 			class == ELFCLASS32 ? 10 : 18, "",
2285 			rel->r_addend,
2286 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2287 	      else
2288 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2289 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2290 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2291 			/* Avoid the leading R_ which isn't carrying any
2292 			   information.  */
2293 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2294 					       buf, sizeof (buf)) + 2
2295 			: _("<INVALID RELOC>"),
2296 			_("INVALID SYMBOL"),
2297 			(long int) GELF_R_SYM (rel->r_info));
2298 	    }
2299 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2300 	    printf ("\
2301   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2302 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2303 		    likely (ebl_reloc_type_check (ebl,
2304 						  GELF_R_TYPE (rel->r_info)))
2305 		    /* Avoid the leading R_ which isn't carrying any
2306 		       information.  */
2307 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2308 					   buf, sizeof (buf)) + 2
2309 		    : _("<INVALID RELOC>"),
2310 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2311 		    rel->r_addend,
2312 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2313 	  else
2314 	    {
2315 	      /* This is a relocation against a STT_SECTION symbol.  */
2316 	      GElf_Shdr secshdr_mem;
2317 	      GElf_Shdr *secshdr;
2318 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2319 						  sym->st_shndx == SHN_XINDEX
2320 						  ? xndx : sym->st_shndx),
2321 				      &secshdr_mem);
2322 
2323 	      if (unlikely (secshdr == NULL))
2324 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2325 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2326 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2327 			/* Avoid the leading R_ which isn't carrying any
2328 			   information.  */
2329 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2330 					       buf, sizeof (buf)) + 2
2331 			: _("<INVALID RELOC>"),
2332 			_("INVALID SECTION"),
2333 			(long int) (sym->st_shndx == SHN_XINDEX
2334 				    ? xndx : sym->st_shndx));
2335 	      else
2336 		printf ("\
2337   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2338 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2339 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2340 			/* Avoid the leading R_ which isn't carrying any
2341 			   information.  */
2342 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2343 					       buf, sizeof (buf)) + 2
2344 			: _("<INVALID RELOC>"),
2345 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2346 			rel->r_addend,
2347 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2348 	    }
2349 	}
2350     }
2351 }
2352 
2353 
2354 /* Print the program header.  */
2355 static void
print_symtab(Ebl * ebl,int type)2356 print_symtab (Ebl *ebl, int type)
2357 {
2358   /* Find the symbol table(s).  For this we have to search through the
2359      section table.  */
2360   Elf_Scn *scn = NULL;
2361 
2362   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2363     {
2364       /* Handle the section if it is a symbol table.  */
2365       GElf_Shdr shdr_mem;
2366       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2367 
2368       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2369 	{
2370 	  if (symbol_table_section != NULL)
2371 	    {
2372 	      /* Get the section header string table index.  */
2373 	      size_t shstrndx;
2374 	      const char *sname;
2375 	      if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2376 		error (EXIT_FAILURE, 0,
2377 		       _("cannot get section header string table index"));
2378 	      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2379 	      if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2380 		continue;
2381 	    }
2382 
2383 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2384 	    {
2385 	      if (elf_compress (scn, 0, 0) < 0)
2386 		printf ("WARNING: %s [%zd]\n",
2387 			_("Couldn't uncompress section"),
2388 			elf_ndxscn (scn));
2389 	      shdr = gelf_getshdr (scn, &shdr_mem);
2390 	      if (unlikely (shdr == NULL))
2391 		error (EXIT_FAILURE, 0,
2392 		       _("cannot get section [%zd] header: %s"),
2393 		       elf_ndxscn (scn), elf_errmsg (-1));
2394 	    }
2395 	  handle_symtab (ebl, scn, shdr);
2396 	}
2397     }
2398 }
2399 
2400 
2401 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2402 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2403 {
2404   Elf_Data *versym_data = NULL;
2405   Elf_Data *verneed_data = NULL;
2406   Elf_Data *verdef_data = NULL;
2407   Elf_Data *xndx_data = NULL;
2408   int class = gelf_getclass (ebl->elf);
2409   Elf32_Word verneed_stridx = 0;
2410   Elf32_Word verdef_stridx = 0;
2411 
2412   /* Get the data of the section.  */
2413   Elf_Data *data = elf_getdata (scn, NULL);
2414   if (data == NULL)
2415     return;
2416 
2417   /* Find out whether we have other sections we might need.  */
2418   Elf_Scn *runscn = NULL;
2419   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2420     {
2421       GElf_Shdr runshdr_mem;
2422       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2423 
2424       if (likely (runshdr != NULL))
2425 	{
2426 	  if (runshdr->sh_type == SHT_GNU_versym
2427 	      && runshdr->sh_link == elf_ndxscn (scn))
2428 	    /* Bingo, found the version information.  Now get the data.  */
2429 	    versym_data = elf_getdata (runscn, NULL);
2430 	  else if (runshdr->sh_type == SHT_GNU_verneed)
2431 	    {
2432 	      /* This is the information about the needed versions.  */
2433 	      verneed_data = elf_getdata (runscn, NULL);
2434 	      verneed_stridx = runshdr->sh_link;
2435 	    }
2436 	  else if (runshdr->sh_type == SHT_GNU_verdef)
2437 	    {
2438 	      /* This is the information about the defined versions.  */
2439 	      verdef_data = elf_getdata (runscn, NULL);
2440 	      verdef_stridx = runshdr->sh_link;
2441 	    }
2442 	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2443 	      && runshdr->sh_link == elf_ndxscn (scn))
2444 	    /* Extended section index.  */
2445 	    xndx_data = elf_getdata (runscn, NULL);
2446 	}
2447     }
2448 
2449   /* Get the section header string table index.  */
2450   size_t shstrndx;
2451   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2452     error (EXIT_FAILURE, 0,
2453 	   _("cannot get section header string table index"));
2454 
2455   GElf_Shdr glink_mem;
2456   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2457 				   &glink_mem);
2458   if (glink == NULL)
2459     error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
2460 	   elf_ndxscn (scn));
2461 
2462   /* Now we can compute the number of entries in the section.  */
2463   unsigned int nsyms = data->d_size / (class == ELFCLASS32
2464 				       ? sizeof (Elf32_Sym)
2465 				       : sizeof (Elf64_Sym));
2466 
2467   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2468 		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
2469 		    nsyms),
2470 	  (unsigned int) elf_ndxscn (scn),
2471 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2472   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
2473 		    " %lu local symbols  String table: [%2u] '%s'\n",
2474 		    shdr->sh_info),
2475 	  (unsigned long int) shdr->sh_info,
2476 	  (unsigned int) shdr->sh_link,
2477 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2478 
2479   fputs_unlocked (class == ELFCLASS32
2480 		  ? _("\
2481   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
2482 		  : _("\
2483   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
2484 		  stdout);
2485 
2486   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2487     {
2488       char typebuf[64];
2489       char bindbuf[64];
2490       char scnbuf[64];
2491       Elf32_Word xndx;
2492       GElf_Sym sym_mem;
2493       GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2494 
2495       if (unlikely (sym == NULL))
2496 	continue;
2497 
2498       /* Determine the real section index.  */
2499       if (likely (sym->st_shndx != SHN_XINDEX))
2500 	xndx = sym->st_shndx;
2501 
2502       printf (_("\
2503 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2504 	      cnt,
2505 	      class == ELFCLASS32 ? 8 : 16,
2506 	      sym->st_value,
2507 	      sym->st_size,
2508 	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2509 				    typebuf, sizeof (typebuf)),
2510 	      ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2511 				       bindbuf, sizeof (bindbuf)),
2512 	      get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2513 	      ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2514 				sizeof (scnbuf), NULL, shnum),
2515 	      elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2516 
2517       if (versym_data != NULL)
2518 	{
2519 	  /* Get the version information.  */
2520 	  GElf_Versym versym_mem;
2521 	  GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2522 
2523 	  if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2524 	    {
2525 	      bool is_nobits = false;
2526 	      bool check_def = xndx != SHN_UNDEF;
2527 
2528 	      if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2529 		{
2530 		  GElf_Shdr symshdr_mem;
2531 		  GElf_Shdr *symshdr =
2532 		    gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2533 
2534 		  is_nobits = (symshdr != NULL
2535 			       && symshdr->sh_type == SHT_NOBITS);
2536 		}
2537 
2538 	      if (is_nobits || ! check_def)
2539 		{
2540 		  /* We must test both.  */
2541 		  GElf_Vernaux vernaux_mem;
2542 		  GElf_Vernaux *vernaux = NULL;
2543 		  size_t vn_offset = 0;
2544 
2545 		  GElf_Verneed verneed_mem;
2546 		  GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2547 							   &verneed_mem);
2548 		  while (verneed != NULL)
2549 		    {
2550 		      size_t vna_offset = vn_offset;
2551 
2552 		      vernaux = gelf_getvernaux (verneed_data,
2553 						 vna_offset += verneed->vn_aux,
2554 						 &vernaux_mem);
2555 		      while (vernaux != NULL
2556 			     && vernaux->vna_other != *versym
2557 			     && vernaux->vna_next != 0)
2558 			{
2559 			  /* Update the offset.  */
2560 			  vna_offset += vernaux->vna_next;
2561 
2562 			  vernaux = (vernaux->vna_next == 0
2563 				     ? NULL
2564 				     : gelf_getvernaux (verneed_data,
2565 							vna_offset,
2566 							&vernaux_mem));
2567 			}
2568 
2569 		      /* Check whether we found the version.  */
2570 		      if (vernaux != NULL && vernaux->vna_other == *versym)
2571 			/* Found it.  */
2572 			break;
2573 
2574 		      vn_offset += verneed->vn_next;
2575 		      verneed = (verneed->vn_next == 0
2576 				 ? NULL
2577 				 : gelf_getverneed (verneed_data, vn_offset,
2578 						    &verneed_mem));
2579 		    }
2580 
2581 		  if (vernaux != NULL && vernaux->vna_other == *versym)
2582 		    {
2583 		      printf ("@%s (%u)",
2584 			      elf_strptr (ebl->elf, verneed_stridx,
2585 					  vernaux->vna_name),
2586 			      (unsigned int) vernaux->vna_other);
2587 		      check_def = 0;
2588 		    }
2589 		  else if (unlikely (! is_nobits))
2590 		    error (0, 0, _("bad dynamic symbol"));
2591 		  else
2592 		    check_def = 1;
2593 		}
2594 
2595 	      if (check_def && *versym != 0x8001)
2596 		{
2597 		  /* We must test both.  */
2598 		  size_t vd_offset = 0;
2599 
2600 		  GElf_Verdef verdef_mem;
2601 		  GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2602 							&verdef_mem);
2603 		  while (verdef != NULL)
2604 		    {
2605 		      if (verdef->vd_ndx == (*versym & 0x7fff))
2606 			/* Found the definition.  */
2607 			break;
2608 
2609 		      vd_offset += verdef->vd_next;
2610 		      verdef = (verdef->vd_next == 0
2611 				? NULL
2612 				: gelf_getverdef (verdef_data, vd_offset,
2613 						  &verdef_mem));
2614 		    }
2615 
2616 		  if (verdef != NULL)
2617 		    {
2618 		      GElf_Verdaux verdaux_mem;
2619 		      GElf_Verdaux *verdaux
2620 			= gelf_getverdaux (verdef_data,
2621 					   vd_offset + verdef->vd_aux,
2622 					   &verdaux_mem);
2623 
2624 		      if (verdaux != NULL)
2625 			printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2626 				elf_strptr (ebl->elf, verdef_stridx,
2627 					    verdaux->vda_name));
2628 		    }
2629 		}
2630 	    }
2631 	}
2632 
2633       putchar_unlocked ('\n');
2634     }
2635 }
2636 
2637 
2638 /* Print version information.  */
2639 static void
print_verinfo(Ebl * ebl)2640 print_verinfo (Ebl *ebl)
2641 {
2642   /* Find the version information sections.  For this we have to
2643      search through the section table.  */
2644   Elf_Scn *scn = NULL;
2645 
2646   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2647     {
2648       /* Handle the section if it is part of the versioning handling.  */
2649       GElf_Shdr shdr_mem;
2650       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2651 
2652       if (likely (shdr != NULL))
2653 	{
2654 	  if (shdr->sh_type == SHT_GNU_verneed)
2655 	    handle_verneed (ebl, scn, shdr);
2656 	  else if (shdr->sh_type == SHT_GNU_verdef)
2657 	    handle_verdef (ebl, scn, shdr);
2658 	  else if (shdr->sh_type == SHT_GNU_versym)
2659 	    handle_versym (ebl, scn, shdr);
2660 	}
2661     }
2662 }
2663 
2664 
2665 static const char *
get_ver_flags(unsigned int flags)2666 get_ver_flags (unsigned int flags)
2667 {
2668   static char buf[32];
2669   char *endp;
2670 
2671   if (flags == 0)
2672     return _("none");
2673 
2674   if (flags & VER_FLG_BASE)
2675     endp = stpcpy (buf, "BASE ");
2676   else
2677     endp = buf;
2678 
2679   if (flags & VER_FLG_WEAK)
2680     {
2681       if (endp != buf)
2682 	endp = stpcpy (endp, "| ");
2683 
2684       endp = stpcpy (endp, "WEAK ");
2685     }
2686 
2687   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2688     {
2689       strncpy (endp, _("| <unknown>"), buf + sizeof (buf) - endp);
2690       buf[sizeof (buf) - 1] = '\0';
2691     }
2692 
2693   return buf;
2694 }
2695 
2696 
2697 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2698 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2699 {
2700   int class = gelf_getclass (ebl->elf);
2701 
2702   /* Get the data of the section.  */
2703   Elf_Data *data = elf_getdata (scn, NULL);
2704   if (data == NULL)
2705     return;
2706 
2707   /* Get the section header string table index.  */
2708   size_t shstrndx;
2709   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2710     error (EXIT_FAILURE, 0,
2711 	   _("cannot get section header string table index"));
2712 
2713   GElf_Shdr glink_mem;
2714   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2715 				   &glink_mem);
2716   if (glink == NULL)
2717     error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
2718 	   elf_ndxscn (scn));
2719 
2720   printf (ngettext ("\
2721 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2722 		    "\
2723 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2724 		    shdr->sh_info),
2725 	  (unsigned int) elf_ndxscn (scn),
2726 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2727 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2728 	  shdr->sh_offset,
2729 	  (unsigned int) shdr->sh_link,
2730 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2731 
2732   unsigned int offset = 0;
2733   for (int cnt = shdr->sh_info; --cnt >= 0; )
2734     {
2735       /* Get the data at the next offset.  */
2736       GElf_Verneed needmem;
2737       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2738       if (unlikely (need == NULL))
2739 	break;
2740 
2741       printf (_("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
2742 	      offset, (unsigned short int) need->vn_version,
2743 	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2744 	      (unsigned short int) need->vn_cnt);
2745 
2746       unsigned int auxoffset = offset + need->vn_aux;
2747       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2748 	{
2749 	  GElf_Vernaux auxmem;
2750 	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2751 	  if (unlikely (aux == NULL))
2752 	    break;
2753 
2754 	  printf (_("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
2755 		  auxoffset,
2756 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2757 		  get_ver_flags (aux->vna_flags),
2758 		  (unsigned short int) aux->vna_other);
2759 
2760 	  if (aux->vna_next == 0)
2761 	    break;
2762 
2763 	  auxoffset += aux->vna_next;
2764 	}
2765 
2766       /* Find the next offset.  */
2767       if (need->vn_next == 0)
2768 	break;
2769 
2770       offset += need->vn_next;
2771     }
2772 }
2773 
2774 
2775 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2776 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2777 {
2778   /* Get the data of the section.  */
2779   Elf_Data *data = elf_getdata (scn, NULL);
2780   if (data == NULL)
2781     return;
2782 
2783   /* Get the section header string table index.  */
2784   size_t shstrndx;
2785   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2786     error (EXIT_FAILURE, 0,
2787 	   _("cannot get section header string table index"));
2788 
2789   GElf_Shdr glink_mem;
2790   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2791 				   &glink_mem);
2792   if (glink == NULL)
2793     error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
2794 	   elf_ndxscn (scn));
2795 
2796   int class = gelf_getclass (ebl->elf);
2797   printf (ngettext ("\
2798 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2799 		    "\
2800 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2801 		    shdr->sh_info),
2802 	  (unsigned int) elf_ndxscn (scn),
2803 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2804 	  shdr->sh_info,
2805 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2806 	  shdr->sh_offset,
2807 	  (unsigned int) shdr->sh_link,
2808 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2809 
2810   unsigned int offset = 0;
2811   for (int cnt = shdr->sh_info; --cnt >= 0; )
2812     {
2813       /* Get the data at the next offset.  */
2814       GElf_Verdef defmem;
2815       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2816       if (unlikely (def == NULL))
2817 	break;
2818 
2819       unsigned int auxoffset = offset + def->vd_aux;
2820       GElf_Verdaux auxmem;
2821       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2822       if (unlikely (aux == NULL))
2823 	break;
2824 
2825       printf (_("\
2826   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
2827 	      offset, def->vd_version,
2828 	      get_ver_flags (def->vd_flags),
2829 	      def->vd_ndx,
2830 	      def->vd_cnt,
2831 	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2832 
2833       auxoffset += aux->vda_next;
2834       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2835 	{
2836 	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
2837 	  if (unlikely (aux == NULL))
2838 	    break;
2839 
2840 	  printf (_("  %#06x: Parent %d: %s\n"),
2841 		  auxoffset, cnt2,
2842 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2843 
2844 	  if (aux->vda_next == 0)
2845 	    break;
2846 
2847 	  auxoffset += aux->vda_next;
2848 	}
2849 
2850       /* Find the next offset.  */
2851       if (def->vd_next == 0)
2852 	break;
2853       offset += def->vd_next;
2854     }
2855 }
2856 
2857 
2858 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2859 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2860 {
2861   int class = gelf_getclass (ebl->elf);
2862   const char **vername;
2863   const char **filename;
2864 
2865   /* Get the data of the section.  */
2866   Elf_Data *data = elf_getdata (scn, NULL);
2867   if (data == NULL)
2868     return;
2869 
2870   /* Get the section header string table index.  */
2871   size_t shstrndx;
2872   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2873     error (EXIT_FAILURE, 0,
2874 	   _("cannot get section header string table index"));
2875 
2876   /* We have to find the version definition section and extract the
2877      version names.  */
2878   Elf_Scn *defscn = NULL;
2879   Elf_Scn *needscn = NULL;
2880 
2881   Elf_Scn *verscn = NULL;
2882   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2883     {
2884       GElf_Shdr vershdr_mem;
2885       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2886 
2887       if (likely (vershdr != NULL))
2888 	{
2889 	  if (vershdr->sh_type == SHT_GNU_verdef)
2890 	    defscn = verscn;
2891 	  else if (vershdr->sh_type == SHT_GNU_verneed)
2892 	    needscn = verscn;
2893 	}
2894     }
2895 
2896   size_t nvername;
2897   if (defscn != NULL || needscn != NULL)
2898     {
2899       /* We have a version information (better should have).  Now get
2900 	 the version names.  First find the maximum version number.  */
2901       nvername = 0;
2902       if (defscn != NULL)
2903 	{
2904 	  /* Run through the version definitions and find the highest
2905 	     index.  */
2906 	  unsigned int offset = 0;
2907 	  Elf_Data *defdata;
2908 	  GElf_Shdr defshdrmem;
2909 	  GElf_Shdr *defshdr;
2910 
2911 	  defdata = elf_getdata (defscn, NULL);
2912 	  if (unlikely (defdata == NULL))
2913 	    return;
2914 
2915 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
2916 	  if (unlikely (defshdr == NULL))
2917 	    return;
2918 
2919 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2920 	    {
2921 	      GElf_Verdef defmem;
2922 	      GElf_Verdef *def;
2923 
2924 	      /* Get the data at the next offset.  */
2925 	      def = gelf_getverdef (defdata, offset, &defmem);
2926 	      if (unlikely (def == NULL))
2927 		break;
2928 
2929 	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2930 
2931 	      if (def->vd_next == 0)
2932 		break;
2933 	      offset += def->vd_next;
2934 	    }
2935 	}
2936       if (needscn != NULL)
2937 	{
2938 	  unsigned int offset = 0;
2939 	  Elf_Data *needdata;
2940 	  GElf_Shdr needshdrmem;
2941 	  GElf_Shdr *needshdr;
2942 
2943 	  needdata = elf_getdata (needscn, NULL);
2944 	  if (unlikely (needdata == NULL))
2945 	    return;
2946 
2947 	  needshdr = gelf_getshdr (needscn, &needshdrmem);
2948 	  if (unlikely (needshdr == NULL))
2949 	    return;
2950 
2951 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2952 	    {
2953 	      GElf_Verneed needmem;
2954 	      GElf_Verneed *need;
2955 	      unsigned int auxoffset;
2956 	      int cnt2;
2957 
2958 	      /* Get the data at the next offset.  */
2959 	      need = gelf_getverneed (needdata, offset, &needmem);
2960 	      if (unlikely (need == NULL))
2961 		break;
2962 
2963 	      /* Run through the auxiliary entries.  */
2964 	      auxoffset = offset + need->vn_aux;
2965 	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2966 		{
2967 		  GElf_Vernaux auxmem;
2968 		  GElf_Vernaux *aux;
2969 
2970 		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2971 		  if (unlikely (aux == NULL))
2972 		    break;
2973 
2974 		  nvername = MAX (nvername,
2975 				  (size_t) (aux->vna_other & 0x7fff));
2976 
2977 		  if (aux->vna_next == 0)
2978 		    break;
2979 		  auxoffset += aux->vna_next;
2980 		}
2981 
2982 	      if (need->vn_next == 0)
2983 		break;
2984 	      offset += need->vn_next;
2985 	    }
2986 	}
2987 
2988       /* This is the number of versions we know about.  */
2989       ++nvername;
2990 
2991       /* Allocate the array.  */
2992       vername = (const char **) alloca (nvername * sizeof (const char *));
2993       memset(vername, 0, nvername * sizeof (const char *));
2994       filename = (const char **) alloca (nvername * sizeof (const char *));
2995       memset(filename, 0, nvername * sizeof (const char *));
2996 
2997       /* Run through the data structures again and collect the strings.  */
2998       if (defscn != NULL)
2999 	{
3000 	  /* Run through the version definitions and find the highest
3001 	     index.  */
3002 	  unsigned int offset = 0;
3003 	  Elf_Data *defdata;
3004 	  GElf_Shdr defshdrmem;
3005 	  GElf_Shdr *defshdr;
3006 
3007 	  defdata = elf_getdata (defscn, NULL);
3008 	  if (unlikely (defdata == NULL))
3009 	    return;
3010 
3011 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
3012 	  if (unlikely (defshdr == NULL))
3013 	    return;
3014 
3015 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3016 	    {
3017 
3018 	      /* Get the data at the next offset.  */
3019 	      GElf_Verdef defmem;
3020 	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3021 	      if (unlikely (def == NULL))
3022 		break;
3023 
3024 	      GElf_Verdaux auxmem;
3025 	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
3026 						   offset + def->vd_aux,
3027 						   &auxmem);
3028 	      if (unlikely (aux == NULL))
3029 		break;
3030 
3031 	      vername[def->vd_ndx & 0x7fff]
3032 		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3033 	      filename[def->vd_ndx & 0x7fff] = NULL;
3034 
3035 	      if (def->vd_next == 0)
3036 		break;
3037 	      offset += def->vd_next;
3038 	    }
3039 	}
3040       if (needscn != NULL)
3041 	{
3042 	  unsigned int offset = 0;
3043 
3044 	  Elf_Data *needdata = elf_getdata (needscn, NULL);
3045 	  GElf_Shdr needshdrmem;
3046 	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3047 	  if (unlikely (needdata == NULL || needshdr == NULL))
3048 	    return;
3049 
3050 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3051 	    {
3052 	      /* Get the data at the next offset.  */
3053 	      GElf_Verneed needmem;
3054 	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
3055 						    &needmem);
3056 	      if (unlikely (need == NULL))
3057 		break;
3058 
3059 	      /* Run through the auxiliary entries.  */
3060 	      unsigned int auxoffset = offset + need->vn_aux;
3061 	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3062 		{
3063 		  GElf_Vernaux auxmem;
3064 		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3065 						       &auxmem);
3066 		  if (unlikely (aux == NULL))
3067 		    break;
3068 
3069 		  vername[aux->vna_other & 0x7fff]
3070 		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3071 		  filename[aux->vna_other & 0x7fff]
3072 		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3073 
3074 		  if (aux->vna_next == 0)
3075 		    break;
3076 		  auxoffset += aux->vna_next;
3077 		}
3078 
3079 	      if (need->vn_next == 0)
3080 		break;
3081 	      offset += need->vn_next;
3082 	    }
3083 	}
3084     }
3085   else
3086     {
3087       vername = NULL;
3088       nvername = 1;
3089       filename = NULL;
3090     }
3091 
3092   GElf_Shdr glink_mem;
3093   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3094 				   &glink_mem);
3095   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3096   if (glink == NULL)
3097     error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
3098 	   elf_ndxscn (scn));
3099 
3100   /* Print the header.  */
3101   printf (ngettext ("\
3102 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
3103 		    "\
3104 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
3105 		    shdr->sh_size / sh_entsize),
3106 	  (unsigned int) elf_ndxscn (scn),
3107 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3108 	  (int) (shdr->sh_size / sh_entsize),
3109 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3110 	  shdr->sh_offset,
3111 	  (unsigned int) shdr->sh_link,
3112 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3113 
3114   /* Now we can finally look at the actual contents of this section.  */
3115   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3116     {
3117       if (cnt % 2 == 0)
3118 	printf ("\n %4d:", cnt);
3119 
3120       GElf_Versym symmem;
3121       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3122       if (sym == NULL)
3123 	break;
3124 
3125       switch (*sym)
3126 	{
3127 	  ssize_t n;
3128 	case 0:
3129 	  fputs_unlocked (_("   0 *local*                     "),
3130 			  stdout);
3131 	  break;
3132 
3133 	case 1:
3134 	  fputs_unlocked (_("   1 *global*                    "),
3135 			  stdout);
3136 	  break;
3137 
3138 	default:
3139 	  n = printf ("%4d%c%s",
3140 		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3141 		      (vername != NULL
3142 		       && (unsigned int) (*sym & 0x7fff) < nvername)
3143 		      ? vername[*sym & 0x7fff] : "???");
3144 	  if ((unsigned int) (*sym & 0x7fff) < nvername
3145 	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
3146 	    n += printf ("(%s)", filename[*sym & 0x7fff]);
3147 	  printf ("%*s", MAX (0, 33 - (int) n), " ");
3148 	  break;
3149 	}
3150     }
3151   putchar_unlocked ('\n');
3152 }
3153 
3154 
3155 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)3156 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3157 		 uint_fast32_t maxlength, Elf32_Word nbucket,
3158 		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3159 {
3160   uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3161 
3162   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3163     ++counts[lengths[cnt]];
3164 
3165   GElf_Shdr glink_mem;
3166   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3167 					       shdr->sh_link),
3168 				   &glink_mem);
3169   if (glink == NULL)
3170     {
3171       error (0, 0, _("invalid sh_link value in section %zu"),
3172 	     elf_ndxscn (scn));
3173       return;
3174     }
3175 
3176   printf (ngettext ("\
3177 \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",
3178 		    "\
3179 \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",
3180 		    nbucket),
3181 	  (unsigned int) elf_ndxscn (scn),
3182 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3183 	  (int) nbucket,
3184 	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3185 	  shdr->sh_addr,
3186 	  shdr->sh_offset,
3187 	  (unsigned int) shdr->sh_link,
3188 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3189 
3190   if (extrastr != NULL)
3191     fputs (extrastr, stdout);
3192 
3193   if (likely (nbucket > 0))
3194     {
3195       uint64_t success = 0;
3196 
3197       /* xgettext:no-c-format */
3198       fputs_unlocked (_("\
3199  Length  Number  % of total  Coverage\n"), stdout);
3200       printf (_("      0  %6" PRIu32 "      %5.1f%%\n"),
3201 	      counts[0], (counts[0] * 100.0) / nbucket);
3202 
3203       uint64_t nzero_counts = 0;
3204       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3205 	{
3206 	  nzero_counts += counts[cnt] * cnt;
3207 	  printf (_("\
3208 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
3209 		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3210 		  (nzero_counts * 100.0) / nsyms);
3211 	}
3212 
3213       Elf32_Word acc = 0;
3214       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3215 	{
3216 	  acc += cnt;
3217 	  success += counts[cnt] * acc;
3218 	}
3219 
3220       printf (_("\
3221  Average number of tests:   successful lookup: %f\n\
3222 			  unsuccessful lookup: %f\n"),
3223 	      (double) success / (double) nzero_counts,
3224 	      (double) nzero_counts / (double) nbucket);
3225     }
3226 
3227   free (counts);
3228 }
3229 
3230 
3231 /* This function handles the traditional System V-style hash table format.  */
3232 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3233 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3234 {
3235   Elf_Data *data = elf_getdata (scn, NULL);
3236   if (unlikely (data == NULL))
3237     {
3238       error (0, 0, _("cannot get data for section %d: %s"),
3239 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3240       return;
3241     }
3242 
3243   if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3244     {
3245     invalid_data:
3246       error (0, 0, _("invalid data in sysv.hash section %d"),
3247 	     (int) elf_ndxscn (scn));
3248       return;
3249     }
3250 
3251   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3252   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3253 
3254   uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3255   if (used_buf > data->d_size)
3256     goto invalid_data;
3257 
3258   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3259   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3260 
3261   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3262 
3263   uint_fast32_t maxlength = 0;
3264   uint_fast32_t nsyms = 0;
3265   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3266     {
3267       Elf32_Word inner = bucket[cnt];
3268       Elf32_Word chain_len = 0;
3269       while (inner > 0 && inner < nchain)
3270 	{
3271 	  ++nsyms;
3272 	  ++chain_len;
3273 	  if (chain_len > nchain)
3274 	    {
3275 	      error (0, 0, _("invalid chain in sysv.hash section %d"),
3276 		     (int) elf_ndxscn (scn));
3277 	      free (lengths);
3278 	      return;
3279 	    }
3280 	  if (maxlength < ++lengths[cnt])
3281 	    ++maxlength;
3282 
3283 	  inner = chain[inner];
3284 	}
3285     }
3286 
3287   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3288 		   lengths, NULL);
3289 
3290   free (lengths);
3291 }
3292 
3293 
3294 /* This function handles the incorrect, System V-style hash table
3295    format some 64-bit architectures use.  */
3296 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3297 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3298 {
3299   Elf_Data *data = elf_getdata (scn, NULL);
3300   if (unlikely (data == NULL))
3301     {
3302       error (0, 0, _("cannot get data for section %d: %s"),
3303 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3304       return;
3305     }
3306 
3307   if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3308     {
3309     invalid_data:
3310       error (0, 0, _("invalid data in sysv.hash64 section %d"),
3311 	     (int) elf_ndxscn (scn));
3312       return;
3313     }
3314 
3315   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3316   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3317 
3318   uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3319   if (maxwords < 2
3320       || maxwords - 2 < nbucket
3321       || maxwords - 2 - nbucket < nchain)
3322     goto invalid_data;
3323 
3324   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3325   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3326 
3327   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3328 
3329   uint_fast32_t maxlength = 0;
3330   uint_fast32_t nsyms = 0;
3331   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3332     {
3333       Elf64_Xword inner = bucket[cnt];
3334       Elf64_Xword chain_len = 0;
3335       while (inner > 0 && inner < nchain)
3336 	{
3337 	  ++nsyms;
3338 	  ++chain_len;
3339 	  if (chain_len > nchain)
3340 	    {
3341 	      error (0, 0, _("invalid chain in sysv.hash64 section %d"),
3342 		     (int) elf_ndxscn (scn));
3343 	      free (lengths);
3344 	      return;
3345 	    }
3346 	  if (maxlength < ++lengths[cnt])
3347 	    ++maxlength;
3348 
3349 	  inner = chain[inner];
3350 	}
3351     }
3352 
3353   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3354 		   lengths, NULL);
3355 
3356   free (lengths);
3357 }
3358 
3359 
3360 /* This function handles the GNU-style hash table format.  */
3361 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3362 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3363 {
3364   uint32_t *lengths = NULL;
3365   Elf_Data *data = elf_getdata (scn, NULL);
3366   if (unlikely (data == NULL))
3367     {
3368       error (0, 0, _("cannot get data for section %d: %s"),
3369 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3370       return;
3371     }
3372 
3373   if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3374     {
3375     invalid_data:
3376       free (lengths);
3377       error (0, 0, _("invalid data in gnu.hash section %d"),
3378 	     (int) elf_ndxscn (scn));
3379       return;
3380     }
3381 
3382   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3383   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3384 
3385   /* Next comes the size of the bitmap.  It's measured in words for
3386      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
3387      64 bit archs.  There is always a bloom filter present, so zero is
3388      an invalid value.  */
3389   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3390   if (gelf_getclass (ebl->elf) == ELFCLASS64)
3391     bitmask_words *= 2;
3392 
3393   if (bitmask_words == 0)
3394     goto invalid_data;
3395 
3396   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3397 
3398   /* Is there still room for the sym chain?
3399      Use uint64_t calculation to prevent 32bit overflow.  */
3400   uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3401   uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3402   if (used_buf > data->d_size)
3403     goto invalid_data;
3404 
3405   lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3406 
3407   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3408   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3409   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3410 						    + nbucket];
3411 
3412   /* Compute distribution of chain lengths.  */
3413   uint_fast32_t maxlength = 0;
3414   uint_fast32_t nsyms = 0;
3415   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3416     if (bucket[cnt] != 0)
3417       {
3418 	Elf32_Word inner = bucket[cnt] - symbias;
3419 	do
3420 	  {
3421 	    ++nsyms;
3422 	    if (maxlength < ++lengths[cnt])
3423 	      ++maxlength;
3424 	    if (inner >= max_nsyms)
3425 	      goto invalid_data;
3426 	  }
3427 	while ((chain[inner++] & 1) == 0);
3428       }
3429 
3430   /* Count bits in bitmask.  */
3431   uint_fast32_t nbits = 0;
3432   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3433     {
3434       uint_fast32_t word = bitmask[cnt];
3435 
3436       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3437       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3438       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3439       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3440       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3441     }
3442 
3443   char *str;
3444   if (unlikely (asprintf (&str, _("\
3445  Symbol Bias: %u\n\
3446  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
3447 			  (unsigned int) symbias,
3448 			  bitmask_words * sizeof (Elf32_Word),
3449 			  ((nbits * 100 + 50)
3450 			   / (uint_fast32_t) (bitmask_words
3451 					      * sizeof (Elf32_Word) * 8)),
3452 			  (unsigned int) shift) == -1))
3453     error (EXIT_FAILURE, 0, _("memory exhausted"));
3454 
3455   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3456 		   lengths, str);
3457 
3458   free (str);
3459   free (lengths);
3460 }
3461 
3462 
3463 /* Find the symbol table(s).  For this we have to search through the
3464    section table.  */
3465 static void
handle_hash(Ebl * ebl)3466 handle_hash (Ebl *ebl)
3467 {
3468   /* Get the section header string table index.  */
3469   size_t shstrndx;
3470   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3471     error (EXIT_FAILURE, 0,
3472 	   _("cannot get section header string table index"));
3473 
3474   Elf_Scn *scn = NULL;
3475   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3476     {
3477       /* Handle the section if it is a symbol table.  */
3478       GElf_Shdr shdr_mem;
3479       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3480 
3481       if (likely (shdr != NULL))
3482 	{
3483 	  if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3484 	      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3485 	    {
3486 	      if (elf_compress (scn, 0, 0) < 0)
3487 		printf ("WARNING: %s [%zd]\n",
3488 			_("Couldn't uncompress section"),
3489 			elf_ndxscn (scn));
3490 	      shdr = gelf_getshdr (scn, &shdr_mem);
3491 	      if (unlikely (shdr == NULL))
3492 		error (EXIT_FAILURE, 0,
3493 		       _("cannot get section [%zd] header: %s"),
3494 		       elf_ndxscn (scn), elf_errmsg (-1));
3495 	    }
3496 
3497 	  if (shdr->sh_type == SHT_HASH)
3498 	    {
3499 	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3500 		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3501 	      else
3502 		handle_sysv_hash (ebl, scn, shdr, shstrndx);
3503 	    }
3504 	  else if (shdr->sh_type == SHT_GNU_HASH)
3505 	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
3506 	}
3507     }
3508 }
3509 
3510 
3511 static void
print_liblist(Ebl * ebl)3512 print_liblist (Ebl *ebl)
3513 {
3514   /* Find the library list sections.  For this we have to search
3515      through the section table.  */
3516   Elf_Scn *scn = NULL;
3517 
3518   /* Get the section header string table index.  */
3519   size_t shstrndx;
3520   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3521     error (EXIT_FAILURE, 0,
3522 	   _("cannot get section header string table index"));
3523 
3524   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3525     {
3526       GElf_Shdr shdr_mem;
3527       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3528 
3529       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3530 	{
3531 	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3532 	  int nentries = shdr->sh_size / sh_entsize;
3533 	  printf (ngettext ("\
3534 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3535 			    "\
3536 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3537 			    nentries),
3538 		  elf_ndxscn (scn),
3539 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3540 		  shdr->sh_offset,
3541 		  nentries);
3542 
3543 	  Elf_Data *data = elf_getdata (scn, NULL);
3544 	  if (data == NULL)
3545 	    return;
3546 
3547 	  puts (_("\
3548        Library                       Time Stamp          Checksum Version Flags"));
3549 
3550 	  for (int cnt = 0; cnt < nentries; ++cnt)
3551 	    {
3552 	      GElf_Lib lib_mem;
3553 	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3554 	      if (unlikely (lib == NULL))
3555 		continue;
3556 
3557 	      time_t t = (time_t) lib->l_time_stamp;
3558 	      struct tm *tm = gmtime (&t);
3559 	      if (unlikely (tm == NULL))
3560 		continue;
3561 
3562 	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3563 		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3564 		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3565 		      tm->tm_hour, tm->tm_min, tm->tm_sec,
3566 		      (unsigned int) lib->l_checksum,
3567 		      (unsigned int) lib->l_version,
3568 		      (unsigned int) lib->l_flags);
3569 	    }
3570 	}
3571     }
3572 }
3573 
3574 static inline size_t
left(Elf_Data * data,const unsigned char * p)3575 left (Elf_Data *data,
3576       const unsigned char *p)
3577 {
3578   return (const unsigned char *) data->d_buf + data->d_size - p;
3579 }
3580 
3581 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3582 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3583 {
3584   /* Find the object attributes sections.  For this we have to search
3585      through the section table.  */
3586   Elf_Scn *scn = NULL;
3587 
3588   /* Get the section header string table index.  */
3589   size_t shstrndx;
3590   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3591     error (EXIT_FAILURE, 0,
3592 	   _("cannot get section header string table index"));
3593 
3594   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3595     {
3596       GElf_Shdr shdr_mem;
3597       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3598 
3599       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3600 			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3601 			       || ehdr->e_machine != EM_ARM)
3602 			   && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
3603 			       || ehdr->e_machine != EM_CSKY)))
3604 	continue;
3605 
3606       printf (_("\
3607 \nObject attributes section [%2zu] '%s' of %" PRIu64
3608 		       " bytes at offset %#0" PRIx64 ":\n"),
3609 	      elf_ndxscn (scn),
3610 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3611 	      shdr->sh_size, shdr->sh_offset);
3612 
3613       Elf_Data *data = elf_rawdata (scn, NULL);
3614       if (unlikely (data == NULL || data->d_size == 0))
3615 	return;
3616 
3617       const unsigned char *p = data->d_buf;
3618 
3619       /* There is only one 'version', A.  */
3620       if (unlikely (*p++ != 'A'))
3621 	return;
3622 
3623       fputs_unlocked (_("  Owner          Size\n"), stdout);
3624 
3625       /* Loop over the sections.  */
3626       while (left (data, p) >= 4)
3627 	{
3628 	  /* Section length.  */
3629 	  uint32_t len;
3630 	  memcpy (&len, p, sizeof len);
3631 
3632 	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3633 	    CONVERT (len);
3634 
3635 	  if (unlikely (len > left (data, p)))
3636 	    break;
3637 
3638 	  /* Section vendor name.  */
3639 	  const unsigned char *name = p + sizeof len;
3640 	  p += len;
3641 
3642 	  unsigned const char *q = memchr (name, '\0', len);
3643 	  if (unlikely (q == NULL))
3644 	    break;
3645 	  ++q;
3646 
3647 	  printf (_("  %-13s  %4" PRIu32 "\n"), name, len);
3648 
3649 	  bool gnu_vendor = (q - name == sizeof "gnu"
3650 			     && !memcmp (name, "gnu", sizeof "gnu"));
3651 
3652 	  /* Loop over subsections.  */
3653 	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3654 	      || gnu_vendor)
3655 	    while (q < p)
3656 	      {
3657 		const unsigned char *const sub = q;
3658 
3659 		unsigned int subsection_tag;
3660 		get_uleb128 (subsection_tag, q, p);
3661 		if (unlikely (q >= p))
3662 		  break;
3663 
3664 		uint32_t subsection_len;
3665 		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3666 		  break;
3667 
3668 		memcpy (&subsection_len, q, sizeof subsection_len);
3669 
3670 		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3671 		  CONVERT (subsection_len);
3672 
3673 		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
3674 		if (unlikely (subsection_len == 0
3675 			      || subsection_len >= (uint32_t) PTRDIFF_MAX
3676 			      || p - sub < (ptrdiff_t) subsection_len))
3677 		  break;
3678 
3679 		const unsigned char *r = q + sizeof subsection_len;
3680 		q = sub + subsection_len;
3681 
3682 		switch (subsection_tag)
3683 		  {
3684 		  default:
3685 		    /* Unknown subsection, print and skip.  */
3686 		    printf (_("    %-4u %12" PRIu32 "\n"),
3687 			    subsection_tag, subsection_len);
3688 		    break;
3689 
3690 		  case 1:	/* Tag_File */
3691 		    printf (_("    File: %11" PRIu32 "\n"),
3692 			    subsection_len);
3693 
3694 		    while (r < q)
3695 		      {
3696 			unsigned int tag;
3697 			get_uleb128 (tag, r, q);
3698 			if (unlikely (r >= q))
3699 			  break;
3700 
3701 			/* GNU style tags have either a uleb128 value,
3702 			   when lowest bit is not set, or a string
3703 			   when the lowest bit is set.
3704 			   "compatibility" (32) is special.  It has
3705 			   both a string and a uleb128 value.  For
3706 			   non-gnu we assume 6 till 31 only take ints.
3707 			   XXX see arm backend, do we need a separate
3708 			   hook?  */
3709 			uint64_t value = 0;
3710 			const char *string = NULL;
3711 			if (tag == 32 || (tag & 1) == 0
3712 			    || (! gnu_vendor && (tag > 5 && tag < 32)))
3713 			  {
3714 			    get_uleb128 (value, r, q);
3715 			    if (r > q)
3716 			      break;
3717 			  }
3718 			if (tag == 32
3719 			    || ((tag & 1) != 0
3720 				&& (gnu_vendor
3721 				    || (! gnu_vendor && tag > 32)))
3722 			    || (! gnu_vendor && tag > 3 && tag < 6))
3723 			  {
3724 			    string = (const char *) r;
3725 			    r = memchr (r, '\0', q - r);
3726 			    if (r == NULL)
3727 			      break;
3728 			    ++r;
3729 			  }
3730 
3731 			const char *tag_name = NULL;
3732 			const char *value_name = NULL;
3733 			ebl_check_object_attribute (ebl, (const char *) name,
3734 						    tag, value,
3735 						    &tag_name, &value_name);
3736 
3737 			if (tag_name != NULL)
3738 			  {
3739 			    if (tag == 32)
3740 			      printf (_("      %s: %" PRId64 ", %s\n"),
3741 				      tag_name, value, string);
3742 			    else if (string == NULL && value_name == NULL)
3743 			      printf (_("      %s: %" PRId64 "\n"),
3744 				      tag_name, value);
3745 			    else
3746 			      printf (_("      %s: %s\n"),
3747 				      tag_name, string ?: value_name);
3748 			  }
3749 			else
3750 			  {
3751 			    /* For "gnu" vendor 32 "compatibility" has
3752 			       already been handled above.  */
3753 			    assert (tag != 32
3754 				    || strcmp ((const char *) name, "gnu"));
3755 			    if (string == NULL)
3756 			      printf (_("      %u: %" PRId64 "\n"),
3757 				      tag, value);
3758 			    else
3759 			      printf (_("      %u: %s\n"),
3760 				      tag, string);
3761 			  }
3762 		      }
3763 		  }
3764 	      }
3765 	}
3766     }
3767 }
3768 
3769 
3770 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3771 print_dwarf_addr (Dwfl_Module *dwflmod,
3772 		  int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3773 {
3774   /* See if there is a name we can give for this address.  */
3775   GElf_Sym sym;
3776   GElf_Off off = 0;
3777   const char *name = (print_address_names && ! print_unresolved_addresses)
3778     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3779     : NULL;
3780 
3781   const char *scn;
3782   if (print_unresolved_addresses)
3783     {
3784       address = raw;
3785       scn = NULL;
3786     }
3787   else
3788     {
3789       /* Relativize the address.  */
3790       int n = dwfl_module_relocations (dwflmod);
3791       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3792 
3793       /* In an ET_REL file there is a section name to refer to.  */
3794       scn = (i < 0 ? NULL
3795 	     : dwfl_module_relocation_info (dwflmod, i, NULL));
3796     }
3797 
3798   if ((name != NULL
3799        ? (off != 0
3800 	  ? (scn != NULL
3801 	     ? (address_size == 0
3802 		? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3803 			  scn, address, name, off)
3804 		: printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3805 			  scn, 2 + address_size * 2, address,
3806 			  name, off))
3807 	     : (address_size == 0
3808 		? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3809 			  address, name, off)
3810 		: printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3811 			  2 + address_size * 2, address,
3812 			  name, off)))
3813 	  : (scn != NULL
3814 	     ? (address_size == 0
3815 		? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3816 		: printf ("%s+%#0*" PRIx64 " <%s>",
3817 			   scn, 2 + address_size * 2, address, name))
3818 	     : (address_size == 0
3819 		? printf ("%#" PRIx64 " <%s>", address, name)
3820 		: printf ("%#0*" PRIx64 " <%s>",
3821 			  2 + address_size * 2, address, name))))
3822        : (scn != NULL
3823 	  ? (address_size == 0
3824 	     ? printf ("%s+%#" PRIx64, scn, address)
3825 	     : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3826 	  : (address_size == 0
3827 	     ? printf ("%#" PRIx64, address)
3828 	     : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3829     error (EXIT_FAILURE, 0, _("sprintf failure"));
3830 }
3831 
3832 
3833 static const char *
dwarf_tag_string(unsigned int tag)3834 dwarf_tag_string (unsigned int tag)
3835 {
3836   switch (tag)
3837     {
3838 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3839       DWARF_ALL_KNOWN_DW_TAG
3840 #undef DWARF_ONE_KNOWN_DW_TAG
3841     default:
3842       return NULL;
3843     }
3844 }
3845 
3846 
3847 static const char *
dwarf_attr_string(unsigned int attrnum)3848 dwarf_attr_string (unsigned int attrnum)
3849 {
3850   switch (attrnum)
3851     {
3852 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3853       DWARF_ALL_KNOWN_DW_AT
3854 #undef DWARF_ONE_KNOWN_DW_AT
3855     default:
3856       return NULL;
3857     }
3858 }
3859 
3860 
3861 static const char *
dwarf_form_string(unsigned int form)3862 dwarf_form_string (unsigned int form)
3863 {
3864   switch (form)
3865     {
3866 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3867       DWARF_ALL_KNOWN_DW_FORM
3868 #undef DWARF_ONE_KNOWN_DW_FORM
3869     default:
3870       return NULL;
3871     }
3872 }
3873 
3874 
3875 static const char *
dwarf_lang_string(unsigned int lang)3876 dwarf_lang_string (unsigned int lang)
3877 {
3878   switch (lang)
3879     {
3880 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3881       DWARF_ALL_KNOWN_DW_LANG
3882 #undef DWARF_ONE_KNOWN_DW_LANG
3883     default:
3884       return NULL;
3885     }
3886 }
3887 
3888 
3889 static const char *
dwarf_inline_string(unsigned int code)3890 dwarf_inline_string (unsigned int code)
3891 {
3892   static const char *const known[] =
3893     {
3894 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3895       DWARF_ALL_KNOWN_DW_INL
3896 #undef DWARF_ONE_KNOWN_DW_INL
3897     };
3898 
3899   if (likely (code < sizeof (known) / sizeof (known[0])))
3900     return known[code];
3901 
3902   return NULL;
3903 }
3904 
3905 
3906 static const char *
dwarf_encoding_string(unsigned int code)3907 dwarf_encoding_string (unsigned int code)
3908 {
3909   static const char *const known[] =
3910     {
3911 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3912       DWARF_ALL_KNOWN_DW_ATE
3913 #undef DWARF_ONE_KNOWN_DW_ATE
3914     };
3915 
3916   if (likely (code < sizeof (known) / sizeof (known[0])))
3917     return known[code];
3918 
3919   return NULL;
3920 }
3921 
3922 
3923 static const char *
dwarf_access_string(unsigned int code)3924 dwarf_access_string (unsigned int code)
3925 {
3926   static const char *const known[] =
3927     {
3928 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3929       DWARF_ALL_KNOWN_DW_ACCESS
3930 #undef DWARF_ONE_KNOWN_DW_ACCESS
3931     };
3932 
3933   if (likely (code < sizeof (known) / sizeof (known[0])))
3934     return known[code];
3935 
3936   return NULL;
3937 }
3938 
3939 
3940 static const char *
dwarf_defaulted_string(unsigned int code)3941 dwarf_defaulted_string (unsigned int code)
3942 {
3943   static const char *const known[] =
3944     {
3945 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3946       DWARF_ALL_KNOWN_DW_DEFAULTED
3947 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3948     };
3949 
3950   if (likely (code < sizeof (known) / sizeof (known[0])))
3951     return known[code];
3952 
3953   return NULL;
3954 }
3955 
3956 
3957 static const char *
dwarf_visibility_string(unsigned int code)3958 dwarf_visibility_string (unsigned int code)
3959 {
3960   static const char *const known[] =
3961     {
3962 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3963       DWARF_ALL_KNOWN_DW_VIS
3964 #undef DWARF_ONE_KNOWN_DW_VIS
3965     };
3966 
3967   if (likely (code < sizeof (known) / sizeof (known[0])))
3968     return known[code];
3969 
3970   return NULL;
3971 }
3972 
3973 
3974 static const char *
dwarf_virtuality_string(unsigned int code)3975 dwarf_virtuality_string (unsigned int code)
3976 {
3977   static const char *const known[] =
3978     {
3979 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3980       DWARF_ALL_KNOWN_DW_VIRTUALITY
3981 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3982     };
3983 
3984   if (likely (code < sizeof (known) / sizeof (known[0])))
3985     return known[code];
3986 
3987   return NULL;
3988 }
3989 
3990 
3991 static const char *
dwarf_identifier_case_string(unsigned int code)3992 dwarf_identifier_case_string (unsigned int code)
3993 {
3994   static const char *const known[] =
3995     {
3996 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3997       DWARF_ALL_KNOWN_DW_ID
3998 #undef DWARF_ONE_KNOWN_DW_ID
3999     };
4000 
4001   if (likely (code < sizeof (known) / sizeof (known[0])))
4002     return known[code];
4003 
4004   return NULL;
4005 }
4006 
4007 
4008 static const char *
dwarf_calling_convention_string(unsigned int code)4009 dwarf_calling_convention_string (unsigned int code)
4010 {
4011   static const char *const known[] =
4012     {
4013 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4014       DWARF_ALL_KNOWN_DW_CC
4015 #undef DWARF_ONE_KNOWN_DW_CC
4016     };
4017 
4018   if (likely (code < sizeof (known) / sizeof (known[0])))
4019     return known[code];
4020 
4021   return NULL;
4022 }
4023 
4024 
4025 static const char *
dwarf_ordering_string(unsigned int code)4026 dwarf_ordering_string (unsigned int code)
4027 {
4028   static const char *const known[] =
4029     {
4030 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4031       DWARF_ALL_KNOWN_DW_ORD
4032 #undef DWARF_ONE_KNOWN_DW_ORD
4033     };
4034 
4035   if (likely (code < sizeof (known) / sizeof (known[0])))
4036     return known[code];
4037 
4038   return NULL;
4039 }
4040 
4041 
4042 static const char *
dwarf_discr_list_string(unsigned int code)4043 dwarf_discr_list_string (unsigned int code)
4044 {
4045   static const char *const known[] =
4046     {
4047 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4048       DWARF_ALL_KNOWN_DW_DSC
4049 #undef DWARF_ONE_KNOWN_DW_DSC
4050     };
4051 
4052   if (likely (code < sizeof (known) / sizeof (known[0])))
4053     return known[code];
4054 
4055   return NULL;
4056 }
4057 
4058 
4059 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4060 dwarf_locexpr_opcode_string (unsigned int code)
4061 {
4062   static const char *const known[] =
4063     {
4064       /* Normally we can't afford building huge table of 64K entries,
4065 	 most of them zero, just because there are a couple defined
4066 	 values at the far end.  In case of opcodes, it's OK.  */
4067 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4068       DWARF_ALL_KNOWN_DW_OP
4069 #undef DWARF_ONE_KNOWN_DW_OP
4070     };
4071 
4072   if (likely (code < sizeof (known) / sizeof (known[0])))
4073     return known[code];
4074 
4075   return NULL;
4076 }
4077 
4078 
4079 static const char *
dwarf_unit_string(unsigned int type)4080 dwarf_unit_string (unsigned int type)
4081 {
4082   switch (type)
4083     {
4084 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4085       DWARF_ALL_KNOWN_DW_UT
4086 #undef DWARF_ONE_KNOWN_DW_UT
4087     default:
4088       return NULL;
4089     }
4090 }
4091 
4092 
4093 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4094 dwarf_range_list_encoding_string (unsigned int kind)
4095 {
4096   switch (kind)
4097     {
4098 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4099       DWARF_ALL_KNOWN_DW_RLE
4100 #undef DWARF_ONE_KNOWN_DW_RLE
4101     default:
4102       return NULL;
4103     }
4104 }
4105 
4106 
4107 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4108 dwarf_loc_list_encoding_string (unsigned int kind)
4109 {
4110   switch (kind)
4111     {
4112 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4113       DWARF_ALL_KNOWN_DW_LLE
4114 #undef DWARF_ONE_KNOWN_DW_LLE
4115     default:
4116       return NULL;
4117     }
4118 }
4119 
4120 
4121 static const char *
dwarf_line_content_description_string(unsigned int kind)4122 dwarf_line_content_description_string (unsigned int kind)
4123 {
4124   switch (kind)
4125     {
4126 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4127       DWARF_ALL_KNOWN_DW_LNCT
4128 #undef DWARF_ONE_KNOWN_DW_LNCT
4129     default:
4130       return NULL;
4131     }
4132 }
4133 
4134 
4135 /* Used by all dwarf_foo_name functions.  */
4136 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4137 string_or_unknown (const char *known, unsigned int code,
4138                    unsigned int lo_user, unsigned int hi_user,
4139 		   bool print_unknown_num)
4140 {
4141   static char unknown_buf[20];
4142 
4143   if (likely (known != NULL))
4144     return known;
4145 
4146   if (lo_user != 0 && code >= lo_user && code <= hi_user)
4147     {
4148       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4149 		code - lo_user);
4150       return unknown_buf;
4151     }
4152 
4153   if (print_unknown_num)
4154     {
4155       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4156       return unknown_buf;
4157     }
4158 
4159   return "???";
4160 }
4161 
4162 
4163 static const char *
dwarf_tag_name(unsigned int tag)4164 dwarf_tag_name (unsigned int tag)
4165 {
4166   const char *ret = dwarf_tag_string (tag);
4167   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4168 }
4169 
4170 static const char *
dwarf_attr_name(unsigned int attr)4171 dwarf_attr_name (unsigned int attr)
4172 {
4173   const char *ret = dwarf_attr_string (attr);
4174   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4175 }
4176 
4177 
4178 static const char *
dwarf_form_name(unsigned int form)4179 dwarf_form_name (unsigned int form)
4180 {
4181   const char *ret = dwarf_form_string (form);
4182   return string_or_unknown (ret, form, 0, 0, true);
4183 }
4184 
4185 
4186 static const char *
dwarf_lang_name(unsigned int lang)4187 dwarf_lang_name (unsigned int lang)
4188 {
4189   const char *ret = dwarf_lang_string (lang);
4190   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4191 }
4192 
4193 
4194 static const char *
dwarf_inline_name(unsigned int code)4195 dwarf_inline_name (unsigned int code)
4196 {
4197   const char *ret = dwarf_inline_string (code);
4198   return string_or_unknown (ret, code, 0, 0, false);
4199 }
4200 
4201 
4202 static const char *
dwarf_encoding_name(unsigned int code)4203 dwarf_encoding_name (unsigned int code)
4204 {
4205   const char *ret = dwarf_encoding_string (code);
4206   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4207 }
4208 
4209 
4210 static const char *
dwarf_access_name(unsigned int code)4211 dwarf_access_name (unsigned int code)
4212 {
4213   const char *ret = dwarf_access_string (code);
4214   return string_or_unknown (ret, code, 0, 0, false);
4215 }
4216 
4217 
4218 static const char *
dwarf_defaulted_name(unsigned int code)4219 dwarf_defaulted_name (unsigned int code)
4220 {
4221   const char *ret = dwarf_defaulted_string (code);
4222   return string_or_unknown (ret, code, 0, 0, false);
4223 }
4224 
4225 
4226 static const char *
dwarf_visibility_name(unsigned int code)4227 dwarf_visibility_name (unsigned int code)
4228 {
4229   const char *ret = dwarf_visibility_string (code);
4230   return string_or_unknown (ret, code, 0, 0, false);
4231 }
4232 
4233 
4234 static const char *
dwarf_virtuality_name(unsigned int code)4235 dwarf_virtuality_name (unsigned int code)
4236 {
4237   const char *ret = dwarf_virtuality_string (code);
4238   return string_or_unknown (ret, code, 0, 0, false);
4239 }
4240 
4241 
4242 static const char *
dwarf_identifier_case_name(unsigned int code)4243 dwarf_identifier_case_name (unsigned int code)
4244 {
4245   const char *ret = dwarf_identifier_case_string (code);
4246   return string_or_unknown (ret, code, 0, 0, false);
4247 }
4248 
4249 
4250 static const char *
dwarf_calling_convention_name(unsigned int code)4251 dwarf_calling_convention_name (unsigned int code)
4252 {
4253   const char *ret = dwarf_calling_convention_string (code);
4254   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4255 }
4256 
4257 
4258 static const char *
dwarf_ordering_name(unsigned int code)4259 dwarf_ordering_name (unsigned int code)
4260 {
4261   const char *ret = dwarf_ordering_string (code);
4262   return string_or_unknown (ret, code, 0, 0, false);
4263 }
4264 
4265 
4266 static const char *
dwarf_discr_list_name(unsigned int code)4267 dwarf_discr_list_name (unsigned int code)
4268 {
4269   const char *ret = dwarf_discr_list_string (code);
4270   return string_or_unknown (ret, code, 0, 0, false);
4271 }
4272 
4273 
4274 static const char *
dwarf_unit_name(unsigned int type)4275 dwarf_unit_name (unsigned int type)
4276 {
4277   const char *ret = dwarf_unit_string (type);
4278   return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4279 }
4280 
4281 
4282 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4283 dwarf_range_list_encoding_name (unsigned int kind)
4284 {
4285   const char *ret = dwarf_range_list_encoding_string (kind);
4286   return string_or_unknown (ret, kind, 0, 0, false);
4287 }
4288 
4289 
4290 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4291 dwarf_loc_list_encoding_name (unsigned int kind)
4292 {
4293   const char *ret = dwarf_loc_list_encoding_string (kind);
4294   return string_or_unknown (ret, kind, 0, 0, false);
4295 }
4296 
4297 
4298 static const char *
dwarf_line_content_description_name(unsigned int kind)4299 dwarf_line_content_description_name (unsigned int kind)
4300 {
4301   const char *ret = dwarf_line_content_description_string (kind);
4302   return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4303 			    false);
4304 }
4305 
4306 
4307 static void
print_block(size_t n,const void * block)4308 print_block (size_t n, const void *block)
4309 {
4310   if (n == 0)
4311     puts (_("empty block"));
4312   else
4313     {
4314       printf (_("%zu byte block:"), n);
4315       const unsigned char *data = block;
4316       do
4317 	printf (" %02x", *data++);
4318       while (--n > 0);
4319       putchar ('\n');
4320     }
4321 }
4322 
4323 static void
print_bytes(size_t n,const unsigned char * bytes)4324 print_bytes (size_t n, const unsigned char *bytes)
4325 {
4326   while (n-- > 0)
4327     {
4328       printf ("%02x", *bytes++);
4329       if (n > 0)
4330 	printf (" ");
4331     }
4332 }
4333 
4334 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4335 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4336 {
4337   if (cu == NULL)
4338     return -1;
4339 
4340   Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4341   if (debug_addr == NULL)
4342     return -1;
4343 
4344   Dwarf_Off base = __libdw_cu_addr_base (cu);
4345   Dwarf_Word off = idx * cu->address_size;
4346   if (base > debug_addr->d_size
4347       || off > debug_addr->d_size - base
4348       || cu->address_size > debug_addr->d_size - base - off)
4349     return -1;
4350 
4351   const unsigned char *addrp = debug_addr->d_buf + base + off;
4352   if (cu->address_size == 4)
4353     *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4354   else
4355     *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4356 
4357   return 0;
4358 }
4359 
4360 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)4361 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4362 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4363 	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4364 {
4365   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4366 
4367   if (len == 0)
4368     {
4369       printf ("%*s(empty)\n", indent, "");
4370       return;
4371     }
4372 
4373 #define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
4374 #define CONSUME(n)	NEED (n); else len -= (n)
4375 
4376   Dwarf_Word offset = 0;
4377   while (len-- > 0)
4378     {
4379       uint_fast8_t op = *data++;
4380 
4381       const char *op_name = dwarf_locexpr_opcode_string (op);
4382       if (unlikely (op_name == NULL))
4383 	{
4384 	  static char buf[20];
4385 	  if (op >= DW_OP_lo_user)
4386 	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4387 	  else
4388 	    snprintf (buf, sizeof buf, "??? (%#x)", op);
4389 	  op_name = buf;
4390 	}
4391 
4392       switch (op)
4393 	{
4394 	case DW_OP_addr:;
4395 	  /* Address operand.  */
4396 	  Dwarf_Word addr;
4397 	  NEED (addrsize);
4398 	  if (addrsize == 4)
4399 	    addr = read_4ubyte_unaligned (dbg, data);
4400 	  else if (addrsize == 8)
4401 	    addr = read_8ubyte_unaligned (dbg, data);
4402 	  else
4403 	    goto invalid;
4404 	  data += addrsize;
4405 	  CONSUME (addrsize);
4406 
4407 	  printf ("%*s[%2" PRIuMAX "] %s ",
4408 		  indent, "", (uintmax_t) offset, op_name);
4409 	  print_dwarf_addr (dwflmod, 0, addr, addr);
4410 	  printf ("\n");
4411 
4412 	  offset += 1 + addrsize;
4413 	  break;
4414 
4415 	case DW_OP_call_ref:
4416 	case DW_OP_GNU_variable_value:
4417 	  /* Offset operand.  */
4418 	  if (ref_size != 4 && ref_size != 8)
4419 	    goto invalid; /* Cannot be used in CFA.  */
4420 	  NEED (ref_size);
4421 	  if (ref_size == 4)
4422 	    addr = read_4ubyte_unaligned (dbg, data);
4423 	  else
4424 	    addr = read_8ubyte_unaligned (dbg, data);
4425 	  data += ref_size;
4426 	  CONSUME (ref_size);
4427 	  /* addr is a DIE offset, so format it as one.  */
4428 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4429 		  indent, "", (uintmax_t) offset,
4430 		  op_name, (uintmax_t) addr);
4431 	  offset += 1 + ref_size;
4432 	  break;
4433 
4434 	case DW_OP_deref_size:
4435 	case DW_OP_xderef_size:
4436 	case DW_OP_pick:
4437 	case DW_OP_const1u:
4438 	  // XXX value might be modified by relocation
4439 	  NEED (1);
4440 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4441 		  indent, "", (uintmax_t) offset,
4442 		  op_name, *((uint8_t *) data));
4443 	  ++data;
4444 	  --len;
4445 	  offset += 2;
4446 	  break;
4447 
4448 	case DW_OP_const2u:
4449 	  NEED (2);
4450 	  // XXX value might be modified by relocation
4451 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4452 		  indent, "", (uintmax_t) offset,
4453 		  op_name, read_2ubyte_unaligned (dbg, data));
4454 	  CONSUME (2);
4455 	  data += 2;
4456 	  offset += 3;
4457 	  break;
4458 
4459 	case DW_OP_const4u:
4460 	  NEED (4);
4461 	  // XXX value might be modified by relocation
4462 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4463 		  indent, "", (uintmax_t) offset,
4464 		  op_name, read_4ubyte_unaligned (dbg, data));
4465 	  CONSUME (4);
4466 	  data += 4;
4467 	  offset += 5;
4468 	  break;
4469 
4470 	case DW_OP_const8u:
4471 	  NEED (8);
4472 	  // XXX value might be modified by relocation
4473 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4474 		  indent, "", (uintmax_t) offset,
4475 		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4476 	  CONSUME (8);
4477 	  data += 8;
4478 	  offset += 9;
4479 	  break;
4480 
4481 	case DW_OP_const1s:
4482 	  NEED (1);
4483 	  // XXX value might be modified by relocation
4484 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4485 		  indent, "", (uintmax_t) offset,
4486 		  op_name, *((int8_t *) data));
4487 	  ++data;
4488 	  --len;
4489 	  offset += 2;
4490 	  break;
4491 
4492 	case DW_OP_const2s:
4493 	  NEED (2);
4494 	  // XXX value might be modified by relocation
4495 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4496 		  indent, "", (uintmax_t) offset,
4497 		  op_name, read_2sbyte_unaligned (dbg, data));
4498 	  CONSUME (2);
4499 	  data += 2;
4500 	  offset += 3;
4501 	  break;
4502 
4503 	case DW_OP_const4s:
4504 	  NEED (4);
4505 	  // XXX value might be modified by relocation
4506 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4507 		  indent, "", (uintmax_t) offset,
4508 		  op_name, read_4sbyte_unaligned (dbg, data));
4509 	  CONSUME (4);
4510 	  data += 4;
4511 	  offset += 5;
4512 	  break;
4513 
4514 	case DW_OP_const8s:
4515 	  NEED (8);
4516 	  // XXX value might be modified by relocation
4517 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4518 		  indent, "", (uintmax_t) offset,
4519 		  op_name, read_8sbyte_unaligned (dbg, data));
4520 	  CONSUME (8);
4521 	  data += 8;
4522 	  offset += 9;
4523 	  break;
4524 
4525 	case DW_OP_piece:
4526 	case DW_OP_regx:
4527 	case DW_OP_plus_uconst:
4528 	case DW_OP_constu:;
4529 	  const unsigned char *start = data;
4530 	  uint64_t uleb;
4531 	  NEED (1);
4532 	  get_uleb128 (uleb, data, data + len);
4533 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4534 		  indent, "", (uintmax_t) offset, op_name, uleb);
4535 	  CONSUME (data - start);
4536 	  offset += 1 + (data - start);
4537 	  break;
4538 
4539 	case DW_OP_addrx:
4540 	case DW_OP_GNU_addr_index:
4541 	case DW_OP_constx:
4542 	case DW_OP_GNU_const_index:;
4543 	  start = data;
4544 	  NEED (1);
4545 	  get_uleb128 (uleb, data, data + len);
4546 	  printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4547 		  indent, "", (uintmax_t) offset, op_name, uleb);
4548 	  CONSUME (data - start);
4549 	  offset += 1 + (data - start);
4550 	  if (get_indexed_addr (cu, uleb, &addr) != 0)
4551 	    printf ("???\n");
4552 	  else
4553 	    {
4554 	      print_dwarf_addr (dwflmod, 0, addr, addr);
4555 	      printf ("\n");
4556 	    }
4557 	  break;
4558 
4559 	case DW_OP_bit_piece:
4560 	  start = data;
4561 	  uint64_t uleb2;
4562 	  NEED (1);
4563 	  get_uleb128 (uleb, data, data + len);
4564 	  NEED (1);
4565 	  get_uleb128 (uleb2, data, data + len);
4566 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4567 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4568 	  CONSUME (data - start);
4569 	  offset += 1 + (data - start);
4570 	  break;
4571 
4572 	case DW_OP_fbreg:
4573 	case DW_OP_breg0 ... DW_OP_breg31:
4574 	case DW_OP_consts:
4575 	  start = data;
4576 	  int64_t sleb;
4577 	  NEED (1);
4578 	  get_sleb128 (sleb, data, data + len);
4579 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4580 		  indent, "", (uintmax_t) offset, op_name, sleb);
4581 	  CONSUME (data - start);
4582 	  offset += 1 + (data - start);
4583 	  break;
4584 
4585 	case DW_OP_bregx:
4586 	  start = data;
4587 	  NEED (1);
4588 	  get_uleb128 (uleb, data, data + len);
4589 	  NEED (1);
4590 	  get_sleb128 (sleb, data, data + len);
4591 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4592 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4593 	  CONSUME (data - start);
4594 	  offset += 1 + (data - start);
4595 	  break;
4596 
4597 	case DW_OP_call2:
4598 	  NEED (2);
4599 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4600 		  indent, "", (uintmax_t) offset, op_name,
4601 		  read_2ubyte_unaligned (dbg, data));
4602 	  CONSUME (2);
4603 	  data += 2;
4604 	  offset += 3;
4605 	  break;
4606 
4607 	case DW_OP_call4:
4608 	  NEED (4);
4609 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4610 		  indent, "", (uintmax_t) offset, op_name,
4611 		  read_4ubyte_unaligned (dbg, data));
4612 	  CONSUME (4);
4613 	  data += 4;
4614 	  offset += 5;
4615 	  break;
4616 
4617 	case DW_OP_skip:
4618 	case DW_OP_bra:
4619 	  NEED (2);
4620 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4621 		  indent, "", (uintmax_t) offset, op_name,
4622 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4623 	  CONSUME (2);
4624 	  data += 2;
4625 	  offset += 3;
4626 	  break;
4627 
4628 	case DW_OP_implicit_value:
4629 	  start = data;
4630 	  NEED (1);
4631 	  get_uleb128 (uleb, data, data + len);
4632 	  printf ("%*s[%2" PRIuMAX "] %s: ",
4633 		  indent, "", (uintmax_t) offset, op_name);
4634 	  NEED (uleb);
4635 	  print_block (uleb, data);
4636 	  data += uleb;
4637 	  CONSUME (data - start);
4638 	  offset += 1 + (data - start);
4639 	  break;
4640 
4641 	case DW_OP_implicit_pointer:
4642 	case DW_OP_GNU_implicit_pointer:
4643 	  /* DIE offset operand.  */
4644 	  start = data;
4645 	  NEED (ref_size);
4646 	  if (ref_size != 4 && ref_size != 8)
4647 	    goto invalid; /* Cannot be used in CFA.  */
4648 	  if (ref_size == 4)
4649 	    addr = read_4ubyte_unaligned (dbg, data);
4650 	  else
4651 	    addr = read_8ubyte_unaligned (dbg, data);
4652 	  data += ref_size;
4653 	  /* Byte offset operand.  */
4654 	  NEED (1);
4655 	  get_sleb128 (sleb, data, data + len);
4656 
4657 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4658 		  indent, "", (intmax_t) offset,
4659 		  op_name, (uintmax_t) addr, sleb);
4660 	  CONSUME (data - start);
4661 	  offset += 1 + (data - start);
4662 	  break;
4663 
4664 	case DW_OP_entry_value:
4665 	case DW_OP_GNU_entry_value:
4666 	  /* Size plus expression block.  */
4667 	  start = data;
4668 	  NEED (1);
4669 	  get_uleb128 (uleb, data, data + len);
4670 	  printf ("%*s[%2" PRIuMAX "] %s:\n",
4671 		  indent, "", (uintmax_t) offset, op_name);
4672 	  NEED (uleb);
4673 	  print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4674 		     addrsize, offset_size, cu, uleb, data);
4675 	  data += uleb;
4676 	  CONSUME (data - start);
4677 	  offset += 1 + (data - start);
4678 	  break;
4679 
4680 	case DW_OP_const_type:
4681 	case DW_OP_GNU_const_type:
4682 	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4683 	     unsigned size plus block.  */
4684 	  start = data;
4685 	  NEED (1);
4686 	  get_uleb128 (uleb, data, data + len);
4687 	  if (! print_unresolved_addresses && cu != NULL)
4688 	    uleb += cu->start;
4689 	  NEED (1);
4690 	  uint8_t usize = *(uint8_t *) data++;
4691 	  NEED (usize);
4692 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4693 		  indent, "", (uintmax_t) offset, op_name, uleb);
4694 	  print_block (usize, data);
4695 	  data += usize;
4696 	  CONSUME (data - start);
4697 	  offset += 1 + (data - start);
4698 	  break;
4699 
4700 	case DW_OP_regval_type:
4701 	case DW_OP_GNU_regval_type:
4702 	  /* uleb128 register number, uleb128 CU relative
4703 	     DW_TAG_base_type DIE offset.  */
4704 	  start = data;
4705 	  NEED (1);
4706 	  get_uleb128 (uleb, data, data + len);
4707 	  NEED (1);
4708 	  get_uleb128 (uleb2, data, data + len);
4709 	  if (! print_unresolved_addresses && cu != NULL)
4710 	    uleb2 += cu->start;
4711 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4712 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4713 	  CONSUME (data - start);
4714 	  offset += 1 + (data - start);
4715 	  break;
4716 
4717 	case DW_OP_deref_type:
4718 	case DW_OP_GNU_deref_type:
4719 	  /* 1-byte unsigned size of value, uleb128 CU relative
4720 	     DW_TAG_base_type DIE offset.  */
4721 	  start = data;
4722 	  NEED (1);
4723 	  usize = *(uint8_t *) data++;
4724 	  NEED (1);
4725 	  get_uleb128 (uleb, data, data + len);
4726 	  if (! print_unresolved_addresses && cu != NULL)
4727 	    uleb += cu->start;
4728 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4729 		  indent, "", (uintmax_t) offset,
4730 		  op_name, usize, uleb);
4731 	  CONSUME (data - start);
4732 	  offset += 1 + (data - start);
4733 	  break;
4734 
4735 	case DW_OP_xderef_type:
4736 	  /* 1-byte unsigned size of value, uleb128 base_type DIE offset.  */
4737 	  start = data;
4738 	  NEED (1);
4739 	  usize = *(uint8_t *) data++;
4740 	  NEED (1);
4741 	  get_uleb128 (uleb, data, data + len);
4742 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4743 		  indent, "", (uintmax_t) offset,
4744 		  op_name, usize, uleb);
4745 	  CONSUME (data - start);
4746 	  offset += 1 + (data - start);
4747 	  break;
4748 
4749 	case DW_OP_convert:
4750 	case DW_OP_GNU_convert:
4751 	case DW_OP_reinterpret:
4752 	case DW_OP_GNU_reinterpret:
4753 	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4754 	     for conversion to untyped.  */
4755 	  start = data;
4756 	  NEED (1);
4757 	  get_uleb128 (uleb, data, data + len);
4758 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4759 	    uleb += cu->start;
4760 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4761 		  indent, "", (uintmax_t) offset, op_name, uleb);
4762 	  CONSUME (data - start);
4763 	  offset += 1 + (data - start);
4764 	  break;
4765 
4766 	case DW_OP_GNU_parameter_ref:
4767 	  /* 4 byte CU relative reference to the abstract optimized away
4768 	     DW_TAG_formal_parameter.  */
4769 	  NEED (4);
4770 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4771 	  if (! print_unresolved_addresses && cu != NULL)
4772 	    param_off += cu->start;
4773 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4774 		  indent, "", (uintmax_t) offset, op_name, param_off);
4775 	  CONSUME (4);
4776 	  data += 4;
4777 	  offset += 5;
4778 	  break;
4779 
4780 	default:
4781 	  /* No Operand.  */
4782 	  printf ("%*s[%2" PRIuMAX "] %s\n",
4783 		  indent, "", (uintmax_t) offset, op_name);
4784 	  ++offset;
4785 	  break;
4786 	}
4787 
4788       indent = indentrest;
4789       continue;
4790 
4791     invalid:
4792       printf (_("%*s[%2" PRIuMAX "] %s  <TRUNCATED>\n"),
4793 	      indent, "", (uintmax_t) offset, op_name);
4794       break;
4795     }
4796 }
4797 
4798 
4799 struct listptr
4800 {
4801   Dwarf_Off offset:(64 - 3);
4802   bool addr64:1;
4803   bool dwarf64:1;
4804   bool warned:1;
4805   struct Dwarf_CU *cu;
4806   unsigned int attr;
4807 };
4808 
4809 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
4810 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
4811 
4812 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4813 cudie_base (Dwarf_Die *cudie)
4814 {
4815   Dwarf_Addr base;
4816   /* Find the base address of the compilation unit.  It will normally
4817      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
4818      address could be overridden by DW_AT_entry_pc.  It's been
4819      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4820      compilation units with discontinuous ranges.  */
4821   if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4822     {
4823       Dwarf_Attribute attr_mem;
4824       if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4825 			  &base) != 0)
4826 	base = 0;
4827     }
4828   return base;
4829 }
4830 
4831 static Dwarf_Addr
listptr_base(struct listptr * p)4832 listptr_base (struct listptr *p)
4833 {
4834   Dwarf_Die cu = CUDIE (p->cu);
4835   return cudie_base (&cu);
4836 }
4837 
4838 /* To store the name used in compare_listptr */
4839 static const char *sort_listptr_name;
4840 
4841 static int
compare_listptr(const void * a,const void * b)4842 compare_listptr (const void *a, const void *b)
4843 {
4844   const char *name = sort_listptr_name;
4845   struct listptr *p1 = (void *) a;
4846   struct listptr *p2 = (void *) b;
4847 
4848   if (p1->offset < p2->offset)
4849     return -1;
4850   if (p1->offset > p2->offset)
4851     return 1;
4852 
4853   if (!p1->warned && !p2->warned)
4854     {
4855       if (p1->addr64 != p2->addr64)
4856 	{
4857 	  p1->warned = p2->warned = true;
4858 	  error (0, 0,
4859 		 _("%s %#" PRIx64 " used with different address sizes"),
4860 		 name, (uint64_t) p1->offset);
4861 	}
4862       if (p1->dwarf64 != p2->dwarf64)
4863 	{
4864 	  p1->warned = p2->warned = true;
4865 	  error (0, 0,
4866 		 _("%s %#" PRIx64 " used with different offset sizes"),
4867 		 name, (uint64_t) p1->offset);
4868 	}
4869       if (listptr_base (p1) != listptr_base (p2))
4870 	{
4871 	  p1->warned = p2->warned = true;
4872 	  error (0, 0,
4873 		 _("%s %#" PRIx64 " used with different base addresses"),
4874 		 name, (uint64_t) p1->offset);
4875 	}
4876       if (p1->attr != p2 ->attr)
4877 	{
4878 	  p1->warned = p2->warned = true;
4879 	  error (0, 0,
4880 		 _("%s %#" PRIx64
4881 			  " used with different attribute %s and %s"),
4882 		 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
4883 		 dwarf_attr_name (p2->attr));
4884 	}
4885     }
4886 
4887   return 0;
4888 }
4889 
4890 struct listptr_table
4891 {
4892   size_t n;
4893   size_t alloc;
4894   struct listptr *table;
4895 };
4896 
4897 static struct listptr_table known_locsptr;
4898 static struct listptr_table known_loclistsptr;
4899 static struct listptr_table known_rangelistptr;
4900 static struct listptr_table known_rnglistptr;
4901 static struct listptr_table known_addrbases;
4902 static struct listptr_table known_stroffbases;
4903 
4904 static void
reset_listptr(struct listptr_table * table)4905 reset_listptr (struct listptr_table *table)
4906 {
4907   free (table->table);
4908   table->table = NULL;
4909   table->n = table->alloc = 0;
4910 }
4911 
4912 /* Returns false if offset doesn't fit.  See struct listptr.  */
4913 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)4914 notice_listptr (enum section_e section, struct listptr_table *table,
4915 		uint_fast8_t address_size, uint_fast8_t offset_size,
4916 		struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4917 {
4918   if (print_debug_sections & section)
4919     {
4920       if (table->n == table->alloc)
4921 	{
4922 	  if (table->alloc == 0)
4923 	    table->alloc = 128;
4924 	  else
4925 	    table->alloc *= 2;
4926 	  table->table = xrealloc (table->table,
4927 				   table->alloc * sizeof table->table[0]);
4928 	}
4929 
4930       struct listptr *p = &table->table[table->n++];
4931 
4932       *p = (struct listptr)
4933 	{
4934 	  .addr64 = address_size == 8,
4935 	  .dwarf64 = offset_size == 8,
4936 	  .offset = offset,
4937 	  .cu = cu,
4938 	  .attr = attr
4939 	};
4940 
4941       if (p->offset != offset)
4942 	{
4943 	  table->n--;
4944 	  return false;
4945 	}
4946     }
4947   return true;
4948 }
4949 
4950 static void
sort_listptr(struct listptr_table * table,const char * name)4951 sort_listptr (struct listptr_table *table, const char *name)
4952 {
4953   if (table->n > 0)
4954     {
4955       sort_listptr_name = name;
4956       qsort (table->table, table->n, sizeof table->table[0],
4957 	     &compare_listptr);
4958     }
4959 }
4960 
4961 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)4962 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4963 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4964 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4965 		   unsigned char **readp, unsigned char *endp,
4966 		   unsigned int *attr)
4967 {
4968   if (table->n == 0)
4969     return false;
4970 
4971   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4972     ++*idxp;
4973 
4974   struct listptr *p = &table->table[*idxp];
4975 
4976   if (*idxp == table->n
4977       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4978     {
4979       *readp = endp;
4980       printf (_(" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
4981 	      offset);
4982       return true;
4983     }
4984 
4985   if (p->offset != (Dwarf_Off) offset)
4986     {
4987       *readp += p->offset - offset;
4988       printf (_(" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4989 	      offset, (Dwarf_Off) p->offset - offset);
4990       return true;
4991     }
4992 
4993   if (address_sizep != NULL)
4994     *address_sizep = listptr_address_size (p);
4995   if (offset_sizep != NULL)
4996     *offset_sizep = listptr_offset_size (p);
4997   if (base != NULL)
4998     *base = listptr_base (p);
4999   if (cu != NULL)
5000     *cu = p->cu;
5001   if (attr != NULL)
5002     *attr = p->attr;
5003 
5004   return false;
5005 }
5006 
5007 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t * idxp,Dwarf_Off off)5008 next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off)
5009 {
5010   /* Note that multiple attributes could in theory point to the same loclist
5011      offset, so make sure we pick one that is bigger than the current one.
5012      The table is sorted on offset.  */
5013   if (*idxp < table->n)
5014     {
5015       while (++*idxp < table->n)
5016 	{
5017 	  Dwarf_Off next = table->table[*idxp].offset;
5018 	  if (next > off)
5019 	    return next;
5020 	}
5021     }
5022   return 0;
5023 }
5024 
5025 /* Returns the listptr associated with the given index, or NULL.  */
5026 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5027 get_listptr (struct listptr_table *table, size_t idx)
5028 {
5029   if (idx >= table->n)
5030     return NULL;
5031   return &table->table[idx];
5032 }
5033 
5034 /* Returns the next index, base address and CU associated with the
5035    list unit offsets.  If there is none false is returned, otherwise
5036    true.  Assumes the table has been sorted.  */
5037 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5038 listptr_cu (struct listptr_table *table, size_t *idxp,
5039 	    Dwarf_Off start, Dwarf_Off end,
5040 	    Dwarf_Addr *base, struct Dwarf_CU **cu)
5041 {
5042   while (*idxp < table->n
5043 	 && table->table[*idxp].offset < start)
5044     ++*idxp;
5045 
5046   if (*idxp < table->n
5047       && table->table[*idxp].offset >= start
5048       && table->table[*idxp].offset < end)
5049     {
5050       struct listptr *p = &table->table[*idxp];
5051       *base = listptr_base (p);
5052       *cu = p->cu;
5053       return true;
5054     }
5055 
5056   return false;
5057 }
5058 
5059 /* Returns the next index with the current CU for the given attribute.
5060    If there is none false is returned, otherwise true.  Assumes the
5061    table has been sorted.  */
5062 static bool
listptr_attr(struct listptr_table * table,size_t idxp,Dwarf_Off offset,unsigned int attr)5063 listptr_attr (struct listptr_table *table, size_t idxp,
5064 	      Dwarf_Off offset, unsigned int attr)
5065 {
5066   struct listptr *listptr;
5067   do
5068     {
5069       listptr = get_listptr (table, idxp);
5070       if (listptr == NULL)
5071 	return false;
5072 
5073       if (listptr->offset == offset && listptr->attr == attr)
5074 	return true;
5075 
5076       idxp++;
5077     }
5078   while (listptr->offset <= offset);
5079 
5080   return false;
5081 }
5082 
5083 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5084 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5085 			    Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5086 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5087 {
5088   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5089 			  dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5090 
5091   printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5092 		   " [ Code]\n"),
5093 	  elf_ndxscn (scn), section_name (ebl, shdr),
5094 	  (uint64_t) shdr->sh_offset);
5095 
5096   Dwarf_Off offset = 0;
5097   while (offset < sh_size)
5098     {
5099       printf (_("\nAbbreviation section at offset %" PRIu64 ":\n"),
5100 	      offset);
5101 
5102       while (1)
5103 	{
5104 	  size_t length;
5105 	  Dwarf_Abbrev abbrev;
5106 
5107 	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5108 	  if (res != 0)
5109 	    {
5110 	      if (unlikely (res < 0))
5111 		{
5112 		  printf (_("\
5113  *** error while reading abbreviation: %s\n"),
5114 			  dwarf_errmsg (-1));
5115 		  return;
5116 		}
5117 
5118 	      /* This is the NUL byte at the end of the section.  */
5119 	      ++offset;
5120 	      break;
5121 	    }
5122 
5123 	  /* We know these calls can never fail.  */
5124 	  unsigned int code = dwarf_getabbrevcode (&abbrev);
5125 	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
5126 	  int has_children = dwarf_abbrevhaschildren (&abbrev);
5127 
5128 	  printf (_(" [%5u] offset: %" PRId64
5129 			   ", children: %s, tag: %s\n"),
5130 		  code, (int64_t) offset,
5131 		  has_children ? yes_str : no_str,
5132 		  dwarf_tag_name (tag));
5133 
5134 	  size_t cnt = 0;
5135 	  unsigned int name;
5136 	  unsigned int form;
5137 	  Dwarf_Sword data;
5138 	  Dwarf_Off enoffset;
5139 	  while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5140 					   &data, &enoffset) == 0)
5141 	    {
5142 	      printf ("          attr: %s, form: %s",
5143 		      dwarf_attr_name (name), dwarf_form_name (form));
5144 	      if (form == DW_FORM_implicit_const)
5145 		printf (" (%" PRId64 ")", data);
5146 	      printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5147 	      ++cnt;
5148 	    }
5149 
5150 	  offset += length;
5151 	}
5152     }
5153 }
5154 
5155 
5156 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5157 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5158 			  Ebl *ebl, GElf_Ehdr *ehdr,
5159 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5160 {
5161   printf (_("\
5162 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5163 	  elf_ndxscn (scn), section_name (ebl, shdr),
5164 	  (uint64_t) shdr->sh_offset);
5165 
5166   if (shdr->sh_size == 0)
5167     return;
5168 
5169   /* We like to get the section from libdw to make sure they are relocated.  */
5170   Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5171 		    ?: elf_rawdata (scn, NULL));
5172   if (unlikely (data == NULL))
5173     {
5174       error (0, 0, _("cannot get .debug_addr section data: %s"),
5175 	     elf_errmsg (-1));
5176       return;
5177     }
5178 
5179   size_t idx = 0;
5180   sort_listptr (&known_addrbases, "addr_base");
5181 
5182   const unsigned char *start = (const unsigned char *) data->d_buf;
5183   const unsigned char *readp = start;
5184   const unsigned char *readendp = ((const unsigned char *) data->d_buf
5185 				   + data->d_size);
5186 
5187   while (readp < readendp)
5188     {
5189       /* We cannot really know whether or not there is an header.  The
5190 	 DebugFission extension to DWARF4 doesn't add one.  The DWARF5
5191 	 .debug_addr variant does.  Whether or not we have an header,
5192 	 DW_AT_[GNU_]addr_base points at "index 0".  So if the current
5193 	 offset equals the CU addr_base then we can just start
5194 	 printing addresses.  If there is no CU with an exact match
5195 	 then we'll try to parse the header first.  */
5196       Dwarf_Off off = (Dwarf_Off) (readp
5197 				   - (const unsigned char *) data->d_buf);
5198 
5199       printf ("Table at offset %" PRIx64 " ", off);
5200 
5201       struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5202       const unsigned char *next_unitp;
5203 
5204       uint64_t unit_length;
5205       uint16_t version;
5206       uint8_t address_size;
5207       uint8_t segment_size;
5208       if (listptr == NULL)
5209 	{
5210 	  error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5211 		 off);
5212 
5213 	  /* We will have to assume it is just addresses to the end... */
5214 	  address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5215 	  next_unitp = readendp;
5216 	  printf ("Unknown CU:\n");
5217 	}
5218       else
5219 	{
5220 	  Dwarf_Die cudie;
5221 	  if (dwarf_cu_die (listptr->cu, &cudie,
5222 			    NULL, NULL, NULL, NULL,
5223 			    NULL, NULL) == NULL)
5224 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5225 	  else
5226 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5227 
5228 	  if (listptr->offset == off)
5229 	    {
5230 	      address_size = listptr_address_size (listptr);
5231 	      segment_size = 0;
5232 	      version = 4;
5233 
5234 	      /* The addresses start here, but where do they end?  */
5235 	      listptr = get_listptr (&known_addrbases, idx);
5236 	      if (listptr == NULL)
5237 		next_unitp = readendp;
5238 	      else if (listptr->cu->version < 5)
5239 		{
5240 		  next_unitp = start + listptr->offset;
5241 		  if (listptr->offset < off || listptr->offset > data->d_size)
5242 		    {
5243 		      error (0, 0,
5244 			     "Warning: Bad address base for next unit at %"
5245 			     PRIx64, off);
5246 		      next_unitp = readendp;
5247 		    }
5248 		}
5249 	      else
5250 		{
5251 		  /* Tricky, we don't have a header for this unit, but
5252 		     there is one for the next.  We will have to
5253 		     "guess" how big it is and subtract it from the
5254 		     offset (because that points after the header).  */
5255 		  unsigned int offset_size = listptr_offset_size (listptr);
5256 		  Dwarf_Off next_off = (listptr->offset
5257 					- (offset_size == 4 ? 4 : 12) /* len */
5258 					- 2 /* version */
5259 					- 1 /* address size */
5260 					- 1); /* segment selector size */
5261 		  next_unitp = start + next_off;
5262 		  if (next_off < off || next_off > data->d_size)
5263 		    {
5264 		      error (0, 0,
5265 			     "Warning: Couldn't calculate .debug_addr "
5266 			     " unit length at %" PRIx64, off);
5267 		      next_unitp = readendp;
5268 		    }
5269 		}
5270 	      unit_length = (uint64_t) (next_unitp - readp);
5271 
5272 	      /* Pretend we have a header.  */
5273 	      printf ("\n");
5274 	      printf (_(" Length:         %8" PRIu64 "\n"),
5275 		      unit_length);
5276 	      printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
5277 	      printf (_(" Address size:   %8" PRIu64 "\n"),
5278 		      (uint64_t) address_size);
5279 	      printf (_(" Segment size:   %8" PRIu64 "\n"),
5280 		      (uint64_t) segment_size);
5281 	      printf ("\n");
5282 	    }
5283 	  else
5284 	    {
5285 	      /* OK, we have to parse an header first.  */
5286 	      unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5287 	      if (unlikely (unit_length == 0xffffffff))
5288 		{
5289 		  if (unlikely (readp > readendp - 8))
5290 		    {
5291 		    invalid_data:
5292 		      error (0, 0, "Invalid data");
5293 		      return;
5294 		    }
5295 		  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5296 		}
5297 	      printf ("\n");
5298 	      printf (_(" Length:         %8" PRIu64 "\n"),
5299 		      unit_length);
5300 
5301 	      /* We need at least 2-bytes (version) + 1-byte
5302 		 (addr_size) + 1-byte (segment_size) = 4 bytes to
5303 		 complete the header.  And this unit cannot go beyond
5304 		 the section data.  */
5305 	      if (readp > readendp - 4
5306 		  || unit_length < 4
5307 		  || unit_length > (uint64_t) (readendp - readp))
5308 		goto invalid_data;
5309 
5310 	      next_unitp = readp + unit_length;
5311 
5312 	      version = read_2ubyte_unaligned_inc (dbg, readp);
5313 	      printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
5314 
5315 	      if (version != 5)
5316 		{
5317 		  error (0, 0, _("Unknown version"));
5318 		  goto next_unit;
5319 		}
5320 
5321 	      address_size = *readp++;
5322 	      printf (_(" Address size:   %8" PRIu64 "\n"),
5323 		      (uint64_t) address_size);
5324 
5325 	      if (address_size != 4 && address_size != 8)
5326 		{
5327 		  error (0, 0, _("unsupported address size"));
5328 		  goto next_unit;
5329 		}
5330 
5331 	      segment_size = *readp++;
5332 	      printf (_(" Segment size:   %8" PRIu64 "\n"),
5333 		      (uint64_t) segment_size);
5334 	      printf ("\n");
5335 
5336 	      if (segment_size != 0)
5337 		{
5338 		  error (0, 0, _("unsupported segment size"));
5339 		  goto next_unit;
5340 		}
5341 
5342 	      if (listptr->offset != (Dwarf_Off) (readp - start))
5343 		{
5344 		  error (0, 0, "Address index doesn't start after header");
5345 		  goto next_unit;
5346 		}
5347 	    }
5348 	}
5349 
5350       int digits = 1;
5351       size_t addresses = (next_unitp - readp) / address_size;
5352       while (addresses >= 10)
5353 	{
5354 	  ++digits;
5355 	  addresses /= 10;
5356 	}
5357 
5358       unsigned int uidx = 0;
5359       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
5360       printf (" Addresses start at offset 0x%zx:\n", index_offset);
5361       while (readp <= next_unitp - address_size)
5362 	{
5363 	  Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5364 						     readp);
5365 	  printf (" [%*u] ", digits, uidx++);
5366 	  print_dwarf_addr (dwflmod, address_size, addr, addr);
5367 	  printf ("\n");
5368 	}
5369       printf ("\n");
5370 
5371       if (readp != next_unitp)
5372 	error (0, 0, "extra %zd bytes at end of unit",
5373 	       (size_t) (next_unitp - readp));
5374 
5375     next_unit:
5376       readp = next_unitp;
5377     }
5378 }
5379 
5380 /* Print content of DWARF .debug_aranges section.  We fortunately do
5381    not have to know a bit about the structure of the section, libdwarf
5382    takes care of it.  */
5383 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5384 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5385 			       GElf_Shdr *shdr, Dwarf *dbg)
5386 {
5387   Dwarf_Aranges *aranges;
5388   size_t cnt;
5389   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5390     {
5391       error (0, 0, _("cannot get .debug_aranges content: %s"),
5392 	     dwarf_errmsg (-1));
5393       return;
5394     }
5395 
5396   GElf_Shdr glink_mem;
5397   GElf_Shdr *glink;
5398   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5399   if (glink == NULL)
5400     {
5401       error (0, 0, _("invalid sh_link value in section %zu"),
5402 	     elf_ndxscn (scn));
5403       return;
5404     }
5405 
5406   printf (ngettext ("\
5407 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5408 		    "\
5409 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5410 		    cnt),
5411 	  elf_ndxscn (scn), section_name (ebl, shdr),
5412 	  (uint64_t) shdr->sh_offset, cnt);
5413 
5414   /* Compute floor(log16(cnt)).  */
5415   size_t tmp = cnt;
5416   int digits = 1;
5417   while (tmp >= 16)
5418     {
5419       ++digits;
5420       tmp >>= 4;
5421     }
5422 
5423   for (size_t n = 0; n < cnt; ++n)
5424     {
5425       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5426       if (unlikely (runp == NULL))
5427 	{
5428 	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5429 	  return;
5430 	}
5431 
5432       Dwarf_Addr start;
5433       Dwarf_Word length;
5434       Dwarf_Off offset;
5435 
5436       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5437 	printf (_(" [%*zu] ???\n"), digits, n);
5438       else
5439 	printf (_(" [%*zu] start: %0#*" PRIx64
5440 			 ", length: %5" PRIu64 ", CU DIE offset: %6"
5441 			 PRId64 "\n"),
5442 		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5443 		(uint64_t) start, (uint64_t) length, (int64_t) offset);
5444     }
5445 }
5446 
5447 
5448 /* Print content of DWARF .debug_aranges section.  */
5449 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5450 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5451 			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5452 			     GElf_Shdr *shdr, Dwarf *dbg)
5453 {
5454   if (decodedaranges)
5455     {
5456       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5457       return;
5458     }
5459 
5460   Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5461 		    ?: elf_rawdata (scn, NULL));
5462 
5463   if (unlikely (data == NULL))
5464     {
5465       error (0, 0, _("cannot get .debug_aranges content: %s"),
5466 	     elf_errmsg (-1));
5467       return;
5468     }
5469 
5470   printf (_("\
5471 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5472 	  elf_ndxscn (scn), section_name (ebl, shdr),
5473 	  (uint64_t) shdr->sh_offset);
5474 
5475   const unsigned char *readp = data->d_buf;
5476   const unsigned char *readendp = readp + data->d_size;
5477 
5478   while (readp < readendp)
5479     {
5480       const unsigned char *hdrstart = readp;
5481       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5482 
5483       printf (_("\nTable at offset %zu:\n"), start_offset);
5484       if (readp + 4 > readendp)
5485 	{
5486 	invalid_data:
5487 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
5488 		 elf_ndxscn (scn), section_name (ebl, shdr));
5489 	  return;
5490 	}
5491 
5492       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5493       unsigned int length_bytes = 4;
5494       if (length == DWARF3_LENGTH_64_BIT)
5495 	{
5496 	  if (readp + 8 > readendp)
5497 	    goto invalid_data;
5498 	  length = read_8ubyte_unaligned_inc (dbg, readp);
5499 	  length_bytes = 8;
5500 	}
5501 
5502       const unsigned char *nexthdr = readp + length;
5503       printf (_("\n Length:        %6" PRIu64 "\n"),
5504 	      (uint64_t) length);
5505 
5506       if (unlikely (length > (size_t) (readendp - readp)))
5507 	goto invalid_data;
5508 
5509       if (length == 0)
5510 	continue;
5511 
5512       if (readp + 2 > readendp)
5513 	goto invalid_data;
5514       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5515       printf (_(" DWARF version: %6" PRIuFAST16 "\n"),
5516 	      version);
5517       if (version != 2)
5518 	{
5519 	  error (0, 0, _("unsupported aranges version"));
5520 	  goto next_table;
5521 	}
5522 
5523       Dwarf_Word offset;
5524       if (readp + length_bytes > readendp)
5525 	goto invalid_data;
5526       if (length_bytes == 8)
5527 	offset = read_8ubyte_unaligned_inc (dbg, readp);
5528       else
5529 	offset = read_4ubyte_unaligned_inc (dbg, readp);
5530       printf (_(" CU offset:     %6" PRIx64 "\n"),
5531 	      (uint64_t) offset);
5532 
5533       if (readp + 1 > readendp)
5534 	goto invalid_data;
5535       unsigned int address_size = *readp++;
5536       printf (_(" Address size:  %6" PRIu64 "\n"),
5537 	      (uint64_t) address_size);
5538       if (address_size != 4 && address_size != 8)
5539 	{
5540 	  error (0, 0, _("unsupported address size"));
5541 	  goto next_table;
5542 	}
5543 
5544       if (readp + 1 > readendp)
5545 	goto invalid_data;
5546       unsigned int segment_size = *readp++;
5547       printf (_(" Segment size:  %6" PRIu64 "\n\n"),
5548 	      (uint64_t) segment_size);
5549       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5550 	{
5551 	  error (0, 0, _("unsupported segment size"));
5552 	  goto next_table;
5553 	}
5554 
5555       /* Round the address to the next multiple of 2*address_size.  */
5556       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5557 		% (2 * address_size));
5558 
5559       while (readp < nexthdr)
5560 	{
5561 	  Dwarf_Word range_address;
5562 	  Dwarf_Word range_length;
5563 	  Dwarf_Word segment = 0;
5564 	  if (readp + 2 * address_size + segment_size > readendp)
5565 	    goto invalid_data;
5566 	  if (address_size == 4)
5567 	    {
5568 	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
5569 	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
5570 	    }
5571 	  else
5572 	    {
5573 	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
5574 	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
5575 	    }
5576 
5577 	  if (segment_size == 4)
5578 	    segment = read_4ubyte_unaligned_inc (dbg, readp);
5579 	  else if (segment_size == 8)
5580 	    segment = read_8ubyte_unaligned_inc (dbg, readp);
5581 
5582 	  if (range_address == 0 && range_length == 0 && segment == 0)
5583 	    break;
5584 
5585 	  printf ("   ");
5586 	  print_dwarf_addr (dwflmod, address_size, range_address,
5587 			    range_address);
5588 	  printf ("..");
5589 	  print_dwarf_addr (dwflmod, address_size,
5590 			    range_address + range_length - 1,
5591 			    range_length);
5592 	  if (segment_size != 0)
5593 	    printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5594 	  else
5595 	    printf ("\n");
5596 	}
5597 
5598     next_table:
5599       if (readp != nexthdr)
5600 	{
5601 	  size_t padding = nexthdr - readp;
5602 	  printf (_("   %zu padding bytes\n"), padding);
5603 	  readp = nexthdr;
5604 	}
5605     }
5606 }
5607 
5608 
5609 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5610 
5611 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5612    DWARF (.dwo) file.  */
5613 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5614 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5615 {
5616   uint64_t id;
5617   if (is_split_dwarf (dbg, &id, cu))
5618     {
5619       Dwarf_Die cudie;
5620       if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5621 	{
5622 	  *cu_base = cudie_base (&cudie);
5623 	  return true;
5624 	}
5625     }
5626   return false;
5627 }
5628 
5629 /* Print content of DWARF .debug_rnglists section.  */
5630 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5631 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5632 			      Ebl *ebl,
5633 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
5634 			      Elf_Scn *scn, GElf_Shdr *shdr,
5635 			      Dwarf *dbg __attribute__((unused)))
5636 {
5637   printf (_("\
5638 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5639 	  elf_ndxscn (scn), section_name (ebl, shdr),
5640 	  (uint64_t) shdr->sh_offset);
5641 
5642   Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5643 		   ?: elf_rawdata (scn, NULL));
5644   if (unlikely (data == NULL))
5645     {
5646       error (0, 0, _("cannot get .debug_rnglists content: %s"),
5647 	     elf_errmsg (-1));
5648       return;
5649     }
5650 
5651   /* For the listptr to get the base address/CU.  */
5652   sort_listptr (&known_rnglistptr, "rnglistptr");
5653   size_t listptr_idx = 0;
5654 
5655   const unsigned char *readp = data->d_buf;
5656   const unsigned char *const dataend = ((unsigned char *) data->d_buf
5657 					+ data->d_size);
5658   while (readp < dataend)
5659     {
5660       if (unlikely (readp > dataend - 4))
5661 	{
5662 	invalid_data:
5663 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
5664 		 elf_ndxscn (scn), section_name (ebl, shdr));
5665 	  return;
5666 	}
5667 
5668       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5669       printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
5670 	      (uint64_t) offset);
5671 
5672       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5673       unsigned int offset_size = 4;
5674       if (unlikely (unit_length == 0xffffffff))
5675 	{
5676 	  if (unlikely (readp > dataend - 8))
5677 	    goto invalid_data;
5678 
5679 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5680 	  offset_size = 8;
5681 	}
5682       printf (_(" Length:         %8" PRIu64 "\n"), unit_length);
5683 
5684       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5685 	 bytes to complete the header.  And this unit cannot go beyond
5686 	 the section data.  */
5687       if (readp > dataend - 8
5688 	  || unit_length < 8
5689 	  || unit_length > (uint64_t) (dataend - readp))
5690 	goto invalid_data;
5691 
5692       const unsigned char *nexthdr = readp + unit_length;
5693 
5694       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5695       printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
5696 
5697       if (version != 5)
5698 	{
5699 	  error (0, 0, _("Unknown version"));
5700 	  goto next_table;
5701 	}
5702 
5703       uint8_t address_size = *readp++;
5704       printf (_(" Address size:   %8" PRIu64 "\n"),
5705 	      (uint64_t) address_size);
5706 
5707       if (address_size != 4 && address_size != 8)
5708 	{
5709 	  error (0, 0, _("unsupported address size"));
5710 	  goto next_table;
5711 	}
5712 
5713       uint8_t segment_size = *readp++;
5714       printf (_(" Segment size:   %8" PRIu64 "\n"),
5715 	      (uint64_t) segment_size);
5716 
5717       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5718         {
5719           error (0, 0, _("unsupported segment size"));
5720           goto next_table;
5721         }
5722 
5723       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5724       printf (_(" Offset entries: %8" PRIu64 "\n"),
5725 	      (uint64_t) offset_entry_count);
5726 
5727       /* We need the CU that uses this unit to get the initial base address. */
5728       Dwarf_Addr cu_base = 0;
5729       struct Dwarf_CU *cu = NULL;
5730       if (listptr_cu (&known_rnglistptr, &listptr_idx,
5731 		      (Dwarf_Off) offset,
5732 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5733 		      &cu_base, &cu)
5734 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
5735 	{
5736 	  Dwarf_Die cudie;
5737 	  if (dwarf_cu_die (cu, &cudie,
5738 			    NULL, NULL, NULL, NULL,
5739 			    NULL, NULL) == NULL)
5740 	    printf (_(" Unknown CU base: "));
5741 	  else
5742 	    printf (_(" CU [%6" PRIx64 "] base: "),
5743 		    dwarf_dieoffset (&cudie));
5744 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5745 	  printf ("\n");
5746 	}
5747       else
5748 	printf (_(" Not associated with a CU.\n"));
5749 
5750       printf ("\n");
5751 
5752       const unsigned char *offset_array_start = readp;
5753       if (offset_entry_count > 0)
5754 	{
5755 	  uint64_t max_entries = (unit_length - 8) / offset_size;
5756 	  if (offset_entry_count > max_entries)
5757 	    {
5758 	      error (0, 0,
5759 		     _("too many offset entries for unit length"));
5760 	      offset_entry_count = max_entries;
5761 	    }
5762 
5763 	  printf (_("  Offsets starting at 0x%" PRIx64 ":\n"),
5764 		  (uint64_t) (offset_array_start
5765 			      - (unsigned char *) data->d_buf));
5766 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5767 	    {
5768 	      printf ("   [%6" PRIu32 "] ", idx);
5769 	      if (offset_size == 4)
5770 		{
5771 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5772 		  printf ("0x%" PRIx32 "\n", off);
5773 		}
5774 	      else
5775 		{
5776 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5777 		  printf ("0x%" PRIx64 "\n", off);
5778 		}
5779 	    }
5780 	  printf ("\n");
5781 	}
5782 
5783       Dwarf_Addr base = cu_base;
5784       bool start_of_list = true;
5785       while (readp < nexthdr)
5786 	{
5787 	  uint8_t kind = *readp++;
5788 	  uint64_t op1, op2;
5789 
5790 	  /* Skip padding.  */
5791 	  if (start_of_list && kind == DW_RLE_end_of_list)
5792 	    continue;
5793 
5794 	  if (start_of_list)
5795 	    {
5796 	      base = cu_base;
5797 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5798 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5799 		      (uint64_t) (readp - offset_array_start - 1));
5800 	      start_of_list = false;
5801 	    }
5802 
5803 	  printf ("    %s", dwarf_range_list_encoding_name (kind));
5804 	  switch (kind)
5805 	    {
5806 	    case DW_RLE_end_of_list:
5807 	      start_of_list = true;
5808 	      printf ("\n\n");
5809 	      break;
5810 
5811 	    case DW_RLE_base_addressx:
5812 	      if ((uint64_t) (nexthdr - readp) < 1)
5813 		{
5814 		invalid_range:
5815 		  error (0, 0, _("invalid range list data"));
5816 		  goto next_table;
5817 		}
5818 	      get_uleb128 (op1, readp, nexthdr);
5819 	      printf (" %" PRIx64 "\n", op1);
5820 	      if (! print_unresolved_addresses)
5821 		{
5822 		  Dwarf_Addr addr;
5823 		  if (get_indexed_addr (cu, op1, &addr) != 0)
5824 		    printf ("      ???\n");
5825 		  else
5826 		    {
5827 		      printf ("      ");
5828 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
5829 		      printf ("\n");
5830 		    }
5831 		}
5832 	      break;
5833 
5834 	    case DW_RLE_startx_endx:
5835 	      if ((uint64_t) (nexthdr - readp) < 1)
5836 		goto invalid_range;
5837 	      get_uleb128 (op1, readp, nexthdr);
5838 	      if ((uint64_t) (nexthdr - readp) < 1)
5839 		goto invalid_range;
5840 	      get_uleb128 (op2, readp, nexthdr);
5841 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5842 	      if (! print_unresolved_addresses)
5843 		{
5844 		  Dwarf_Addr addr1;
5845 		  Dwarf_Addr addr2;
5846 		  if (get_indexed_addr (cu, op1, &addr1) != 0
5847 		      || get_indexed_addr (cu, op2, &addr2) != 0)
5848 		    {
5849 		      printf ("      ???..\n");
5850 		      printf ("      ???\n");
5851 		    }
5852 		  else
5853 		    {
5854 		      printf ("      ");
5855 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5856 		      printf ("..\n      ");
5857 		      print_dwarf_addr (dwflmod, address_size,
5858 					addr2 - 1, addr2);
5859 		      printf ("\n");
5860 		    }
5861 		}
5862 	      break;
5863 
5864 	    case DW_RLE_startx_length:
5865 	      if ((uint64_t) (nexthdr - readp) < 1)
5866 		goto invalid_range;
5867 	      get_uleb128 (op1, readp, nexthdr);
5868 	      if ((uint64_t) (nexthdr - readp) < 1)
5869 		goto invalid_range;
5870 	      get_uleb128 (op2, readp, nexthdr);
5871 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5872 	      if (! print_unresolved_addresses)
5873 		{
5874 		  Dwarf_Addr addr1;
5875 		  Dwarf_Addr addr2;
5876 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
5877 		    {
5878 		      printf ("      ???..\n");
5879 		      printf ("      ???\n");
5880 		    }
5881 		  else
5882 		    {
5883 		      addr2 = addr1 + op2;
5884 		      printf ("      ");
5885 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5886 		      printf ("..\n      ");
5887 		      print_dwarf_addr (dwflmod, address_size,
5888 					addr2 - 1, addr2);
5889 		      printf ("\n");
5890 		    }
5891 		}
5892 	      break;
5893 
5894 	    case DW_RLE_offset_pair:
5895 	      if ((uint64_t) (nexthdr - readp) < 1)
5896 		goto invalid_range;
5897 	      get_uleb128 (op1, readp, nexthdr);
5898 	      if ((uint64_t) (nexthdr - readp) < 1)
5899 		goto invalid_range;
5900 	      get_uleb128 (op2, readp, nexthdr);
5901 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5902 	      if (! print_unresolved_addresses)
5903 		{
5904 		  op1 += base;
5905 		  op2 += base;
5906 		  printf ("      ");
5907 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5908 		  printf ("..\n      ");
5909 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5910 		  printf ("\n");
5911 		}
5912 	      break;
5913 
5914 	    case DW_RLE_base_address:
5915 	      if (address_size == 4)
5916 		{
5917 		  if ((uint64_t) (nexthdr - readp) < 4)
5918 		    goto invalid_range;
5919 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5920 		}
5921 	      else
5922 		{
5923 		  if ((uint64_t) (nexthdr - readp) < 8)
5924 		    goto invalid_range;
5925 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5926 		}
5927 	      base = op1;
5928 	      printf (" 0x%" PRIx64 "\n", base);
5929 	      if (! print_unresolved_addresses)
5930 		{
5931 		  printf ("      ");
5932 		  print_dwarf_addr (dwflmod, address_size, base, base);
5933 		  printf ("\n");
5934 		}
5935 	      break;
5936 
5937 	    case DW_RLE_start_end:
5938 	      if (address_size == 4)
5939 		{
5940 		  if ((uint64_t) (nexthdr - readp) < 8)
5941 		    goto invalid_range;
5942 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5943 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
5944 		}
5945 	      else
5946 		{
5947 		  if ((uint64_t) (nexthdr - readp) < 16)
5948 		    goto invalid_range;
5949 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5950 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
5951 		}
5952 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5953 	      if (! print_unresolved_addresses)
5954 		{
5955 		  printf ("      ");
5956 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5957 		  printf ("..\n      ");
5958 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5959 		  printf ("\n");
5960 		}
5961 	      break;
5962 
5963 	    case DW_RLE_start_length:
5964 	      if (address_size == 4)
5965 		{
5966 		  if ((uint64_t) (nexthdr - readp) < 4)
5967 		    goto invalid_range;
5968 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5969 		}
5970 	      else
5971 		{
5972 		  if ((uint64_t) (nexthdr - readp) < 8)
5973 		    goto invalid_range;
5974 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5975 		}
5976 	      if ((uint64_t) (nexthdr - readp) < 1)
5977 		goto invalid_range;
5978 	      get_uleb128 (op2, readp, nexthdr);
5979 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5980 	      if (! print_unresolved_addresses)
5981 		{
5982 		  op2 = op1 + op2;
5983 		  printf ("      ");
5984 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5985 		  printf ("..\n      ");
5986 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5987 		  printf ("\n");
5988 		}
5989 	      break;
5990 
5991 	    default:
5992 	      goto invalid_range;
5993 	    }
5994 	}
5995 
5996     next_table:
5997       if (readp != nexthdr)
5998 	{
5999           size_t padding = nexthdr - readp;
6000           printf (_("   %zu padding bytes\n\n"), padding);
6001 	  readp = nexthdr;
6002 	}
6003     }
6004 }
6005 
6006 /* Print content of DWARF .debug_ranges section.  */
6007 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6008 print_debug_ranges_section (Dwfl_Module *dwflmod,
6009 			    Ebl *ebl, GElf_Ehdr *ehdr,
6010 			    Elf_Scn *scn, GElf_Shdr *shdr,
6011 			    Dwarf *dbg)
6012 {
6013   Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
6014 		    ?: elf_rawdata (scn, NULL));
6015   if (unlikely (data == NULL))
6016     {
6017       error (0, 0, _("cannot get .debug_ranges content: %s"),
6018 	     elf_errmsg (-1));
6019       return;
6020     }
6021 
6022   printf (_("\
6023 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6024 	  elf_ndxscn (scn), section_name (ebl, shdr),
6025 	  (uint64_t) shdr->sh_offset);
6026 
6027   sort_listptr (&known_rangelistptr, "rangelistptr");
6028   size_t listptr_idx = 0;
6029 
6030   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6031 
6032   bool first = true;
6033   Dwarf_Addr base = 0;
6034   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6035   unsigned char *readp = data->d_buf;
6036   Dwarf_CU *last_cu = NULL;
6037   while (readp < endp)
6038     {
6039       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6040       Dwarf_CU *cu = last_cu;
6041 
6042       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6043 				      &address_size, NULL, &base, &cu,
6044 				      offset, &readp, endp, NULL))
6045 	continue;
6046 
6047       if (last_cu != cu)
6048 	{
6049 	  Dwarf_Die cudie;
6050 	  if (dwarf_cu_die (cu, &cudie,
6051 			    NULL, NULL, NULL, NULL,
6052 			    NULL, NULL) == NULL)
6053 	    printf (_("\n Unknown CU base: "));
6054 	  else
6055 	    printf (_("\n CU [%6" PRIx64 "] base: "),
6056 		    dwarf_dieoffset (&cudie));
6057 	  print_dwarf_addr (dwflmod, address_size, base, base);
6058 	  printf ("\n");
6059 	}
6060       last_cu = cu;
6061 
6062       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6063 	{
6064 	  printf (_(" [%6tx]  <INVALID DATA>\n"), offset);
6065 	  break;
6066 	}
6067 
6068       Dwarf_Addr begin;
6069       Dwarf_Addr end;
6070       if (address_size == 8)
6071 	{
6072 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
6073 	  end = read_8ubyte_unaligned_inc (dbg, readp);
6074 	}
6075       else
6076 	{
6077 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
6078 	  end = read_4ubyte_unaligned_inc (dbg, readp);
6079 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
6080 	    begin = (Dwarf_Addr) -1l;
6081 	}
6082 
6083       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
6084 	{
6085 	  if (first)
6086 	    printf (" [%6tx] ", offset);
6087 	  else
6088 	    printf ("          ");
6089 	  puts (_("base address"));
6090 	  printf ("          ");
6091 	  print_dwarf_addr (dwflmod, address_size, end, end);
6092 	  printf ("\n");
6093 	  base = end;
6094 	  first = false;
6095 	}
6096       else if (begin == 0 && end == 0) /* End of list entry.  */
6097 	{
6098 	  if (first)
6099 	    printf (_(" [%6tx] empty list\n"), offset);
6100 	  first = true;
6101 	}
6102       else
6103 	{
6104 	  /* We have an address range entry.  */
6105 	  if (first)		/* First address range entry in a list.  */
6106 	    printf (" [%6tx] ", offset);
6107 	  else
6108 	    printf ("          ");
6109 
6110 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6111 	  if (! print_unresolved_addresses)
6112 	    {
6113 	      printf ("          ");
6114 	      print_dwarf_addr (dwflmod, address_size, base + begin,
6115 			        base + begin);
6116 	      printf ("..\n          ");
6117 	      print_dwarf_addr (dwflmod, address_size,
6118 				base + end - 1, base + end);
6119 	      printf ("\n");
6120 	    }
6121 
6122 	  first = false;
6123 	}
6124     }
6125 }
6126 
6127 #define REGNAMESZ 16
6128 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6129 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6130 	       char name[REGNAMESZ], int *bits, int *type)
6131 {
6132   const char *set;
6133   const char *pfx;
6134   int ignore;
6135   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6136 				 bits ?: &ignore, type ?: &ignore);
6137   if (n <= 0)
6138     {
6139       if (loc != NULL)
6140 	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6141       else
6142 	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6143       if (bits != NULL)
6144 	*bits = loc != NULL ? loc->bits : 0;
6145       if (type != NULL)
6146 	*type = DW_ATE_unsigned;
6147       set = "??? unrecognized";
6148     }
6149   else
6150     {
6151       if (bits != NULL && *bits <= 0)
6152 	*bits = loc != NULL ? loc->bits : 0;
6153       if (type != NULL && *type == DW_ATE_void)
6154 	*type = DW_ATE_unsigned;
6155 
6156     }
6157   return set;
6158 }
6159 
6160 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6161 read_encoded (unsigned int encoding, const unsigned char *readp,
6162 	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6163 {
6164   if ((encoding & 0xf) == DW_EH_PE_absptr)
6165     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6166       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6167 
6168   switch (encoding & 0xf)
6169     {
6170     case DW_EH_PE_uleb128:
6171       get_uleb128 (*res, readp, endp);
6172       break;
6173     case DW_EH_PE_sleb128:
6174       get_sleb128 (*res, readp, endp);
6175       break;
6176     case DW_EH_PE_udata2:
6177       if (readp + 2 > endp)
6178 	goto invalid;
6179       *res = read_2ubyte_unaligned_inc (dbg, readp);
6180       break;
6181     case DW_EH_PE_udata4:
6182       if (readp + 4 > endp)
6183 	goto invalid;
6184       *res = read_4ubyte_unaligned_inc (dbg, readp);
6185       break;
6186     case DW_EH_PE_udata8:
6187       if (readp + 8 > endp)
6188 	goto invalid;
6189       *res = read_8ubyte_unaligned_inc (dbg, readp);
6190       break;
6191     case DW_EH_PE_sdata2:
6192       if (readp + 2 > endp)
6193 	goto invalid;
6194       *res = read_2sbyte_unaligned_inc (dbg, readp);
6195       break;
6196     case DW_EH_PE_sdata4:
6197       if (readp + 4 > endp)
6198 	goto invalid;
6199       *res = read_4sbyte_unaligned_inc (dbg, readp);
6200       break;
6201     case DW_EH_PE_sdata8:
6202       if (readp + 8 > endp)
6203 	goto invalid;
6204       *res = read_8sbyte_unaligned_inc (dbg, readp);
6205       break;
6206     default:
6207     invalid:
6208       error (1, 0,
6209 	     _("invalid encoding"));
6210     }
6211 
6212   return readp;
6213 }
6214 
6215 static const char *
regname(Ebl * ebl,unsigned int regno,char * regnamebuf)6216 regname (Ebl *ebl, unsigned int regno, char *regnamebuf)
6217 {
6218   register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6219 
6220   return regnamebuf;
6221 }
6222 
6223 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,GElf_Ehdr * ehdr,Dwarf * dbg)6224 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6225 		   Dwarf_Word vma_base, unsigned int code_align,
6226 		   int data_align,
6227 		   unsigned int version, unsigned int ptr_size,
6228 		   unsigned int encoding,
6229 		   Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
6230 {
6231   char regnamebuf[REGNAMESZ];
6232 
6233   puts ("\n   Program:");
6234   Dwarf_Word pc = vma_base;
6235   while (readp < endp)
6236     {
6237       unsigned int opcode = *readp++;
6238 
6239       if (opcode < DW_CFA_advance_loc)
6240 	/* Extended opcode.  */
6241 	switch (opcode)
6242 	  {
6243 	    uint64_t op1;
6244 	    int64_t sop1;
6245 	    uint64_t op2;
6246 	    int64_t sop2;
6247 
6248 	  case DW_CFA_nop:
6249 	    puts ("     nop");
6250 	    break;
6251 	  case DW_CFA_set_loc:
6252 	    if ((uint64_t) (endp - readp) < 1)
6253 	      goto invalid;
6254 	    readp = read_encoded (encoding, readp, endp, &op1, dbg);
6255 	    printf ("     set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6256 		    op1, pc = vma_base + op1);
6257 	    break;
6258 	  case DW_CFA_advance_loc1:
6259 	    if ((uint64_t) (endp - readp) < 1)
6260 	      goto invalid;
6261 	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
6262 		    *readp, pc += *readp * code_align);
6263 	    ++readp;
6264 	    break;
6265 	  case DW_CFA_advance_loc2:
6266 	    if ((uint64_t) (endp - readp) < 2)
6267 	      goto invalid;
6268 	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
6269 	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6270 		    op1, pc += op1 * code_align);
6271 	    break;
6272 	  case DW_CFA_advance_loc4:
6273 	    if ((uint64_t) (endp - readp) < 4)
6274 	      goto invalid;
6275 	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
6276 	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6277 		    op1, pc += op1 * code_align);
6278 	    break;
6279 	  case DW_CFA_offset_extended:
6280 	    if ((uint64_t) (endp - readp) < 1)
6281 	      goto invalid;
6282 	    get_uleb128 (op1, readp, endp);
6283 	    if ((uint64_t) (endp - readp) < 1)
6284 	      goto invalid;
6285 	    get_uleb128 (op2, readp, endp);
6286 	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6287 		    "\n",
6288 		    op1, regname (ebl, op1, regnamebuf), op2 * data_align);
6289 	    break;
6290 	  case DW_CFA_restore_extended:
6291 	    if ((uint64_t) (endp - readp) < 1)
6292 	      goto invalid;
6293 	    get_uleb128 (op1, readp, endp);
6294 	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
6295 		    op1, regname (ebl, op1, regnamebuf));
6296 	    break;
6297 	  case DW_CFA_undefined:
6298 	    if ((uint64_t) (endp - readp) < 1)
6299 	      goto invalid;
6300 	    get_uleb128 (op1, readp, endp);
6301 	    printf ("     undefined r%" PRIu64 " (%s)\n", op1,
6302 		    regname (ebl, op1, regnamebuf));
6303 	    break;
6304 	  case DW_CFA_same_value:
6305 	    if ((uint64_t) (endp - readp) < 1)
6306 	      goto invalid;
6307 	    get_uleb128 (op1, readp, endp);
6308 	    printf ("     same_value r%" PRIu64 " (%s)\n", op1,
6309 		    regname (ebl, op1, regnamebuf));
6310 	    break;
6311 	  case DW_CFA_register:
6312 	    if ((uint64_t) (endp - readp) < 1)
6313 	      goto invalid;
6314 	    get_uleb128 (op1, readp, endp);
6315 	    if ((uint64_t) (endp - readp) < 1)
6316 	      goto invalid;
6317 	    get_uleb128 (op2, readp, endp);
6318 	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6319 		    op1, regname (ebl, op1, regnamebuf), op2,
6320 		    regname (ebl, op2, regnamebuf));
6321 	    break;
6322 	  case DW_CFA_remember_state:
6323 	    puts ("     remember_state");
6324 	    break;
6325 	  case DW_CFA_restore_state:
6326 	    puts ("     restore_state");
6327 	    break;
6328 	  case DW_CFA_def_cfa:
6329 	    if ((uint64_t) (endp - readp) < 1)
6330 	      goto invalid;
6331 	    get_uleb128 (op1, readp, endp);
6332 	    if ((uint64_t) (endp - readp) < 1)
6333 	      goto invalid;
6334 	    get_uleb128 (op2, readp, endp);
6335 	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6336 		    op1, regname (ebl, op1, regnamebuf), op2);
6337 	    break;
6338 	  case DW_CFA_def_cfa_register:
6339 	    if ((uint64_t) (endp - readp) < 1)
6340 	      goto invalid;
6341 	    get_uleb128 (op1, readp, endp);
6342 	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
6343 		    op1, regname (ebl, op1, regnamebuf));
6344 	    break;
6345 	  case DW_CFA_def_cfa_offset:
6346 	    if ((uint64_t) (endp - readp) < 1)
6347 	      goto invalid;
6348 	    get_uleb128 (op1, readp, endp);
6349 	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
6350 	    break;
6351 	  case DW_CFA_def_cfa_expression:
6352 	    if ((uint64_t) (endp - readp) < 1)
6353 	      goto invalid;
6354 	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
6355 	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
6356 	    if ((uint64_t) (endp - readp) < op1)
6357 	      {
6358 	    invalid:
6359 	        fputs (_("         <INVALID DATA>\n"), stdout);
6360 		return;
6361 	      }
6362 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6363 		       op1, readp);
6364 	    readp += op1;
6365 	    break;
6366 	  case DW_CFA_expression:
6367 	    if ((uint64_t) (endp - readp) < 1)
6368 	      goto invalid;
6369 	    get_uleb128 (op1, readp, endp);
6370 	    if ((uint64_t) (endp - readp) < 1)
6371 	      goto invalid;
6372 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6373 	    printf ("     expression r%" PRIu64 " (%s) \n",
6374 		    op1, regname (ebl, op1, regnamebuf));
6375 	    if ((uint64_t) (endp - readp) < op2)
6376 	      goto invalid;
6377 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6378 		       op2, readp);
6379 	    readp += op2;
6380 	    break;
6381 	  case DW_CFA_offset_extended_sf:
6382 	    if ((uint64_t) (endp - readp) < 1)
6383 	      goto invalid;
6384 	    get_uleb128 (op1, readp, endp);
6385 	    if ((uint64_t) (endp - readp) < 1)
6386 	      goto invalid;
6387 	    get_sleb128 (sop2, readp, endp);
6388 	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6389 		    PRId64 "\n",
6390 		    op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6391 	    break;
6392 	  case DW_CFA_def_cfa_sf:
6393 	    if ((uint64_t) (endp - readp) < 1)
6394 	      goto invalid;
6395 	    get_uleb128 (op1, readp, endp);
6396 	    if ((uint64_t) (endp - readp) < 1)
6397 	      goto invalid;
6398 	    get_sleb128 (sop2, readp, endp);
6399 	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6400 		    op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6401 	    break;
6402 	  case DW_CFA_def_cfa_offset_sf:
6403 	    if ((uint64_t) (endp - readp) < 1)
6404 	      goto invalid;
6405 	    get_sleb128 (sop1, readp, endp);
6406 	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6407 	    break;
6408 	  case DW_CFA_val_offset:
6409 	    if ((uint64_t) (endp - readp) < 1)
6410 	      goto invalid;
6411 	    get_uleb128 (op1, readp, endp);
6412 	    if ((uint64_t) (endp - readp) < 1)
6413 	      goto invalid;
6414 	    get_uleb128 (op2, readp, endp);
6415 	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6416 		    op1, op2 * data_align);
6417 	    break;
6418 	  case DW_CFA_val_offset_sf:
6419 	    if ((uint64_t) (endp - readp) < 1)
6420 	      goto invalid;
6421 	    get_uleb128 (op1, readp, endp);
6422 	    if ((uint64_t) (endp - readp) < 1)
6423 	      goto invalid;
6424 	    get_sleb128 (sop2, readp, endp);
6425 	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6426 		    op1, sop2 * data_align);
6427 	    break;
6428 	  case DW_CFA_val_expression:
6429 	    if ((uint64_t) (endp - readp) < 1)
6430 	      goto invalid;
6431 	    get_uleb128 (op1, readp, endp);
6432 	    if ((uint64_t) (endp - readp) < 1)
6433 	      goto invalid;
6434 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6435 	    printf ("     val_expression r%" PRIu64 " (%s)\n",
6436 		    op1, regname (ebl, op1, regnamebuf));
6437 	    if ((uint64_t) (endp - readp) < op2)
6438 	      goto invalid;
6439 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6440 		       NULL, op2, readp);
6441 	    readp += op2;
6442 	    break;
6443 	  case DW_CFA_MIPS_advance_loc8:
6444 	    if ((uint64_t) (endp - readp) < 8)
6445 	      goto invalid;
6446 	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
6447 	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6448 		    op1, pc += op1 * code_align);
6449 	    break;
6450 	  case DW_CFA_GNU_window_save:  /* DW_CFA_AARCH64_negate_ra_state  */
6451 	    if (ehdr->e_machine == EM_AARCH64)
6452 	      puts ("     AARCH64_negate_ra_state");
6453 	    else
6454 	      puts ("     GNU_window_save");
6455 	    break;
6456 	  case DW_CFA_GNU_args_size:
6457 	    if ((uint64_t) (endp - readp) < 1)
6458 	      goto invalid;
6459 	    get_uleb128 (op1, readp, endp);
6460 	    printf ("     args_size %" PRIu64 "\n", op1);
6461 	    break;
6462 	  default:
6463 	    printf ("     ??? (%u)\n", opcode);
6464 	    break;
6465 	  }
6466       else if (opcode < DW_CFA_offset)
6467 	printf ("     advance_loc %u to %#" PRIx64 "\n",
6468 		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6469       else if (opcode < DW_CFA_restore)
6470 	{
6471 	  uint64_t offset;
6472 	  if ((uint64_t) (endp - readp) < 1)
6473 	    goto invalid;
6474 	  get_uleb128 (offset, readp, endp);
6475 	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
6476 		  opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf),
6477 		  offset * data_align);
6478 	}
6479       else
6480 	printf ("     restore r%u (%s)\n",
6481 		opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf));
6482     }
6483 }
6484 
6485 
6486 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6487 encoded_ptr_size (int encoding, unsigned int ptr_size)
6488 {
6489   switch (encoding & 7)
6490     {
6491     case DW_EH_PE_udata4:
6492       return 4;
6493     case DW_EH_PE_udata8:
6494       return 8;
6495     case 0:
6496       return ptr_size;
6497     }
6498 
6499   fprintf (stderr, "Unsupported pointer encoding: %#x, "
6500 	   "assuming pointer size of %d.\n", encoding, ptr_size);
6501   return ptr_size;
6502 }
6503 
6504 
6505 static unsigned int
print_encoding(unsigned int val)6506 print_encoding (unsigned int val)
6507 {
6508   switch (val & 0xf)
6509     {
6510     case DW_EH_PE_absptr:
6511       fputs ("absptr", stdout);
6512       break;
6513     case DW_EH_PE_uleb128:
6514       fputs ("uleb128", stdout);
6515       break;
6516     case DW_EH_PE_udata2:
6517       fputs ("udata2", stdout);
6518       break;
6519     case DW_EH_PE_udata4:
6520       fputs ("udata4", stdout);
6521       break;
6522     case DW_EH_PE_udata8:
6523       fputs ("udata8", stdout);
6524       break;
6525     case DW_EH_PE_sleb128:
6526       fputs ("sleb128", stdout);
6527       break;
6528     case DW_EH_PE_sdata2:
6529       fputs ("sdata2", stdout);
6530       break;
6531     case DW_EH_PE_sdata4:
6532       fputs ("sdata4", stdout);
6533       break;
6534     case DW_EH_PE_sdata8:
6535       fputs ("sdata8", stdout);
6536       break;
6537     default:
6538       /* We did not use any of the bits after all.  */
6539       return val;
6540     }
6541 
6542   return val & ~0xf;
6543 }
6544 
6545 
6546 static unsigned int
print_relinfo(unsigned int val)6547 print_relinfo (unsigned int val)
6548 {
6549   switch (val & 0x70)
6550     {
6551     case DW_EH_PE_pcrel:
6552       fputs ("pcrel", stdout);
6553       break;
6554     case DW_EH_PE_textrel:
6555       fputs ("textrel", stdout);
6556       break;
6557     case DW_EH_PE_datarel:
6558       fputs ("datarel", stdout);
6559       break;
6560     case DW_EH_PE_funcrel:
6561       fputs ("funcrel", stdout);
6562       break;
6563     case DW_EH_PE_aligned:
6564       fputs ("aligned", stdout);
6565       break;
6566     default:
6567       return val;
6568     }
6569 
6570   return val & ~0x70;
6571 }
6572 
6573 
6574 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6575 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6576 {
6577   printf ("(%s", pfx);
6578 
6579   if (fde_encoding == DW_EH_PE_omit)
6580     puts ("omit)");
6581   else
6582     {
6583       unsigned int w = fde_encoding;
6584 
6585       w = print_encoding (w);
6586 
6587       if (w & 0x70)
6588 	{
6589 	  if (w != fde_encoding)
6590 	    fputc_unlocked (' ', stdout);
6591 
6592 	  w = print_relinfo (w);
6593 	}
6594 
6595       if (w != 0)
6596 	printf ("%s%x", w != fde_encoding ? " " : "", w);
6597 
6598       puts (")");
6599     }
6600 }
6601 
6602 
6603 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6604 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6605 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6606 {
6607   size_t shstrndx;
6608   /* We know this call will succeed since it did in the caller.  */
6609   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6610   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6611 
6612   /* Needed if we find PC-relative addresses.  */
6613   GElf_Addr bias;
6614   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6615     {
6616       error (0, 0, _("cannot get ELF: %s"), dwfl_errmsg (-1));
6617       return;
6618     }
6619 
6620   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6621   Elf_Data *data = (is_eh_frame
6622 		    ? elf_rawdata (scn, NULL)
6623 		    : (dbg->sectiondata[IDX_debug_frame]
6624 		       ?: elf_rawdata (scn, NULL)));
6625 
6626   if (unlikely (data == NULL))
6627     {
6628       error (0, 0, _("cannot get %s content: %s"),
6629 	     scnname, elf_errmsg (-1));
6630       return;
6631     }
6632 
6633   if (is_eh_frame)
6634     printf (_("\
6635 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6636 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6637   else
6638     printf (_("\
6639 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6640 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6641 
6642   struct cieinfo
6643   {
6644     ptrdiff_t cie_offset;
6645     const char *augmentation;
6646     unsigned int code_alignment_factor;
6647     unsigned int data_alignment_factor;
6648     uint8_t address_size;
6649     uint8_t fde_encoding;
6650     uint8_t lsda_encoding;
6651     struct cieinfo *next;
6652   } *cies = NULL;
6653 
6654   const unsigned char *readp = data->d_buf;
6655   const unsigned char *const dataend = ((unsigned char *) data->d_buf
6656 					+ data->d_size);
6657   while (readp < dataend)
6658     {
6659       if (unlikely (readp + 4 > dataend))
6660 	{
6661 	invalid_data:
6662 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
6663 		     elf_ndxscn (scn), scnname);
6664 	      return;
6665 	}
6666 
6667       /* At the beginning there must be a CIE.  There can be multiple,
6668 	 hence we test tis in a loop.  */
6669       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6670 
6671       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6672       unsigned int length = 4;
6673       if (unlikely (unit_length == 0xffffffff))
6674 	{
6675 	  if (unlikely (readp + 8 > dataend))
6676 	    goto invalid_data;
6677 
6678 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6679 	  length = 8;
6680 	}
6681 
6682       if (unlikely (unit_length == 0))
6683 	{
6684 	  printf (_("\n [%6tx] Zero terminator\n"), offset);
6685 	  continue;
6686 	}
6687 
6688       Dwarf_Word maxsize = dataend - readp;
6689       if (unlikely (unit_length > maxsize))
6690 	goto invalid_data;
6691 
6692       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6693 
6694       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6695       const unsigned char *const cieend = readp + unit_length;
6696       if (unlikely (cieend > dataend))
6697 	goto invalid_data;
6698 
6699       Dwarf_Off cie_id;
6700       if (length == 4)
6701 	{
6702 	  if (unlikely (cieend - readp < 4))
6703 	    goto invalid_data;
6704 	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6705 	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6706 	    cie_id = DW_CIE_ID_64;
6707 	}
6708       else
6709 	{
6710 	  if (unlikely (cieend - readp < 8))
6711 	    goto invalid_data;
6712 	  cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6713 	}
6714 
6715       uint_fast8_t version = 2;
6716       unsigned int code_alignment_factor;
6717       int data_alignment_factor;
6718       unsigned int fde_encoding = 0;
6719       unsigned int lsda_encoding = 0;
6720       Dwarf_Word initial_location = 0;
6721       Dwarf_Word vma_base = 0;
6722 
6723       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6724 	{
6725 	  if (unlikely (cieend - readp < 2))
6726 	    goto invalid_data;
6727 	  version = *readp++;
6728 	  const char *const augmentation = (const char *) readp;
6729 	  readp = memchr (readp, '\0', cieend - readp);
6730 	  if (unlikely (readp == NULL))
6731 	    goto invalid_data;
6732 	  ++readp;
6733 
6734 	  uint_fast8_t segment_size = 0;
6735 	  if (version >= 4)
6736 	    {
6737 	      if (cieend - readp < 5)
6738 		goto invalid_data;
6739 	      ptr_size = *readp++;
6740 	      segment_size = *readp++;
6741 	    }
6742 
6743 	  if (cieend - readp < 1)
6744 	    goto invalid_data;
6745 	  get_uleb128 (code_alignment_factor, readp, cieend);
6746 	  if (cieend - readp < 1)
6747 	    goto invalid_data;
6748 	  get_sleb128 (data_alignment_factor, readp, cieend);
6749 
6750 	  /* In some variant for unwind data there is another field.  */
6751 	  if (strcmp (augmentation, "eh") == 0)
6752 	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6753 
6754 	  unsigned int return_address_register;
6755 	  if (cieend - readp < 1)
6756 	    goto invalid_data;
6757 	  if (unlikely (version == 1))
6758 	    return_address_register = *readp++;
6759 	  else
6760 	    get_uleb128 (return_address_register, readp, cieend);
6761 
6762 	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6763 		  "   CIE_id:                   %" PRIu64 "\n"
6764 		  "   version:                  %u\n"
6765 		  "   augmentation:             \"%s\"\n",
6766 		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
6767 		  version, augmentation);
6768 	  if (version >= 4)
6769 	    printf ("   address_size:             %u\n"
6770 		    "   segment_size:             %u\n",
6771 		    ptr_size, segment_size);
6772 	  printf ("   code_alignment_factor:    %u\n"
6773 		  "   data_alignment_factor:    %d\n"
6774 		  "   return_address_register:  %u\n",
6775 		  code_alignment_factor,
6776 		  data_alignment_factor, return_address_register);
6777 
6778 	  if (augmentation[0] == 'z')
6779 	    {
6780 	      unsigned int augmentationlen;
6781 	      get_uleb128 (augmentationlen, readp, cieend);
6782 
6783 	      if (augmentationlen > (size_t) (cieend - readp))
6784 		{
6785 		  error (0, 0, _("invalid augmentation length"));
6786 		  readp = cieend;
6787 		  continue;
6788 		}
6789 
6790 	      const char *hdr = "Augmentation data:";
6791 	      const char *cp = augmentation + 1;
6792 	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6793 		{
6794 		  printf ("   %-26s%#x ", hdr, *readp);
6795 		  hdr = "";
6796 
6797 		  if (*cp == 'R')
6798 		    {
6799 		      fde_encoding = *readp++;
6800 		      print_encoding_base (_("FDE address encoding: "),
6801 					   fde_encoding);
6802 		    }
6803 		  else if (*cp == 'L')
6804 		    {
6805 		      lsda_encoding = *readp++;
6806 		      print_encoding_base (_("LSDA pointer encoding: "),
6807 					   lsda_encoding);
6808 		    }
6809 		  else if (*cp == 'P')
6810 		    {
6811 		      /* Personality.  This field usually has a relocation
6812 			 attached pointing to __gcc_personality_v0.  */
6813 		      const unsigned char *startp = readp;
6814 		      unsigned int encoding = *readp++;
6815 		      uint64_t val = 0;
6816 		      readp = read_encoded (encoding, readp,
6817 					    readp - 1 + augmentationlen,
6818 					    &val, dbg);
6819 
6820 		      while (++startp < readp)
6821 			printf ("%#x ", *startp);
6822 
6823 		      putchar ('(');
6824 		      print_encoding (encoding);
6825 		      putchar (' ');
6826 		      switch (encoding & 0xf)
6827 			{
6828 			case DW_EH_PE_sleb128:
6829 			case DW_EH_PE_sdata2:
6830 			case DW_EH_PE_sdata4:
6831 			  printf ("%" PRId64 ")\n", val);
6832 			  break;
6833 			default:
6834 			  printf ("%#" PRIx64 ")\n", val);
6835 			  break;
6836 			}
6837 		    }
6838 		  else
6839 		    printf ("(%x)\n", *readp++);
6840 
6841 		  ++cp;
6842 		}
6843 	    }
6844 
6845 	  if (likely (ptr_size == 4 || ptr_size == 8))
6846 	    {
6847 	      struct cieinfo *newp = alloca (sizeof (*newp));
6848 	      newp->cie_offset = offset;
6849 	      newp->augmentation = augmentation;
6850 	      newp->fde_encoding = fde_encoding;
6851 	      newp->lsda_encoding = lsda_encoding;
6852 	      newp->address_size = ptr_size;
6853 	      newp->code_alignment_factor = code_alignment_factor;
6854 	      newp->data_alignment_factor = data_alignment_factor;
6855 	      newp->next = cies;
6856 	      cies = newp;
6857 	    }
6858 	}
6859       else
6860 	{
6861 	  struct cieinfo *cie = cies;
6862 	  while (cie != NULL)
6863 	    if (is_eh_frame
6864 		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6865 		: cie_id == (Dwarf_Off) cie->cie_offset)
6866 	      break;
6867 	    else
6868 	      cie = cie->next;
6869 	  if (unlikely (cie == NULL))
6870 	    {
6871 	      puts ("invalid CIE reference in FDE");
6872 	      return;
6873 	    }
6874 
6875 	  /* Initialize from CIE data.  */
6876 	  fde_encoding = cie->fde_encoding;
6877 	  lsda_encoding = cie->lsda_encoding;
6878 	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6879 	  code_alignment_factor = cie->code_alignment_factor;
6880 	  data_alignment_factor = cie->data_alignment_factor;
6881 
6882 	  const unsigned char *base = readp;
6883 	  // XXX There are sometimes relocations for this value
6884 	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6885 	  Dwarf_Word address_range
6886 	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
6887 
6888 	  /* pcrel for an FDE address is relative to the runtime
6889 	     address of the start_address field itself.  Sign extend
6890 	     if necessary to make sure the calculation is done on the
6891 	     full 64 bit address even when initial_location only holds
6892 	     the lower 32 bits.  */
6893 	  Dwarf_Addr pc_start = initial_location;
6894 	  if (ptr_size == 4)
6895 	    pc_start = (uint64_t) (int32_t) pc_start;
6896 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6897 	    pc_start += ((uint64_t) shdr->sh_addr
6898 			 + (base - (const unsigned char *) data->d_buf)
6899 			 - bias);
6900 
6901 	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6902 		  "   CIE_pointer:              %" PRIu64 "\n"
6903 		  "   initial_location:         ",
6904 		  offset, (uint64_t) unit_length,
6905 		  cie->cie_offset, (uint64_t) cie_id);
6906 	  print_dwarf_addr (dwflmod, cie->address_size,
6907 			    pc_start, initial_location);
6908 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6909 	    {
6910 	      vma_base = (((uint64_t) shdr->sh_offset
6911 			   + (base - (const unsigned char *) data->d_buf)
6912 			   + (uint64_t) initial_location)
6913 			  & (ptr_size == 4
6914 			     ? UINT64_C (0xffffffff)
6915 			     : UINT64_C (0xffffffffffffffff)));
6916 	      printf (_(" (offset: %#" PRIx64 ")"),
6917 		      (uint64_t) vma_base);
6918 	    }
6919 
6920 	  printf ("\n   address_range:            %#" PRIx64,
6921 		  (uint64_t) address_range);
6922 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6923 	    printf (_(" (end offset: %#" PRIx64 ")"),
6924 		    ((uint64_t) vma_base + (uint64_t) address_range)
6925 		    & (ptr_size == 4
6926 		       ? UINT64_C (0xffffffff)
6927 		       : UINT64_C (0xffffffffffffffff)));
6928 	  putchar ('\n');
6929 
6930 	  if (cie->augmentation[0] == 'z')
6931 	    {
6932 	      unsigned int augmentationlen;
6933 	      if (cieend - readp < 1)
6934 		goto invalid_data;
6935 	      get_uleb128 (augmentationlen, readp, cieend);
6936 
6937 	      if (augmentationlen > (size_t) (cieend - readp))
6938 		{
6939 		  error (0, 0, _("invalid augmentation length"));
6940 		  readp = cieend;
6941 		  continue;
6942 		}
6943 
6944 	      if (augmentationlen > 0)
6945 		{
6946 		  const char *hdr = "Augmentation data:";
6947 		  const char *cp = cie->augmentation + 1;
6948 		  unsigned int u = 0;
6949 		  while (*cp != '\0'
6950 			 && cp < cie->augmentation + augmentationlen + 1)
6951 		    {
6952 		      if (*cp == 'L')
6953 			{
6954 			  uint64_t lsda_pointer;
6955 			  const unsigned char *p
6956 			    = read_encoded (lsda_encoding, &readp[u],
6957 					    &readp[augmentationlen],
6958 					    &lsda_pointer, dbg);
6959 			  u = p - readp;
6960 			  printf (_("\
6961    %-26sLSDA pointer: %#" PRIx64 "\n"),
6962 				  hdr, lsda_pointer);
6963 			  hdr = "";
6964 			}
6965 		      ++cp;
6966 		    }
6967 
6968 		  while (u < augmentationlen)
6969 		    {
6970 		      printf ("   %-26s%#x\n", hdr, readp[u++]);
6971 		      hdr = "";
6972 		    }
6973 		}
6974 
6975 	      readp += augmentationlen;
6976 	    }
6977 	}
6978 
6979       /* Handle the initialization instructions.  */
6980       if (ptr_size != 4 && ptr_size !=8)
6981 	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6982       else
6983 	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6984 			   data_alignment_factor, version, ptr_size,
6985 			   fde_encoding, dwflmod, ebl, ehdr, dbg);
6986       readp = cieend;
6987     }
6988 }
6989 
6990 
6991 /* Returns the signedness (or false if it cannot be determined) and
6992    the byte size (or zero if it cannot be gotten) of the given DIE
6993    DW_AT_type attribute.  Uses dwarf_peel_type and dwarf_aggregate_size.  */
6994 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)6995 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
6996 {
6997   Dwarf_Attribute attr;
6998   Dwarf_Die type;
6999 
7000   *bytes = 0;
7001   *is_signed = false;
7002 
7003   if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
7004 								DW_AT_type,
7005 								&attr), &type),
7006 		       &type) == 0)
7007     {
7008       Dwarf_Word val;
7009       *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
7010 						 &attr), &val) == 0
7011 		    && (val == DW_ATE_signed || val == DW_ATE_signed_char));
7012 
7013       if (dwarf_aggregate_size (&type, &val) == 0)
7014 	*bytes = val;
7015     }
7016 }
7017 
7018 struct attrcb_args
7019 {
7020   Dwfl_Module *dwflmod;
7021   Dwarf *dbg;
7022   Dwarf_Die *dies;
7023   int level;
7024   bool silent;
7025   bool is_split;
7026   unsigned int version;
7027   unsigned int addrsize;
7028   unsigned int offset_size;
7029   struct Dwarf_CU *cu;
7030 };
7031 
7032 
7033 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)7034 attr_callback (Dwarf_Attribute *attrp, void *arg)
7035 {
7036   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
7037   const int level = cbargs->level;
7038   Dwarf_Die *die = &cbargs->dies[level];
7039   bool is_split = cbargs->is_split;
7040 
7041   unsigned int attr = dwarf_whatattr (attrp);
7042   if (unlikely (attr == 0))
7043     {
7044       if (!cbargs->silent)
7045 	error (0, 0, _("DIE [%" PRIx64 "] "
7046 			      "cannot get attribute code: %s"),
7047 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7048       return DWARF_CB_ABORT;
7049     }
7050 
7051   unsigned int form = dwarf_whatform (attrp);
7052   if (unlikely (form == 0))
7053     {
7054       if (!cbargs->silent)
7055 	error (0, 0, _("DIE [%" PRIx64 "] "
7056 			      "cannot get attribute form: %s"),
7057 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7058       return DWARF_CB_ABORT;
7059     }
7060 
7061   switch (form)
7062     {
7063     case DW_FORM_addr:
7064     case DW_FORM_addrx:
7065     case DW_FORM_addrx1:
7066     case DW_FORM_addrx2:
7067     case DW_FORM_addrx3:
7068     case DW_FORM_addrx4:
7069     case DW_FORM_GNU_addr_index:
7070       if (!cbargs->silent)
7071 	{
7072 	  Dwarf_Addr addr;
7073 	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7074 	    {
7075 	    attrval_out:
7076 	      if (!cbargs->silent)
7077 		error (0, 0, _("DIE [%" PRIx64 "] "
7078 				      "cannot get attribute '%s' (%s) value: "
7079 				      "%s"),
7080 		       dwarf_dieoffset (die),
7081 		       dwarf_attr_name (attr),
7082 		       dwarf_form_name (form),
7083 		       dwarf_errmsg (-1));
7084 	      /* Don't ABORT, it might be other attributes can be resolved.  */
7085 	      return DWARF_CB_OK;
7086 	    }
7087 	  if (form != DW_FORM_addr )
7088 	    {
7089 	      Dwarf_Word word;
7090 	      if (dwarf_formudata (attrp, &word) != 0)
7091 		goto attrval_out;
7092 	      printf ("           %*s%-20s (%s) [%" PRIx64 "] ",
7093 		      (int) (level * 2), "", dwarf_attr_name (attr),
7094 		      dwarf_form_name (form), word);
7095 	    }
7096 	  else
7097 	    printf ("           %*s%-20s (%s) ",
7098 		    (int) (level * 2), "", dwarf_attr_name (attr),
7099 		    dwarf_form_name (form));
7100 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7101 	  printf ("\n");
7102 	}
7103       break;
7104 
7105     case DW_FORM_indirect:
7106     case DW_FORM_strp:
7107     case DW_FORM_line_strp:
7108     case DW_FORM_strx:
7109     case DW_FORM_strx1:
7110     case DW_FORM_strx2:
7111     case DW_FORM_strx3:
7112     case DW_FORM_strx4:
7113     case DW_FORM_string:
7114     case DW_FORM_GNU_strp_alt:
7115     case DW_FORM_GNU_str_index:
7116       if (cbargs->silent)
7117 	break;
7118       const char *str = dwarf_formstring (attrp);
7119       if (unlikely (str == NULL))
7120 	goto attrval_out;
7121       printf ("           %*s%-20s (%s) \"%s\"\n",
7122 	      (int) (level * 2), "", dwarf_attr_name (attr),
7123 	      dwarf_form_name (form), str);
7124       break;
7125 
7126     case DW_FORM_ref_addr:
7127     case DW_FORM_ref_udata:
7128     case DW_FORM_ref8:
7129     case DW_FORM_ref4:
7130     case DW_FORM_ref2:
7131     case DW_FORM_ref1:
7132     case DW_FORM_GNU_ref_alt:
7133     case DW_FORM_ref_sup4:
7134     case DW_FORM_ref_sup8:
7135       if (cbargs->silent)
7136 	break;
7137       Dwarf_Die ref;
7138       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7139 	goto attrval_out;
7140 
7141       printf ("           %*s%-20s (%s) ",
7142 	      (int) (level * 2), "", dwarf_attr_name (attr),
7143 	      dwarf_form_name (form));
7144       if (is_split)
7145 	printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7146       else
7147 	printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7148       break;
7149 
7150     case DW_FORM_ref_sig8:
7151       if (cbargs->silent)
7152 	break;
7153       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
7154 	      (int) (level * 2), "", dwarf_attr_name (attr),
7155 	      dwarf_form_name (form),
7156 	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7157       break;
7158 
7159     case DW_FORM_sec_offset:
7160     case DW_FORM_rnglistx:
7161     case DW_FORM_loclistx:
7162     case DW_FORM_implicit_const:
7163     case DW_FORM_udata:
7164     case DW_FORM_sdata:
7165     case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7166     case DW_FORM_data4:
7167     case DW_FORM_data2:
7168     case DW_FORM_data1:;
7169       Dwarf_Word num;
7170       if (unlikely (dwarf_formudata (attrp, &num) != 0))
7171 	goto attrval_out;
7172 
7173       const char *valuestr = NULL;
7174       bool as_hex_id = false;
7175       switch (attr)
7176 	{
7177 	  /* This case can take either a constant or a loclistptr.  */
7178 	case DW_AT_data_member_location:
7179 	  if (form != DW_FORM_sec_offset
7180 	      && (cbargs->version >= 4
7181 		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7182 	    {
7183 	      if (!cbargs->silent)
7184 		printf ("           %*s%-20s (%s) %" PRIuMAX "\n",
7185 			(int) (level * 2), "", dwarf_attr_name (attr),
7186 			dwarf_form_name (form), (uintmax_t) num);
7187 	      return DWARF_CB_OK;
7188 	    }
7189 	  FALLTHROUGH;
7190 
7191 	/* These cases always take a loclist[ptr] and no constant. */
7192 	case DW_AT_location:
7193 	case DW_AT_data_location:
7194 	case DW_AT_vtable_elem_location:
7195 	case DW_AT_string_length:
7196 	case DW_AT_use_location:
7197 	case DW_AT_frame_base:
7198 	case DW_AT_return_addr:
7199 	case DW_AT_static_link:
7200 	case DW_AT_segment:
7201 	case DW_AT_GNU_call_site_value:
7202 	case DW_AT_GNU_call_site_data_value:
7203 	case DW_AT_GNU_call_site_target:
7204 	case DW_AT_GNU_call_site_target_clobbered:
7205 	case DW_AT_GNU_locviews:
7206 	  {
7207 	    bool nlpt;
7208 	    if (cbargs->cu->version < 5)
7209 	      {
7210 		if (! cbargs->is_split)
7211 		  {
7212 		    nlpt = notice_listptr (section_loc, &known_locsptr,
7213 					   cbargs->addrsize,
7214 					   cbargs->offset_size,
7215 					   cbargs->cu, num, attr);
7216 		  }
7217 		else
7218 		  nlpt = true;
7219 	      }
7220 	    else
7221 	      {
7222 		/* Only register for a real section offset.  Otherwise
7223 		   it is a DW_FORM_loclistx which is just an index
7224 		   number and we should already have registered the
7225 		   section offset for the index when we saw the
7226 		   DW_AT_loclists_base CU attribute.  */
7227 		if (form == DW_FORM_sec_offset)
7228 		  nlpt = notice_listptr (section_loc, &known_loclistsptr,
7229 					 cbargs->addrsize, cbargs->offset_size,
7230 					 cbargs->cu, num, attr);
7231 		else
7232 		  nlpt = true;
7233 
7234 	      }
7235 
7236 	    if (!cbargs->silent)
7237 	      {
7238 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7239 		  printf ("           %*s%-20s (%s) location list [%6"
7240 			  PRIxMAX "]%s\n",
7241 			  (int) (level * 2), "", dwarf_attr_name (attr),
7242 			  dwarf_form_name (form), (uintmax_t) num,
7243 			  nlpt ? "" : " <WARNING offset too big>");
7244 		else
7245 		  printf ("           %*s%-20s (%s) location index [%6"
7246 			  PRIxMAX "]\n",
7247 			  (int) (level * 2), "", dwarf_attr_name (attr),
7248 			  dwarf_form_name (form), (uintmax_t) num);
7249 	      }
7250 	  }
7251 	  return DWARF_CB_OK;
7252 
7253 	case DW_AT_loclists_base:
7254 	  {
7255 	    bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7256                                         cbargs->addrsize, cbargs->offset_size,
7257                                         cbargs->cu, num, attr);
7258 
7259 	    if (!cbargs->silent)
7260 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7261 		      (int) (level * 2), "", dwarf_attr_name (attr),
7262 		      dwarf_form_name (form), (uintmax_t) num,
7263 		      nlpt ? "" : " <WARNING offset too big>");
7264 	  }
7265 	  return DWARF_CB_OK;
7266 
7267 	case DW_AT_ranges:
7268 	case DW_AT_start_scope:
7269 	  {
7270 	    bool nlpt;
7271 	    if (cbargs->cu->version < 5)
7272 	      nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7273 				     cbargs->addrsize, cbargs->offset_size,
7274 				     cbargs->cu, num, attr);
7275 	    else
7276 	      {
7277 		/* Only register for a real section offset.  Otherwise
7278 		   it is a DW_FORM_rangelistx which is just an index
7279 		   number and we should already have registered the
7280 		   section offset for the index when we saw the
7281 		   DW_AT_rnglists_base CU attribute.  */
7282 		if (form == DW_FORM_sec_offset)
7283 		  nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7284 					 cbargs->addrsize, cbargs->offset_size,
7285 					 cbargs->cu, num, attr);
7286 		else
7287 		  nlpt = true;
7288 	      }
7289 
7290 	    if (!cbargs->silent)
7291 	      {
7292 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7293 		  printf ("           %*s%-20s (%s) range list [%6"
7294 			  PRIxMAX "]%s\n",
7295 			  (int) (level * 2), "", dwarf_attr_name (attr),
7296 			  dwarf_form_name (form), (uintmax_t) num,
7297 			  nlpt ? "" : " <WARNING offset too big>");
7298 		else
7299 		  printf ("           %*s%-20s (%s) range index [%6"
7300 			  PRIxMAX "]\n",
7301 			  (int) (level * 2), "", dwarf_attr_name (attr),
7302 			  dwarf_form_name (form), (uintmax_t) num);
7303 	      }
7304 	  }
7305 	  return DWARF_CB_OK;
7306 
7307 	case DW_AT_rnglists_base:
7308 	  {
7309 	    bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7310 					cbargs->addrsize, cbargs->offset_size,
7311 					cbargs->cu, num, attr);
7312 	    if (!cbargs->silent)
7313 	      printf ("           %*s%-20s (%s) range list [%6"
7314 		      PRIxMAX "]%s\n",
7315 		      (int) (level * 2), "", dwarf_attr_name (attr),
7316 		      dwarf_form_name (form), (uintmax_t) num,
7317 		      nlpt ? "" : " <WARNING offset too big>");
7318 	  }
7319 	  return DWARF_CB_OK;
7320 
7321 	case DW_AT_addr_base:
7322 	case DW_AT_GNU_addr_base:
7323 	  {
7324 	    bool addrbase = notice_listptr (section_addr, &known_addrbases,
7325 					    cbargs->addrsize,
7326 					    cbargs->offset_size,
7327 					    cbargs->cu, num, attr);
7328 	    if (!cbargs->silent)
7329 	      printf ("           %*s%-20s (%s) address base [%6"
7330 		      PRIxMAX "]%s\n",
7331 		      (int) (level * 2), "", dwarf_attr_name (attr),
7332 		      dwarf_form_name (form), (uintmax_t) num,
7333 		      addrbase ? "" : " <WARNING offset too big>");
7334 	  }
7335 	  return DWARF_CB_OK;
7336 
7337 	case DW_AT_str_offsets_base:
7338 	  {
7339 	    bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7340 					      cbargs->addrsize,
7341 					      cbargs->offset_size,
7342 					      cbargs->cu, num, attr);
7343 	    if (!cbargs->silent)
7344 	      printf ("           %*s%-20s (%s) str offsets base [%6"
7345 		      PRIxMAX "]%s\n",
7346 		      (int) (level * 2), "", dwarf_attr_name (attr),
7347 		      dwarf_form_name (form), (uintmax_t) num,
7348 		      stroffbase ? "" : " <WARNING offset too big>");
7349 	  }
7350 	  return DWARF_CB_OK;
7351 
7352 	case DW_AT_language:
7353 	  valuestr = dwarf_lang_name (num);
7354 	  break;
7355 	case DW_AT_encoding:
7356 	  valuestr = dwarf_encoding_name (num);
7357 	  break;
7358 	case DW_AT_accessibility:
7359 	  valuestr = dwarf_access_name (num);
7360 	  break;
7361 	case DW_AT_defaulted:
7362 	  valuestr = dwarf_defaulted_name (num);
7363 	  break;
7364 	case DW_AT_visibility:
7365 	  valuestr = dwarf_visibility_name (num);
7366 	  break;
7367 	case DW_AT_virtuality:
7368 	  valuestr = dwarf_virtuality_name (num);
7369 	  break;
7370 	case DW_AT_identifier_case:
7371 	  valuestr = dwarf_identifier_case_name (num);
7372 	  break;
7373 	case DW_AT_calling_convention:
7374 	  valuestr = dwarf_calling_convention_name (num);
7375 	  break;
7376 	case DW_AT_inline:
7377 	  valuestr = dwarf_inline_name (num);
7378 	  break;
7379 	case DW_AT_ordering:
7380 	  valuestr = dwarf_ordering_name (num);
7381 	  break;
7382 	case DW_AT_decl_file:
7383 	case DW_AT_call_file:
7384 	  {
7385 	    if (cbargs->silent)
7386 	      break;
7387 
7388 	    /* Try to get the actual file, the current interface only
7389 	       gives us full paths, but we only want to show the file
7390 	       name for now.  */
7391 	    Dwarf_Die cudie;
7392 	    if (dwarf_cu_die (cbargs->cu, &cudie,
7393 			      NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7394 	      {
7395 		Dwarf_Files *files;
7396 		size_t nfiles;
7397 		if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7398 		  {
7399 		    valuestr = dwarf_filesrc (files, num, NULL, NULL);
7400 		    if (valuestr != NULL)
7401 		      {
7402 			char *filename = strrchr (valuestr, '/');
7403 			if (filename != NULL)
7404 			  valuestr = filename + 1;
7405 		      }
7406 		    else
7407 		      error (0, 0, _("invalid file (%" PRId64 "): %s"),
7408 			     num, dwarf_errmsg (-1));
7409 		  }
7410 		else
7411 		  error (0, 0, _("no srcfiles for CU [%" PRIx64 "]"),
7412 			 dwarf_dieoffset (&cudie));
7413 	      }
7414 	    else
7415 	     error (0, 0, _("couldn't get DWARF CU: %s"),
7416 		    dwarf_errmsg (-1));
7417 	    if (valuestr == NULL)
7418 	      valuestr = "???";
7419 	  }
7420 	  break;
7421 	case DW_AT_GNU_dwo_id:
7422 	  as_hex_id = true;
7423 	  break;
7424 
7425 	default:
7426 	  /* Nothing.  */
7427 	  break;
7428 	}
7429 
7430       if (cbargs->silent)
7431 	break;
7432 
7433       /* When highpc is in constant form it is relative to lowpc.
7434 	 In that case also show the address.  */
7435       Dwarf_Addr highpc;
7436       if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7437 	{
7438 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (",
7439 		  (int) (level * 2), "", dwarf_attr_name (attr),
7440 		  dwarf_form_name (form), (uintmax_t) num);
7441 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7442 	  printf (")\n");
7443 	}
7444       else
7445 	{
7446 	  if (as_hex_id)
7447 	    {
7448 	      printf ("           %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7449 		      (int) (level * 2), "", dwarf_attr_name (attr),
7450 		      dwarf_form_name (form), num);
7451 	    }
7452 	  else
7453 	    {
7454 	      Dwarf_Sword snum = 0;
7455 	      bool is_signed;
7456 	      int bytes = 0;
7457 	      if (attr == DW_AT_const_value)
7458 		die_type_sign_bytes (die, &is_signed, &bytes);
7459 	      else
7460 		is_signed = (form == DW_FORM_sdata
7461 			     || form == DW_FORM_implicit_const);
7462 
7463 	      if (is_signed)
7464 		if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7465 		  goto attrval_out;
7466 
7467 	      if (valuestr == NULL)
7468 		{
7469 		  printf ("           %*s%-20s (%s) ",
7470 			  (int) (level * 2), "", dwarf_attr_name (attr),
7471 			  dwarf_form_name (form));
7472 		}
7473 	      else
7474 		{
7475 		  printf ("           %*s%-20s (%s) %s (",
7476 			  (int) (level * 2), "", dwarf_attr_name (attr),
7477 			  dwarf_form_name (form), valuestr);
7478 		}
7479 
7480 	      switch (bytes)
7481 		{
7482 		case 1:
7483 		  if (is_signed)
7484 		    printf ("%" PRId8, (int8_t) snum);
7485 		  else
7486 		    printf ("%" PRIu8, (uint8_t) num);
7487 		  break;
7488 
7489 		case 2:
7490 		  if (is_signed)
7491 		    printf ("%" PRId16, (int16_t) snum);
7492 		  else
7493 		    printf ("%" PRIu16, (uint16_t) num);
7494 		  break;
7495 
7496 		case 4:
7497 		  if (is_signed)
7498 		    printf ("%" PRId32, (int32_t) snum);
7499 		  else
7500 		    printf ("%" PRIu32, (uint32_t) num);
7501 		  break;
7502 
7503 		case 8:
7504 		  if (is_signed)
7505 		    printf ("%" PRId64, (int64_t) snum);
7506 		  else
7507 		    printf ("%" PRIu64, (uint64_t) num);
7508 		  break;
7509 
7510 		default:
7511 		  if (is_signed)
7512 		    printf ("%" PRIdMAX, (intmax_t) snum);
7513 		  else
7514 		    printf ("%" PRIuMAX, (uintmax_t) num);
7515 		  break;
7516 		}
7517 
7518 	      /* Make clear if we switched from a signed encoding to
7519 		 an unsigned value.  */
7520 	      if (attr == DW_AT_const_value
7521 		  && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7522 		  && !is_signed)
7523 		printf (" (%" PRIdMAX ")", (intmax_t) num);
7524 
7525 	      if (valuestr == NULL)
7526 		printf ("\n");
7527 	      else
7528 		printf (")\n");
7529 	    }
7530 	}
7531       break;
7532 
7533     case DW_FORM_flag:
7534       if (cbargs->silent)
7535 	break;
7536       bool flag;
7537       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7538 	goto attrval_out;
7539 
7540       printf ("           %*s%-20s (%s) %s\n",
7541 	      (int) (level * 2), "", dwarf_attr_name (attr),
7542 	      dwarf_form_name (form), flag ? yes_str : no_str);
7543       break;
7544 
7545     case DW_FORM_flag_present:
7546       if (cbargs->silent)
7547 	break;
7548       printf ("           %*s%-20s (%s) %s\n",
7549 	      (int) (level * 2), "", dwarf_attr_name (attr),
7550 	      dwarf_form_name (form), yes_str);
7551       break;
7552 
7553     case DW_FORM_exprloc:
7554     case DW_FORM_block4:
7555     case DW_FORM_block2:
7556     case DW_FORM_block1:
7557     case DW_FORM_block:
7558     case DW_FORM_data16: /* DWARF5 calls this a constant class.  */
7559       if (cbargs->silent)
7560 	break;
7561       Dwarf_Block block;
7562       if (unlikely (dwarf_formblock (attrp, &block) != 0))
7563 	goto attrval_out;
7564 
7565       printf ("           %*s%-20s (%s) ",
7566 	      (int) (level * 2), "", dwarf_attr_name (attr),
7567 	      dwarf_form_name (form));
7568 
7569       switch (attr)
7570 	{
7571 	default:
7572 	  if (form != DW_FORM_exprloc)
7573 	    {
7574 	      print_block (block.length, block.data);
7575 	      break;
7576 	    }
7577 	  FALLTHROUGH;
7578 
7579 	case DW_AT_location:
7580 	case DW_AT_data_location:
7581 	case DW_AT_data_member_location:
7582 	case DW_AT_vtable_elem_location:
7583 	case DW_AT_string_length:
7584 	case DW_AT_use_location:
7585 	case DW_AT_frame_base:
7586 	case DW_AT_return_addr:
7587 	case DW_AT_static_link:
7588 	case DW_AT_allocated:
7589 	case DW_AT_associated:
7590 	case DW_AT_bit_size:
7591 	case DW_AT_bit_offset:
7592 	case DW_AT_bit_stride:
7593 	case DW_AT_byte_size:
7594 	case DW_AT_byte_stride:
7595 	case DW_AT_count:
7596 	case DW_AT_lower_bound:
7597 	case DW_AT_upper_bound:
7598 	case DW_AT_GNU_call_site_value:
7599 	case DW_AT_GNU_call_site_data_value:
7600 	case DW_AT_GNU_call_site_target:
7601 	case DW_AT_GNU_call_site_target_clobbered:
7602 	  if (form != DW_FORM_data16)
7603 	    {
7604 	      putchar ('\n');
7605 	      print_ops (cbargs->dwflmod, cbargs->dbg,
7606 			 12 + level * 2, 12 + level * 2,
7607 			 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7608 			 attrp->cu, block.length, block.data);
7609 	    }
7610 	  else
7611 	    print_block (block.length, block.data);
7612 	  break;
7613 
7614 	case DW_AT_discr_list:
7615 	  if (block.length == 0)
7616 	    puts ("<default>");
7617 	  else if (form != DW_FORM_data16)
7618 	    {
7619 	      const unsigned char *readp = block.data;
7620 	      const unsigned char *readendp = readp + block.length;
7621 
7622 	      /* See if we are dealing with a signed or unsigned
7623 		 values.  If the parent of this variant DIE is a
7624 		 variant_part then it will either have a discriminant
7625 		 which points to the member which type is the
7626 		 discriminant type.  Or the variant_part itself has a
7627 		 type representing the discriminant.  */
7628 	      bool is_signed = false;
7629 	      if (level > 0)
7630 		{
7631 		  Dwarf_Die *parent = &cbargs->dies[level - 1];
7632 		  if (dwarf_tag (die) == DW_TAG_variant
7633 		      && dwarf_tag (parent) == DW_TAG_variant_part)
7634 		    {
7635 		      Dwarf_Die member;
7636 		      Dwarf_Attribute discr_attr;
7637 		      int bytes;
7638 		      if (dwarf_formref_die (dwarf_attr (parent,
7639 							 DW_AT_discr,
7640 							 &discr_attr),
7641 					     &member) != NULL)
7642 			die_type_sign_bytes (&member, &is_signed, &bytes);
7643 		      else
7644 			die_type_sign_bytes (parent, &is_signed, &bytes);
7645 		    }
7646 		}
7647 	      while (readp < readendp)
7648 		{
7649 		  int d = (int) *readp++;
7650 		  printf ("%s ", dwarf_discr_list_name (d));
7651 		  if (readp >= readendp)
7652 		    goto attrval_out;
7653 
7654 		  Dwarf_Word val;
7655 		  Dwarf_Sword sval;
7656 		  if (d == DW_DSC_label)
7657 		    {
7658 		      if (is_signed)
7659 			{
7660 			  get_sleb128 (sval, readp, readendp);
7661 			  printf ("%" PRId64 "", sval);
7662 			}
7663 		      else
7664 			{
7665 			  get_uleb128 (val, readp, readendp);
7666 			  printf ("%" PRIu64 "", val);
7667 			}
7668 		    }
7669 		  else if (d == DW_DSC_range)
7670 		    {
7671 		      if (is_signed)
7672 			{
7673 			  get_sleb128 (sval, readp, readendp);
7674 			  printf ("%" PRId64 "..", sval);
7675 			  if (readp >= readendp)
7676 			    goto attrval_out;
7677 			  get_sleb128 (sval, readp, readendp);
7678 			  printf ("%" PRId64 "", sval);
7679 			}
7680 		      else
7681 			{
7682 			  get_uleb128 (val, readp, readendp);
7683 			  printf ("%" PRIu64 "..", val);
7684 			  if (readp >= readendp)
7685 			    goto attrval_out;
7686 			  get_uleb128 (val, readp, readendp);
7687 			  printf ("%" PRIu64 "", val);
7688 			}
7689 		    }
7690 		  else
7691 		    {
7692 		      print_block (readendp - readp, readp);
7693 		      break;
7694 		    }
7695 		  if (readp < readendp)
7696 		    printf (", ");
7697 		}
7698 	      putchar ('\n');
7699 	    }
7700 	  else
7701 	    print_block (block.length, block.data);
7702 	  break;
7703 	}
7704       break;
7705 
7706     default:
7707       if (cbargs->silent)
7708 	break;
7709       printf ("           %*s%-20s (%s) ???\n",
7710 	      (int) (level * 2), "", dwarf_attr_name (attr),
7711 	      dwarf_form_name (form));
7712       break;
7713     }
7714 
7715   return DWARF_CB_OK;
7716 }
7717 
7718 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7719 print_debug_units (Dwfl_Module *dwflmod,
7720 		   Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7721 		   Elf_Scn *scn, GElf_Shdr *shdr,
7722 		   Dwarf *dbg, bool debug_types)
7723 {
7724   const bool silent = !(print_debug_sections & section_info) && !debug_types;
7725   const char *secname = section_name (ebl, shdr);
7726 
7727   if (!silent)
7728     printf (_("\
7729 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7730 	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7731 
7732   /* If the section is empty we don't have to do anything.  */
7733   if (!silent && shdr->sh_size == 0)
7734     return;
7735 
7736   int maxdies = 20;
7737   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
7738 
7739   /* New compilation unit.  */
7740   Dwarf_Half version;
7741 
7742   Dwarf_Die result;
7743   Dwarf_Off abbroffset;
7744   uint8_t addrsize;
7745   uint8_t offsize;
7746   uint64_t unit_id;
7747   Dwarf_Off subdie_off;
7748 
7749   int unit_res;
7750   Dwarf_CU *cu;
7751   Dwarf_CU cu_mem;
7752   uint8_t unit_type;
7753   Dwarf_Die cudie;
7754 
7755   /* We cheat a little because we want to see only the CUs from .debug_info
7756      or .debug_types.  We know the Dwarf_CU struct layout.  Set it up at
7757      the end of .debug_info if we want .debug_types only.  Check the returned
7758      Dwarf_CU is still in the expected section.  */
7759   if (debug_types)
7760     {
7761       cu_mem.dbg = dbg;
7762       cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7763       cu_mem.sec_idx = IDX_debug_info;
7764       cu = &cu_mem;
7765     }
7766   else
7767     cu = NULL;
7768 
7769  next_cu:
7770   unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7771 			      &cudie, NULL);
7772   if (unit_res == 1)
7773     goto do_return;
7774 
7775   if (unit_res == -1)
7776     {
7777       if (!silent)
7778 	error (0, 0, _("cannot get next unit: %s"), dwarf_errmsg (-1));
7779       goto do_return;
7780     }
7781 
7782   if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7783     goto do_return;
7784 
7785   dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7786 		&unit_id, &subdie_off);
7787 
7788   if (!silent)
7789     {
7790       Dwarf_Off offset = cu->start;
7791       if (debug_types && version < 5)
7792 	{
7793 	  Dwarf_Die typedie;
7794 	  Dwarf_Off dieoffset;
7795 	  dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
7796 							   &typedie));
7797 	  printf (_(" Type unit at offset %" PRIu64 ":\n"
7798 			   " Version: %" PRIu16
7799 			   ", Abbreviation section offset: %" PRIu64
7800 			   ", Address size: %" PRIu8
7801 			   ", Offset size: %" PRIu8
7802 			   "\n Type signature: %#" PRIx64
7803 			   ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7804 		  (uint64_t) offset, version, abbroffset, addrsize, offsize,
7805 		  unit_id, (uint64_t) subdie_off, dieoffset);
7806 	}
7807       else
7808 	{
7809 	  printf (_(" Compilation unit at offset %" PRIu64 ":\n"
7810 			   " Version: %" PRIu16
7811 			   ", Abbreviation section offset: %" PRIu64
7812 			   ", Address size: %" PRIu8
7813 			   ", Offset size: %" PRIu8 "\n"),
7814 		  (uint64_t) offset, version, abbroffset, addrsize, offsize);
7815 
7816 	  if (version >= 5 || (unit_type != DW_UT_compile
7817 			       && unit_type != DW_UT_partial))
7818 	    {
7819 	      printf (_(" Unit type: %s (%" PRIu8 ")"),
7820 			       dwarf_unit_name (unit_type), unit_type);
7821 	      if (unit_type == DW_UT_type
7822 		  || unit_type == DW_UT_skeleton
7823 		  || unit_type == DW_UT_split_compile
7824 		  || unit_type == DW_UT_split_type)
7825 		printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7826 	      if (unit_type == DW_UT_type
7827 		  || unit_type == DW_UT_split_type)
7828 		{
7829 		  Dwarf_Die typedie;
7830 		  Dwarf_Off dieoffset;
7831 		  dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7832 				 NULL, NULL, NULL);
7833 		  dieoffset = dwarf_dieoffset (&typedie);
7834 		  printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7835 			  subdie_off, dieoffset);
7836 		}
7837 	      printf ("\n");
7838 	    }
7839 	}
7840     }
7841 
7842   if (version < 2 || version > 5
7843       || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7844     {
7845       if (!silent)
7846 	error (0, 0, _("unknown version (%d) or unit type (%d)"),
7847 	       version, unit_type);
7848       goto next_cu;
7849     }
7850 
7851   struct attrcb_args args =
7852     {
7853       .dwflmod = dwflmod,
7854       .silent = silent,
7855       .version = version,
7856       .addrsize = addrsize,
7857       .offset_size = offsize
7858     };
7859 
7860   bool is_split = false;
7861   int level = 0;
7862   dies[0] = cudie;
7863   args.cu = dies[0].cu;
7864   args.dbg = dbg;
7865   args.is_split = is_split;
7866 
7867   /* We might return here again for the split CU subdie.  */
7868   do_cu:
7869   do
7870     {
7871       Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7872       if (unlikely (offset == (Dwarf_Off) -1))
7873 	{
7874 	  if (!silent)
7875 	    error (0, 0, _("cannot get DIE offset: %s"),
7876 		   dwarf_errmsg (-1));
7877 	  goto do_return;
7878 	}
7879 
7880       int tag = dwarf_tag (&dies[level]);
7881       if (unlikely (tag == DW_TAG_invalid))
7882 	{
7883 	  if (!silent)
7884 	    error (0, 0, _("cannot get tag of DIE at offset [%" PRIx64
7885 				  "] in section '%s': %s"),
7886 		   (uint64_t) offset, secname, dwarf_errmsg (-1));
7887 	  goto do_return;
7888 	}
7889 
7890       if (!silent)
7891 	{
7892 	  unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7893 	  if (is_split)
7894 	    printf (" {%6" PRIx64 "}  ", (uint64_t) offset);
7895 	  else
7896 	    printf (" [%6" PRIx64 "]  ", (uint64_t) offset);
7897 	  printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7898 		  dwarf_tag_name (tag), code);
7899 	}
7900 
7901       /* Print the attribute values.  */
7902       args.level = level;
7903       args.dies = dies;
7904       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7905 
7906       /* Make room for the next level's DIE.  */
7907       if (level + 1 == maxdies)
7908 	dies = (Dwarf_Die *) xrealloc (dies,
7909 				       (maxdies += 10)
7910 				       * sizeof (Dwarf_Die));
7911 
7912       int res = dwarf_child (&dies[level], &dies[level + 1]);
7913       if (res > 0)
7914 	{
7915 	  while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7916 	    if (level-- == 0)
7917 	      break;
7918 
7919 	  if (unlikely (res == -1))
7920 	    {
7921 	      if (!silent)
7922 		error (0, 0, _("cannot get next DIE: %s\n"),
7923 		       dwarf_errmsg (-1));
7924 	      goto do_return;
7925 	    }
7926 	}
7927       else if (unlikely (res < 0))
7928 	{
7929 	  if (!silent)
7930 	    error (0, 0, _("cannot get next DIE: %s"),
7931 		   dwarf_errmsg (-1));
7932 	  goto do_return;
7933 	}
7934       else
7935 	++level;
7936     }
7937   while (level >= 0);
7938 
7939   /* We might want to show the split compile unit if this was a skeleton.
7940      We need to scan it if we are requesting printing .debug_ranges for
7941      DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7942      section.  */
7943   if (unit_type == DW_UT_skeleton
7944       && ((!silent && show_split_units)
7945 	  || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7946     {
7947       Dwarf_Die subdie;
7948       if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7949 	  || dwarf_tag (&subdie) == DW_TAG_invalid)
7950 	{
7951 	  if (!silent)
7952 	    {
7953 	      Dwarf_Attribute dwo_at;
7954 	      const char *dwo_name =
7955 		(dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7956 					       &dwo_at))
7957 		 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7958 						   &dwo_at))
7959 		     ?: "<unknown>"));
7960 	      fprintf (stderr,
7961 		       "Could not find split unit '%s', id: %" PRIx64 "\n",
7962 		       dwo_name, unit_id);
7963 	    }
7964 	}
7965       else
7966 	{
7967 	  Dwarf_CU *split_cu = subdie.cu;
7968 	  dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7969 			&addrsize, &offsize, &unit_id, &subdie_off);
7970 	  Dwarf_Off offset = cu->start;
7971 
7972 	  if (!silent)
7973 	    {
7974 	      printf (_(" Split compilation unit at offset %"
7975 			       PRIu64 ":\n"
7976 			       " Version: %" PRIu16
7977 			       ", Abbreviation section offset: %" PRIu64
7978 			       ", Address size: %" PRIu8
7979 			       ", Offset size: %" PRIu8 "\n"),
7980 		      (uint64_t) offset, version, abbroffset,
7981 		      addrsize, offsize);
7982 	      printf (_(" Unit type: %s (%" PRIu8 ")"),
7983 		      dwarf_unit_name (unit_type), unit_type);
7984 	      printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7985 	      printf ("\n");
7986 	    }
7987 
7988 	  unit_type = DW_UT_split_compile;
7989 	  is_split = true;
7990 	  level = 0;
7991 	  dies[0] = subdie;
7992 	  args.cu = dies[0].cu;
7993 	  args.dbg = split_cu->dbg;
7994 	  args.is_split = is_split;
7995 	  goto do_cu;
7996 	}
7997     }
7998 
7999   /* And again... */
8000   goto next_cu;
8001 
8002  do_return:
8003   free (dies);
8004 }
8005 
8006 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8007 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8008 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8009 {
8010   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
8011 }
8012 
8013 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8014 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8015 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8016 {
8017   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
8018 }
8019 
8020 
8021 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8022 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
8023 			    GElf_Ehdr *ehdr __attribute__ ((unused)),
8024 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8025 {
8026   printf (_("\
8027 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
8028 	  elf_ndxscn (scn), section_name (ebl, shdr),
8029 	  (uint64_t) shdr->sh_offset);
8030 
8031   size_t address_size
8032     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8033 
8034   Dwarf_Lines *lines;
8035   size_t nlines;
8036   Dwarf_Off off, next_off = 0;
8037   Dwarf_CU *cu = NULL;
8038   while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
8039 			   &lines, &nlines) == 0)
8040     {
8041       Dwarf_Die cudie;
8042       if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8043 				       NULL, NULL, NULL, NULL) == 0)
8044 	printf (" CU [%" PRIx64 "] %s\n",
8045 		dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8046       else
8047 	{
8048 	  /* DWARF5 lines can be independent of any CU, but they probably
8049 	     are used by some CU.  Determine the CU this block is for.  */
8050 	  Dwarf_Off cuoffset;
8051 	  Dwarf_Off ncuoffset = 0;
8052 	  size_t hsize;
8053 	  while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8054 			       NULL, NULL, NULL) == 0)
8055 	    {
8056 	      if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8057 		continue;
8058 	      Dwarf_Attribute stmt_list;
8059 	      if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8060 		continue;
8061 	      Dwarf_Word lineoff;
8062 	      if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8063 		continue;
8064 	      if (lineoff == off)
8065 		{
8066 		  /* Found the CU.  */
8067 		  cu = cudie.cu;
8068 		  break;
8069 		}
8070 	    }
8071 
8072 	  if (cu != NULL)
8073 	    printf (" CU [%" PRIx64 "] %s\n",
8074 		    dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8075 	  else
8076 	    printf (" No CU\n");
8077 	}
8078 
8079       printf ("  line:col SBPE* disc isa op address"
8080 	      " (Statement Block Prologue Epilogue *End)\n");
8081       const char *last_file = "";
8082       for (size_t n = 0; n < nlines; n++)
8083 	{
8084 	  Dwarf_Line *line = dwarf_onesrcline (lines, n);
8085 	  if (line == NULL)
8086 	    {
8087 	      printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8088 	      continue;
8089 	    }
8090 	  Dwarf_Word mtime, length;
8091 	  const char *file = dwarf_linesrc (line, &mtime, &length);
8092 	  if (file == NULL)
8093 	    {
8094 	      printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8095 	      last_file = "";
8096 	    }
8097 	  else if (strcmp (last_file, file) != 0)
8098 	    {
8099 	      printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8100 		      file, mtime, length);
8101 	      last_file = file;
8102 	    }
8103 
8104 	  int lineno, colno;
8105 	  bool statement, endseq, block, prologue_end, epilogue_begin;
8106 	  unsigned int lineop, isa, disc;
8107 	  Dwarf_Addr address;
8108 	  dwarf_lineaddr (line, &address);
8109 	  dwarf_lineno (line, &lineno);
8110 	  dwarf_linecol (line, &colno);
8111 	  dwarf_lineop_index (line, &lineop);
8112 	  dwarf_linebeginstatement (line, &statement);
8113 	  dwarf_lineendsequence (line, &endseq);
8114 	  dwarf_lineblock (line, &block);
8115 	  dwarf_lineprologueend (line, &prologue_end);
8116 	  dwarf_lineepiloguebegin (line, &epilogue_begin);
8117 	  dwarf_lineisa (line, &isa);
8118 	  dwarf_linediscriminator (line, &disc);
8119 
8120 	  /* End sequence is special, it is one byte past.  */
8121 	  printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8122 		  lineno, colno,
8123 		  (statement ? 'S' : ' '),
8124 		  (block ? 'B' : ' '),
8125 		  (prologue_end ? 'P' : ' '),
8126 		  (epilogue_begin ? 'E' : ' '),
8127 		  (endseq ? '*' : ' '),
8128 		  disc, isa, lineop);
8129 	  print_dwarf_addr (dwflmod, address_size,
8130 			    address - (endseq ? 1 : 0), address);
8131 	  printf ("\n");
8132 
8133 	  if (endseq)
8134 	    printf("\n");
8135 	}
8136     }
8137 }
8138 
8139 
8140 /* Print the value of a form.
8141    Returns new value of readp, or readendp on failure.  */
8142 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)8143 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8144 		 const unsigned char *readendp, unsigned int offset_len,
8145 		 Dwarf_Off str_offsets_base)
8146 {
8147   Dwarf_Word val;
8148   unsigned char *endp;
8149   Elf_Data *data;
8150   char *str;
8151   switch (form)
8152     {
8153     case DW_FORM_data1:
8154       if (readendp - readp < 1)
8155 	{
8156 	invalid_data:
8157 	  error (0, 0, "invalid data");
8158 	  return readendp;
8159 	}
8160       val = *readp++;
8161       printf (" %" PRIx8, (unsigned int) val);
8162       break;
8163 
8164     case DW_FORM_data2:
8165       if (readendp - readp < 2)
8166 	goto invalid_data;
8167       val = read_2ubyte_unaligned_inc (dbg, readp);
8168       printf(" %" PRIx16, (unsigned int) val);
8169       break;
8170 
8171     case DW_FORM_data4:
8172       if (readendp - readp < 4)
8173 	goto invalid_data;
8174       val = read_4ubyte_unaligned_inc (dbg, readp);
8175       printf (" %" PRIx32, (unsigned int) val);
8176       break;
8177 
8178     case DW_FORM_data8:
8179       if (readendp - readp < 8)
8180 	goto invalid_data;
8181       val = read_8ubyte_unaligned_inc (dbg, readp);
8182       printf (" %" PRIx64, val);
8183       break;
8184 
8185     case DW_FORM_sdata:
8186       if (readendp - readp < 1)
8187 	goto invalid_data;
8188       get_sleb128 (val, readp, readendp);
8189       printf (" %" PRIx64, val);
8190       break;
8191 
8192     case DW_FORM_udata:
8193       if (readendp - readp < 1)
8194 	goto invalid_data;
8195       get_uleb128 (val, readp, readendp);
8196       printf (" %" PRIx64, val);
8197       break;
8198 
8199     case DW_FORM_block:
8200       if (readendp - readp < 1)
8201 	goto invalid_data;
8202       get_uleb128 (val, readp, readendp);
8203       if ((size_t) (readendp - readp) < val)
8204 	goto invalid_data;
8205       print_bytes (val, readp);
8206       readp += val;
8207       break;
8208 
8209     case DW_FORM_block1:
8210       if (readendp - readp < 1)
8211 	goto invalid_data;
8212       val = *readp++;
8213       if ((size_t) (readendp - readp) < val)
8214 	goto invalid_data;
8215       print_bytes (val, readp);
8216       readp += val;
8217       break;
8218 
8219     case DW_FORM_block2:
8220       if (readendp - readp < 2)
8221 	goto invalid_data;
8222       val = read_2ubyte_unaligned_inc (dbg, readp);
8223       if ((size_t) (readendp - readp) < val)
8224 	goto invalid_data;
8225       print_bytes (val, readp);
8226       readp += val;
8227       break;
8228 
8229     case DW_FORM_block4:
8230       if (readendp - readp < 4)
8231 	goto invalid_data;
8232       val = read_4ubyte_unaligned_inc (dbg, readp);
8233       if ((size_t) (readendp - readp) < val)
8234 	goto invalid_data;
8235       print_bytes (val, readp);
8236       readp += val;
8237       break;
8238 
8239     case DW_FORM_data16:
8240       if (readendp - readp < 16)
8241 	goto invalid_data;
8242       print_bytes (16, readp);
8243       readp += 16;
8244       break;
8245 
8246     case DW_FORM_flag:
8247       if (readendp - readp < 1)
8248 	goto invalid_data;
8249       val = *readp++;
8250       printf ("%s", val != 0 ? yes_str : no_str);
8251       break;
8252 
8253     case DW_FORM_string:
8254       endp = memchr (readp, '\0', readendp - readp);
8255       if (endp == NULL)
8256 	goto invalid_data;
8257       printf ("%s", readp);
8258       readp = endp + 1;
8259       break;
8260 
8261     case DW_FORM_strp:
8262     case DW_FORM_line_strp:
8263     case DW_FORM_strp_sup:
8264       if ((size_t) (readendp - readp) < offset_len)
8265 	goto invalid_data;
8266       if (offset_len == 8)
8267 	val = read_8ubyte_unaligned_inc (dbg, readp);
8268       else
8269 	val = read_4ubyte_unaligned_inc (dbg, readp);
8270       if (form == DW_FORM_strp)
8271 	data = dbg->sectiondata[IDX_debug_str];
8272       else if (form == DW_FORM_line_strp)
8273 	data = dbg->sectiondata[IDX_debug_line_str];
8274       else /* form == DW_FORM_strp_sup */
8275 	{
8276 	  Dwarf *alt = dwarf_getalt (dbg);
8277 	  data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8278 	}
8279       if (data == NULL || val >= data->d_size
8280 	  || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8281 	str = "???";
8282       else
8283 	str = (char *) data->d_buf + val;
8284       printf ("%s (%" PRIu64 ")", str, val);
8285       break;
8286 
8287     case DW_FORM_sec_offset:
8288       if ((size_t) (readendp - readp) < offset_len)
8289 	goto invalid_data;
8290       if (offset_len == 8)
8291 	val = read_8ubyte_unaligned_inc (dbg, readp);
8292       else
8293 	val = read_4ubyte_unaligned_inc (dbg, readp);
8294       printf ("[%" PRIx64 "]", val);
8295       break;
8296 
8297     case DW_FORM_strx:
8298     case DW_FORM_GNU_str_index:
8299       if (readendp - readp < 1)
8300 	goto invalid_data;
8301       get_uleb128 (val, readp, readendp);
8302     strx_val:
8303       data = dbg->sectiondata[IDX_debug_str_offsets];
8304       if (data == NULL
8305 	  || data->d_size - str_offsets_base < val)
8306 	str = "???";
8307       else
8308 	{
8309 	  const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8310 	  const unsigned char *strreadendp = data->d_buf + data->d_size;
8311 	  if ((size_t) (strreadendp - strreadp) < offset_len)
8312 	    str = "???";
8313 	  else
8314 	    {
8315 	      Dwarf_Off idx;
8316 	      if (offset_len == 8)
8317 		idx = read_8ubyte_unaligned (dbg, strreadp);
8318 	      else
8319 		idx = read_4ubyte_unaligned (dbg, strreadp);
8320 
8321 	      data = dbg->sectiondata[IDX_debug_str];
8322 	      if (data == NULL || idx >= data->d_size
8323 		  || memchr (data->d_buf + idx, '\0',
8324 			     data->d_size - idx) == NULL)
8325 		str = "???";
8326 	      else
8327 		str = (char *) data->d_buf + idx;
8328 	    }
8329 	}
8330       printf ("%s (%" PRIu64 ")", str, val);
8331       break;
8332 
8333     case DW_FORM_strx1:
8334       if (readendp - readp < 1)
8335 	goto invalid_data;
8336       val = *readp++;
8337       goto strx_val;
8338 
8339     case DW_FORM_strx2:
8340       if (readendp - readp < 2)
8341 	goto invalid_data;
8342       val = read_2ubyte_unaligned_inc (dbg, readp);
8343       goto strx_val;
8344 
8345     case DW_FORM_strx3:
8346       if (readendp - readp < 3)
8347 	goto invalid_data;
8348       val = read_3ubyte_unaligned_inc (dbg, readp);
8349       goto strx_val;
8350 
8351     case DW_FORM_strx4:
8352       if (readendp - readp < 4)
8353 	goto invalid_data;
8354       val = read_4ubyte_unaligned_inc (dbg, readp);
8355       goto strx_val;
8356 
8357     default:
8358       error (0, 0, _("unknown form: %s"), dwarf_form_name (form));
8359       return readendp;
8360     }
8361 
8362   return readp;
8363 }
8364 
8365 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8366 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8367 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8368 {
8369   if (decodedline)
8370     {
8371       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8372       return;
8373     }
8374 
8375   printf (_("\
8376 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8377 	  elf_ndxscn (scn), section_name (ebl, shdr),
8378 	  (uint64_t) shdr->sh_offset);
8379 
8380   if (shdr->sh_size == 0)
8381     return;
8382 
8383   /* There is no functionality in libdw to read the information in the
8384      way it is represented here.  Hardcode the decoder.  */
8385   Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8386 		    ?: elf_rawdata (scn, NULL));
8387   if (unlikely (data == NULL))
8388     {
8389       error (0, 0, _("cannot get line data section data: %s"),
8390 	     elf_errmsg (-1));
8391       return;
8392     }
8393 
8394   const unsigned char *linep = (const unsigned char *) data->d_buf;
8395   const unsigned char *lineendp;
8396 
8397   while (linep
8398 	 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8399     {
8400       size_t start_offset = linep - (const unsigned char *) data->d_buf;
8401 
8402       printf (_("\nTable at offset %zu:\n"), start_offset);
8403 
8404       if (unlikely (linep + 4 > lineendp))
8405 	goto invalid_data;
8406       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8407       unsigned int length = 4;
8408       if (unlikely (unit_length == 0xffffffff))
8409 	{
8410 	  if (unlikely (linep + 8 > lineendp))
8411 	    {
8412 	    invalid_data:
8413 	      error (0, 0, _("invalid data in section [%zu] '%s'"),
8414 		     elf_ndxscn (scn), section_name (ebl, shdr));
8415 	      return;
8416 	    }
8417 	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8418 	  length = 8;
8419 	}
8420 
8421       /* Check whether we have enough room in the section.  */
8422       if (unlikely (unit_length > (size_t) (lineendp - linep)))
8423 	goto invalid_data;
8424       lineendp = linep + unit_length;
8425 
8426       /* The next element of the header is the version identifier.  */
8427       if ((size_t) (lineendp - linep) < 2)
8428 	goto invalid_data;
8429       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8430 
8431       size_t address_size
8432 	= elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8433       unsigned char segment_selector_size = 0;
8434       if (version > 4)
8435 	{
8436 	  if ((size_t) (lineendp - linep) < 2)
8437 	    goto invalid_data;
8438 	  address_size = *linep++;
8439 	  segment_selector_size = *linep++;
8440 	}
8441 
8442       /* Next comes the header length.  */
8443       Dwarf_Word header_length;
8444       if (length == 4)
8445 	{
8446 	  if ((size_t) (lineendp - linep) < 4)
8447 	    goto invalid_data;
8448 	  header_length = read_4ubyte_unaligned_inc (dbg, linep);
8449 	}
8450       else
8451 	{
8452 	  if ((size_t) (lineendp - linep) < 8)
8453 	    goto invalid_data;
8454 	  header_length = read_8ubyte_unaligned_inc (dbg, linep);
8455 	}
8456 
8457       /* Next the minimum instruction length.  */
8458       if ((size_t) (lineendp - linep) < 1)
8459 	goto invalid_data;
8460       uint_fast8_t minimum_instr_len = *linep++;
8461 
8462       /* Next the maximum operations per instruction, in version 4 format.  */
8463       uint_fast8_t max_ops_per_instr;
8464       if (version < 4)
8465 	max_ops_per_instr = 1;
8466       else
8467 	{
8468 	  if ((size_t) (lineendp - linep) < 1)
8469 	    goto invalid_data;
8470 	  max_ops_per_instr = *linep++;
8471 	}
8472 
8473       /* We need at least 4 more bytes.  */
8474       if ((size_t) (lineendp - linep) < 4)
8475 	goto invalid_data;
8476 
8477       /* Then the flag determining the default value of the is_stmt
8478 	 register.  */
8479       uint_fast8_t default_is_stmt = *linep++;
8480 
8481       /* Now the line base.  */
8482       int_fast8_t line_base = *linep++;
8483 
8484       /* And the line range.  */
8485       uint_fast8_t line_range = *linep++;
8486 
8487       /* The opcode base.  */
8488       uint_fast8_t opcode_base = *linep++;
8489 
8490       /* Print what we got so far.  */
8491       printf (_("\n"
8492 		       " Length:                         %" PRIu64 "\n"
8493 		       " DWARF version:                  %" PRIuFAST16 "\n"
8494 		       " Prologue length:                %" PRIu64 "\n"
8495 		       " Address size:                   %zd\n"
8496 		       " Segment selector size:          %zd\n"
8497 		       " Min instruction length:         %" PRIuFAST8 "\n"
8498 		       " Max operations per instruction: %" PRIuFAST8 "\n"
8499 		       " Initial value if 'is_stmt':     %" PRIuFAST8 "\n"
8500 		       " Line base:                      %" PRIdFAST8 "\n"
8501 		       " Line range:                     %" PRIuFAST8 "\n"
8502 		       " Opcode base:                    %" PRIuFAST8 "\n"
8503 		       "\n"
8504 		       "Opcodes:\n"),
8505 	      (uint64_t) unit_length, version, (uint64_t) header_length,
8506 	      address_size, (size_t) segment_selector_size,
8507 	      minimum_instr_len, max_ops_per_instr,
8508 	      default_is_stmt, line_base,
8509 	      line_range, opcode_base);
8510 
8511       if (version < 2 || version > 5)
8512 	{
8513 	  error (0, 0, _("cannot handle .debug_line version: %u\n"),
8514 		 (unsigned int) version);
8515 	  linep = lineendp;
8516 	  continue;
8517 	}
8518 
8519       if (address_size != 4 && address_size != 8)
8520 	{
8521 	  error (0, 0, _("cannot handle address size: %u\n"),
8522 		 (unsigned int) address_size);
8523 	  linep = lineendp;
8524 	  continue;
8525 	}
8526 
8527       if (segment_selector_size != 0)
8528 	{
8529 	  error (0, 0, _("cannot handle segment selector size: %u\n"),
8530 		 (unsigned int) segment_selector_size);
8531 	  linep = lineendp;
8532 	  continue;
8533 	}
8534 
8535       if (unlikely (linep + opcode_base - 1 >= lineendp))
8536 	{
8537 	invalid_unit:
8538 	  error (0, 0,
8539 		 _("invalid data at offset %tu in section [%zu] '%s'"),
8540 		 linep - (const unsigned char *) data->d_buf,
8541 		 elf_ndxscn (scn), section_name (ebl, shdr));
8542 	  linep = lineendp;
8543 	  continue;
8544 	}
8545       int opcode_base_l10 = 1;
8546       unsigned int tmp = opcode_base;
8547       while (tmp > 10)
8548 	{
8549 	  tmp /= 10;
8550 	  ++opcode_base_l10;
8551 	}
8552       const uint8_t *standard_opcode_lengths = linep - 1;
8553       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8554 	printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
8555 			  "  [%*" PRIuFAST8 "]  %hhu arguments\n",
8556 			  (int) linep[cnt - 1]),
8557 		opcode_base_l10, cnt, linep[cnt - 1]);
8558       linep += opcode_base - 1;
8559 
8560       if (unlikely (linep >= lineendp))
8561 	goto invalid_unit;
8562 
8563       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8564 
8565       puts (_("\nDirectory table:"));
8566       if (version > 4)
8567 	{
8568 	  struct encpair { uint16_t desc; uint16_t form; };
8569 	  struct encpair enc[256];
8570 
8571 	  printf (_("      ["));
8572 	  if ((size_t) (lineendp - linep) < 1)
8573 	    goto invalid_data;
8574 	  unsigned char directory_entry_format_count = *linep++;
8575 	  for (int i = 0; i < directory_entry_format_count; i++)
8576 	    {
8577 	      uint16_t desc, form;
8578 	      if ((size_t) (lineendp - linep) < 1)
8579 		goto invalid_data;
8580 	      get_uleb128 (desc, linep, lineendp);
8581 	      if ((size_t) (lineendp - linep) < 1)
8582 		goto invalid_data;
8583 	      get_uleb128 (form, linep, lineendp);
8584 
8585 	      enc[i].desc = desc;
8586 	      enc[i].form = form;
8587 
8588 	      printf ("%s(%s)",
8589 		      dwarf_line_content_description_name (desc),
8590 		      dwarf_form_name (form));
8591 	      if (i + 1 < directory_entry_format_count)
8592 		printf (", ");
8593 	    }
8594 	  printf ("]\n");
8595 
8596 	  uint64_t directories_count;
8597 	  if ((size_t) (lineendp - linep) < 1)
8598             goto invalid_data;
8599 	  get_uleb128 (directories_count, linep, lineendp);
8600 
8601 	  if (directory_entry_format_count == 0
8602 	      && directories_count != 0)
8603 	    goto invalid_data;
8604 
8605 	  for (uint64_t i = 0; i < directories_count; i++)
8606 	    {
8607 	      printf (" %-5" PRIu64 " ", i);
8608 	      for (int j = 0; j < directory_entry_format_count; j++)
8609 		{
8610 		  linep = print_form_data (dbg, enc[j].form,
8611 					   linep, lineendp, length,
8612 					   str_offsets_base);
8613 		  if (j + 1 < directory_entry_format_count)
8614 		    printf (", ");
8615 		}
8616 	      printf ("\n");
8617 	      if (linep >= lineendp)
8618 		goto invalid_unit;
8619 	    }
8620 	}
8621       else
8622 	{
8623 	  while (linep < lineendp && *linep != 0)
8624 	    {
8625 	      unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8626 	      if (unlikely (endp == NULL))
8627 		goto invalid_unit;
8628 
8629 	      printf (" %s\n", (char *) linep);
8630 
8631 	      linep = endp + 1;
8632 	    }
8633 	  if (linep >= lineendp || *linep != 0)
8634 	    goto invalid_unit;
8635 	  /* Skip the final NUL byte.  */
8636 	  ++linep;
8637 	}
8638 
8639       if (unlikely (linep >= lineendp))
8640 	goto invalid_unit;
8641 
8642       puts (_("\nFile name table:"));
8643       if (version > 4)
8644 	{
8645 	  struct encpair { uint16_t desc; uint16_t form; };
8646 	  struct encpair enc[256];
8647 
8648 	  printf (_("      ["));
8649 	  if ((size_t) (lineendp - linep) < 1)
8650 	    goto invalid_data;
8651 	  unsigned char file_name_format_count = *linep++;
8652 	  for (int i = 0; i < file_name_format_count; i++)
8653 	    {
8654 	      uint64_t desc, form;
8655 	      if ((size_t) (lineendp - linep) < 1)
8656 		goto invalid_data;
8657 	      get_uleb128 (desc, linep, lineendp);
8658 	      if ((size_t) (lineendp - linep) < 1)
8659 		goto invalid_data;
8660 	      get_uleb128 (form, linep, lineendp);
8661 
8662 	      if (! libdw_valid_user_form (form))
8663 		goto invalid_data;
8664 
8665 	      enc[i].desc = desc;
8666 	      enc[i].form = form;
8667 
8668 	      printf ("%s(%s)",
8669 		      dwarf_line_content_description_name (desc),
8670 		      dwarf_form_name (form));
8671 	      if (i + 1 < file_name_format_count)
8672 		printf (", ");
8673 	    }
8674 	  printf ("]\n");
8675 
8676 	  uint64_t file_name_count;
8677 	  if ((size_t) (lineendp - linep) < 1)
8678             goto invalid_data;
8679 	  get_uleb128 (file_name_count, linep, lineendp);
8680 
8681 	  if (file_name_format_count == 0
8682 	      && file_name_count != 0)
8683 	    goto invalid_data;
8684 
8685 	  for (uint64_t i = 0; i < file_name_count; i++)
8686 	    {
8687 	      printf (" %-5" PRIu64 " ", i);
8688 	      for (int j = 0; j < file_name_format_count; j++)
8689 		{
8690 		  linep = print_form_data (dbg, enc[j].form,
8691 					   linep, lineendp, length,
8692 					   str_offsets_base);
8693 		  if (j + 1 < file_name_format_count)
8694 		    printf (", ");
8695 		}
8696 	      printf ("\n");
8697 	      if (linep > lineendp)
8698 		goto invalid_unit;
8699 	    }
8700 	}
8701       else
8702 	{
8703 	  puts (_(" Entry Dir   Time      Size      Name"));
8704 	  for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8705 	    {
8706 	      /* First comes the file name.  */
8707 	      char *fname = (char *) linep;
8708 	      unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8709 	      if (unlikely (endp == NULL))
8710 		goto invalid_unit;
8711 	      linep = endp + 1;
8712 
8713 	      /* Then the index.  */
8714 	      unsigned int diridx;
8715 	      if (lineendp - linep < 1)
8716 		goto invalid_unit;
8717 	      get_uleb128 (diridx, linep, lineendp);
8718 
8719 	      /* Next comes the modification time.  */
8720 	      unsigned int mtime;
8721 	      if (lineendp - linep < 1)
8722 		goto invalid_unit;
8723 	      get_uleb128 (mtime, linep, lineendp);
8724 
8725 	      /* Finally the length of the file.  */
8726 	      unsigned int fsize;
8727 	      if (lineendp - linep < 1)
8728 		goto invalid_unit;
8729 	      get_uleb128 (fsize, linep, lineendp);
8730 
8731 	      printf (" %-5u %-5u %-9u %-9u %s\n",
8732 		      cnt, diridx, mtime, fsize, fname);
8733 	    }
8734 	  if (linep >= lineendp || *linep != '\0')
8735 	    goto invalid_unit;
8736 	  /* Skip the final NUL byte.  */
8737 	  ++linep;
8738 	}
8739 
8740       if (linep == lineendp)
8741 	{
8742 	  puts (_("\nNo line number statements."));
8743 	  return;
8744 	}
8745 
8746       puts (_("\nLine number statements:"));
8747       Dwarf_Word address = 0;
8748       unsigned int op_index = 0;
8749       size_t line = 1;
8750       uint_fast8_t is_stmt = default_is_stmt;
8751 
8752       /* Apply the "operation advance" from a special opcode
8753 	 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
8754       unsigned int op_addr_advance;
8755       inline void advance_pc (unsigned int op_advance)
8756       {
8757 	op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8758 					       / max_ops_per_instr);
8759 	address += op_addr_advance;
8760 	op_index = (op_index + op_advance) % max_ops_per_instr;
8761       }
8762 
8763       if (max_ops_per_instr == 0)
8764 	{
8765 	  error (0, 0,
8766 		 _("invalid maximum operations per instruction is zero"));
8767 	  linep = lineendp;
8768 	  continue;
8769 	}
8770 
8771       while (linep < lineendp)
8772 	{
8773 	  size_t offset = linep - (const unsigned char *) data->d_buf;
8774 	  unsigned int u128;
8775 	  int s128;
8776 
8777 	  /* Read the opcode.  */
8778 	  unsigned int opcode = *linep++;
8779 
8780 	  printf (" [%6" PRIx64 "]", (uint64_t)offset);
8781 	  /* Is this a special opcode?  */
8782 	  if (likely (opcode >= opcode_base))
8783 	    {
8784 	      if (unlikely (line_range == 0))
8785 		goto invalid_unit;
8786 
8787 	      /* Yes.  Handling this is quite easy since the opcode value
8788 		 is computed with
8789 
8790 		 opcode = (desired line increment - line_base)
8791 			   + (line_range * address advance) + opcode_base
8792 	      */
8793 	      int line_increment = (line_base
8794 				    + (opcode - opcode_base) % line_range);
8795 
8796 	      /* Perform the increments.  */
8797 	      line += line_increment;
8798 	      advance_pc ((opcode - opcode_base) / line_range);
8799 
8800 	      printf (_(" special opcode %u: address+%u = "),
8801 		      opcode, op_addr_advance);
8802 	      print_dwarf_addr (dwflmod, 0, address, address);
8803 	      if (op_index > 0)
8804 		printf (_(", op_index = %u, line%+d = %zu\n"),
8805 			op_index, line_increment, line);
8806 	      else
8807 		printf (_(", line%+d = %zu\n"),
8808 			line_increment, line);
8809 	    }
8810 	  else if (opcode == 0)
8811 	    {
8812 	      /* This an extended opcode.  */
8813 	      if (unlikely (linep + 2 > lineendp))
8814 		goto invalid_unit;
8815 
8816 	      /* The length.  */
8817 	      unsigned int len = *linep++;
8818 
8819 	      if (unlikely (linep + len > lineendp))
8820 		goto invalid_unit;
8821 
8822 	      /* The sub-opcode.  */
8823 	      opcode = *linep++;
8824 
8825 	      printf (_(" extended opcode %u: "), opcode);
8826 
8827 	      switch (opcode)
8828 		{
8829 		case DW_LNE_end_sequence:
8830 		  puts (_(" end of sequence"));
8831 
8832 		  /* Reset the registers we care about.  */
8833 		  address = 0;
8834 		  op_index = 0;
8835 		  line = 1;
8836 		  is_stmt = default_is_stmt;
8837 		  break;
8838 
8839 		case DW_LNE_set_address:
8840 		  op_index = 0;
8841 		  if (unlikely ((size_t) (lineendp - linep) < address_size))
8842 		    goto invalid_unit;
8843 		  if (address_size == 4)
8844 		    address = read_4ubyte_unaligned_inc (dbg, linep);
8845 		  else
8846 		    address = read_8ubyte_unaligned_inc (dbg, linep);
8847 		  {
8848 		    printf (_(" set address to "));
8849 		    print_dwarf_addr (dwflmod, 0, address, address);
8850 		    printf ("\n");
8851 		  }
8852 		  break;
8853 
8854 		case DW_LNE_define_file:
8855 		  {
8856 		    char *fname = (char *) linep;
8857 		    unsigned char *endp = memchr (linep, '\0',
8858 						  lineendp - linep);
8859 		    if (unlikely (endp == NULL))
8860 		      goto invalid_unit;
8861 		    linep = endp + 1;
8862 
8863 		    unsigned int diridx;
8864 		    if (lineendp - linep < 1)
8865 		      goto invalid_unit;
8866 		    get_uleb128 (diridx, linep, lineendp);
8867 		    Dwarf_Word mtime;
8868 		    if (lineendp - linep < 1)
8869 		      goto invalid_unit;
8870 		    get_uleb128 (mtime, linep, lineendp);
8871 		    Dwarf_Word filelength;
8872 		    if (lineendp - linep < 1)
8873 		      goto invalid_unit;
8874 		    get_uleb128 (filelength, linep, lineendp);
8875 
8876 		    printf (_("\
8877  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8878 			    diridx, (uint64_t) mtime, (uint64_t) filelength,
8879 			    fname);
8880 		  }
8881 		  break;
8882 
8883 		case DW_LNE_set_discriminator:
8884 		  /* Takes one ULEB128 parameter, the discriminator.  */
8885 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8886 				|| lineendp - linep < 1))
8887 		    goto invalid_unit;
8888 
8889 		  get_uleb128 (u128, linep, lineendp);
8890 		  printf (_(" set discriminator to %u\n"), u128);
8891 		  break;
8892 
8893 		default:
8894 		  /* Unknown, ignore it.  */
8895 		  puts (_(" unknown opcode"));
8896 		  linep += len - 1;
8897 		  break;
8898 		}
8899 	    }
8900 	  else if (opcode <= DW_LNS_set_isa)
8901 	    {
8902 	      /* This is a known standard opcode.  */
8903 	      switch (opcode)
8904 		{
8905 		case DW_LNS_copy:
8906 		  /* Takes no argument.  */
8907 		  puts (_(" copy"));
8908 		  break;
8909 
8910 		case DW_LNS_advance_pc:
8911 		  /* Takes one uleb128 parameter which is added to the
8912 		     address.  */
8913 		  if (lineendp - linep < 1)
8914 		    goto invalid_unit;
8915 		  get_uleb128 (u128, linep, lineendp);
8916 		  advance_pc (u128);
8917 		  {
8918 		    printf (_(" advance address by %u to "),
8919 			    op_addr_advance);
8920 		    print_dwarf_addr (dwflmod, 0, address, address);
8921 		    if (op_index > 0)
8922 		      printf (_(", op_index to %u"), op_index);
8923 		    printf ("\n");
8924 		  }
8925 		  break;
8926 
8927 		case DW_LNS_advance_line:
8928 		  /* Takes one sleb128 parameter which is added to the
8929 		     line.  */
8930 		  if (lineendp - linep < 1)
8931 		    goto invalid_unit;
8932 		  get_sleb128 (s128, linep, lineendp);
8933 		  line += s128;
8934 		  printf (_("\
8935  advance line by constant %d to %" PRId64 "\n"),
8936 			  s128, (int64_t) line);
8937 		  break;
8938 
8939 		case DW_LNS_set_file:
8940 		  /* Takes one uleb128 parameter which is stored in file.  */
8941 		  if (lineendp - linep < 1)
8942 		    goto invalid_unit;
8943 		  get_uleb128 (u128, linep, lineendp);
8944 		  printf (_(" set file to %" PRIu64 "\n"),
8945 			  (uint64_t) u128);
8946 		  break;
8947 
8948 		case DW_LNS_set_column:
8949 		  /* Takes one uleb128 parameter which is stored in column.  */
8950 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8951 				|| lineendp - linep < 1))
8952 		    goto invalid_unit;
8953 
8954 		  get_uleb128 (u128, linep, lineendp);
8955 		  printf (_(" set column to %" PRIu64 "\n"),
8956 			  (uint64_t) u128);
8957 		  break;
8958 
8959 		case DW_LNS_negate_stmt:
8960 		  /* Takes no argument.  */
8961 		  is_stmt = 1 - is_stmt;
8962 		  printf (_(" set '%s' to %" PRIuFAST8 "\n"),
8963 			  "is_stmt", is_stmt);
8964 		  break;
8965 
8966 		case DW_LNS_set_basic_block:
8967 		  /* Takes no argument.  */
8968 		  puts (_(" set basic block flag"));
8969 		  break;
8970 
8971 		case DW_LNS_const_add_pc:
8972 		  /* Takes no argument.  */
8973 
8974 		  if (unlikely (line_range == 0))
8975 		    goto invalid_unit;
8976 
8977 		  advance_pc ((255 - opcode_base) / line_range);
8978 		  {
8979 		    printf (_(" advance address by constant %u to "),
8980 			    op_addr_advance);
8981 		    print_dwarf_addr (dwflmod, 0, address, address);
8982 		    if (op_index > 0)
8983 		      printf (_(", op_index to %u"), op_index);
8984 		    printf ("\n");
8985 		  }
8986 		  break;
8987 
8988 		case DW_LNS_fixed_advance_pc:
8989 		  /* Takes one 16 bit parameter which is added to the
8990 		     address.  */
8991 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8992 				|| lineendp - linep < 2))
8993 		    goto invalid_unit;
8994 
8995 		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
8996 		  address += u128;
8997 		  op_index = 0;
8998 		  {
8999 		    printf (_("\
9000  advance address by fixed value %u to \n"),
9001 			    u128);
9002 		    print_dwarf_addr (dwflmod, 0, address, address);
9003 		    printf ("\n");
9004 		  }
9005 		  break;
9006 
9007 		case DW_LNS_set_prologue_end:
9008 		  /* Takes no argument.  */
9009 		  puts (_(" set prologue end flag"));
9010 		  break;
9011 
9012 		case DW_LNS_set_epilogue_begin:
9013 		  /* Takes no argument.  */
9014 		  puts (_(" set epilogue begin flag"));
9015 		  break;
9016 
9017 		case DW_LNS_set_isa:
9018 		  /* Takes one uleb128 parameter which is stored in isa.  */
9019 		  if (unlikely (standard_opcode_lengths[opcode] != 1
9020 				|| lineendp - linep < 1))
9021 		    goto invalid_unit;
9022 
9023 		  get_uleb128 (u128, linep, lineendp);
9024 		  printf (_(" set isa to %u\n"), u128);
9025 		  break;
9026 		}
9027 	    }
9028 	  else
9029 	    {
9030 	      /* This is a new opcode the generator but not we know about.
9031 		 Read the parameters associated with it but then discard
9032 		 everything.  Read all the parameters for this opcode.  */
9033 	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
9034 				" unknown opcode with %" PRIu8 " parameters:",
9035 				standard_opcode_lengths[opcode]),
9036 		      standard_opcode_lengths[opcode]);
9037 	      for (int n = standard_opcode_lengths[opcode];
9038 		   n > 0 && linep < lineendp; --n)
9039 		{
9040 		  get_uleb128 (u128, linep, lineendp);
9041 		  if (n != standard_opcode_lengths[opcode])
9042 		    putc_unlocked (',', stdout);
9043 		  printf (" %u", u128);
9044 		}
9045 
9046 	      /* Next round, ignore this opcode.  */
9047 	      continue;
9048 	    }
9049 	}
9050     }
9051 
9052   /* There must only be one data block.  */
9053   assert (elf_getdata (scn, data) == NULL);
9054 }
9055 
9056 
9057 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9058 print_debug_loclists_section (Dwfl_Module *dwflmod,
9059 			      Ebl *ebl,
9060 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
9061 			      Elf_Scn *scn, GElf_Shdr *shdr,
9062 			      Dwarf *dbg)
9063 {
9064   printf (_("\
9065 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9066 	  elf_ndxscn (scn), section_name (ebl, shdr),
9067 	  (uint64_t) shdr->sh_offset);
9068 
9069   Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9070 		    ?: elf_rawdata (scn, NULL));
9071   if (unlikely (data == NULL))
9072     {
9073       error (0, 0, _("cannot get .debug_loclists content: %s"),
9074 	     elf_errmsg (-1));
9075       return;
9076     }
9077 
9078   /* For the listptr to get the base address/CU.  */
9079   sort_listptr (&known_loclistsptr, "loclistsptr");
9080   size_t listptr_idx = 0;
9081 
9082   const unsigned char *readp = data->d_buf;
9083   const unsigned char *const dataend = ((unsigned char *) data->d_buf
9084 					+ data->d_size);
9085   while (readp < dataend)
9086     {
9087       if (unlikely (readp > dataend - 4))
9088 	{
9089 	invalid_data:
9090 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
9091 		 elf_ndxscn (scn), section_name (ebl, shdr));
9092 	  return;
9093 	}
9094 
9095       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9096       printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
9097 	      (uint64_t) offset);
9098 
9099       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9100       unsigned int offset_size = 4;
9101       if (unlikely (unit_length == 0xffffffff))
9102 	{
9103 	  if (unlikely (readp > dataend - 8))
9104 	    goto invalid_data;
9105 
9106 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9107 	  offset_size = 8;
9108 	}
9109       printf (_(" Length:         %8" PRIu64 "\n"), unit_length);
9110 
9111       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9112 	 bytes to complete the header.  And this unit cannot go beyond
9113 	 the section data.  */
9114       if (readp > dataend - 8
9115 	  || unit_length < 8
9116 	  || unit_length > (uint64_t) (dataend - readp))
9117 	goto invalid_data;
9118 
9119       const unsigned char *nexthdr = readp + unit_length;
9120 
9121       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9122       printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
9123 
9124       if (version != 5)
9125 	{
9126 	  error (0, 0, _("Unknown version"));
9127 	  goto next_table;
9128 	}
9129 
9130       uint8_t address_size = *readp++;
9131       printf (_(" Address size:   %8" PRIu64 "\n"),
9132 	      (uint64_t) address_size);
9133 
9134       if (address_size != 4 && address_size != 8)
9135 	{
9136 	  error (0, 0, _("unsupported address size"));
9137 	  goto next_table;
9138 	}
9139 
9140       uint8_t segment_size = *readp++;
9141       printf (_(" Segment size:   %8" PRIu64 "\n"),
9142 	      (uint64_t) segment_size);
9143 
9144       if (segment_size != 0)
9145         {
9146           error (0, 0, _("unsupported segment size"));
9147           goto next_table;
9148         }
9149 
9150       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9151       printf (_(" Offset entries: %8" PRIu64 "\n"),
9152 	      (uint64_t) offset_entry_count);
9153 
9154       /* We need the CU that uses this unit to get the initial base address. */
9155       Dwarf_Addr cu_base = 0;
9156       struct Dwarf_CU *cu = NULL;
9157       if (listptr_cu (&known_loclistsptr, &listptr_idx,
9158 		      (Dwarf_Off) offset,
9159 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9160 		      &cu_base, &cu)
9161 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
9162 	{
9163 	  Dwarf_Die cudie;
9164 	  if (dwarf_cu_die (cu, &cudie,
9165 			    NULL, NULL, NULL, NULL,
9166 			    NULL, NULL) == NULL)
9167 	    printf (_(" Unknown CU base: "));
9168 	  else
9169 	    printf (_(" CU [%6" PRIx64 "] base: "),
9170 		    dwarf_dieoffset (&cudie));
9171 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9172 	  printf ("\n");
9173 	}
9174       else
9175 	printf (_(" Not associated with a CU.\n"));
9176 
9177       printf ("\n");
9178 
9179       const unsigned char *offset_array_start = readp;
9180       if (offset_entry_count > 0)
9181 	{
9182 	  uint64_t max_entries = (unit_length - 8) / offset_size;
9183 	  if (offset_entry_count > max_entries)
9184 	    {
9185 	      error (0, 0,
9186 		     _("too many offset entries for unit length"));
9187 	      offset_entry_count = max_entries;
9188 	    }
9189 
9190 	  printf (_("  Offsets starting at 0x%" PRIx64 ":\n"),
9191 		  (uint64_t) (offset_array_start
9192 			      - (unsigned char *) data->d_buf));
9193 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9194 	    {
9195 	      printf ("   [%6" PRIu32 "] ", idx);
9196 	      if (offset_size == 4)
9197 		{
9198 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9199 		  printf ("0x%" PRIx32 "\n", off);
9200 		}
9201 	      else
9202 		{
9203 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9204 		  printf ("0x%" PRIx64 "\n", off);
9205 		}
9206 	    }
9207 	  printf ("\n");
9208 	}
9209 
9210       Dwarf_Addr base = cu_base;
9211       bool start_of_list = true;
9212       while (readp < nexthdr)
9213 	{
9214 	  Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf);
9215 	  if (listptr_attr (&known_loclistsptr, listptr_idx, off,
9216 			    DW_AT_GNU_locviews))
9217 	    {
9218 	      Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
9219 							&listptr_idx, off);
9220 	      const unsigned char *locp = readp;
9221 	      const unsigned char *locendp;
9222 	      if (next_off == 0
9223 		  || next_off > (size_t) (nexthdr - ((const unsigned char *)
9224 						     data->d_buf)))
9225 		locendp = nexthdr;
9226 	      else
9227 		locendp = (const unsigned char *) data->d_buf + next_off;
9228 
9229 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9230 		      (uint64_t) (readp - (unsigned char *) data->d_buf),
9231 		      (uint64_t) (readp - offset_array_start));
9232 
9233 	      while (locp < locendp)
9234 		{
9235 		  uint64_t v1, v2;
9236 		  get_uleb128 (v1, locp, locendp);
9237 		  if (locp >= locendp)
9238 		    {
9239 		      printf (_("    <INVALID DATA>\n"));
9240 		      break;
9241 		    }
9242 		  get_uleb128 (v2, locp, locendp);
9243 		  printf ("    view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9244 		}
9245 
9246 	      printf ("\n");
9247 	      readp = (unsigned char *) locendp;
9248 	      continue;
9249 	    }
9250 
9251 	  uint8_t kind = *readp++;
9252 	  uint64_t op1, op2, len;
9253 
9254 	  /* Skip padding.  */
9255 	  if (start_of_list && kind == DW_LLE_end_of_list)
9256 	    continue;
9257 
9258 	  if (start_of_list)
9259 	    {
9260 	      base = cu_base;
9261 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9262 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9263 		      (uint64_t) (readp - offset_array_start - 1));
9264 	      start_of_list = false;
9265 	    }
9266 
9267 	  printf ("    %s", dwarf_loc_list_encoding_name (kind));
9268 	  switch (kind)
9269 	    {
9270 	    case DW_LLE_end_of_list:
9271 	      start_of_list = true;
9272 	      printf ("\n\n");
9273 	      break;
9274 
9275 	    case DW_LLE_base_addressx:
9276 	      if ((uint64_t) (nexthdr - readp) < 1)
9277 		{
9278 		invalid_entry:
9279 		  error (0, 0, _("invalid loclists data"));
9280 		  goto next_table;
9281 		}
9282 	      get_uleb128 (op1, readp, nexthdr);
9283 	      printf (" %" PRIx64 "\n", op1);
9284 	      if (! print_unresolved_addresses)
9285 		{
9286 		  Dwarf_Addr addr;
9287 		  if (get_indexed_addr (cu, op1, &addr) != 0)
9288 		    printf ("      ???\n");
9289 		  else
9290 		    {
9291 		      printf ("      ");
9292 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
9293 		      printf ("\n");
9294 		    }
9295 		}
9296 	      break;
9297 
9298 	    case DW_LLE_startx_endx:
9299 	      if ((uint64_t) (nexthdr - readp) < 1)
9300 		goto invalid_entry;
9301 	      get_uleb128 (op1, readp, nexthdr);
9302 	      if ((uint64_t) (nexthdr - readp) < 1)
9303 		goto invalid_entry;
9304 	      get_uleb128 (op2, readp, nexthdr);
9305 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9306 	      if (! print_unresolved_addresses)
9307 		{
9308 		  Dwarf_Addr addr1;
9309 		  Dwarf_Addr addr2;
9310 		  if (get_indexed_addr (cu, op1, &addr1) != 0
9311 		      || get_indexed_addr (cu, op2, &addr2) != 0)
9312 		    {
9313 		      printf ("      ???..\n");
9314 		      printf ("      ???\n");
9315 		    }
9316 		  else
9317 		    {
9318 		      printf ("      ");
9319 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9320 		      printf ("..\n      ");
9321 		      print_dwarf_addr (dwflmod, address_size,
9322 					addr2 - 1, addr2);
9323 		      printf ("\n");
9324 		    }
9325 		}
9326 	      if ((uint64_t) (nexthdr - readp) < 1)
9327 		goto invalid_entry;
9328 	      get_uleb128 (len, readp, nexthdr);
9329 	      if ((uint64_t) (nexthdr - readp) < len)
9330 		goto invalid_entry;
9331 	      print_ops (dwflmod, dbg, 8, 8, version,
9332 			 address_size, offset_size, cu, len, readp);
9333 	      readp += len;
9334 	      break;
9335 
9336 	    case DW_LLE_startx_length:
9337 	      if ((uint64_t) (nexthdr - readp) < 1)
9338 		goto invalid_entry;
9339 	      get_uleb128 (op1, readp, nexthdr);
9340 	      if ((uint64_t) (nexthdr - readp) < 1)
9341 		goto invalid_entry;
9342 	      get_uleb128 (op2, readp, nexthdr);
9343 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9344 	      if (! print_unresolved_addresses)
9345 		{
9346 		  Dwarf_Addr addr1;
9347 		  Dwarf_Addr addr2;
9348 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
9349 		    {
9350 		      printf ("      ???..\n");
9351 		      printf ("      ???\n");
9352 		    }
9353 		  else
9354 		    {
9355 		      addr2 = addr1 + op2;
9356 		      printf ("      ");
9357 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9358 		      printf ("..\n      ");
9359 		      print_dwarf_addr (dwflmod, address_size,
9360 					addr2 - 1, addr2);
9361 		      printf ("\n");
9362 		    }
9363 		}
9364 	      if ((uint64_t) (nexthdr - readp) < 1)
9365 		goto invalid_entry;
9366 	      get_uleb128 (len, readp, nexthdr);
9367 	      if ((uint64_t) (nexthdr - readp) < len)
9368 		goto invalid_entry;
9369 	      print_ops (dwflmod, dbg, 8, 8, version,
9370 			 address_size, offset_size, cu, len, readp);
9371 	      readp += len;
9372 	      break;
9373 
9374 	    case DW_LLE_offset_pair:
9375 	      if ((uint64_t) (nexthdr - readp) < 1)
9376 		goto invalid_entry;
9377 	      get_uleb128 (op1, readp, nexthdr);
9378 	      if ((uint64_t) (nexthdr - readp) < 1)
9379 		goto invalid_entry;
9380 	      get_uleb128 (op2, readp, nexthdr);
9381 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9382 	      if (! print_unresolved_addresses)
9383 		{
9384 		  op1 += base;
9385 		  op2 += base;
9386 		  printf ("      ");
9387 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9388 		  printf ("..\n      ");
9389 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9390 		  printf ("\n");
9391 		}
9392 	      if ((uint64_t) (nexthdr - readp) < 1)
9393 		goto invalid_entry;
9394 	      get_uleb128 (len, readp, nexthdr);
9395 	      if ((uint64_t) (nexthdr - readp) < len)
9396 		goto invalid_entry;
9397 	      print_ops (dwflmod, dbg, 8, 8, version,
9398 			 address_size, offset_size, cu, len, readp);
9399 	      readp += len;
9400 	      break;
9401 
9402 	    case DW_LLE_default_location:
9403 	      if ((uint64_t) (nexthdr - readp) < 1)
9404 		goto invalid_entry;
9405 	      get_uleb128 (len, readp, nexthdr);
9406 	      if ((uint64_t) (nexthdr - readp) < len)
9407 		goto invalid_entry;
9408 	      print_ops (dwflmod, dbg, 8, 8, version,
9409 			 address_size, offset_size, cu, len, readp);
9410 	      readp += len;
9411 	      break;
9412 
9413 	    case DW_LLE_base_address:
9414 	      if (address_size == 4)
9415 		{
9416 		  if ((uint64_t) (nexthdr - readp) < 4)
9417 		    goto invalid_entry;
9418 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9419 		}
9420 	      else
9421 		{
9422 		  if ((uint64_t) (nexthdr - readp) < 8)
9423 		    goto invalid_entry;
9424 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9425 		}
9426 	      base = op1;
9427 	      printf (" 0x%" PRIx64 "\n", base);
9428 	      if (! print_unresolved_addresses)
9429 		{
9430 		  printf ("      ");
9431 		  print_dwarf_addr (dwflmod, address_size, base, base);
9432 		  printf ("\n");
9433 		}
9434 	      break;
9435 
9436 	    case DW_LLE_start_end:
9437 	      if (address_size == 4)
9438 		{
9439 		  if ((uint64_t) (nexthdr - readp) < 8)
9440 		    goto invalid_entry;
9441 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9442 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
9443 		}
9444 	      else
9445 		{
9446 		  if ((uint64_t) (nexthdr - readp) < 16)
9447 		    goto invalid_entry;
9448 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9449 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
9450 		}
9451 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9452 	      if (! print_unresolved_addresses)
9453 		{
9454 		  printf ("      ");
9455 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9456 		  printf ("..\n      ");
9457 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9458 		  printf ("\n");
9459 		}
9460 	      if ((uint64_t) (nexthdr - readp) < 1)
9461 		goto invalid_entry;
9462 	      get_uleb128 (len, readp, nexthdr);
9463 	      if ((uint64_t) (nexthdr - readp) < len)
9464 		goto invalid_entry;
9465 	      print_ops (dwflmod, dbg, 8, 8, version,
9466 			 address_size, offset_size, cu, len, readp);
9467 	      readp += len;
9468 	      break;
9469 
9470 	    case DW_LLE_start_length:
9471 	      if (address_size == 4)
9472 		{
9473 		  if ((uint64_t) (nexthdr - readp) < 4)
9474 		    goto invalid_entry;
9475 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9476 		}
9477 	      else
9478 		{
9479 		  if ((uint64_t) (nexthdr - readp) < 8)
9480 		    goto invalid_entry;
9481 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9482 		}
9483 	      if ((uint64_t) (nexthdr - readp) < 1)
9484 		goto invalid_entry;
9485 	      get_uleb128 (op2, readp, nexthdr);
9486 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9487 	      if (! print_unresolved_addresses)
9488 		{
9489 		  op2 = op1 + op2;
9490 		  printf ("      ");
9491 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9492 		  printf ("..\n      ");
9493 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9494 		  printf ("\n");
9495 		}
9496 	      if ((uint64_t) (nexthdr - readp) < 1)
9497 		goto invalid_entry;
9498 	      get_uleb128 (len, readp, nexthdr);
9499 	      if ((uint64_t) (nexthdr - readp) < len)
9500 		goto invalid_entry;
9501 	      print_ops (dwflmod, dbg, 8, 8, version,
9502 			 address_size, offset_size, cu, len, readp);
9503 	      readp += len;
9504 	      break;
9505 
9506 	    default:
9507 	      goto invalid_entry;
9508 	    }
9509 	}
9510 
9511     next_table:
9512       if (readp != nexthdr)
9513 	{
9514           size_t padding = nexthdr - readp;
9515           printf (_("   %zu padding bytes\n\n"), padding);
9516 	  readp = nexthdr;
9517 	}
9518     }
9519 }
9520 
9521 
9522 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9523 print_debug_loc_section (Dwfl_Module *dwflmod,
9524 			 Ebl *ebl, GElf_Ehdr *ehdr,
9525 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9526 {
9527   Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9528 		    ?: elf_rawdata (scn, NULL));
9529 
9530   if (unlikely (data == NULL))
9531     {
9532       error (0, 0, _("cannot get .debug_loc content: %s"),
9533 	     elf_errmsg (-1));
9534       return;
9535     }
9536 
9537   printf (_("\
9538 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9539 	  elf_ndxscn (scn), section_name (ebl, shdr),
9540 	  (uint64_t) shdr->sh_offset);
9541 
9542   sort_listptr (&known_locsptr, "loclistptr");
9543   size_t listptr_idx = 0;
9544 
9545   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9546   uint_fast8_t offset_size = 4;
9547 
9548   bool first = true;
9549   Dwarf_Addr base = 0;
9550   unsigned char *readp = data->d_buf;
9551   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9552   Dwarf_CU *last_cu = NULL;
9553   while (readp < endp)
9554     {
9555       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9556       Dwarf_CU *cu = last_cu;
9557       unsigned int attr = 0;
9558 
9559       if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9560 				      &address_size, &offset_size, &base,
9561 				      &cu, offset, &readp, endp, &attr))
9562 	continue;
9563 
9564       if (last_cu != cu)
9565        {
9566 	Dwarf_Die cudie;
9567 	if (dwarf_cu_die (cu, &cudie,
9568 			  NULL, NULL, NULL, NULL,
9569 			  NULL, NULL) == NULL)
9570 	  printf (_("\n Unknown CU base: "));
9571 	else
9572 	  printf (_("\n CU [%6" PRIx64 "] base: "),
9573 		  dwarf_dieoffset (&cudie));
9574 	print_dwarf_addr (dwflmod, address_size, base, base);
9575 	printf ("\n");
9576        }
9577       last_cu = cu;
9578 
9579       if (attr == DW_AT_GNU_locviews)
9580 	{
9581 	  Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9582 						    &listptr_idx, offset);
9583 	  const unsigned char *locp = readp;
9584 	  const unsigned char *locendp;
9585 	  if (next_off == 0
9586 	      || next_off > (size_t) (endp
9587 				      - (const unsigned char *) data->d_buf))
9588 	    locendp = endp;
9589 	  else
9590 	    locendp = (const unsigned char *) data->d_buf + next_off;
9591 
9592 	  while (locp < locendp)
9593 	    {
9594 	      uint64_t v1, v2;
9595 	      get_uleb128 (v1, locp, locendp);
9596 	      if (locp >= locendp)
9597 		{
9598 		  printf (_(" [%6tx]  <INVALID DATA>\n"), offset);
9599 		  break;
9600 		}
9601 	      get_uleb128 (v2, locp, locendp);
9602 	      if (first)		/* First view pair in a list.  */
9603 		printf (" [%6tx] ", offset);
9604 	      else
9605 		printf ("          ");
9606 	      printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9607 	      first = false;
9608 	    }
9609 
9610 	  first = true;
9611 	  readp = (unsigned char *) locendp;
9612 	  continue;
9613 	}
9614 
9615       /* GNU DebugFission encoded addresses as addrx.  */
9616       bool is_debugfission = ((cu != NULL
9617 			       || split_dwarf_cu_base (dbg, &cu, &base))
9618 			      && (cu->version < 5
9619 				  && cu->unit_type == DW_UT_split_compile));
9620       if (!is_debugfission
9621 	  && unlikely (data->d_size - offset < (size_t) address_size * 2))
9622         {
9623 	invalid_data:
9624 	  printf (_(" [%6tx]  <INVALID DATA>\n"), offset);
9625 	  break;
9626 	}
9627 
9628       Dwarf_Addr begin;
9629       Dwarf_Addr end;
9630       bool use_base = true;
9631       if (is_debugfission)
9632 	{
9633 	  const unsigned char *locp = readp;
9634 	  const unsigned char *locendp = readp + data->d_size;
9635 	  if (locp >= locendp)
9636 	    goto invalid_data;
9637 
9638 	  Dwarf_Word idx;
9639 	  unsigned char code = *locp++;
9640 	  switch (code)
9641 	    {
9642 	    case DW_LLE_GNU_end_of_list_entry:
9643 	      begin = 0;
9644 	      end = 0;
9645 	      break;
9646 
9647 	    case DW_LLE_GNU_base_address_selection_entry:
9648 	      if (locp >= locendp)
9649 		goto invalid_data;
9650 	      begin = (Dwarf_Addr) -1;
9651 	      get_uleb128 (idx, locp, locendp);
9652 	      if (get_indexed_addr (cu, idx, &end) != 0)
9653 		end = idx; /* ... */
9654 	      break;
9655 
9656 	    case DW_LLE_GNU_start_end_entry:
9657 	      if (locp >= locendp)
9658 		goto invalid_data;
9659 	      get_uleb128 (idx, locp, locendp);
9660 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9661 		begin = idx; /* ... */
9662 	      if (locp >= locendp)
9663 		goto invalid_data;
9664 	      get_uleb128 (idx, locp, locendp);
9665 	      if (get_indexed_addr (cu, idx, &end) != 0)
9666 		end = idx; /* ... */
9667 	      use_base = false;
9668 	      break;
9669 
9670 	    case DW_LLE_GNU_start_length_entry:
9671 	      if (locp >= locendp)
9672 		goto invalid_data;
9673 	      get_uleb128 (idx, locp, locendp);
9674 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9675 		begin = idx; /* ... */
9676 	      if (locendp - locp < 4)
9677 		goto invalid_data;
9678 	      end = read_4ubyte_unaligned_inc (dbg, locp);
9679 	      end += begin;
9680 	      use_base = false;
9681 	      break;
9682 
9683 	    default:
9684 		goto invalid_data;
9685 	    }
9686 
9687 	  readp = (unsigned char *) locp;
9688 	}
9689       else if (address_size == 8)
9690 	{
9691 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
9692 	  end = read_8ubyte_unaligned_inc (dbg, readp);
9693 	}
9694       else
9695 	{
9696 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
9697 	  end = read_4ubyte_unaligned_inc (dbg, readp);
9698 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
9699 	    begin = (Dwarf_Addr) -1l;
9700 	}
9701 
9702       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
9703 	{
9704 	  if (first)
9705 	    printf (" [%6tx] ", offset);
9706 	  else
9707 	    printf ("          ");
9708 	  puts (_("base address"));
9709 	  printf ("          ");
9710 	  print_dwarf_addr (dwflmod, address_size, end, end);
9711 	  printf ("\n");
9712 	  base = end;
9713 	  first = false;
9714 	}
9715       else if (begin == 0 && end == 0) /* End of list entry.  */
9716 	{
9717 	  if (first)
9718 	    printf (_(" [%6tx] empty list\n"), offset);
9719 	  first = true;
9720 	}
9721       else
9722 	{
9723 	  /* We have a location expression entry.  */
9724 	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9725 
9726 	  if (first)		/* First entry in a list.  */
9727 	    printf (" [%6tx] ", offset);
9728 	  else
9729 	    printf ("          ");
9730 
9731 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9732 	  if (! print_unresolved_addresses)
9733 	    {
9734 	      Dwarf_Addr dab = use_base ? base + begin : begin;
9735 	      Dwarf_Addr dae = use_base ? base + end : end;
9736 	      printf ("          ");
9737 	      print_dwarf_addr (dwflmod, address_size, dab, dab);
9738 	      printf ("..\n          ");
9739 	      print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9740 	      printf ("\n");
9741 	    }
9742 
9743 	  if (endp - readp <= (ptrdiff_t) len)
9744 	    {
9745 	      fputs (_("   <INVALID DATA>\n"), stdout);
9746 	      break;
9747 	    }
9748 
9749 	  print_ops (dwflmod, dbg, 11, 11,
9750 		     cu != NULL ? cu->version : 3,
9751 		     address_size, offset_size, cu, len, readp);
9752 
9753 	  first = false;
9754 	  readp += len;
9755 	}
9756     }
9757 }
9758 
9759 struct mac_culist
9760 {
9761   Dwarf_Die die;
9762   Dwarf_Off offset;
9763   Dwarf_Files *files;
9764   struct mac_culist *next;
9765 };
9766 
9767 
9768 static int
mac_compare(const void * p1,const void * p2)9769 mac_compare (const void *p1, const void *p2)
9770 {
9771   struct mac_culist *m1 = (struct mac_culist *) p1;
9772   struct mac_culist *m2 = (struct mac_culist *) p2;
9773 
9774   if (m1->offset < m2->offset)
9775     return -1;
9776   if (m1->offset > m2->offset)
9777     return 1;
9778   return 0;
9779 }
9780 
9781 
9782 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9783 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9784 			     Ebl *ebl,
9785 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
9786 			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9787 {
9788   printf (_("\
9789 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9790 	  elf_ndxscn (scn), section_name (ebl, shdr),
9791 	  (uint64_t) shdr->sh_offset);
9792   putc_unlocked ('\n', stdout);
9793 
9794   /* There is no function in libdw to iterate over the raw content of
9795      the section but it is easy enough to do.  */
9796   Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9797 		    ?: elf_rawdata (scn, NULL));
9798   if (unlikely (data == NULL))
9799     {
9800       error (0, 0, _("cannot get macro information section data: %s"),
9801 	     elf_errmsg (-1));
9802       return;
9803     }
9804 
9805   /* Get the source file information for all CUs.  */
9806   Dwarf_Off offset;
9807   Dwarf_Off ncu = 0;
9808   size_t hsize;
9809   struct mac_culist *culist = NULL;
9810   size_t nculist = 0;
9811   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9812     {
9813       Dwarf_Die cudie;
9814       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9815 	continue;
9816 
9817       Dwarf_Attribute attr;
9818       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9819 	continue;
9820 
9821       Dwarf_Word macoff;
9822       if (dwarf_formudata (&attr, &macoff) != 0)
9823 	continue;
9824 
9825       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9826       newp->die = cudie;
9827       newp->offset = macoff;
9828       newp->files = NULL;
9829       newp->next = culist;
9830       culist = newp;
9831       ++nculist;
9832     }
9833 
9834   /* Convert the list into an array for easier consumption.  */
9835   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9836 							 * sizeof (*cus));
9837   /* Add sentinel.  */
9838   cus[nculist].offset = data->d_size;
9839   cus[nculist].files = (Dwarf_Files *) -1l;
9840   if (nculist > 0)
9841     {
9842       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9843 	{
9844 	  assert (cnt < nculist);
9845 	  cus[cnt] = *culist;
9846 	  culist = culist->next;
9847 	}
9848 
9849       /* Sort the array according to the offset in the .debug_macinfo
9850 	 section.  Note we keep the sentinel at the end.  */
9851       qsort (cus, nculist, sizeof (*cus), mac_compare);
9852     }
9853 
9854   const unsigned char *readp = (const unsigned char *) data->d_buf;
9855   const unsigned char *readendp = readp + data->d_size;
9856   int level = 1;
9857 
9858   while (readp < readendp)
9859     {
9860       unsigned int opcode = *readp++;
9861       unsigned int u128;
9862       unsigned int u128_2;
9863       const unsigned char *endp;
9864 
9865       switch (opcode)
9866 	{
9867 	case DW_MACINFO_define:
9868 	case DW_MACINFO_undef:
9869 	case DW_MACINFO_vendor_ext:
9870 	  /*  For the first two opcodes the parameters are
9871 		line, string
9872 	      For the latter
9873 		number, string.
9874 	      We can treat these cases together.  */
9875 	  get_uleb128 (u128, readp, readendp);
9876 
9877 	  endp = memchr (readp, '\0', readendp - readp);
9878 	  if (unlikely (endp == NULL))
9879 	    {
9880 	      printf (_("\
9881 %*s*** non-terminated string at end of section"),
9882 		      level, "");
9883 	      return;
9884 	    }
9885 
9886 	  if (opcode == DW_MACINFO_define)
9887 	    printf ("%*s#define %s, line %u\n",
9888 		    level, "", (char *) readp, u128);
9889 	  else if (opcode == DW_MACINFO_undef)
9890 	    printf ("%*s#undef %s, line %u\n",
9891 		    level, "", (char *) readp, u128);
9892 	  else
9893 	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9894 
9895 	  readp = endp + 1;
9896 	  break;
9897 
9898 	case DW_MACINFO_start_file:
9899 	  /* The two parameters are line and file index, in this order.  */
9900 	  get_uleb128 (u128, readp, readendp);
9901 	  if (readendp - readp < 1)
9902 	    {
9903 	      printf (_("\
9904 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9905 		      level, "");
9906 	      return;
9907 	    }
9908 	  get_uleb128 (u128_2, readp, readendp);
9909 
9910 	  /* Find the CU DIE for this file.  */
9911 	  size_t macoff = readp - (const unsigned char *) data->d_buf;
9912 	  const char *fname = "???";
9913 	  if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
9914 	    {
9915 	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9916 		++cus;
9917 
9918 	      if (cus[0].files == NULL
9919 		  && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9920 		cus[0].files = (Dwarf_Files *) -1l;
9921 
9922 	      if (cus[0].files != (Dwarf_Files *) -1l)
9923 		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9924 			 ?: "???");
9925 	    }
9926 
9927 	  printf ("%*sstart_file %u, [%u] %s\n",
9928 		  level, "", u128, u128_2, fname);
9929 	  ++level;
9930 	  break;
9931 
9932 	case DW_MACINFO_end_file:
9933 	  --level;
9934 	  printf ("%*send_file\n", level, "");
9935 	  /* Nothing more to do.  */
9936 	  break;
9937 
9938 	default:
9939 	  // XXX gcc seems to generate files with a trailing zero.
9940 	  if (unlikely (opcode != 0 || readp != readendp))
9941 	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9942 	  break;
9943 	}
9944     }
9945 }
9946 
9947 
9948 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9949 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9950 			   Ebl *ebl,
9951 			   GElf_Ehdr *ehdr __attribute__ ((unused)),
9952 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9953 {
9954   printf (_("\
9955 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9956 	  elf_ndxscn (scn), section_name (ebl, shdr),
9957 	  (uint64_t) shdr->sh_offset);
9958   putc_unlocked ('\n', stdout);
9959 
9960   Elf_Data *data =  elf_getdata (scn, NULL);
9961   if (unlikely (data == NULL))
9962     {
9963       error (0, 0, _("cannot get macro information section data: %s"),
9964 	     elf_errmsg (-1));
9965       return;
9966     }
9967 
9968   /* Get the source file information for all CUs.  Uses same
9969      datastructure as macinfo.  But uses offset field to directly
9970      match .debug_line offset.  And just stored in a list.  */
9971   Dwarf_Off offset;
9972   Dwarf_Off ncu = 0;
9973   size_t hsize;
9974   struct mac_culist *culist = NULL;
9975   size_t nculist = 0;
9976   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9977     {
9978       Dwarf_Die cudie;
9979       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9980 	continue;
9981 
9982       Dwarf_Attribute attr;
9983       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9984 	continue;
9985 
9986       Dwarf_Word lineoff;
9987       if (dwarf_formudata (&attr, &lineoff) != 0)
9988 	continue;
9989 
9990       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9991       newp->die = cudie;
9992       newp->offset = lineoff;
9993       newp->files = NULL;
9994       newp->next = culist;
9995       culist = newp;
9996       ++nculist;
9997     }
9998 
9999   const unsigned char *readp = (const unsigned char *) data->d_buf;
10000   const unsigned char *readendp = readp + data->d_size;
10001 
10002   while (readp < readendp)
10003     {
10004       printf (_(" Offset:             0x%" PRIx64 "\n"),
10005 	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
10006 
10007       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
10008       // optional vendor extension macro entry table.
10009       if (readp + 2 > readendp)
10010 	{
10011 	invalid_data:
10012 	  error (0, 0, _("invalid data"));
10013 	  return;
10014 	}
10015       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
10016       printf (_(" Version:            %" PRIu16 "\n"), vers);
10017 
10018       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
10019       // 5 when it gets standardized.
10020       if (vers != 4 && vers != 5)
10021 	{
10022 	  printf (_("  unknown version, cannot parse section\n"));
10023 	  return;
10024 	}
10025 
10026       if (readp + 1 > readendp)
10027 	goto invalid_data;
10028       const unsigned char flag = *readp++;
10029       printf (_(" Flag:               0x%" PRIx8), flag);
10030       if (flag != 0)
10031 	{
10032 	  printf (" (");
10033 	  if ((flag & 0x01) != 0)
10034 	    {
10035 	      printf ("offset_size");
10036 	      if ((flag & 0xFE) !=  0)
10037 		printf (", ");
10038 	    }
10039 	  if ((flag & 0x02) != 0)
10040 	    {
10041 	      printf ("debug_line_offset");
10042 	      if ((flag & 0xFC) !=  0)
10043 		printf (", ");
10044 	    }
10045 	  if ((flag & 0x04) != 0)
10046 	    {
10047 	      printf ("operands_table");
10048 	      if ((flag & 0xF8) !=  0)
10049 		printf (", ");
10050 	    }
10051 	  if ((flag & 0xF8) != 0)
10052 	    printf ("unknown");
10053 	  printf (")");
10054 	}
10055       printf ("\n");
10056 
10057       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
10058       printf (_(" Offset length:      %" PRIu8 "\n"), offset_len);
10059       Dwarf_Off line_offset = -1;
10060       if (flag & 0x02)
10061 	{
10062 	  if (offset_len == 8)
10063 	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
10064 	  else
10065 	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
10066 	  printf (_(" .debug_line offset: 0x%" PRIx64 "\n"),
10067 		  line_offset);
10068 	}
10069 
10070       struct mac_culist *cu = NULL;
10071       if (line_offset != (Dwarf_Off) -1)
10072 	{
10073 	  cu = culist;
10074 	  while (cu != NULL && line_offset != cu->offset)
10075 	    cu = cu->next;
10076 	}
10077 
10078       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
10079 							       ? cu->die.cu
10080 							       : NULL));
10081 
10082       const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
10083       memset (vendor, 0, sizeof vendor);
10084       if (flag & 0x04)
10085 	{
10086 	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
10087 	  // of arguments, for each argument 1 byte form code.
10088 	  if (readp + 1 > readendp)
10089 	    goto invalid_data;
10090 	  unsigned int tlen = *readp++;
10091 	  printf (_("  extension opcode table, %" PRIu8 " items:\n"),
10092 		  tlen);
10093 	  for (unsigned int i = 0; i < tlen; i++)
10094 	    {
10095 	      if (readp + 1 > readendp)
10096 		goto invalid_data;
10097 	      unsigned int opcode = *readp++;
10098 	      printf (_("    [%" PRIx8 "]"), opcode);
10099 	      if (opcode < DW_MACRO_lo_user
10100 		  || opcode > DW_MACRO_hi_user)
10101 		goto invalid_data;
10102 	      // Record the start of description for this vendor opcode.
10103 	      // uleb128 nr args, 1 byte per arg form.
10104 	      vendor[opcode - DW_MACRO_lo_user] = readp;
10105 	      if (readp + 1 > readendp)
10106 		goto invalid_data;
10107 	      unsigned int args = *readp++;
10108 	      if (args > 0)
10109 		{
10110 		  printf (_(" %" PRIu8 " arguments:"), args);
10111 		  while (args > 0)
10112 		    {
10113 		      if (readp + 1 > readendp)
10114 			goto invalid_data;
10115 		      unsigned int form = *readp++;
10116 		      printf (" %s", dwarf_form_name (form));
10117 		      if (! libdw_valid_user_form (form))
10118 			goto invalid_data;
10119 		      args--;
10120 		      if (args > 0)
10121 			putchar_unlocked (',');
10122 		    }
10123 		}
10124 	      else
10125 		printf (_(" no arguments."));
10126 	      putchar_unlocked ('\n');
10127 	    }
10128 	}
10129       putchar_unlocked ('\n');
10130 
10131       int level = 1;
10132       if (readp + 1 > readendp)
10133 	goto invalid_data;
10134       unsigned int opcode = *readp++;
10135       while (opcode != 0)
10136 	{
10137 	  unsigned int u128;
10138 	  unsigned int u128_2;
10139 	  const unsigned char *endp;
10140 	  uint64_t off;
10141 
10142           switch (opcode)
10143             {
10144             case DW_MACRO_start_file:
10145 	      get_uleb128 (u128, readp, readendp);
10146 	      if (readp >= readendp)
10147 		goto invalid_data;
10148 	      get_uleb128 (u128_2, readp, readendp);
10149 
10150 	      /* Find the CU DIE that matches this line offset.  */
10151 	      const char *fname = "???";
10152 	      if (cu != NULL)
10153 		{
10154 		  if (cu->files == NULL
10155 		      && dwarf_getsrcfiles (&cu->die, &cu->files,
10156 					    NULL) != 0)
10157 		    cu->files = (Dwarf_Files *) -1l;
10158 
10159 		  if (cu->files != (Dwarf_Files *) -1l)
10160 		    fname = (dwarf_filesrc (cu->files, u128_2,
10161 					    NULL, NULL) ?: "???");
10162 		}
10163 	      printf ("%*sstart_file %u, [%u] %s\n",
10164 		      level, "", u128, u128_2, fname);
10165 	      ++level;
10166 	      break;
10167 
10168 	    case DW_MACRO_end_file:
10169 	      --level;
10170 	      printf ("%*send_file\n", level, "");
10171 	      break;
10172 
10173 	    case DW_MACRO_define:
10174 	      get_uleb128 (u128, readp, readendp);
10175 	      endp = memchr (readp, '\0', readendp - readp);
10176 	      if (endp == NULL)
10177 		goto invalid_data;
10178 	      printf ("%*s#define %s, line %u\n",
10179 		      level, "", readp, u128);
10180 	      readp = endp + 1;
10181 	      break;
10182 
10183 	    case DW_MACRO_undef:
10184 	      get_uleb128 (u128, readp, readendp);
10185 	      endp = memchr (readp, '\0', readendp - readp);
10186 	      if (endp == NULL)
10187 		goto invalid_data;
10188 	      printf ("%*s#undef %s, line %u\n",
10189 		      level, "", readp, u128);
10190 	      readp = endp + 1;
10191 	      break;
10192 
10193 	    case DW_MACRO_define_strp:
10194 	      get_uleb128 (u128, readp, readendp);
10195 	      if (readp + offset_len > readendp)
10196 		goto invalid_data;
10197 	      if (offset_len == 8)
10198 		off = read_8ubyte_unaligned_inc (dbg, readp);
10199 	      else
10200 		off = read_4ubyte_unaligned_inc (dbg, readp);
10201 	      printf ("%*s#define %s, line %u (indirect)\n",
10202 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10203 	      break;
10204 
10205 	    case DW_MACRO_undef_strp:
10206 	      get_uleb128 (u128, readp, readendp);
10207 	      if (readp + offset_len > readendp)
10208 		goto invalid_data;
10209 	      if (offset_len == 8)
10210 		off = read_8ubyte_unaligned_inc (dbg, readp);
10211 	      else
10212 		off = read_4ubyte_unaligned_inc (dbg, readp);
10213 	      printf ("%*s#undef %s, line %u (indirect)\n",
10214 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10215 	      break;
10216 
10217 	    case DW_MACRO_import:
10218 	      if (readp + offset_len > readendp)
10219 		goto invalid_data;
10220 	      if (offset_len == 8)
10221 		off = read_8ubyte_unaligned_inc (dbg, readp);
10222 	      else
10223 		off = read_4ubyte_unaligned_inc (dbg, readp);
10224 	      printf ("%*s#include offset 0x%" PRIx64 "\n",
10225 		      level, "", off);
10226 	      break;
10227 
10228 	    case DW_MACRO_define_sup:
10229 	      get_uleb128 (u128, readp, readendp);
10230 	      if (readp + offset_len > readendp)
10231 		goto invalid_data;
10232 	      printf ("%*s#define ", level, "");
10233 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10234 					readp, readendp, offset_len,
10235 					str_offsets_base);
10236 	      printf (", line %u (sup)\n", u128);
10237 	      break;
10238 
10239 	    case DW_MACRO_undef_sup:
10240 	      get_uleb128 (u128, readp, readendp);
10241 	      if (readp + offset_len > readendp)
10242 		goto invalid_data;
10243 	      printf ("%*s#undef ", level, "");
10244 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10245 					readp, readendp, offset_len,
10246 					str_offsets_base);
10247 	      printf (", line %u (sup)\n", u128);
10248 	      break;
10249 
10250 	    case DW_MACRO_import_sup:
10251 	      if (readp + offset_len > readendp)
10252 		goto invalid_data;
10253 	      if (offset_len == 8)
10254 		off = read_8ubyte_unaligned_inc (dbg, readp);
10255 	      else
10256 		off = read_4ubyte_unaligned_inc (dbg, readp);
10257 	      // XXX Needs support for reading from supplementary object file.
10258 	      printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10259 		      level, "", off);
10260 	      break;
10261 
10262 	    case DW_MACRO_define_strx:
10263 	      get_uleb128 (u128, readp, readendp);
10264 	      if (readp + offset_len > readendp)
10265 		goto invalid_data;
10266 	      printf ("%*s#define ", level, "");
10267 	      readp =  print_form_data (dbg, DW_FORM_strx,
10268 					readp, readendp, offset_len,
10269 					str_offsets_base);
10270 	      printf (", line %u (strx)\n", u128);
10271 	      break;
10272 
10273 	    case DW_MACRO_undef_strx:
10274 	      get_uleb128 (u128, readp, readendp);
10275 	      if (readp + offset_len > readendp)
10276 		goto invalid_data;
10277 	      printf ("%*s#undef ", level, "");
10278 	      readp =  print_form_data (dbg, DW_FORM_strx,
10279 					readp, readendp, offset_len,
10280 					str_offsets_base);
10281 	      printf (", line %u (strx)\n", u128);
10282 	      break;
10283 
10284 	    default:
10285 	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10286 	      if (opcode < DW_MACRO_lo_user
10287 		  || opcode > DW_MACRO_lo_user
10288 		  || vendor[opcode - DW_MACRO_lo_user] == NULL)
10289 		goto invalid_data;
10290 
10291 	      const unsigned char *op_desc;
10292 	      op_desc = vendor[opcode - DW_MACRO_lo_user];
10293 
10294 	      // Just skip the arguments, we cannot really interpret them,
10295 	      // but print as much as we can.
10296 	      unsigned int args = *op_desc++;
10297 	      while (args > 0 && readp < readendp)
10298 		{
10299 		  unsigned int form = *op_desc++;
10300 		  readp = print_form_data (dbg, form, readp, readendp,
10301 					   offset_len, str_offsets_base);
10302 		  args--;
10303 		  if (args > 0)
10304 		    printf (", ");
10305 		}
10306 	      putchar_unlocked ('\n');
10307 	    }
10308 
10309 	  if (readp + 1 > readendp)
10310 	    goto invalid_data;
10311 	  opcode = *readp++;
10312 	  if (opcode == 0)
10313 	    putchar_unlocked ('\n');
10314 	}
10315     }
10316 }
10317 
10318 
10319 /* Callback for printing global names.  */
10320 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10321 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10322 		void *arg)
10323 {
10324   int *np = (int *) arg;
10325 
10326   printf (_(" [%5d] DIE offset: %6" PRId64
10327 		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10328 	  (*np)++, global->die_offset, global->cu_offset, global->name);
10329 
10330   return 0;
10331 }
10332 
10333 
10334 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
10335 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10336 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10337 			      Ebl *ebl,
10338 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
10339 			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10340 {
10341   printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10342 	  elf_ndxscn (scn), section_name (ebl, shdr),
10343 	  (uint64_t) shdr->sh_offset);
10344 
10345   int n = 0;
10346   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10347 }
10348 
10349 /* Print the content of the DWARF string section '.debug_str'.  */
10350 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10351 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10352 			 Ebl *ebl,
10353 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10354 			 Elf_Scn *scn, GElf_Shdr *shdr,
10355 			 Dwarf *dbg __attribute__ ((unused)))
10356 {
10357   Elf_Data *data = elf_rawdata (scn, NULL);
10358   const size_t sh_size = data ? data->d_size : 0;
10359 
10360   /* Compute floor(log16(shdr->sh_size)).  */
10361   GElf_Addr tmp = sh_size;
10362   int digits = 1;
10363   while (tmp >= 16)
10364     {
10365       ++digits;
10366       tmp >>= 4;
10367     }
10368   digits = MAX (4, digits);
10369 
10370   printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10371 		   " %*s  String\n"),
10372 	  elf_ndxscn (scn),
10373 	  section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10374 	  /* TRANS: the debugstr| prefix makes the string unique.  */
10375 	  digits + 2, sgettext ("debugstr|Offset"));
10376 
10377   Dwarf_Off offset = 0;
10378   while (offset < sh_size)
10379     {
10380       size_t len;
10381       const char *str = (const char *) data->d_buf + offset;
10382       const char *endp = memchr (str, '\0', sh_size - offset);
10383       if (unlikely (endp == NULL))
10384 	{
10385 	  printf (_(" *** error, missing string terminator\n"));
10386 	  break;
10387 	}
10388 
10389       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
10390       len = endp - str;
10391       offset += len + 1;
10392     }
10393 }
10394 
10395 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10396 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10397 				 Ebl *ebl,
10398 				 GElf_Ehdr *ehdr __attribute__ ((unused)),
10399 				 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10400 {
10401   printf (_("\
10402 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10403 	  elf_ndxscn (scn), section_name (ebl, shdr),
10404 	  (uint64_t) shdr->sh_offset);
10405 
10406   if (shdr->sh_size == 0)
10407     return;
10408 
10409   /* We like to get the section from libdw to make sure they are relocated.  */
10410   Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10411 		    ?: elf_rawdata (scn, NULL));
10412   if (unlikely (data == NULL))
10413     {
10414       error (0, 0, _("cannot get .debug_str_offsets section data: %s"),
10415 	     elf_errmsg (-1));
10416       return;
10417     }
10418 
10419   size_t idx = 0;
10420   sort_listptr (&known_stroffbases, "str_offsets");
10421 
10422   const unsigned char *start = (const unsigned char *) data->d_buf;
10423   const unsigned char *readp = start;
10424   const unsigned char *readendp = ((const unsigned char *) data->d_buf
10425 				   + data->d_size);
10426 
10427   while (readp < readendp)
10428     {
10429       /* Most string offset tables will have a header.  For split
10430 	 dwarf unit GNU DebugFission didn't add one.  But they were
10431 	 also only defined for split units (main or skeleton units
10432 	 didn't have indirect strings).  So if we don't have a
10433 	 DW_AT_str_offsets_base at all and this is offset zero, then
10434 	 just start printing offsets immediately, if this is a .dwo
10435 	 section.  */
10436       Dwarf_Off off = (Dwarf_Off) (readp
10437 				   - (const unsigned char *) data->d_buf);
10438 
10439       printf ("Table at offset %" PRIx64 " ", off);
10440 
10441       struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10442       const unsigned char *next_unitp = readendp;
10443       uint8_t offset_size;
10444       bool has_header;
10445       if (listptr == NULL)
10446 	{
10447 	  /* This can happen for .dwo files.  There is only an header
10448 	     in the case this is a version 5 split DWARF file.  */
10449 	  Dwarf_CU *cu;
10450 	  uint8_t unit_type;
10451 	  if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10452 			       NULL, NULL) != 0)
10453 	    {
10454 	      error (0, 0, "Warning: Cannot find any DWARF unit.");
10455 	      /* Just guess some values.  */
10456 	      has_header = false;
10457 	      offset_size = 4;
10458 	    }
10459 	  else if (off == 0
10460 		   && (unit_type == DW_UT_split_type
10461 		       || unit_type == DW_UT_split_compile))
10462 	    {
10463 	      has_header = cu->version > 4;
10464 	      offset_size = cu->offset_size;
10465 	    }
10466 	  else
10467 	    {
10468 	      error (0, 0,
10469 		     "Warning: No CU references .debug_str_offsets after %"
10470 		     PRIx64, off);
10471 	      has_header = cu->version > 4;
10472 	      offset_size = cu->offset_size;
10473 	    }
10474 	  printf ("\n");
10475 	}
10476       else
10477 	{
10478 	  /* This must be DWARF5, since GNU DebugFission didn't define
10479 	     DW_AT_str_offsets_base.  */
10480 	  has_header = true;
10481 
10482 	  Dwarf_Die cudie;
10483 	  if (dwarf_cu_die (listptr->cu, &cudie,
10484 			    NULL, NULL, NULL, NULL,
10485 			    NULL, NULL) == NULL)
10486 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10487 	  else
10488 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10489 	}
10490 
10491       if (has_header)
10492 	{
10493 	  uint64_t unit_length;
10494 	  uint16_t version;
10495 	  uint16_t padding;
10496 
10497 	  unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10498 	  if (unlikely (unit_length == 0xffffffff))
10499 	    {
10500 	      if (unlikely (readp > readendp - 8))
10501 		{
10502 		invalid_data:
10503 		  error (0, 0, "Invalid data");
10504 		  return;
10505 		}
10506 	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10507 	      offset_size = 8;
10508 	    }
10509 	  else
10510 	    offset_size = 4;
10511 
10512 	  printf ("\n");
10513 	  printf (_(" Length:        %8" PRIu64 "\n"),
10514 		  unit_length);
10515 	  printf (_(" Offset size:   %8" PRIu8 "\n"),
10516 		  offset_size);
10517 
10518 	  /* We need at least 2-bytes (version) + 2-bytes (padding) =
10519 	     4 bytes to complete the header.  And this unit cannot go
10520 	     beyond the section data.  */
10521 	  if (readp > readendp - 4
10522 	      || unit_length < 4
10523 	      || unit_length > (uint64_t) (readendp - readp))
10524 	    goto invalid_data;
10525 
10526 	  next_unitp = readp + unit_length;
10527 
10528 	  version = read_2ubyte_unaligned_inc (dbg, readp);
10529 	  printf (_(" DWARF version: %8" PRIu16 "\n"), version);
10530 
10531 	  if (version != 5)
10532 	    {
10533 	      error (0, 0, _("Unknown version"));
10534 	      goto next_unit;
10535 	    }
10536 
10537 	  padding = read_2ubyte_unaligned_inc (dbg, readp);
10538 	  printf (_(" Padding:       %8" PRIx16 "\n"), padding);
10539 
10540 	  if (listptr != NULL
10541 	      && listptr->offset != (Dwarf_Off) (readp - start))
10542 	    {
10543 	      error (0, 0, "String offsets index doesn't start after header");
10544 	      goto next_unit;
10545 	    }
10546 
10547 	  printf ("\n");
10548 	}
10549 
10550       int digits = 1;
10551       size_t offsets = (next_unitp - readp) / offset_size;
10552       while (offsets >= 10)
10553 	{
10554 	  ++digits;
10555 	  offsets /= 10;
10556 	}
10557 
10558       unsigned int uidx = 0;
10559       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
10560       printf (" Offsets start at 0x%zx:\n", index_offset);
10561       while (readp <= next_unitp - offset_size)
10562 	{
10563 	  Dwarf_Word offset;
10564 	  if (offset_size == 4)
10565 	    offset = read_4ubyte_unaligned_inc (dbg, readp);
10566 	  else
10567 	    offset = read_8ubyte_unaligned_inc (dbg, readp);
10568 	  const char *str = dwarf_getstring (dbg, offset, NULL);
10569 	  printf (" [%*u] [%*" PRIx64 "]  \"%s\"\n",
10570 		  digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10571 	}
10572       printf ("\n");
10573 
10574       if (readp != next_unitp)
10575 	error (0, 0, "extra %zd bytes at end of unit",
10576 	       (size_t) (next_unitp - readp));
10577 
10578     next_unit:
10579       readp = next_unitp;
10580     }
10581 }
10582 
10583 
10584 /* Print the content of the call frame search table section
10585    '.eh_frame_hdr'.  */
10586 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10587 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10588 			       Ebl *ebl __attribute__ ((unused)),
10589 			       GElf_Ehdr *ehdr __attribute__ ((unused)),
10590 			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10591 {
10592   printf (_("\
10593 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10594 	  elf_ndxscn (scn));
10595 
10596   Elf_Data *data = elf_rawdata (scn, NULL);
10597 
10598   if (unlikely (data == NULL))
10599     {
10600       error (0, 0, _("cannot get %s content: %s"),
10601 	     ".eh_frame_hdr", elf_errmsg (-1));
10602       return;
10603     }
10604 
10605   const unsigned char *readp = data->d_buf;
10606   const unsigned char *const dataend = ((unsigned char *) data->d_buf
10607 					+ data->d_size);
10608 
10609   if (unlikely (readp + 4 > dataend))
10610     {
10611     invalid_data:
10612       error (0, 0, _("invalid data"));
10613       return;
10614     }
10615 
10616   unsigned int version = *readp++;
10617   unsigned int eh_frame_ptr_enc = *readp++;
10618   unsigned int fde_count_enc = *readp++;
10619   unsigned int table_enc = *readp++;
10620 
10621   printf (" version:          %u\n"
10622 	  " eh_frame_ptr_enc: %#x ",
10623 	  version, eh_frame_ptr_enc);
10624   print_encoding_base ("", eh_frame_ptr_enc);
10625   printf (" fde_count_enc:    %#x ", fde_count_enc);
10626   print_encoding_base ("", fde_count_enc);
10627   printf (" table_enc:        %#x ", table_enc);
10628   print_encoding_base ("", table_enc);
10629 
10630   uint64_t eh_frame_ptr = 0;
10631   if (eh_frame_ptr_enc != DW_EH_PE_omit)
10632     {
10633       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10634 			    dbg);
10635       if (unlikely (readp == NULL))
10636 	goto invalid_data;
10637 
10638       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
10639       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10640 	printf (" (offset: %#" PRIx64 ")",
10641 		/* +4 because of the 4 byte header of the section.  */
10642 		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10643 
10644       putchar_unlocked ('\n');
10645     }
10646 
10647   uint64_t fde_count = 0;
10648   if (fde_count_enc != DW_EH_PE_omit)
10649     {
10650       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10651       if (unlikely (readp == NULL))
10652 	goto invalid_data;
10653 
10654       printf (" fde_count:        %" PRIu64 "\n", fde_count);
10655     }
10656 
10657   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10658     return;
10659 
10660   puts (" Table:");
10661 
10662   /* Optimize for the most common case.  */
10663   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10664     while (fde_count > 0 && readp + 8 <= dataend)
10665       {
10666 	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10667 	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10668 				   + (int64_t) initial_location);
10669 	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10670 	// XXX Possibly print symbol name or section offset for initial_offset
10671 	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10672 		" fde=[%6" PRIx64 "]\n",
10673 		initial_location, initial_offset,
10674 		address, address - (eh_frame_ptr + 4));
10675       }
10676   else
10677     while (0 && readp < dataend)
10678       {
10679 
10680       }
10681 }
10682 
10683 
10684 /* Print the content of the exception handling table section
10685    '.eh_frame_hdr'.  */
10686 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10687 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10688 			     Ebl *ebl __attribute__ ((unused)),
10689 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
10690 			     Elf_Scn *scn,
10691 			     GElf_Shdr *shdr __attribute__ ((unused)),
10692 			     Dwarf *dbg __attribute__ ((unused)))
10693 {
10694   printf (_("\
10695 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10696 	  elf_ndxscn (scn));
10697 
10698   Elf_Data *data = elf_rawdata (scn, NULL);
10699 
10700   if (unlikely (data == NULL))
10701     {
10702       error (0, 0, _("cannot get %s content: %s"),
10703 	     ".gcc_except_table", elf_errmsg (-1));
10704       return;
10705     }
10706 
10707   const unsigned char *readp = data->d_buf;
10708   const unsigned char *const dataend = readp + data->d_size;
10709 
10710   if (unlikely (readp + 1 > dataend))
10711     {
10712     invalid_data:
10713       error (0, 0, _("invalid data"));
10714       return;
10715     }
10716   unsigned int lpstart_encoding = *readp++;
10717   printf (_(" LPStart encoding:    %#x "), lpstart_encoding);
10718   print_encoding_base ("", lpstart_encoding);
10719   if (lpstart_encoding != DW_EH_PE_omit)
10720     {
10721       uint64_t lpstart;
10722       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10723       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
10724     }
10725 
10726   if (unlikely (readp + 1 > dataend))
10727     goto invalid_data;
10728   unsigned int ttype_encoding = *readp++;
10729   printf (_(" TType encoding:      %#x "), ttype_encoding);
10730   print_encoding_base ("", ttype_encoding);
10731   const unsigned char *ttype_base = NULL;
10732   if (ttype_encoding != DW_EH_PE_omit)
10733     {
10734       unsigned int ttype_base_offset;
10735       get_uleb128 (ttype_base_offset, readp, dataend);
10736       printf (" TType base offset:   %#x\n", ttype_base_offset);
10737       if ((size_t) (dataend - readp) > ttype_base_offset)
10738         ttype_base = readp + ttype_base_offset;
10739     }
10740 
10741   if (unlikely (readp + 1 > dataend))
10742     goto invalid_data;
10743   unsigned int call_site_encoding = *readp++;
10744   printf (_(" Call site encoding:  %#x "), call_site_encoding);
10745   print_encoding_base ("", call_site_encoding);
10746   unsigned int call_site_table_len;
10747   get_uleb128 (call_site_table_len, readp, dataend);
10748 
10749   const unsigned char *const action_table = readp + call_site_table_len;
10750   if (unlikely (action_table > dataend))
10751     goto invalid_data;
10752   unsigned int u = 0;
10753   unsigned int max_action = 0;
10754   while (readp < action_table)
10755     {
10756       if (u == 0)
10757 	puts (_("\n Call site table:"));
10758 
10759       uint64_t call_site_start;
10760       readp = read_encoded (call_site_encoding, readp, dataend,
10761 			    &call_site_start, dbg);
10762       uint64_t call_site_length;
10763       readp = read_encoded (call_site_encoding, readp, dataend,
10764 			    &call_site_length, dbg);
10765       uint64_t landing_pad;
10766       readp = read_encoded (call_site_encoding, readp, dataend,
10767 			    &landing_pad, dbg);
10768       unsigned int action;
10769       get_uleb128 (action, readp, dataend);
10770       max_action = MAX (action, max_action);
10771       printf (_(" [%4u] Call site start:   %#" PRIx64 "\n"
10772 		       "        Call site length:  %" PRIu64 "\n"
10773 		       "        Landing pad:       %#" PRIx64 "\n"
10774 		       "        Action:            %u\n"),
10775 	      u++, call_site_start, call_site_length, landing_pad, action);
10776     }
10777   if (readp != action_table)
10778     goto invalid_data;
10779 
10780   unsigned int max_ar_filter = 0;
10781   if (max_action > 0)
10782     {
10783       puts ("\n Action table:");
10784 
10785       size_t maxdata = (size_t) (dataend - action_table);
10786       if (max_action > maxdata || maxdata - max_action < 1)
10787 	{
10788 	invalid_action_table:
10789 	  fputs (_("   <INVALID DATA>\n"), stdout);
10790 	  return;
10791 	}
10792 
10793       const unsigned char *const action_table_end
10794 	= action_table + max_action + 1;
10795 
10796       u = 0;
10797       do
10798 	{
10799 	  int ar_filter;
10800 	  get_sleb128 (ar_filter, readp, action_table_end);
10801 	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10802 	    max_ar_filter = ar_filter;
10803 	  int ar_disp;
10804 	  if (readp >= action_table_end)
10805 	    goto invalid_action_table;
10806 	  get_sleb128 (ar_disp, readp, action_table_end);
10807 
10808 	  printf (" [%4u] ar_filter:  % d\n"
10809 		  "        ar_disp:    % -5d",
10810 		  u, ar_filter, ar_disp);
10811 	  if (abs (ar_disp) & 1)
10812 	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10813 	  else if (ar_disp != 0)
10814 	    puts (" -> ???");
10815 	  else
10816 	    putchar_unlocked ('\n');
10817 	  ++u;
10818 	}
10819       while (readp < action_table_end);
10820     }
10821 
10822   if (max_ar_filter > 0 && ttype_base != NULL)
10823     {
10824       unsigned char dsize;
10825       puts ("\n TType table:");
10826 
10827       // XXX Not *4, size of encoding;
10828       switch (ttype_encoding & 7)
10829 	{
10830 	case DW_EH_PE_udata2:
10831 	case DW_EH_PE_sdata2:
10832 	  dsize = 2;
10833 	  break;
10834 	case DW_EH_PE_udata4:
10835 	case DW_EH_PE_sdata4:
10836 	  dsize = 4;
10837 	  break;
10838 	case DW_EH_PE_udata8:
10839 	case DW_EH_PE_sdata8:
10840 	  dsize = 8;
10841 	  break;
10842 	default:
10843 	  dsize = 0;
10844 	  error (1, 0, _("invalid TType encoding"));
10845 	}
10846 
10847       if (max_ar_filter
10848 	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10849 	goto invalid_data;
10850 
10851       readp = ttype_base - max_ar_filter * dsize;
10852       do
10853 	{
10854 	  uint64_t ttype;
10855 	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10856 				dbg);
10857 	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10858 	}
10859       while (readp < ttype_base);
10860     }
10861 }
10862 
10863 /* Print the content of the '.gdb_index' section.
10864    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10865 */
10866 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10867 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10868 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10869 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10870 {
10871   printf (_("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10872 		   " contains %" PRId64 " bytes :\n"),
10873 	  elf_ndxscn (scn), section_name (ebl, shdr),
10874 	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10875 
10876   Elf_Data *data = elf_rawdata (scn, NULL);
10877 
10878   if (unlikely (data == NULL))
10879     {
10880       error (0, 0, _("cannot get %s content: %s"),
10881 	     ".gdb_index", elf_errmsg (-1));
10882       return;
10883     }
10884 
10885   // .gdb_index is always in little endian.
10886   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10887   dbg = &dummy_dbg;
10888 
10889   const unsigned char *readp = data->d_buf;
10890   const unsigned char *const dataend = readp + data->d_size;
10891 
10892   if (unlikely (readp + 4 > dataend))
10893     {
10894     invalid_data:
10895       error (0, 0, _("invalid data"));
10896       return;
10897     }
10898 
10899   int32_t vers = read_4ubyte_unaligned (dbg, readp);
10900   printf (_(" Version:         %" PRId32 "\n"), vers);
10901 
10902   // The only difference between version 4 and version 5 is the
10903   // hash used for generating the table.  Version 6 contains symbols
10904   // for inlined functions, older versions didn't.  Version 7 adds
10905   // symbol kinds.  Version 8 just indicates that it correctly includes
10906   // TUs for symbols.
10907   if (vers < 4 || vers > 8)
10908     {
10909       printf (_("  unknown version, cannot parse section\n"));
10910       return;
10911     }
10912 
10913   readp += 4;
10914   if (unlikely (readp + 4 > dataend))
10915     goto invalid_data;
10916 
10917   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10918   printf (_(" CU offset:       %#" PRIx32 "\n"), cu_off);
10919 
10920   readp += 4;
10921   if (unlikely (readp + 4 > dataend))
10922     goto invalid_data;
10923 
10924   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10925   printf (_(" TU offset:       %#" PRIx32 "\n"), tu_off);
10926 
10927   readp += 4;
10928   if (unlikely (readp + 4 > dataend))
10929     goto invalid_data;
10930 
10931   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10932   printf (_(" address offset:  %#" PRIx32 "\n"), addr_off);
10933 
10934   readp += 4;
10935   if (unlikely (readp + 4 > dataend))
10936     goto invalid_data;
10937 
10938   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10939   printf (_(" symbol offset:   %#" PRIx32 "\n"), sym_off);
10940 
10941   readp += 4;
10942   if (unlikely (readp + 4 > dataend))
10943     goto invalid_data;
10944 
10945   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10946   printf (_(" constant offset: %#" PRIx32 "\n"), const_off);
10947 
10948   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10949 		< const_off))
10950     goto invalid_data;
10951 
10952   readp = data->d_buf + cu_off;
10953 
10954   const unsigned char *nextp = data->d_buf + tu_off;
10955   if (tu_off >= data->d_size)
10956     goto invalid_data;
10957 
10958   size_t cu_nr = (nextp - readp) / 16;
10959 
10960   printf (_("\n CU list at offset %#" PRIx32
10961 		   " contains %zu entries:\n"),
10962 	  cu_off, cu_nr);
10963 
10964   size_t n = 0;
10965   while (dataend - readp >= 16 && n < cu_nr)
10966     {
10967       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10968       readp += 8;
10969 
10970       uint64_t len = read_8ubyte_unaligned (dbg, readp);
10971       readp += 8;
10972 
10973       printf (" [%4zu] start: %0#8" PRIx64
10974 	      ", length: %5" PRIu64 "\n", n, off, len);
10975       n++;
10976     }
10977 
10978   readp = data->d_buf + tu_off;
10979   nextp = data->d_buf + addr_off;
10980   if (addr_off >= data->d_size)
10981     goto invalid_data;
10982 
10983   size_t tu_nr = (nextp - readp) / 24;
10984 
10985   printf (_("\n TU list at offset %#" PRIx32
10986 		   " contains %zu entries:\n"),
10987 	  tu_off, tu_nr);
10988 
10989   n = 0;
10990   while (dataend - readp >= 24 && n < tu_nr)
10991     {
10992       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10993       readp += 8;
10994 
10995       uint64_t type = read_8ubyte_unaligned (dbg, readp);
10996       readp += 8;
10997 
10998       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10999       readp += 8;
11000 
11001       printf (" [%4zu] CU offset: %5" PRId64
11002 	      ", type offset: %5" PRId64
11003 	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
11004       n++;
11005     }
11006 
11007   readp = data->d_buf + addr_off;
11008   nextp = data->d_buf + sym_off;
11009   if (sym_off >= data->d_size)
11010     goto invalid_data;
11011 
11012   size_t addr_nr = (nextp - readp) / 20;
11013 
11014   printf (_("\n Address list at offset %#" PRIx32
11015 		   " contains %zu entries:\n"),
11016 	  addr_off, addr_nr);
11017 
11018   n = 0;
11019   while (dataend - readp >= 20 && n < addr_nr)
11020     {
11021       uint64_t low = read_8ubyte_unaligned (dbg, readp);
11022       readp += 8;
11023 
11024       uint64_t high = read_8ubyte_unaligned (dbg, readp);
11025       readp += 8;
11026 
11027       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
11028       readp += 4;
11029 
11030       printf (" [%4zu] ", n);
11031       print_dwarf_addr (dwflmod, 8, low, low);
11032       printf ("..");
11033       print_dwarf_addr (dwflmod, 8, high - 1, high);
11034       printf (", CU index: %5" PRId32 "\n", idx);
11035       n++;
11036     }
11037 
11038   const unsigned char *const_start = data->d_buf + const_off;
11039   if (const_off >= data->d_size)
11040     goto invalid_data;
11041 
11042   readp = data->d_buf + sym_off;
11043   nextp = const_start;
11044   size_t sym_nr = (nextp - readp) / 8;
11045 
11046   printf (_("\n Symbol table at offset %#" PRIx32
11047 		   " contains %zu slots:\n"),
11048 	  addr_off, sym_nr);
11049 
11050   n = 0;
11051   while (dataend - readp >= 8 && n < sym_nr)
11052     {
11053       uint32_t name = read_4ubyte_unaligned (dbg, readp);
11054       readp += 4;
11055 
11056       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
11057       readp += 4;
11058 
11059       if (name != 0 || vector != 0)
11060 	{
11061 	  const unsigned char *sym = const_start + name;
11062 	  if (unlikely ((size_t) (dataend - const_start) < name
11063 			|| memchr (sym, '\0', dataend - sym) == NULL))
11064 	    goto invalid_data;
11065 
11066 	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
11067 
11068 	  const unsigned char *readcus = const_start + vector;
11069 	  if (unlikely ((size_t) (dataend - const_start) < vector))
11070 	    goto invalid_data;
11071 	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
11072 	  while (cus--)
11073 	    {
11074 	      uint32_t cu_kind, cu, kind;
11075 	      bool is_static;
11076 	      readcus += 4;
11077 	      if (unlikely (readcus + 4 > dataend))
11078 		goto invalid_data;
11079 	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
11080 	      cu = cu_kind & ((1 << 24) - 1);
11081 	      kind = (cu_kind >> 28) & 7;
11082 	      is_static = cu_kind & (1U << 31);
11083 	      if (cu > cu_nr - 1)
11084 		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
11085 	      else
11086 		printf ("%" PRId32, cu);
11087 	      if (kind != 0)
11088 		{
11089 		  printf (" (");
11090 		  switch (kind)
11091 		    {
11092 		    case 1:
11093 		      printf ("type");
11094 		      break;
11095 		    case 2:
11096 		      printf ("var");
11097 		      break;
11098 		    case 3:
11099 		      printf ("func");
11100 		      break;
11101 		    case 4:
11102 		      printf ("other");
11103 		      break;
11104 		    default:
11105 		      printf ("unknown-0x%" PRIx32, kind);
11106 		      break;
11107 		    }
11108 		  printf (":%c)", (is_static ? 'S' : 'G'));
11109 		}
11110 	      if (cus > 0)
11111 		printf (", ");
11112 	    }
11113 	  printf ("\n");
11114 	}
11115       n++;
11116     }
11117 }
11118 
11119 /* Returns true and sets split DWARF CU id if there is a split compile
11120    unit in the given Dwarf, and no non-split units are found (before it).  */
11121 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11122 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11123 {
11124   Dwarf_CU *cu = NULL;
11125   while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11126     {
11127       uint8_t unit_type;
11128       if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11129 			 id, NULL, NULL) != 0)
11130 	return false;
11131 
11132       if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11133 	return false;
11134 
11135       /* We really only care about the split compile unit, the types
11136 	 should be fine and self sufficient.  Also they don't have an
11137 	 id that we can match with a skeleton unit.  */
11138       if (unit_type == DW_UT_split_compile)
11139 	{
11140 	  *split_cu = cu;
11141 	  return true;
11142 	}
11143     }
11144 
11145   return false;
11146 }
11147 
11148 /* Check that there is one and only one Dwfl_Module, return in arg.  */
11149 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11150 getone_dwflmod (Dwfl_Module *dwflmod,
11151 	       void **userdata __attribute__ ((unused)),
11152 	       const char *name __attribute__ ((unused)),
11153 	       Dwarf_Addr base __attribute__ ((unused)),
11154 	       void *arg)
11155 {
11156   Dwfl_Module **m = (Dwfl_Module **) arg;
11157   if (*m != NULL)
11158     return DWARF_CB_ABORT;
11159   *m = dwflmod;
11160   return DWARF_CB_OK;
11161 }
11162 
11163 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11164 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11165 {
11166   /* Used for skeleton file, if necessary for split DWARF.  */
11167   Dwfl *skel_dwfl = NULL;
11168   Dwfl_Module *skel_mod = NULL;
11169   char *skel_name = NULL;
11170   Dwarf *split_dbg = NULL;
11171   Dwarf_CU *split_cu = NULL;
11172 
11173   /* Before we start the real work get a debug context descriptor.  */
11174   Dwarf_Addr dwbias;
11175   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11176   Dwarf dummy_dbg =
11177     {
11178       .elf = ebl->elf,
11179       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11180     };
11181   if (dbg == NULL)
11182     {
11183       if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
11184 	error (0, 0, _("cannot get debug context descriptor: %s"),
11185 	       dwfl_errmsg (-1));
11186       dbg = &dummy_dbg;
11187     }
11188   else
11189     {
11190       /* If we are asked about a split dwarf (.dwo) file, use the user
11191 	 provided, or find the corresponding skeleton file. If we got
11192 	 a skeleton file, replace the given dwflmod and dbg, with one
11193 	 derived from the skeleton file to provide enough context.  */
11194       uint64_t split_id;
11195       if (is_split_dwarf (dbg, &split_id, &split_cu))
11196 	{
11197 	  if (dwarf_skeleton != NULL)
11198 	    skel_name = strdup (dwarf_skeleton);
11199 	  else
11200 	    {
11201 	      /* Replace file.dwo with file.o and see if that matches. */
11202 	      const char *fname;
11203 	      dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11204 				&fname, NULL);
11205 	      if (fname != NULL)
11206 		{
11207 		  size_t flen = strlen (fname);
11208 		  if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11209 		    {
11210 		      skel_name = strdup (fname);
11211 		      if (skel_name != NULL)
11212 			{
11213 			  skel_name[flen - 3] = 'o';
11214 			  skel_name[flen - 2] = '\0';
11215 			}
11216 		    }
11217 		}
11218 	    }
11219 
11220 	  if (skel_name != NULL)
11221 	    {
11222 	      int skel_fd = open (skel_name, O_RDONLY);
11223 	      if (skel_fd == -1)
11224 		fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11225 			 " '%s'\n", skel_name);
11226 	      else
11227 		skel_dwfl = create_dwfl (skel_fd, skel_name);
11228 
11229 	      if (skel_dwfl != NULL)
11230 		{
11231 		  if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11232 				       &skel_mod, 0) != 0)
11233 		    {
11234 		      fprintf (stderr, "Warning: Bad DWARF skeleton,"
11235 			       " multiple modules '%s'\n", skel_name);
11236 		      dwfl_end (skel_dwfl);
11237 		      skel_mod = NULL;
11238 		    }
11239 		}
11240 	      else if (skel_fd != -1)
11241 		fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11242 			 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11243 
11244 	      if (skel_mod != NULL)
11245 		{
11246 		  Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11247 		  if (skel_dbg != NULL)
11248 		    {
11249 		      /* First check the skeleton CU DIE, only fetch
11250 			 the split DIE if we know the id matches to
11251 			 not unnecessary search for any split DIEs we
11252 			 don't need. */
11253 		      Dwarf_CU *cu = NULL;
11254 		      while (dwarf_get_units (skel_dbg, cu, &cu,
11255 					      NULL, NULL, NULL, NULL) == 0)
11256 			{
11257 			  uint8_t unit_type;
11258 			  uint64_t skel_id;
11259 			  if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11260 					     &skel_id, NULL, NULL) == 0
11261 			      && unit_type == DW_UT_skeleton
11262 			      && split_id == skel_id)
11263 			    {
11264 			      Dwarf_Die subdie;
11265 			      if (dwarf_cu_info (cu, NULL, NULL, NULL,
11266 						 &subdie,
11267 						 NULL, NULL, NULL) == 0
11268 				  && dwarf_tag (&subdie) != DW_TAG_invalid)
11269 				{
11270 				  split_dbg = dwarf_cu_getdwarf (subdie.cu);
11271 				  if (split_dbg == NULL)
11272 				    fprintf (stderr,
11273 					     "Warning: Couldn't get split_dbg:"
11274 					     " %s\n", dwarf_errmsg (-1));
11275 				  break;
11276 				}
11277 			      else
11278 				{
11279 				  /* Everything matches up, but not
11280 				     according to libdw. Which means
11281 				     the user knew better.  So...
11282 				     Terrible hack... We can never
11283 				     destroy the underlying dwfl
11284 				     because it would free the wrong
11285 				     Dwarfs... So we leak memory...*/
11286 				  if (cu->split == NULL
11287 				      && dwarf_skeleton != NULL)
11288 				    {
11289 				      do_not_close_dwfl = true;
11290 				      __libdw_link_skel_split (cu, split_cu);
11291 				      split_dbg = dwarf_cu_getdwarf (split_cu);
11292 				      break;
11293 				    }
11294 				  else
11295 				    fprintf (stderr, "Warning: Couldn't get"
11296 					     " skeleton subdie: %s\n",
11297 					     dwarf_errmsg (-1));
11298 				}
11299 			    }
11300 			}
11301 		      if (split_dbg == NULL)
11302 			fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11303 		    }
11304 		  else
11305 		    fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11306 			     " %s\n", dwfl_errmsg (-1));
11307 		}
11308 	    }
11309 
11310 	  if (split_dbg != NULL)
11311 	    {
11312 	      dbg = split_dbg;
11313 	      dwflmod = skel_mod;
11314 	    }
11315 	  else if (skel_name == NULL)
11316 	    fprintf (stderr,
11317 		     "Warning: split DWARF file, but no skeleton found.\n");
11318 	}
11319       else if (dwarf_skeleton != NULL)
11320 	fprintf (stderr, "Warning: DWARF skeleton given,"
11321 		 " but not a split DWARF file\n");
11322     }
11323 
11324   /* Get the section header string table index.  */
11325   size_t shstrndx;
11326   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11327     error (EXIT_FAILURE, 0,
11328 	   _("cannot get section header string table index"));
11329 
11330   /* If the .debug_info section is listed as implicitly required then
11331      we must make sure to handle it before handling any other debug
11332      section.  Various other sections depend on the CU DIEs being
11333      scanned (silently) first.  */
11334   bool implicit_info = (implicit_debug_sections & section_info) != 0;
11335   bool explicit_info = (print_debug_sections & section_info) != 0;
11336   if (implicit_info)
11337     {
11338       Elf_Scn *scn = NULL;
11339       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11340 	{
11341 	  GElf_Shdr shdr_mem;
11342 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11343 
11344 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11345 	    {
11346 	      const char *name = elf_strptr (ebl->elf, shstrndx,
11347 					     shdr->sh_name);
11348 	      if (name == NULL)
11349 		continue;
11350 
11351 	      if (strcmp (name, ".debug_info") == 0
11352 		  || strcmp (name, ".debug_info.dwo") == 0
11353 		  || strcmp (name, ".zdebug_info") == 0
11354 		  || strcmp (name, ".zdebug_info.dwo") == 0
11355 		  || strcmp (name, ".gnu.debuglto_.debug_info") == 0)
11356 		{
11357 		  print_debug_info_section (dwflmod, ebl, ehdr,
11358 					    scn, shdr, dbg);
11359 		  break;
11360 		}
11361 	    }
11362 	}
11363       print_debug_sections &= ~section_info;
11364       implicit_debug_sections &= ~section_info;
11365     }
11366 
11367   /* Look through all the sections for the debugging sections to print.  */
11368   Elf_Scn *scn = NULL;
11369   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11370     {
11371       GElf_Shdr shdr_mem;
11372       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11373 
11374       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11375 	{
11376 	  static const struct
11377 	  {
11378 	    const char *name;
11379 	    enum section_e bitmask;
11380 	    void (*fp) (Dwfl_Module *, Ebl *,
11381 			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11382 	  } debug_sections[] =
11383 	    {
11384 #define NEW_SECTION(name) \
11385 	      { ".debug_" #name, section_##name, print_debug_##name##_section }
11386 	      NEW_SECTION (abbrev),
11387 	      NEW_SECTION (addr),
11388 	      NEW_SECTION (aranges),
11389 	      NEW_SECTION (frame),
11390 	      NEW_SECTION (info),
11391 	      NEW_SECTION (types),
11392 	      NEW_SECTION (line),
11393 	      NEW_SECTION (loc),
11394 	      /* loclists is loc for DWARF5.  */
11395 	      { ".debug_loclists", section_loc,
11396 		print_debug_loclists_section },
11397 	      NEW_SECTION (pubnames),
11398 	      NEW_SECTION (str),
11399 	      /* A DWARF5 specialised debug string section.  */
11400 	      { ".debug_line_str", section_str,
11401 		print_debug_str_section },
11402 	      /* DWARF5 string offsets table.  */
11403 	      { ".debug_str_offsets", section_str,
11404 		print_debug_str_offsets_section },
11405 	      NEW_SECTION (macinfo),
11406 	      NEW_SECTION (macro),
11407 	      NEW_SECTION (ranges),
11408 	      /* rnglists is ranges for DWARF5.  */
11409 	      { ".debug_rnglists", section_ranges,
11410 		print_debug_rnglists_section },
11411 	      { ".eh_frame", section_frame | section_exception,
11412 		print_debug_frame_section },
11413 	      { ".eh_frame_hdr", section_frame | section_exception,
11414 		print_debug_frame_hdr_section },
11415 	      { ".gcc_except_table", section_frame | section_exception,
11416 		print_debug_exception_table },
11417 	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
11418 	    };
11419 	  const int ndebug_sections = (sizeof (debug_sections)
11420 				       / sizeof (debug_sections[0]));
11421 	  const char *name = elf_strptr (ebl->elf, shstrndx,
11422 					 shdr->sh_name);
11423 	  if (name == NULL)
11424 	    continue;
11425 
11426 	  int n;
11427 	  for (n = 0; n < ndebug_sections; ++n)
11428 	    {
11429 	      size_t dbglen = strlen (debug_sections[n].name);
11430 	      size_t scnlen = strlen (name);
11431 	      if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11432 		   && (dbglen == scnlen
11433 		       || (scnlen == dbglen + 4
11434 			   && strstr (name, ".dwo") == name + dbglen)))
11435 		  || (name[0] == '.' && name[1] == 'z'
11436 		      && debug_sections[n].name[1] == 'd'
11437 		      && strncmp (&name[2], &debug_sections[n].name[1],
11438 				  dbglen - 1) == 0
11439 		      && (scnlen == dbglen + 1
11440 			  || (scnlen == dbglen + 5
11441 			      && strstr (name, ".dwo") == name + dbglen + 1)))
11442 		  || (scnlen > 14 /* .gnu.debuglto_ prefix. */
11443 		      && strncmp (name, ".gnu.debuglto_", 14) == 0
11444 		      && strcmp (&name[14], debug_sections[n].name) == 0)
11445 )
11446 		{
11447 		  if ((print_debug_sections | implicit_debug_sections)
11448 		      & debug_sections[n].bitmask)
11449 		    debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11450 		  break;
11451 		}
11452 	    }
11453 	}
11454     }
11455 
11456   dwfl_end (skel_dwfl);
11457   free (skel_name);
11458 
11459   /* Turn implicit and/or explicit back on in case we go over another file.  */
11460   if (implicit_info)
11461     implicit_debug_sections |= section_info;
11462   if (explicit_info)
11463     print_debug_sections |= section_info;
11464 
11465   reset_listptr (&known_locsptr);
11466   reset_listptr (&known_loclistsptr);
11467   reset_listptr (&known_rangelistptr);
11468   reset_listptr (&known_rnglistptr);
11469   reset_listptr (&known_addrbases);
11470   reset_listptr (&known_stroffbases);
11471 }
11472 
11473 
11474 #define ITEM_INDENT		4
11475 #define WRAP_COLUMN		75
11476 
11477 /* Print "NAME: FORMAT", wrapping when output text would make the line
11478    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
11479    but this function is also used for registers which should be printed
11480    aligned.  Fortunately registers output uses fixed fields width (such
11481    as %11d) for the alignment.
11482 
11483    Line breaks should not depend on the particular values although that
11484    may happen in some cases of the core items.  */
11485 
11486 static unsigned int
11487 __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,...)11488 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11489 		 size_t name_width, const char *name, const char *format, ...)
11490 {
11491   size_t len = strlen (name);
11492   if (name_width < len)
11493     name_width = len;
11494 
11495   char *out;
11496   va_list ap;
11497   va_start (ap, format);
11498   int out_len = vasprintf (&out, format, ap);
11499   va_end (ap);
11500   if (out_len == -1)
11501     error (EXIT_FAILURE, 0, _("memory exhausted"));
11502 
11503   size_t n = name_width + sizeof ": " - 1 + out_len;
11504 
11505   if (colno == 0)
11506     {
11507       printf ("%*s", ITEM_INDENT, "");
11508       colno = ITEM_INDENT + n;
11509     }
11510   else if (colno + 2 + n < wrap)
11511     {
11512       printf ("%c ", sep);
11513       colno += 2 + n;
11514     }
11515   else
11516     {
11517       printf ("\n%*s", ITEM_INDENT, "");
11518       colno = ITEM_INDENT + n;
11519     }
11520 
11521   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11522 
11523   free (out);
11524 
11525   return colno;
11526 }
11527 
11528 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11529 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11530 	 void *value, const void *data, size_t size)
11531 {
11532   Elf_Data valuedata =
11533     {
11534       .d_type = type,
11535       .d_buf = value,
11536       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11537       .d_version = EV_CURRENT,
11538     };
11539   Elf_Data indata =
11540     {
11541       .d_type = type,
11542       .d_buf = (void *) data,
11543       .d_size = valuedata.d_size,
11544       .d_version = EV_CURRENT,
11545     };
11546 
11547   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11548 		 ? elf32_xlatetom : elf64_xlatetom)
11549     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11550   if (d == NULL)
11551     error (EXIT_FAILURE, 0,
11552 	   _("cannot convert core note data: %s"), elf_errmsg (-1));
11553 
11554   return data + indata.d_size;
11555 }
11556 
11557 typedef uint8_t GElf_Byte;
11558 
11559 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11560 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11561 		  unsigned int colno, size_t *repeated_size)
11562 {
11563   uint_fast16_t count = item->count ?: 1;
11564   /* Ebl_Core_Item count is always a small number.
11565      Make sure the backend didn't put in some large bogus value.  */
11566   assert (count < 128);
11567 
11568 #define TYPES								      \
11569   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
11570   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
11571   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
11572   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
11573   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
11574   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11575 
11576 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11577   typedef union { TYPES; } value_t;
11578   void *data = alloca (count * sizeof (value_t));
11579 #undef DO_TYPE
11580 
11581 #define DO_TYPE(NAME, Name, hex, dec) \
11582     GElf_##Name *value_##Name __attribute__((unused)) = data
11583   TYPES;
11584 #undef DO_TYPE
11585 
11586   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11587   size_t convsize = size;
11588   if (repeated_size != NULL)
11589     {
11590       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11591 	{
11592 	  data = alloca (*repeated_size);
11593 	  count *= *repeated_size / size;
11594 	  convsize = count * size;
11595 	  *repeated_size -= convsize;
11596 	}
11597       else if (item->count != 0 || item->format != '\n')
11598 	*repeated_size -= size;
11599     }
11600 
11601   convert (core, item->type, count, data, desc + item->offset, convsize);
11602 
11603   Elf_Type type = item->type;
11604   if (type == ELF_T_ADDR)
11605     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11606 
11607   switch (item->format)
11608     {
11609     case 'd':
11610       assert (count == 1);
11611       switch (type)
11612 	{
11613 #define DO_TYPE(NAME, Name, hex, dec)					      \
11614 	  case ELF_T_##NAME:						      \
11615 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11616 				     0, item->name, dec, value_##Name[0]); \
11617 	    break
11618 	  TYPES;
11619 #undef DO_TYPE
11620 	default:
11621 	  abort ();
11622 	}
11623       break;
11624 
11625     case 'x':
11626       assert (count == 1);
11627       switch (type)
11628 	{
11629 #define DO_TYPE(NAME, Name, hex, dec)					      \
11630 	  case ELF_T_##NAME:						      \
11631 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11632 				     0, item->name, hex, value_##Name[0]);      \
11633 	    break
11634 	  TYPES;
11635 #undef DO_TYPE
11636 	default:
11637 	  abort ();
11638 	}
11639       break;
11640 
11641     case 'b':
11642     case 'B':
11643       assert (size % sizeof (unsigned int) == 0);
11644       unsigned int nbits = count * size * 8;
11645       unsigned int pop = 0;
11646       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11647 	pop += __builtin_popcount (*i);
11648       bool negate = pop > nbits / 2;
11649       const unsigned int bias = item->format == 'b';
11650 
11651       {
11652 	char printed[(negate ? nbits - pop : pop) * 16 + 1];
11653 	char *p = printed;
11654 	*p = '\0';
11655 
11656 	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11657 	  {
11658 	    assert (size == sizeof (unsigned int) * 2);
11659 	    for (unsigned int *i = data;
11660 		 (void *) i < data + count * size; i += 2)
11661 	      {
11662 		unsigned int w = i[1];
11663 		i[1] = i[0];
11664 		i[0] = w;
11665 	      }
11666 	  }
11667 
11668 	unsigned int lastbit = 0;
11669 	unsigned int run = 0;
11670 	for (const unsigned int *i = data;
11671 	     (void *) i < data + count * size; ++i)
11672 	  {
11673 	    unsigned int bit = ((void *) i - data) * 8;
11674 	    unsigned int w = negate ? ~*i : *i;
11675 	    while (w != 0)
11676 	      {
11677 		/* Note that a right shift equal to (or greater than)
11678 		   the number of bits of w is undefined behaviour.  In
11679 		   particular when the least significant bit is bit 32
11680 		   (w = 0x8000000) then w >>= n is undefined.  So
11681 		   explicitly handle that case separately.  */
11682 		unsigned int n = ffs (w);
11683 		if (n < sizeof (w) * 8)
11684 		  w >>= n;
11685 		else
11686 		  w = 0;
11687 		bit += n;
11688 
11689 		if (lastbit != 0 && lastbit + 1 == bit)
11690 		  ++run;
11691 		else
11692 		  {
11693 		    if (lastbit == 0)
11694 		      p += sprintf (p, "%u", bit - bias);
11695 		    else if (run == 0)
11696 		      p += sprintf (p, ",%u", bit - bias);
11697 		    else
11698 		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11699 		    run = 0;
11700 		  }
11701 
11702 		lastbit = bit;
11703 	      }
11704 	  }
11705 	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11706 	  p += sprintf (p, "-%u", lastbit - bias);
11707 
11708 	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11709 				 negate ? "~<%s>" : "<%s>", printed);
11710       }
11711       break;
11712 
11713     case 'T':
11714     case (char) ('T'|0x80):
11715       assert (count == 2);
11716       Dwarf_Word sec;
11717       Dwarf_Word usec;
11718       switch (type)
11719 	{
11720 #define DO_TYPE(NAME, Name, hex, dec)					      \
11721 	  case ELF_T_##NAME:						      \
11722 	    sec = value_##Name[0];					      \
11723 	    usec = value_##Name[1];					      \
11724 	    break
11725 	  TYPES;
11726 #undef DO_TYPE
11727 	default:
11728 	  abort ();
11729 	}
11730       if (unlikely (item->format == (char) ('T'|0x80)))
11731 	{
11732 	  /* This is a hack for an ill-considered 64-bit ABI where
11733 	     tv_usec is actually a 32-bit field with 32 bits of padding
11734 	     rounding out struct timeval.  We've already converted it as
11735 	     a 64-bit field.  For little-endian, this just means the
11736 	     high half is the padding; it's presumably zero, but should
11737 	     be ignored anyway.  For big-endian, it means the 32-bit
11738 	     field went into the high half of USEC.  */
11739 	  GElf_Ehdr ehdr_mem;
11740 	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11741 	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11742 	    usec >>= 32;
11743 	  else
11744 	    usec &= UINT32_MAX;
11745 	}
11746       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11747 			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
11748       break;
11749 
11750     case 'c':
11751       assert (count == 1);
11752       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11753 			       "%c", value_Byte[0]);
11754       break;
11755 
11756     case 's':
11757       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11758 			       "%.*s", (int) count, value_Byte);
11759       break;
11760 
11761     case '\n':
11762       /* This is a list of strings separated by '\n'.  */
11763       assert (item->count == 0);
11764       assert (repeated_size != NULL);
11765       assert (item->name == NULL);
11766       if (unlikely (item->offset >= *repeated_size))
11767 	break;
11768 
11769       const char *s = desc + item->offset;
11770       size = *repeated_size - item->offset;
11771       *repeated_size = 0;
11772       while (size > 0)
11773 	{
11774 	  const char *eol = memchr (s, '\n', size);
11775 	  int len = size;
11776 	  if (eol != NULL)
11777 	    len = eol - s;
11778 	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11779 	  if (eol == NULL)
11780 	    break;
11781 	  size -= eol + 1 - s;
11782 	  s = eol + 1;
11783 	}
11784 
11785       colno = WRAP_COLUMN;
11786       break;
11787 
11788     case 'h':
11789       break;
11790 
11791     default:
11792       error (0, 0, "XXX not handling format '%c' for %s",
11793 	     item->format, item->name);
11794       break;
11795     }
11796 
11797 #undef TYPES
11798 
11799   return colno;
11800 }
11801 
11802 
11803 /* Sort items by group, and by layout offset within each group.  */
11804 static int
compare_core_items(const void * a,const void * b)11805 compare_core_items (const void *a, const void *b)
11806 {
11807   const Ebl_Core_Item *const *p1 = a;
11808   const Ebl_Core_Item *const *p2 = b;
11809   const Ebl_Core_Item *item1 = *p1;
11810   const Ebl_Core_Item *item2 = *p2;
11811 
11812   return ((item1->group == item2->group ? 0
11813 	   : strcmp (item1->group, item2->group))
11814 	  ?: (int) item1->offset - (int) item2->offset);
11815 }
11816 
11817 /* Sort item groups by layout offset of the first item in the group.  */
11818 static int
compare_core_item_groups(const void * a,const void * b)11819 compare_core_item_groups (const void *a, const void *b)
11820 {
11821   const Ebl_Core_Item *const *const *p1 = a;
11822   const Ebl_Core_Item *const *const *p2 = b;
11823   const Ebl_Core_Item *const *group1 = *p1;
11824   const Ebl_Core_Item *const *group2 = *p2;
11825   const Ebl_Core_Item *item1 = *group1;
11826   const Ebl_Core_Item *item2 = *group2;
11827 
11828   return (int) item1->offset - (int) item2->offset;
11829 }
11830 
11831 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11832 handle_core_items (Elf *core, const void *desc, size_t descsz,
11833 		   const Ebl_Core_Item *items, size_t nitems)
11834 {
11835   if (nitems == 0)
11836     return 0;
11837   unsigned int colno = 0;
11838 
11839   /* FORMAT '\n' makes sense to be present only as a single item as it
11840      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
11841      if present as a single item but they can be also processed with other
11842      items below.  */
11843   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11844 		      || items[0].format == 'B'))
11845     {
11846       assert (items[0].offset == 0);
11847       size_t size = descsz;
11848       colno = handle_core_item (core, items, desc, colno, &size);
11849       /* If SIZE is not zero here there is some remaining data.  But we do not
11850 	 know how to process it anyway.  */
11851       return colno;
11852     }
11853   for (size_t i = 0; i < nitems; ++i)
11854     assert (items[i].format != '\n');
11855 
11856   /* Sort to collect the groups together.  */
11857   const Ebl_Core_Item *sorted_items[nitems];
11858   for (size_t i = 0; i < nitems; ++i)
11859     sorted_items[i] = &items[i];
11860   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11861 
11862   /* Collect the unique groups and sort them.  */
11863   const Ebl_Core_Item **groups[nitems];
11864   groups[0] = &sorted_items[0];
11865   size_t ngroups = 1;
11866   for (size_t i = 1; i < nitems; ++i)
11867     if (sorted_items[i]->group != sorted_items[i - 1]->group
11868 	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11869       groups[ngroups++] = &sorted_items[i];
11870   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11871 
11872   /* Write out all the groups.  */
11873   const void *last = desc;
11874   do
11875     {
11876       for (size_t i = 0; i < ngroups; ++i)
11877 	{
11878 	  for (const Ebl_Core_Item **item = groups[i];
11879 	       (item < &sorted_items[nitems]
11880 		&& ((*item)->group == groups[i][0]->group
11881 		    || !strcmp ((*item)->group, groups[i][0]->group)));
11882 	       ++item)
11883 	    colno = handle_core_item (core, *item, desc, colno, NULL);
11884 
11885 	  /* Force a line break at the end of the group.  */
11886 	  colno = WRAP_COLUMN;
11887 	}
11888 
11889       if (descsz == 0)
11890 	break;
11891 
11892       /* This set of items consumed a certain amount of the note's data.
11893 	 If there is more data there, we have another unit of the same size.
11894 	 Loop to print that out too.  */
11895       const Ebl_Core_Item *item = &items[nitems - 1];
11896       size_t eltsz = item->offset + gelf_fsize (core, item->type,
11897 						item->count ?: 1, EV_CURRENT);
11898 
11899       int reps = -1;
11900       do
11901 	{
11902 	  ++reps;
11903 	  desc += eltsz;
11904 	  descsz -= eltsz;
11905 	}
11906       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11907 
11908       if (reps == 1)
11909 	{
11910 	  /* For just one repeat, print it unabridged twice.  */
11911 	  desc -= eltsz;
11912 	  descsz += eltsz;
11913 	}
11914       else if (reps > 1)
11915 	printf (_("\n%*s... <repeats %u more times> ..."),
11916 		ITEM_INDENT, "", reps);
11917 
11918       last = desc;
11919     }
11920   while (descsz > 0);
11921 
11922   return colno;
11923 }
11924 
11925 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11926 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11927 		      unsigned int colno)
11928 {
11929   desc += regloc->offset;
11930 
11931   abort ();			/* XXX */
11932   return colno;
11933 }
11934 
11935 
11936 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11937 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11938 		      const Ebl_Register_Location *regloc, const void *desc,
11939 		      unsigned int colno)
11940 {
11941   if (regloc->bits % 8 != 0)
11942     return handle_bit_registers (regloc, desc, colno);
11943 
11944   desc += regloc->offset;
11945 
11946   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11947     {
11948       char name[REGNAMESZ];
11949       int bits;
11950       int type;
11951       register_info (ebl, reg, regloc, name, &bits, &type);
11952 
11953 #define TYPES								      \
11954       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
11955       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
11956       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
11957       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
11958 
11959 #define BITS(bits, xtype, sfmt, ufmt)				\
11960       uint##bits##_t b##bits; int##bits##_t b##bits##s
11961       union { TYPES; uint64_t b128[2]; } value;
11962 #undef	BITS
11963 
11964       switch (type)
11965 	{
11966 	case DW_ATE_unsigned:
11967 	case DW_ATE_signed:
11968 	case DW_ATE_address:
11969 	  switch (bits)
11970 	    {
11971 #define BITS(bits, xtype, sfmt, ufmt)					      \
11972 	    case bits:							      \
11973 	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
11974 	      if (type == DW_ATE_signed)				      \
11975 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11976 					 maxregname, name,		      \
11977 					 sfmt, value.b##bits##s);	      \
11978 	      else							      \
11979 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11980 					 maxregname, name,		      \
11981 					 ufmt, value.b##bits);		      \
11982 	      break
11983 
11984 	    TYPES;
11985 
11986 	    case 128:
11987 	      assert (type == DW_ATE_unsigned);
11988 	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11989 	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11990 	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
11991 				       maxregname, name,
11992 				       "0x%.16" PRIx64 "%.16" PRIx64,
11993 				       value.b128[!be], value.b128[be]);
11994 	      break;
11995 
11996 	    default:
11997 	      abort ();
11998 #undef	BITS
11999 	    }
12000 	  break;
12001 
12002 	default:
12003 	  /* Print each byte in hex, the whole thing in native byte order.  */
12004 	  assert (bits % 8 == 0);
12005 	  const uint8_t *bytes = desc;
12006 	  desc += bits / 8;
12007 	  char hex[bits / 4 + 1];
12008 	  hex[bits / 4] = '\0';
12009 	  int incr = 1;
12010 	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
12011 	    {
12012 	      bytes += bits / 8 - 1;
12013 	      incr = -1;
12014 	    }
12015 	  size_t idx = 0;
12016 	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
12017 	    {
12018 	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
12019 	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
12020 	    }
12021 	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
12022 				   maxregname, name, "0x%s", hex);
12023 	  break;
12024 	}
12025       desc += regloc->pad;
12026 
12027 #undef TYPES
12028     }
12029 
12030   return colno;
12031 }
12032 
12033 
12034 struct register_info
12035 {
12036   const Ebl_Register_Location *regloc;
12037   const char *set;
12038   char name[REGNAMESZ];
12039   int regno;
12040   int bits;
12041   int type;
12042 };
12043 
12044 static int
register_bitpos(const struct register_info * r)12045 register_bitpos (const struct register_info *r)
12046 {
12047   return (r->regloc->offset * 8
12048 	  + ((r->regno - r->regloc->regno)
12049 	     * (r->regloc->bits + r->regloc->pad * 8)));
12050 }
12051 
12052 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)12053 compare_sets_by_info (const struct register_info *r1,
12054 		      const struct register_info *r2)
12055 {
12056   return ((int) r2->bits - (int) r1->bits
12057 	  ?: register_bitpos (r1) - register_bitpos (r2));
12058 }
12059 
12060 /* Sort registers by set, and by size and layout offset within each set.  */
12061 static int
compare_registers(const void * a,const void * b)12062 compare_registers (const void *a, const void *b)
12063 {
12064   const struct register_info *r1 = a;
12065   const struct register_info *r2 = b;
12066 
12067   /* Unused elements sort last.  */
12068   if (r1->regloc == NULL)
12069     return r2->regloc == NULL ? 0 : 1;
12070   if (r2->regloc == NULL)
12071     return -1;
12072 
12073   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
12074 	  ?: compare_sets_by_info (r1, r2));
12075 }
12076 
12077 /* Sort register sets by layout offset of the first register in the set.  */
12078 static int
compare_register_sets(const void * a,const void * b)12079 compare_register_sets (const void *a, const void *b)
12080 {
12081   const struct register_info *const *p1 = a;
12082   const struct register_info *const *p2 = b;
12083   return compare_sets_by_info (*p1, *p2);
12084 }
12085 
12086 static inline bool
same_set(const struct register_info * a,const struct register_info * b,const struct register_info * regs,size_t maxnreg)12087 same_set (const struct register_info *a,
12088 	  const struct register_info *b,
12089 	  const struct register_info *regs,
12090 	  size_t maxnreg)
12091 {
12092   return (a < &regs[maxnreg] && a->regloc != NULL
12093 	  && b < &regs[maxnreg] && b->regloc != NULL
12094 	  && a->bits == b->bits
12095 	  && (a->set == b->set || !strcmp (a->set, b->set)));
12096 }
12097 
12098 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)12099 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
12100 		       const Ebl_Register_Location *reglocs, size_t nregloc)
12101 {
12102   if (nregloc == 0)
12103     return 0;
12104 
12105   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12106   if (maxnreg <= 0)
12107     {
12108       for (size_t i = 0; i < nregloc; ++i)
12109 	if (maxnreg < reglocs[i].regno + reglocs[i].count)
12110 	  maxnreg = reglocs[i].regno + reglocs[i].count;
12111       assert (maxnreg > 0);
12112     }
12113 
12114   struct register_info regs[maxnreg];
12115   memset (regs, 0, sizeof regs);
12116 
12117   /* Sort to collect the sets together.  */
12118   int maxreg = 0;
12119   for (size_t i = 0; i < nregloc; ++i)
12120     for (int reg = reglocs[i].regno;
12121 	 reg < reglocs[i].regno + reglocs[i].count;
12122 	 ++reg)
12123       {
12124 	assert (reg < maxnreg);
12125 	if (reg > maxreg)
12126 	  maxreg = reg;
12127 	struct register_info *info = &regs[reg];
12128 	info->regloc = &reglocs[i];
12129 	info->regno = reg;
12130 	info->set = register_info (ebl, reg, &reglocs[i],
12131 				   info->name, &info->bits, &info->type);
12132       }
12133   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12134 
12135   /* Collect the unique sets and sort them.  */
12136   struct register_info *sets[maxreg + 1];
12137   sets[0] = &regs[0];
12138   size_t nsets = 1;
12139   for (int i = 1; i <= maxreg; ++i)
12140     if (regs[i].regloc != NULL
12141 	&& !same_set (&regs[i], &regs[i - 1], regs, maxnreg))
12142       sets[nsets++] = &regs[i];
12143   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12144 
12145   /* Write out all the sets.  */
12146   unsigned int colno = 0;
12147   for (size_t i = 0; i < nsets; ++i)
12148     {
12149       /* Find the longest name of a register in this set.  */
12150       size_t maxname = 0;
12151       const struct register_info *end;
12152       for (end = sets[i]; same_set (sets[i], end, regs, maxnreg); ++end)
12153 	{
12154 	  size_t len = strlen (end->name);
12155 	  if (len > maxname)
12156 	    maxname = len;
12157 	}
12158 
12159       for (const struct register_info *reg = sets[i];
12160 	   reg < end;
12161 	   reg += reg->regloc->count ?: 1)
12162 	colno = handle_core_register (ebl, core, maxname,
12163 				      reg->regloc, desc, colno);
12164 
12165       /* Force a line break at the end of the group.  */
12166       colno = WRAP_COLUMN;
12167     }
12168 
12169   return colno;
12170 }
12171 
12172 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12173 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12174 {
12175   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12176   if (data == NULL)
12177   elf_error:
12178     error (EXIT_FAILURE, 0,
12179 	   _("cannot convert core note data: %s"), elf_errmsg (-1));
12180 
12181   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12182   for (size_t i = 0; i < nauxv; ++i)
12183     {
12184       GElf_auxv_t av_mem;
12185       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12186       if (av == NULL)
12187 	goto elf_error;
12188 
12189       const char *name;
12190       const char *fmt;
12191       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12192 	{
12193 	  /* Unknown type.  */
12194 	  if (av->a_un.a_val == 0)
12195 	    printf ("    %" PRIu64 "\n", av->a_type);
12196 	  else
12197 	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
12198 		    av->a_type, av->a_un.a_val);
12199 	}
12200       else
12201 	switch (fmt[0])
12202 	  {
12203 	  case '\0':		/* Normally zero.  */
12204 	    if (av->a_un.a_val == 0)
12205 	      {
12206 		printf ("    %s\n", name);
12207 		break;
12208 	      }
12209 	    FALLTHROUGH;
12210 	  case 'x':		/* hex */
12211 	  case 'p':		/* address */
12212 	  case 's':		/* address of string */
12213 	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12214 	    break;
12215 	  case 'u':
12216 	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
12217 	    break;
12218 	  case 'd':
12219 	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
12220 	    break;
12221 
12222 	  case 'b':
12223 	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
12224 	    GElf_Xword bit = 1;
12225 	    const char *pfx = "<";
12226 	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12227 	      {
12228 		if (av->a_un.a_val & bit)
12229 		  {
12230 		    printf ("%s%s", pfx, p);
12231 		    pfx = " ";
12232 		  }
12233 		bit <<= 1;
12234 	      }
12235 	    printf (">\n");
12236 	    break;
12237 
12238 	  default:
12239 	    abort ();
12240 	  }
12241     }
12242 }
12243 
12244 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12245 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12246 {
12247   return ptr < end && (size_t) (end - ptr) >= sz;
12248 }
12249 
12250 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12251 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12252 	      int *retp)
12253 {
12254   if (! buf_has_data (*ptrp, end, 4))
12255     return false;
12256 
12257   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12258   return true;
12259 }
12260 
12261 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12262 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12263 		uint64_t *retp)
12264 {
12265   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12266   if (! buf_has_data (*ptrp, end, sz))
12267     return false;
12268 
12269   union
12270   {
12271     uint64_t u64;
12272     uint32_t u32;
12273   } u;
12274 
12275   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12276 
12277   if (sz == 4)
12278     *retp = u.u32;
12279   else
12280     *retp = u.u64;
12281   return true;
12282 }
12283 
12284 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12285 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12286 {
12287   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12288   if (data == NULL)
12289     error (EXIT_FAILURE, 0,
12290 	   _("cannot convert core note data: %s"), elf_errmsg (-1));
12291 
12292   unsigned char const *ptr = data->d_buf;
12293   unsigned char const *const end = data->d_buf + data->d_size;
12294 
12295   /* Siginfo head is three ints: signal number, error number, origin
12296      code.  */
12297   int si_signo, si_errno, si_code;
12298   if (! buf_read_int (core, &ptr, end, &si_signo)
12299       || ! buf_read_int (core, &ptr, end, &si_errno)
12300       || ! buf_read_int (core, &ptr, end, &si_code))
12301     {
12302     fail:
12303       printf ("    Not enough data in NT_SIGINFO note.\n");
12304       return;
12305     }
12306 
12307   /* Next is a pointer-aligned union of structures.  On 64-bit
12308      machines, that implies a word of padding.  */
12309   if (gelf_getclass (core) == ELFCLASS64)
12310     ptr += 4;
12311 
12312   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
12313 	  si_signo, si_errno, si_code);
12314 
12315   if (si_code > 0)
12316     switch (si_signo)
12317       {
12318       case CORE_SIGILL:
12319       case CORE_SIGFPE:
12320       case CORE_SIGSEGV:
12321       case CORE_SIGBUS:
12322 	{
12323 	  uint64_t addr;
12324 	  if (! buf_read_ulong (core, &ptr, end, &addr))
12325 	    goto fail;
12326 	  printf ("    fault address: %#" PRIx64 "\n", addr);
12327 	  break;
12328 	}
12329       default:
12330 	;
12331       }
12332   else if (si_code == CORE_SI_USER)
12333     {
12334       int pid, uid;
12335       if (! buf_read_int (core, &ptr, end, &pid)
12336 	  || ! buf_read_int (core, &ptr, end, &uid))
12337 	goto fail;
12338       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
12339     }
12340 }
12341 
12342 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12343 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12344 {
12345   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12346   if (data == NULL)
12347     error (EXIT_FAILURE, 0,
12348 	   _("cannot convert core note data: %s"), elf_errmsg (-1));
12349 
12350   unsigned char const *ptr = data->d_buf;
12351   unsigned char const *const end = data->d_buf + data->d_size;
12352 
12353   uint64_t count, page_size;
12354   if (! buf_read_ulong (core, &ptr, end, &count)
12355       || ! buf_read_ulong (core, &ptr, end, &page_size))
12356     {
12357     fail:
12358       printf ("    Not enough data in NT_FILE note.\n");
12359       return;
12360     }
12361 
12362   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12363   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12364   if (count > maxcount)
12365     goto fail;
12366 
12367   /* Where file names are stored.  */
12368   unsigned char const *const fstart = ptr + 3 * count * addrsize;
12369   char const *fptr = (char *) fstart;
12370 
12371   printf ("    %" PRId64 " files:\n", count);
12372   for (uint64_t i = 0; i < count; ++i)
12373     {
12374       uint64_t mstart, mend, moffset;
12375       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12376 	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
12377 	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12378 	goto fail;
12379 
12380       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12381       if (fnext == NULL)
12382 	goto fail;
12383 
12384       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
12385 		       " %08" PRIx64 " %" PRId64,
12386 		       mstart, mend, moffset * page_size, mend - mstart);
12387       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12388 
12389       fptr = fnext + 1;
12390     }
12391 }
12392 
12393 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12394 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12395 		  const char *name, const void *desc)
12396 {
12397   GElf_Word regs_offset;
12398   size_t nregloc;
12399   const Ebl_Register_Location *reglocs;
12400   size_t nitems;
12401   const Ebl_Core_Item *items;
12402 
12403   if (! ebl_core_note (ebl, nhdr, name, desc,
12404 		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
12405     return;
12406 
12407   /* Pass 0 for DESCSZ when there are registers in the note,
12408      so that the ITEMS array does not describe the whole thing.
12409      For non-register notes, the actual descsz might be a multiple
12410      of the unit size, not just exactly the unit size.  */
12411   unsigned int colno = handle_core_items (ebl->elf, desc,
12412 					  nregloc == 0 ? nhdr->n_descsz : 0,
12413 					  items, nitems);
12414   if (colno != 0)
12415     putchar_unlocked ('\n');
12416 
12417   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12418 				 reglocs, nregloc);
12419   if (colno != 0)
12420     putchar_unlocked ('\n');
12421 }
12422 
12423 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12424 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12425 		   GElf_Off start, Elf_Data *data)
12426 {
12427   fputs_unlocked (_("  Owner          Data size  Type\n"), stdout);
12428 
12429   if (data == NULL)
12430     goto bad_note;
12431 
12432   size_t offset = 0;
12433   GElf_Nhdr nhdr;
12434   size_t name_offset;
12435   size_t desc_offset;
12436   while (offset < data->d_size
12437 	 && (offset = gelf_getnote (data, offset,
12438 				    &nhdr, &name_offset, &desc_offset)) > 0)
12439     {
12440       const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12441       const char *desc = data->d_buf + desc_offset;
12442 
12443       /* GNU Build Attributes are weird, they store most of their data
12444 	 into the owner name field.  Extract just the owner name
12445 	 prefix here, then use the rest later as data.  */
12446       bool is_gnu_build_attr
12447 	= strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12448 		   strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12449       const char *print_name = (is_gnu_build_attr
12450 				? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12451       size_t print_namesz = (is_gnu_build_attr
12452 			     ? strlen (print_name) : nhdr.n_namesz);
12453 
12454       char buf[100];
12455       char buf2[100];
12456       printf (_("  %-13.*s  %9" PRId32 "  %s\n"),
12457 	      (int) print_namesz, print_name, nhdr.n_descsz,
12458 	      ehdr->e_type == ET_CORE
12459 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
12460 					 buf, sizeof (buf))
12461 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12462 					   nhdr.n_descsz,
12463 					   buf2, sizeof (buf2)));
12464 
12465       /* Filter out invalid entries.  */
12466       if (memchr (name, '\0', nhdr.n_namesz) != NULL
12467 	  /* XXX For now help broken Linux kernels.  */
12468 	  || 1)
12469 	{
12470 	  if (ehdr->e_type == ET_CORE)
12471 	    {
12472 	      if (nhdr.n_type == NT_AUXV
12473 		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
12474 		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
12475 		  && !memcmp (name, "CORE", 4))
12476 		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12477 				  start + desc_offset);
12478 	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12479 		switch (nhdr.n_type)
12480 		  {
12481 		  case NT_SIGINFO:
12482 		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12483 					 start + desc_offset);
12484 		    break;
12485 
12486 		  case NT_FILE:
12487 		    handle_file_note (ebl->elf, nhdr.n_descsz,
12488 				      start + desc_offset);
12489 		    break;
12490 
12491 		  default:
12492 		    handle_core_note (ebl, &nhdr, name, desc);
12493 		  }
12494 	      else
12495 		handle_core_note (ebl, &nhdr, name, desc);
12496 	    }
12497 	  else
12498 	    ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12499 			     nhdr.n_descsz, desc);
12500 	}
12501     }
12502 
12503   if (offset == data->d_size)
12504     return;
12505 
12506  bad_note:
12507   error (0, 0,
12508 	 _("cannot get content of note: %s"),
12509 	 data != NULL ? "garbage data" : elf_errmsg (-1));
12510 }
12511 
12512 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12513 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12514 {
12515   /* If we have section headers, just look for SHT_NOTE sections.
12516      In a debuginfo file, the program headers are not reliable.  */
12517   if (shnum != 0)
12518     {
12519       /* Get the section header string table index.  */
12520       size_t shstrndx;
12521       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12522 	error (EXIT_FAILURE, 0,
12523 	       _("cannot get section header string table index"));
12524 
12525       Elf_Scn *scn = NULL;
12526       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12527 	{
12528 	  GElf_Shdr shdr_mem;
12529 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12530 
12531 	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12532 	    /* Not what we are looking for.  */
12533 	    continue;
12534 
12535 	  if (notes_section != NULL)
12536 	    {
12537 	      char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12538 	      if (sname == NULL || strcmp (sname, notes_section) != 0)
12539 		continue;
12540 	    }
12541 
12542 	  printf (_("\
12543 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12544 		  elf_ndxscn (scn),
12545 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12546 		  shdr->sh_size, shdr->sh_offset);
12547 
12548 	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
12549 			     elf_getdata (scn, NULL));
12550 	}
12551       return;
12552     }
12553 
12554   /* We have to look through the program header to find the note
12555      sections.  There can be more than one.  */
12556   for (size_t cnt = 0; cnt < phnum; ++cnt)
12557     {
12558       GElf_Phdr mem;
12559       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12560 
12561       if (phdr == NULL || phdr->p_type != PT_NOTE)
12562 	/* Not what we are looking for.  */
12563 	continue;
12564 
12565       printf (_("\
12566 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12567 	      phdr->p_filesz, phdr->p_offset);
12568 
12569       handle_notes_data (ebl, ehdr, phdr->p_offset,
12570 			 elf_getdata_rawchunk (ebl->elf,
12571 					       phdr->p_offset, phdr->p_filesz,
12572 					       (phdr->p_align == 8
12573 						? ELF_T_NHDR8 : ELF_T_NHDR)));
12574     }
12575 }
12576 
12577 
12578 static void
hex_dump(const uint8_t * data,size_t len)12579 hex_dump (const uint8_t *data, size_t len)
12580 {
12581   size_t pos = 0;
12582   while (pos < len)
12583     {
12584       printf ("  0x%08zx ", pos);
12585 
12586       const size_t chunk = MIN (len - pos, 16);
12587 
12588       for (size_t i = 0; i < chunk; ++i)
12589 	if (i % 4 == 3)
12590 	  printf ("%02x ", data[pos + i]);
12591 	else
12592 	  printf ("%02x", data[pos + i]);
12593 
12594       if (chunk < 16)
12595 	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12596 
12597       for (size_t i = 0; i < chunk; ++i)
12598 	{
12599 	  unsigned char b = data[pos + i];
12600 	  printf ("%c", isprint (b) ? b : '.');
12601 	}
12602 
12603       putchar ('\n');
12604       pos += chunk;
12605     }
12606 }
12607 
12608 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12609 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12610 {
12611   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12612     printf (_("\nSection [%zu] '%s' has no data to dump.\n"),
12613 	    elf_ndxscn (scn), name);
12614   else
12615     {
12616       if (print_decompress)
12617 	{
12618 	  /* We try to decompress the section, but keep the old shdr around
12619 	     so we can show both the original shdr size and the uncompressed
12620 	     data size.   */
12621 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12622 	    {
12623 	      if (elf_compress (scn, 0, 0) < 0)
12624 		printf ("WARNING: %s [%zd]\n",
12625 			_("Couldn't uncompress section"),
12626 			elf_ndxscn (scn));
12627 	    }
12628 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12629 	    {
12630 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12631 		printf ("WARNING: %s [%zd]\n",
12632 			_("Couldn't uncompress section"),
12633 			elf_ndxscn (scn));
12634 	    }
12635 	}
12636 
12637       Elf_Data *data = elf_rawdata (scn, NULL);
12638       if (data == NULL)
12639 	error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
12640 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12641       else
12642 	{
12643 	  if (data->d_size == shdr->sh_size)
12644 	    printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
12645 			     " bytes at offset %#0" PRIx64 ":\n"),
12646 		    elf_ndxscn (scn), name,
12647 		    shdr->sh_size, shdr->sh_offset);
12648 	  else
12649 	    printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
12650 			     " bytes (%zd uncompressed) at offset %#0"
12651 			     PRIx64 ":\n"),
12652 		    elf_ndxscn (scn), name,
12653 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12654 	  hex_dump (data->d_buf, data->d_size);
12655 	}
12656     }
12657 }
12658 
12659 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12660 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12661 {
12662   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12663     printf (_("\nSection [%zu] '%s' has no strings to dump.\n"),
12664 	    elf_ndxscn (scn), name);
12665   else
12666     {
12667       if (print_decompress)
12668 	{
12669 	  /* We try to decompress the section, but keep the old shdr around
12670 	     so we can show both the original shdr size and the uncompressed
12671 	     data size.  */
12672 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12673 	    {
12674 	      if (elf_compress (scn, 0, 0) < 0)
12675 		printf ("WARNING: %s [%zd]\n",
12676 			_("Couldn't uncompress section"),
12677 			elf_ndxscn (scn));
12678 	    }
12679 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12680 	    {
12681 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12682 		printf ("WARNING: %s [%zd]\n",
12683 			_("Couldn't uncompress section"),
12684 			elf_ndxscn (scn));
12685 	    }
12686 	}
12687 
12688       Elf_Data *data = elf_rawdata (scn, NULL);
12689       if (data == NULL)
12690 	error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
12691 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12692       else
12693 	{
12694 	  if (data->d_size == shdr->sh_size)
12695 	    printf (_("\nString section [%zu] '%s' contains %" PRIu64
12696 			     " bytes at offset %#0" PRIx64 ":\n"),
12697 		    elf_ndxscn (scn), name,
12698 		    shdr->sh_size, shdr->sh_offset);
12699 	  else
12700 	    printf (_("\nString section [%zu] '%s' contains %" PRIu64
12701 			     " bytes (%zd uncompressed) at offset %#0"
12702 			     PRIx64 ":\n"),
12703 		    elf_ndxscn (scn), name,
12704 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12705 
12706 	  const char *start = data->d_buf;
12707 	  const char *const limit = start + data->d_size;
12708 	  do
12709 	    {
12710 	      const char *end = memchr (start, '\0', limit - start);
12711 	      const size_t pos = start - (const char *) data->d_buf;
12712 	      if (unlikely (end == NULL))
12713 		{
12714 		  printf ("  [%6zx]- %.*s\n",
12715 			  pos, (int) (limit - start), start);
12716 		  break;
12717 		}
12718 	      printf ("  [%6zx]  %s\n", pos, start);
12719 	      start = end + 1;
12720 	    } while (start < limit);
12721 	}
12722     }
12723 }
12724 
12725 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))12726 for_each_section_argument (Elf *elf, const struct section_argument *list,
12727 			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12728 					 const char *name))
12729 {
12730   /* Get the section header string table index.  */
12731   size_t shstrndx;
12732   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12733     error (EXIT_FAILURE, 0,
12734 	   _("cannot get section header string table index"));
12735 
12736   for (const struct section_argument *a = list; a != NULL; a = a->next)
12737     {
12738       Elf_Scn *scn;
12739       GElf_Shdr shdr_mem;
12740       const char *name = NULL;
12741 
12742       char *endp = NULL;
12743       unsigned long int shndx = strtoul (a->arg, &endp, 0);
12744       if (endp != a->arg && *endp == '\0')
12745 	{
12746 	  scn = elf_getscn (elf, shndx);
12747 	  if (scn == NULL)
12748 	    {
12749 	      error (0, 0, _("\nsection [%lu] does not exist"), shndx);
12750 	      continue;
12751 	    }
12752 
12753 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
12754 	    error (EXIT_FAILURE, 0, _("cannot get section header: %s"),
12755 		   elf_errmsg (-1));
12756 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12757 	  (*dump) (scn, &shdr_mem, name);
12758 	}
12759       else
12760 	{
12761 	  /* Need to look up the section by name.  */
12762 	  scn = NULL;
12763 	  bool found = false;
12764 	  while ((scn = elf_nextscn (elf, scn)) != NULL)
12765 	    {
12766 	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
12767 		continue;
12768 	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12769 	      if (name == NULL)
12770 		continue;
12771 	      if (!strcmp (name, a->arg))
12772 		{
12773 		  found = true;
12774 		  (*dump) (scn, &shdr_mem, name);
12775 		}
12776 	    }
12777 
12778 	  if (unlikely (!found) && !a->implicit)
12779 	    error (0, 0, _("\nsection '%s' does not exist"), a->arg);
12780 	}
12781     }
12782 }
12783 
12784 static void
dump_data(Ebl * ebl)12785 dump_data (Ebl *ebl)
12786 {
12787   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12788 }
12789 
12790 static void
dump_strings(Ebl * ebl)12791 dump_strings (Ebl *ebl)
12792 {
12793   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12794 }
12795 
12796 static void
print_strings(Ebl * ebl)12797 print_strings (Ebl *ebl)
12798 {
12799   /* Get the section header string table index.  */
12800   size_t shstrndx;
12801   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12802     error (EXIT_FAILURE, 0,
12803 	   _("cannot get section header string table index"));
12804 
12805   Elf_Scn *scn;
12806   GElf_Shdr shdr_mem;
12807   const char *name;
12808   scn = NULL;
12809   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12810     {
12811       if (gelf_getshdr (scn, &shdr_mem) == NULL)
12812 	continue;
12813 
12814       if (shdr_mem.sh_type != SHT_PROGBITS
12815 	  || !(shdr_mem.sh_flags & SHF_STRINGS))
12816 	continue;
12817 
12818       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12819       if (name == NULL)
12820 	continue;
12821 
12822       print_string_section (scn, &shdr_mem, name);
12823     }
12824 }
12825 
12826 static void
dump_archive_index(Elf * elf,const char * fname)12827 dump_archive_index (Elf *elf, const char *fname)
12828 {
12829   size_t narsym;
12830   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12831   if (arsym == NULL)
12832     {
12833       int result = elf_errno ();
12834       if (unlikely (result != ELF_E_NO_INDEX))
12835 	error (EXIT_FAILURE, 0,
12836 	       _("cannot get symbol index of archive '%s': %s"),
12837 	       fname, elf_errmsg (result));
12838       else
12839 	printf (_("\nArchive '%s' has no symbol index\n"), fname);
12840       return;
12841     }
12842 
12843   printf (_("\nIndex of archive '%s' has %zu entries:\n"),
12844 	  fname, narsym);
12845 
12846   size_t as_off = 0;
12847   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12848     {
12849       if (s->as_off != as_off)
12850 	{
12851 	  as_off = s->as_off;
12852 
12853 	  Elf *subelf = NULL;
12854 	  if (unlikely (elf_rand (elf, as_off) == 0)
12855 	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12856 			   == NULL))
12857 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12858 	    while (1)
12859 #endif
12860 	      error (EXIT_FAILURE, 0,
12861 		     _("cannot extract member at offset %zu in '%s': %s"),
12862 		     as_off, fname, elf_errmsg (-1));
12863 
12864 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
12865 
12866 	  printf (_("Archive member '%s' contains:\n"), h->ar_name);
12867 
12868 	  elf_end (subelf);
12869 	}
12870 
12871       printf ("\t%s\n", s->as_name);
12872     }
12873 }
12874 
12875 #include "debugpred.h"
12876