• 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 = gettext ("yes");
351   no_str = gettext ("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 
385 /* Handle program arguments.  */
386 static error_t
parse_opt(int key,char * arg,struct argp_state * state)387 parse_opt (int key, char *arg,
388 	   struct argp_state *state __attribute__ ((unused)))
389 {
390   void add_dump_section (const char *name, bool implicit)
391   {
392     struct section_argument *a = xmalloc (sizeof *a);
393     a->arg = name;
394     a->next = NULL;
395     a->implicit = implicit;
396     struct section_argument ***tailp
397       = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
398     **tailp = a;
399     *tailp = &a->next;
400   }
401 
402   switch (key)
403     {
404     case 'a':
405       print_file_header = true;
406       print_program_header = true;
407       print_relocations = true;
408       print_section_header = true;
409       print_symbol_table = true;
410       print_version_info = true;
411       print_dynamic_table = true;
412       print_section_groups = true;
413       print_histogram = true;
414       print_arch = true;
415       print_notes = true;
416       implicit_debug_sections |= section_exception;
417       add_dump_section (".strtab", true);
418       add_dump_section (".dynstr", true);
419       add_dump_section (".comment", true);
420       any_control_option = true;
421       break;
422     case 'A':
423       print_arch = true;
424       any_control_option = true;
425       break;
426     case 'd':
427       print_dynamic_table = true;
428       any_control_option = true;
429       break;
430     case 'e':
431       print_debug_sections |= section_exception;
432       any_control_option = true;
433       break;
434     case 'g':
435       print_section_groups = true;
436       any_control_option = true;
437       break;
438     case 'h':
439       print_file_header = true;
440       any_control_option = true;
441       break;
442     case 'I':
443       print_histogram = true;
444       any_control_option = true;
445       break;
446     case 'l':
447       print_program_header = true;
448       any_control_option = true;
449       break;
450     case 'n':
451       print_notes = true;
452       any_control_option = true;
453       notes_section = arg;
454       break;
455     case 'r':
456       print_relocations = true;
457       any_control_option = true;
458      break;
459     case 'S':
460       print_section_header = true;
461       any_control_option = true;
462       break;
463     case 's':
464       print_symbol_table = true;
465       any_control_option = true;
466       symbol_table_section = arg;
467       break;
468     case PRINT_DYNSYM_TABLE:
469       print_dynsym_table = true;
470       any_control_option = true;
471       break;
472     case 'V':
473       print_version_info = true;
474       any_control_option = true;
475       break;
476     case 'c':
477       print_archive_index = true;
478       break;
479     case 'w':
480       if (arg == NULL)
481 	{
482 	  print_debug_sections = section_all;
483 	  implicit_debug_sections = section_info;
484 	  show_split_units = true;
485 	}
486       else if (strcmp (arg, "abbrev") == 0)
487 	print_debug_sections |= section_abbrev;
488       else if (strcmp (arg, "addr") == 0)
489 	{
490 	  print_debug_sections |= section_addr;
491 	  implicit_debug_sections |= section_info;
492 	}
493       else if (strcmp (arg, "aranges") == 0)
494 	print_debug_sections |= section_aranges;
495       else if (strcmp (arg, "decodedaranges") == 0)
496 	{
497 	  print_debug_sections |= section_aranges;
498 	  decodedaranges = true;
499 	}
500       else if (strcmp (arg, "ranges") == 0)
501 	{
502 	  print_debug_sections |= section_ranges;
503 	  implicit_debug_sections |= section_info;
504 	}
505       else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
506 	print_debug_sections |= section_frame;
507       else if (strcmp (arg, "info") == 0)
508 	{
509 	  print_debug_sections |= section_info;
510 	  print_debug_sections |= section_types;
511 	}
512       else if (strcmp (arg, "info+") == 0)
513 	{
514 	  print_debug_sections |= section_info;
515 	  print_debug_sections |= section_types;
516 	  show_split_units = true;
517 	}
518       else if (strcmp (arg, "loc") == 0)
519 	{
520 	  print_debug_sections |= section_loc;
521 	  implicit_debug_sections |= section_info;
522 	}
523       else if (strcmp (arg, "line") == 0)
524 	print_debug_sections |= section_line;
525       else if (strcmp (arg, "decodedline") == 0)
526 	{
527 	  print_debug_sections |= section_line;
528 	  decodedline = true;
529 	}
530       else if (strcmp (arg, "pubnames") == 0)
531 	print_debug_sections |= section_pubnames;
532       else if (strcmp (arg, "str") == 0)
533 	{
534 	  print_debug_sections |= section_str;
535 	  /* For mapping string offset tables to CUs.  */
536 	  implicit_debug_sections |= section_info;
537 	}
538       else if (strcmp (arg, "macinfo") == 0)
539 	print_debug_sections |= section_macinfo;
540       else if (strcmp (arg, "macro") == 0)
541 	print_debug_sections |= section_macro;
542       else if (strcmp (arg, "exception") == 0)
543 	print_debug_sections |= section_exception;
544       else if (strcmp (arg, "gdb_index") == 0)
545 	print_debug_sections |= section_gdb_index;
546       else
547 	{
548 	  fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
549 		   arg);
550 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
551 		     program_invocation_short_name);
552 	  exit (1);
553 	}
554       any_control_option = true;
555       break;
556     case 'p':
557       any_control_option = true;
558       if (arg == NULL)
559 	{
560 	  print_string_sections = true;
561 	  break;
562 	}
563       FALLTHROUGH;
564     case 'x':
565       add_dump_section (arg, false);
566       any_control_option = true;
567       break;
568     case 'N':
569       print_address_names = false;
570       break;
571     case 'U':
572       print_unresolved_addresses = true;
573       break;
574     case ARGP_KEY_NO_ARGS:
575       fputs (gettext ("Missing file name.\n"), stderr);
576       goto do_argp_help;
577     case ARGP_KEY_FINI:
578       if (! any_control_option && ! print_archive_index)
579 	{
580 	  fputs (gettext ("No operation specified.\n"), stderr);
581 	do_argp_help:
582 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
583 		     program_invocation_short_name);
584 	  exit (EXIT_FAILURE);
585 	}
586       break;
587     case 'W':			/* Ignored.  */
588       break;
589     case 'z':
590       print_decompress = true;
591       break;
592     case ELF_INPUT_SECTION:
593       if (arg == NULL)
594 	elf_input_section = ".gnu_debugdata";
595       else
596 	elf_input_section = arg;
597       break;
598     case DWARF_SKELETON:
599       dwarf_skeleton = arg;
600       break;
601     default:
602       return ARGP_ERR_UNKNOWN;
603     }
604   return 0;
605 }
606 
607 
608 /* Create a file descriptor to read the data from the
609    elf_input_section given a file descriptor to an ELF file.  */
610 static int
open_input_section(int fd)611 open_input_section (int fd)
612 {
613   size_t shnums;
614   size_t cnt;
615   size_t shstrndx;
616   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
617   if (elf == NULL)
618     {
619       error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
620 	     elf_errmsg (-1));
621       return -1;
622     }
623 
624   if (elf_getshdrnum (elf, &shnums) < 0)
625     {
626       error (0, 0, gettext ("cannot determine number of sections: %s"),
627 	     elf_errmsg (-1));
628     open_error:
629       elf_end (elf);
630       return -1;
631     }
632 
633   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
634     {
635       error (0, 0, gettext ("cannot get section header string table index"));
636       goto open_error;
637     }
638 
639   for (cnt = 0; cnt < shnums; ++cnt)
640     {
641       Elf_Scn *scn = elf_getscn (elf, cnt);
642       if (scn == NULL)
643 	{
644 	  error (0, 0, gettext ("cannot get section: %s"),
645 		 elf_errmsg (-1));
646 	  goto open_error;
647 	}
648 
649       GElf_Shdr shdr_mem;
650       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
651       if (unlikely (shdr == NULL))
652 	{
653 	  error (0, 0, gettext ("cannot get section header: %s"),
654 		 elf_errmsg (-1));
655 	  goto open_error;
656 	}
657 
658       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
659       if (sname == NULL)
660 	{
661 	  error (0, 0, gettext ("cannot get section name"));
662 	  goto open_error;
663 	}
664 
665       if (strcmp (sname, elf_input_section) == 0)
666 	{
667 	  Elf_Data *data = elf_rawdata (scn, NULL);
668 	  if (data == NULL)
669 	    {
670 	      error (0, 0, gettext ("cannot get %s content: %s"),
671 		     sname, elf_errmsg (-1));
672 	      goto open_error;
673 	    }
674 
675 	  /* Create (and immediately unlink) a temporary file to store
676 	     section data in to create a file descriptor for it.  */
677 	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
678 	  static const char suffix[] = "/readelfXXXXXX";
679 	  int tmplen = strlen (tmpdir) + sizeof (suffix);
680 	  char *tempname = alloca (tmplen);
681 	  sprintf (tempname, "%s%s", tmpdir, suffix);
682 
683 	  int sfd = mkstemp (tempname);
684 	  if (sfd == -1)
685 	    {
686 	      error (0, 0, gettext ("cannot create temp file '%s'"),
687 		     tempname);
688 	      goto open_error;
689 	    }
690 	  unlink (tempname);
691 
692 	  ssize_t size = data->d_size;
693 	  if (write_retry (sfd, data->d_buf, size) != size)
694 	    {
695 	      error (0, 0, gettext ("cannot write section data"));
696 	      goto open_error;
697 	    }
698 
699 	  if (elf_end (elf) != 0)
700 	    {
701 	      error (0, 0, gettext ("error while closing Elf descriptor: %s"),
702 		     elf_errmsg (-1));
703 	      return -1;
704 	    }
705 
706 	  if (lseek (sfd, 0, SEEK_SET) == -1)
707 	    {
708 	      error (0, 0, gettext ("error while rewinding file descriptor"));
709 	      return -1;
710 	    }
711 
712 	  return sfd;
713 	}
714     }
715 
716   /* Named section not found.  */
717   if (elf_end (elf) != 0)
718     error (0, 0, gettext ("error while closing Elf descriptor: %s"),
719 	   elf_errmsg (-1));
720   return -1;
721 }
722 
723 /* Check if the file is an archive, and if so dump its index.  */
724 static void
check_archive_index(int fd,const char * fname,bool only_one)725 check_archive_index (int fd, const char *fname, bool only_one)
726 {
727   /* Create an `Elf' descriptor.  */
728   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
729   if (elf == NULL)
730     error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
731 	   elf_errmsg (-1));
732   else
733     {
734       if (elf_kind (elf) == ELF_K_AR)
735 	{
736 	  if (!only_one)
737 	    printf ("\n%s:\n\n", fname);
738 	  dump_archive_index (elf, fname);
739 	}
740       else
741 	error (0, 0,
742 	       gettext ("'%s' is not an archive, cannot print archive index"),
743 	       fname);
744 
745       /* Now we can close the descriptor.  */
746       if (elf_end (elf) != 0)
747 	error (0, 0, gettext ("error while closing Elf descriptor: %s"),
748 	       elf_errmsg (-1));
749     }
750 }
751 
752 /* Trivial callback used for checking if we opened an archive.  */
753 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)754 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
755 	       void **userdata __attribute__ ((unused)),
756 	       const char *name __attribute__ ((unused)),
757 	       Dwarf_Addr base __attribute__ ((unused)),
758 	       void *arg)
759 {
760   if (*(bool *) arg)
761     return DWARF_CB_ABORT;
762   *(bool *) arg = true;
763   return DWARF_CB_OK;
764 }
765 
766 struct process_dwflmod_args
767 {
768   int fd;
769   bool only_one;
770 };
771 
772 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)773 process_dwflmod (Dwfl_Module *dwflmod,
774 		 void **userdata __attribute__ ((unused)),
775 		 const char *name __attribute__ ((unused)),
776 		 Dwarf_Addr base __attribute__ ((unused)),
777 		 void *arg)
778 {
779   const struct process_dwflmod_args *a = arg;
780 
781   /* Print the file name.  */
782   if (!a->only_one)
783     {
784       const char *fname;
785       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
786 
787       printf ("\n%s:\n\n", fname);
788     }
789 
790   process_elf_file (dwflmod, a->fd);
791 
792   return DWARF_CB_OK;
793 }
794 
795 /* Stub libdwfl callback, only the ELF handle already open is ever used.
796    Only used for finding the alternate debug file if the Dwarf comes from
797    the main file.  We are not interested in separate debuginfo.  */
798 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)799 find_no_debuginfo (Dwfl_Module *mod,
800 		   void **userdata,
801 		   const char *modname,
802 		   Dwarf_Addr base,
803 		   const char *file_name,
804 		   const char *debuglink_file,
805 		   GElf_Word debuglink_crc,
806 		   char **debuginfo_file_name)
807 {
808   Dwarf_Addr dwbias;
809   dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
810 
811   /* We are only interested if the Dwarf has been setup on the main
812      elf file but is only missing the alternate debug link.  If dwbias
813      hasn't even been setup, this is searching for separate debuginfo
814      for the main elf.  We don't care in that case.  */
815   if (dwbias == (Dwarf_Addr) -1)
816     return -1;
817 
818   return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
819 				       file_name, debuglink_file,
820 				       debuglink_crc, debuginfo_file_name);
821 }
822 
823 static Dwfl *
create_dwfl(int fd,const char * fname)824 create_dwfl (int fd, const char *fname)
825 {
826   /* Duplicate an fd for dwfl_report_offline to swallow.  */
827   int dwfl_fd = dup (fd);
828   if (unlikely (dwfl_fd < 0))
829     error (EXIT_FAILURE, errno, "dup");
830 
831   /* Use libdwfl in a trivial way to open the libdw handle for us.
832      This takes care of applying relocations to DWARF data in ET_REL files.  */
833   static const Dwfl_Callbacks callbacks =
834     {
835       .section_address = dwfl_offline_section_address,
836       .find_debuginfo = find_no_debuginfo
837     };
838   Dwfl *dwfl = dwfl_begin (&callbacks);
839   if (likely (dwfl != NULL))
840     /* Let 0 be the logical address of the file (or first in archive).  */
841     dwfl->offline_next_address = 0;
842   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
843     {
844       struct stat st;
845       if (fstat (dwfl_fd, &st) != 0)
846 	error (0, errno, gettext ("cannot stat input file"));
847       else if (unlikely (st.st_size == 0))
848 	error (0, 0, gettext ("input file is empty"));
849       else
850 	error (0, 0, gettext ("failed reading '%s': %s"),
851 	       fname, dwfl_errmsg (-1));
852       close (dwfl_fd);		/* Consumed on success, not on failure.  */
853       dwfl = NULL;
854     }
855   else
856     dwfl_report_end (dwfl, NULL, NULL);
857 
858   return dwfl;
859 }
860 
861 /* Process one input file.  */
862 static void
process_file(int fd,const char * fname,bool only_one)863 process_file (int fd, const char *fname, bool only_one)
864 {
865   if (print_archive_index)
866     check_archive_index (fd, fname, only_one);
867 
868   if (!any_control_option)
869     return;
870 
871   if (elf_input_section != NULL)
872     {
873       /* Replace fname and fd with section content. */
874       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
875       sprintf (fnname, "%s:%s", fname, elf_input_section);
876       fd = open_input_section (fd);
877       if (fd == -1)
878         {
879           error (0, 0, gettext ("No such section '%s' in '%s'"),
880 		 elf_input_section, fname);
881           return;
882         }
883       fname = fnname;
884     }
885 
886   Dwfl *dwfl = create_dwfl (fd, fname);
887   if (dwfl != NULL)
888     {
889       if (only_one)
890 	{
891 	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
892 	  bool seen = false;
893 	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
894 	}
895 
896       /* Process the one or more modules gleaned from this file.  */
897       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
898       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
899     }
900   /* Terrible hack for hooking unrelated skeleton/split compile units,
901      see __libdw_link_skel_split in print_debug.  */
902   if (! do_not_close_dwfl)
903     dwfl_end (dwfl);
904 
905   /* Need to close the replaced fd if we created it.  Caller takes
906      care of original.  */
907   if (elf_input_section != NULL)
908     close (fd);
909 }
910 
911 /* Check whether there are any compressed sections in the ELF file.  */
912 static bool
elf_contains_chdrs(Elf * elf)913 elf_contains_chdrs (Elf *elf)
914 {
915   Elf_Scn *scn = NULL;
916   while ((scn = elf_nextscn (elf, scn)) != NULL)
917     {
918       GElf_Shdr shdr_mem;
919       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
920       if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
921 	return true;
922     }
923   return false;
924 }
925 
926 /* Process one ELF file.  */
927 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)928 process_elf_file (Dwfl_Module *dwflmod, int fd)
929 {
930   GElf_Addr dwflbias;
931   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
932 
933   GElf_Ehdr ehdr_mem;
934   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
935 
936   if (ehdr == NULL)
937     {
938       error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
939       return;
940     }
941 
942   Ebl *ebl = ebl_openbackend (elf);
943   if (unlikely (ebl == NULL))
944     {
945     ebl_error:
946       error (0, errno, gettext ("cannot create EBL handle"));
947       return;
948     }
949 
950   /* Determine the number of sections.  */
951   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
952     error (EXIT_FAILURE, 0,
953 	   gettext ("cannot determine number of sections: %s"),
954 	   elf_errmsg (-1));
955 
956   /* Determine the number of phdrs.  */
957   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
958     error (EXIT_FAILURE, 0,
959 	   gettext ("cannot determine number of program headers: %s"),
960 	   elf_errmsg (-1));
961 
962   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
963      may have applied relocation to some sections.  If there are any
964      compressed sections, any pass (or libdw/libdwfl) might have
965      uncompressed them.  So we need to get a fresh Elf handle on the
966      file to display those.  */
967   bool print_unchanged = ((print_section_header
968 			   || print_relocations
969 			   || dump_data_sections != NULL
970 			   || print_notes)
971 			  && (ehdr->e_type == ET_REL
972 			      || elf_contains_chdrs (ebl->elf)));
973 
974   Elf *pure_elf = NULL;
975   Ebl *pure_ebl = ebl;
976   if (print_unchanged)
977     {
978       /* Read the file afresh.  */
979       off_t aroff = elf_getaroff (elf);
980       pure_elf = dwelf_elf_begin (fd);
981       if (aroff > 0)
982 	{
983 	  /* Archive member.  */
984 	  (void) elf_rand (pure_elf, aroff);
985 	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
986 	  elf_end (pure_elf);
987 	  pure_elf = armem;
988 	}
989       if (pure_elf == NULL)
990 	{
991 	  error (0, 0, gettext ("cannot read ELF: %s"), elf_errmsg (-1));
992 	  return;
993 	}
994       pure_ebl = ebl_openbackend (pure_elf);
995       if (pure_ebl == NULL)
996 	goto ebl_error;
997     }
998 
999   if (print_file_header)
1000     print_ehdr (ebl, ehdr);
1001   if (print_section_header)
1002     print_shdr (pure_ebl, ehdr);
1003   if (print_program_header)
1004     print_phdr (ebl, ehdr);
1005   if (print_section_groups)
1006     print_scngrp (ebl);
1007   if (print_dynamic_table)
1008     print_dynamic (ebl);
1009   if (print_relocations)
1010     print_relocs (pure_ebl, ehdr);
1011   if (print_histogram)
1012     handle_hash (ebl);
1013   if (print_symbol_table || print_dynsym_table)
1014     print_symtab (ebl, SHT_DYNSYM);
1015   if (print_version_info)
1016     print_verinfo (ebl);
1017   if (print_symbol_table)
1018     print_symtab (ebl, SHT_SYMTAB);
1019   if (print_arch)
1020     print_liblist (ebl);
1021   if (print_arch)
1022     print_attributes (ebl, ehdr);
1023   if (dump_data_sections != NULL)
1024     dump_data (pure_ebl);
1025   if (string_sections != NULL)
1026     dump_strings (ebl);
1027   if ((print_debug_sections | implicit_debug_sections) != 0)
1028     print_debug (dwflmod, ebl, ehdr);
1029   if (print_notes)
1030     handle_notes (pure_ebl, ehdr);
1031   if (print_string_sections)
1032     print_strings (ebl);
1033 
1034   ebl_closebackend (ebl);
1035 
1036   if (pure_ebl != ebl)
1037     {
1038       ebl_closebackend (pure_ebl);
1039       elf_end (pure_elf);
1040     }
1041 }
1042 
1043 
1044 /* Print file type.  */
1045 static void
print_file_type(unsigned short int e_type)1046 print_file_type (unsigned short int e_type)
1047 {
1048   if (likely (e_type <= ET_CORE))
1049     {
1050       static const char *const knowntypes[] =
1051       {
1052 	N_("NONE (None)"),
1053 	N_("REL (Relocatable file)"),
1054 	N_("EXEC (Executable file)"),
1055 	N_("DYN (Shared object file)"),
1056 	N_("CORE (Core file)")
1057       };
1058       puts (gettext (knowntypes[e_type]));
1059     }
1060   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1061     printf (gettext ("OS Specific: (%x)\n"),  e_type);
1062   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1063     printf (gettext ("Processor Specific: (%x)\n"),  e_type);
1064   else
1065     puts ("???");
1066 }
1067 
1068 
1069 /* Print ELF header.  */
1070 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1071 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1072 {
1073   fputs_unlocked (gettext ("ELF Header:\n  Magic:  "), stdout);
1074   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1075     printf (" %02hhx", ehdr->e_ident[cnt]);
1076 
1077   printf (gettext ("\n  Class:                             %s\n"),
1078 	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1079 	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1080 	  : "\?\?\?");
1081 
1082   printf (gettext ("  Data:                              %s\n"),
1083 	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1084 	  ? "2's complement, little endian"
1085 	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1086 	  ? "2's complement, big endian" : "\?\?\?");
1087 
1088   printf (gettext ("  Ident Version:                     %hhd %s\n"),
1089 	  ehdr->e_ident[EI_VERSION],
1090 	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
1091 	  : "(\?\?\?)");
1092 
1093   char buf[512];
1094   printf (gettext ("  OS/ABI:                            %s\n"),
1095 	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1096 
1097   printf (gettext ("  ABI Version:                       %hhd\n"),
1098 	  ehdr->e_ident[EI_ABIVERSION]);
1099 
1100   fputs_unlocked (gettext ("  Type:                              "), stdout);
1101   print_file_type (ehdr->e_type);
1102 
1103   const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1104   if (machine != NULL)
1105     printf (gettext ("  Machine:                           %s\n"), machine);
1106   else
1107     printf (gettext ("  Machine:                           <unknown>: 0x%x\n"),
1108 	    ehdr->e_machine);
1109 
1110   printf (gettext ("  Version:                           %d %s\n"),
1111 	  ehdr->e_version,
1112 	  ehdr->e_version  == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1113 
1114   printf (gettext ("  Entry point address:               %#" PRIx64 "\n"),
1115 	  ehdr->e_entry);
1116 
1117   printf (gettext ("  Start of program headers:          %" PRId64 " %s\n"),
1118 	  ehdr->e_phoff, gettext ("(bytes into file)"));
1119 
1120   printf (gettext ("  Start of section headers:          %" PRId64 " %s\n"),
1121 	  ehdr->e_shoff, gettext ("(bytes into file)"));
1122 
1123   printf (gettext ("  Flags:                             %s\n"),
1124 	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1125 
1126   printf (gettext ("  Size of this header:               %" PRId16 " %s\n"),
1127 	  ehdr->e_ehsize, gettext ("(bytes)"));
1128 
1129   printf (gettext ("  Size of program header entries:    %" PRId16 " %s\n"),
1130 	  ehdr->e_phentsize, gettext ("(bytes)"));
1131 
1132   printf (gettext ("  Number of program headers entries: %" PRId16),
1133 	  ehdr->e_phnum);
1134   if (ehdr->e_phnum == PN_XNUM)
1135     {
1136       GElf_Shdr shdr_mem;
1137       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1138       if (shdr != NULL)
1139 	printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1140 		(uint32_t) shdr->sh_info);
1141       else
1142 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
1143     }
1144   fputc_unlocked ('\n', stdout);
1145 
1146   printf (gettext ("  Size of section header entries:    %" PRId16 " %s\n"),
1147 	  ehdr->e_shentsize, gettext ("(bytes)"));
1148 
1149   printf (gettext ("  Number of section headers entries: %" PRId16),
1150 	  ehdr->e_shnum);
1151   if (ehdr->e_shnum == 0)
1152     {
1153       GElf_Shdr shdr_mem;
1154       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1155       if (shdr != NULL)
1156 	printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1157 		(uint32_t) shdr->sh_size);
1158       else
1159 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
1160     }
1161   fputc_unlocked ('\n', stdout);
1162 
1163   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1164     {
1165       GElf_Shdr shdr_mem;
1166       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1167       if (shdr != NULL)
1168 	/* We managed to get the zeroth section.  */
1169 	snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1170 		  (uint32_t) shdr->sh_link);
1171       else
1172 	{
1173 	  strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1174 	  buf[sizeof (buf) - 1] = '\0';
1175 	}
1176 
1177       printf (gettext ("  Section header string table index: XINDEX%s\n\n"),
1178 	      buf);
1179     }
1180   else
1181     printf (gettext ("  Section header string table index: %" PRId16 "\n\n"),
1182 	    ehdr->e_shstrndx);
1183 }
1184 
1185 
1186 static const char *
get_visibility_type(int value)1187 get_visibility_type (int value)
1188 {
1189   switch (value)
1190     {
1191     case STV_DEFAULT:
1192       return "DEFAULT";
1193     case STV_INTERNAL:
1194       return "INTERNAL";
1195     case STV_HIDDEN:
1196       return "HIDDEN";
1197     case STV_PROTECTED:
1198       return "PROTECTED";
1199     default:
1200       return "???";
1201     }
1202 }
1203 
1204 static const char *
elf_ch_type_name(unsigned int code)1205 elf_ch_type_name (unsigned int code)
1206 {
1207   if (code == 0)
1208     return "NONE";
1209 
1210   if (code == ELFCOMPRESS_ZLIB)
1211     return "ZLIB";
1212 
1213   return "UNKNOWN";
1214 }
1215 
1216 /* Print the section headers.  */
1217 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1218 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1219 {
1220   size_t cnt;
1221   size_t shstrndx;
1222 
1223   if (! print_file_header)
1224     {
1225       size_t sections;
1226       if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
1227 	error (EXIT_FAILURE, 0,
1228 	       gettext ("cannot get number of sections: %s"),
1229 	       elf_errmsg (-1));
1230 
1231       printf (gettext ("\
1232 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1233 \n"),
1234 	      sections, ehdr->e_shoff);
1235     }
1236 
1237   /* Get the section header string table index.  */
1238   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1239     error (EXIT_FAILURE, 0,
1240 	   gettext ("cannot get section header string table index: %s"),
1241 	   elf_errmsg (-1));
1242 
1243   puts (gettext ("Section Headers:"));
1244 
1245   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1246     puts (gettext ("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
1247   else
1248     puts (gettext ("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
1249 
1250   if (print_decompress)
1251     {
1252       if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1253 	puts (gettext ("     [Compression  Size   Al]"));
1254       else
1255 	puts (gettext ("     [Compression  Size     Al]"));
1256     }
1257 
1258   for (cnt = 0; cnt < shnum; ++cnt)
1259     {
1260       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1261 
1262       if (unlikely (scn == NULL))
1263 	error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1264 	       elf_errmsg (-1));
1265 
1266       /* Get the section header.  */
1267       GElf_Shdr shdr_mem;
1268       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1269       if (unlikely (shdr == NULL))
1270 	error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1271 	       elf_errmsg (-1));
1272 
1273       char flagbuf[20];
1274       char *cp = flagbuf;
1275       if (shdr->sh_flags & SHF_WRITE)
1276 	*cp++ = 'W';
1277       if (shdr->sh_flags & SHF_ALLOC)
1278 	*cp++ = 'A';
1279       if (shdr->sh_flags & SHF_EXECINSTR)
1280 	*cp++ = 'X';
1281       if (shdr->sh_flags & SHF_MERGE)
1282 	*cp++ = 'M';
1283       if (shdr->sh_flags & SHF_STRINGS)
1284 	*cp++ = 'S';
1285       if (shdr->sh_flags & SHF_INFO_LINK)
1286 	*cp++ = 'I';
1287       if (shdr->sh_flags & SHF_LINK_ORDER)
1288 	*cp++ = 'L';
1289       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1290 	*cp++ = 'N';
1291       if (shdr->sh_flags & SHF_GROUP)
1292 	*cp++ = 'G';
1293       if (shdr->sh_flags & SHF_TLS)
1294 	*cp++ = 'T';
1295       if (shdr->sh_flags & SHF_COMPRESSED)
1296 	*cp++ = 'C';
1297       if (shdr->sh_flags & SHF_ORDERED)
1298 	*cp++ = 'O';
1299       if (shdr->sh_flags & SHF_EXCLUDE)
1300 	*cp++ = 'E';
1301       *cp = '\0';
1302 
1303       const char *sname;
1304       char buf[128];
1305       sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1306       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1307 	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1308 	      " %2" PRId64 "\n",
1309 	      cnt, sname,
1310 	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1311 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1312 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1313 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1314 	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1315 	      shdr->sh_addralign);
1316 
1317       if (print_decompress)
1318 	{
1319 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1320 	    {
1321 	      GElf_Chdr chdr;
1322 	      if (gelf_getchdr (scn, &chdr) != NULL)
1323 		printf ("     [ELF %s (%" PRId32 ") %0*" PRIx64
1324 			" %2" PRId64 "]\n",
1325 			elf_ch_type_name (chdr.ch_type),
1326 			chdr.ch_type,
1327 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1328 			chdr.ch_size, chdr.ch_addralign);
1329 	      else
1330 		error (0, 0,
1331 		       gettext ("bad compression header for section %zd: %s"),
1332 		       elf_ndxscn (scn), elf_errmsg (-1));
1333 	    }
1334 	  else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1335 	    {
1336 	      ssize_t size;
1337 	      if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1338 		printf ("     [GNU ZLIB     %0*zx   ]\n",
1339 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1340 	      else
1341 		error (0, 0,
1342 		       gettext ("bad gnu compressed size for section %zd: %s"),
1343 		       elf_ndxscn (scn), elf_errmsg (-1));
1344 	    }
1345 	}
1346     }
1347 
1348   fputc_unlocked ('\n', stdout);
1349 }
1350 
1351 
1352 /* Print the program header.  */
1353 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1354 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1355 {
1356   if (phnum == 0)
1357     /* No program header, this is OK in relocatable objects.  */
1358     return;
1359 
1360   puts (gettext ("Program Headers:"));
1361   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1362     puts (gettext ("\
1363   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
1364   else
1365     puts (gettext ("\
1366   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
1367 
1368   /* Process all program headers.  */
1369   bool has_relro = false;
1370   GElf_Addr relro_from = 0;
1371   GElf_Addr relro_to = 0;
1372   for (size_t cnt = 0; cnt < phnum; ++cnt)
1373     {
1374       char buf[128];
1375       GElf_Phdr mem;
1376       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1377 
1378       /* If for some reason the header cannot be returned show this.  */
1379       if (unlikely (phdr == NULL))
1380 	{
1381 	  puts ("  ???");
1382 	  continue;
1383 	}
1384 
1385       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1386 	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1387 	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1388 	      phdr->p_offset,
1389 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1390 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1391 	      phdr->p_filesz,
1392 	      phdr->p_memsz,
1393 	      phdr->p_flags & PF_R ? 'R' : ' ',
1394 	      phdr->p_flags & PF_W ? 'W' : ' ',
1395 	      phdr->p_flags & PF_X ? 'E' : ' ',
1396 	      phdr->p_align);
1397 
1398       if (phdr->p_type == PT_INTERP)
1399 	{
1400 	  /* If we are sure the file offset is valid then we can show
1401 	     the user the name of the interpreter.  We check whether
1402 	     there is a section at the file offset.  Normally there
1403 	     would be a section called ".interp".  But in separate
1404 	     .debug files it is a NOBITS section (and so doesn't match
1405 	     with gelf_offscn).  Which probably means the offset is
1406 	     not valid another reason could be because the ELF file
1407 	     just doesn't contain any section headers, in that case
1408 	     just play it safe and don't display anything.  */
1409 
1410 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1411 	  GElf_Shdr shdr_mem;
1412 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1413 
1414 	  size_t maxsize;
1415 	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
1416 
1417 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1418 	      && filedata != NULL && phdr->p_offset < maxsize
1419 	      && phdr->p_filesz <= maxsize - phdr->p_offset
1420 	      && memchr (filedata + phdr->p_offset, '\0',
1421 			 phdr->p_filesz) != NULL)
1422 	    printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1423 		    filedata + phdr->p_offset);
1424 	}
1425       else if (phdr->p_type == PT_GNU_RELRO)
1426 	{
1427 	  has_relro = true;
1428 	  relro_from = phdr->p_vaddr;
1429 	  relro_to = relro_from + phdr->p_memsz;
1430 	}
1431     }
1432 
1433   size_t sections;
1434   if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
1435     error (EXIT_FAILURE, 0,
1436            gettext ("cannot get number of sections: %s"),
1437            elf_errmsg (-1));
1438 
1439   if (sections == 0)
1440     /* No sections in the file.  Punt.  */
1441     return;
1442 
1443   /* Get the section header string table index.  */
1444   size_t shstrndx;
1445   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1446     error (EXIT_FAILURE, 0,
1447 	   gettext ("cannot get section header string table index"));
1448 
1449   puts (gettext ("\n Section to Segment mapping:\n  Segment Sections..."));
1450 
1451   for (size_t cnt = 0; cnt < phnum; ++cnt)
1452     {
1453       /* Print the segment number.  */
1454       printf ("   %2.2zu     ", cnt);
1455 
1456       GElf_Phdr phdr_mem;
1457       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1458       /* This must not happen.  */
1459       if (unlikely (phdr == NULL))
1460 	error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1461 	       elf_errmsg (-1));
1462 
1463       /* Iterate over the sections.  */
1464       bool in_relro = false;
1465       bool in_ro = false;
1466       for (size_t inner = 1; inner < shnum; ++inner)
1467 	{
1468 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1469 	  /* This should not happen.  */
1470 	  if (unlikely (scn == NULL))
1471 	    error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1472 		   elf_errmsg (-1));
1473 
1474 	  /* Get the section header.  */
1475 	  GElf_Shdr shdr_mem;
1476 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1477 	  if (unlikely (shdr == NULL))
1478 	    error (EXIT_FAILURE, 0,
1479 		   gettext ("cannot get section header: %s"),
1480 		   elf_errmsg (-1));
1481 
1482 	  if (shdr->sh_size > 0
1483 	      /* Compare allocated sections by VMA, unallocated
1484 		 sections by file offset.  */
1485 	      && (shdr->sh_flags & SHF_ALLOC
1486 		  ? (shdr->sh_addr >= phdr->p_vaddr
1487 		     && (shdr->sh_addr + shdr->sh_size
1488 			 <= phdr->p_vaddr + phdr->p_memsz))
1489 		  : (shdr->sh_offset >= phdr->p_offset
1490 		     && (shdr->sh_offset + shdr->sh_size
1491 			 <= phdr->p_offset + phdr->p_filesz))))
1492 	    {
1493 	      if (has_relro && !in_relro
1494 		  && shdr->sh_addr >= relro_from
1495 		  && shdr->sh_addr + shdr->sh_size <= relro_to)
1496 		{
1497 		  fputs_unlocked (" [RELRO:", stdout);
1498 		  in_relro = true;
1499 		}
1500 	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1501 		{
1502 		  fputs_unlocked ("]", stdout);
1503 		  in_relro =  false;
1504 		}
1505 	      else if (has_relro && in_relro
1506 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1507 		fputs_unlocked ("] <RELRO:", stdout);
1508 	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1509 		{
1510 		  if (!in_ro)
1511 		    {
1512 		      fputs_unlocked (" [RO:", stdout);
1513 		      in_ro = true;
1514 		    }
1515 		}
1516 	      else
1517 		{
1518 		  /* Determine the segment this section is part of.  */
1519 		  size_t cnt2;
1520 		  GElf_Phdr phdr2_mem;
1521 		  GElf_Phdr *phdr2 = NULL;
1522 		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1523 		    {
1524 		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1525 
1526 		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1527 			  && shdr->sh_addr >= phdr2->p_vaddr
1528 			  && (shdr->sh_addr + shdr->sh_size
1529 			      <= phdr2->p_vaddr + phdr2->p_memsz))
1530 			break;
1531 		    }
1532 
1533 		  if (cnt2 < phnum)
1534 		    {
1535 		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1536 			{
1537 			  fputs_unlocked (" [RO:", stdout);
1538 			  in_ro = true;
1539 			}
1540 		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1541 			{
1542 			  fputs_unlocked ("]", stdout);
1543 			  in_ro = false;
1544 			}
1545 		    }
1546 		}
1547 
1548 	      printf (" %s",
1549 		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1550 
1551 	      /* Signal that this sectin is only partially covered.  */
1552 	      if (has_relro && in_relro
1553 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1554 		{
1555 		  fputs_unlocked (">", stdout);
1556 		  in_relro =  false;
1557 		}
1558 	    }
1559 	}
1560       if (in_relro || in_ro)
1561 	fputs_unlocked ("]", stdout);
1562 
1563       /* Finish the line.  */
1564       fputc_unlocked ('\n', stdout);
1565     }
1566 }
1567 
1568 
1569 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1570 section_name (Ebl *ebl, GElf_Shdr *shdr)
1571 {
1572   size_t shstrndx;
1573   if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1574     return "???";
1575   return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1576 }
1577 
1578 
1579 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1580 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1581 {
1582   /* Get the data of the section.  */
1583   Elf_Data *data = elf_getdata (scn, NULL);
1584 
1585   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1586   GElf_Shdr symshdr_mem;
1587   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1588   Elf_Data *symdata = elf_getdata (symscn, NULL);
1589 
1590   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1591       || symdata == NULL)
1592     return;
1593 
1594   /* Get the section header string table index.  */
1595   size_t shstrndx;
1596   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1597     error (EXIT_FAILURE, 0,
1598 	   gettext ("cannot get section header string table index"));
1599 
1600   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1601 
1602   GElf_Sym sym_mem;
1603   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1604 
1605   printf ((grpref[0] & GRP_COMDAT)
1606 	  ? ngettext ("\
1607 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1608 		      "\
1609 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1610 		      data->d_size / sizeof (Elf32_Word) - 1)
1611 	  : ngettext ("\
1612 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1613 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1614 		      data->d_size / sizeof (Elf32_Word) - 1),
1615 	  elf_ndxscn (scn),
1616 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1617 	  (sym == NULL ? NULL
1618 	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1619 	  ?: gettext ("<INVALID SYMBOL>"),
1620 	  data->d_size / sizeof (Elf32_Word) - 1);
1621 
1622   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1623     {
1624       GElf_Shdr grpshdr_mem;
1625       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1626 					 &grpshdr_mem);
1627 
1628       const char *str;
1629       printf ("  [%2u] %s\n",
1630 	      grpref[cnt],
1631 	      grpshdr != NULL
1632 	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1633 	      ? str : gettext ("<INVALID SECTION>"));
1634     }
1635 }
1636 
1637 
1638 static void
print_scngrp(Ebl * ebl)1639 print_scngrp (Ebl *ebl)
1640 {
1641   /* Find all relocation sections and handle them.  */
1642   Elf_Scn *scn = NULL;
1643 
1644   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1645     {
1646        /* Handle the section if it is a symbol table.  */
1647       GElf_Shdr shdr_mem;
1648       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1649 
1650       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1651 	{
1652 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1653 	    {
1654 	      if (elf_compress (scn, 0, 0) < 0)
1655 		printf ("WARNING: %s [%zd]\n",
1656 			gettext ("Couldn't uncompress section"),
1657 			elf_ndxscn (scn));
1658 	      shdr = gelf_getshdr (scn, &shdr_mem);
1659 	      if (unlikely (shdr == NULL))
1660 		error (EXIT_FAILURE, 0,
1661 		       gettext ("cannot get section [%zd] header: %s"),
1662 		       elf_ndxscn (scn),
1663 		       elf_errmsg (-1));
1664 	    }
1665 	  handle_scngrp (ebl, scn, shdr);
1666 	}
1667     }
1668 }
1669 
1670 
1671 static const struct flags
1672 {
1673   int mask;
1674   const char *str;
1675 } dt_flags[] =
1676   {
1677     { DF_ORIGIN, "ORIGIN" },
1678     { DF_SYMBOLIC, "SYMBOLIC" },
1679     { DF_TEXTREL, "TEXTREL" },
1680     { DF_BIND_NOW, "BIND_NOW" },
1681     { DF_STATIC_TLS, "STATIC_TLS" }
1682   };
1683 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1684 
1685 static const struct flags dt_flags_1[] =
1686   {
1687     { DF_1_NOW, "NOW" },
1688     { DF_1_GLOBAL, "GLOBAL" },
1689     { DF_1_GROUP, "GROUP" },
1690     { DF_1_NODELETE, "NODELETE" },
1691     { DF_1_LOADFLTR, "LOADFLTR" },
1692     { DF_1_INITFIRST, "INITFIRST" },
1693     { DF_1_NOOPEN, "NOOPEN" },
1694     { DF_1_ORIGIN, "ORIGIN" },
1695     { DF_1_DIRECT, "DIRECT" },
1696     { DF_1_TRANS, "TRANS" },
1697     { DF_1_INTERPOSE, "INTERPOSE" },
1698     { DF_1_NODEFLIB, "NODEFLIB" },
1699     { DF_1_NODUMP, "NODUMP" },
1700     { DF_1_CONFALT, "CONFALT" },
1701     { DF_1_ENDFILTEE, "ENDFILTEE" },
1702     { DF_1_DISPRELDNE, "DISPRELDNE" },
1703     { DF_1_DISPRELPND, "DISPRELPND" },
1704   };
1705 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1706 
1707 static const struct flags dt_feature_1[] =
1708   {
1709     { DTF_1_PARINIT, "PARINIT" },
1710     { DTF_1_CONFEXP, "CONFEXP" }
1711   };
1712 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1713 				  / sizeof (dt_feature_1[0]));
1714 
1715 static const struct flags dt_posflag_1[] =
1716   {
1717     { DF_P1_LAZYLOAD, "LAZYLOAD" },
1718     { DF_P1_GROUPPERM, "GROUPPERM" }
1719   };
1720 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1721 				  / sizeof (dt_posflag_1[0]));
1722 
1723 
1724 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1725 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1726 		int nflags)
1727 {
1728   bool first = true;
1729   int cnt;
1730 
1731   for (cnt = 0; cnt < nflags; ++cnt)
1732     if (d_val & flags[cnt].mask)
1733       {
1734 	if (!first)
1735 	  putchar_unlocked (' ');
1736 	fputs_unlocked (flags[cnt].str, stdout);
1737 	d_val &= ~flags[cnt].mask;
1738 	first = false;
1739       }
1740 
1741   if (d_val != 0)
1742     {
1743       if (!first)
1744 	putchar_unlocked (' ');
1745       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1746     }
1747 
1748   putchar_unlocked ('\n');
1749 }
1750 
1751 
1752 static void
print_dt_flags(int class,GElf_Xword d_val)1753 print_dt_flags (int class, GElf_Xword d_val)
1754 {
1755   print_flags (class, d_val, dt_flags, ndt_flags);
1756 }
1757 
1758 
1759 static void
print_dt_flags_1(int class,GElf_Xword d_val)1760 print_dt_flags_1 (int class, GElf_Xword d_val)
1761 {
1762   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1763 }
1764 
1765 
1766 static void
print_dt_feature_1(int class,GElf_Xword d_val)1767 print_dt_feature_1 (int class, GElf_Xword d_val)
1768 {
1769   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1770 }
1771 
1772 
1773 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1774 print_dt_posflag_1 (int class, GElf_Xword d_val)
1775 {
1776   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1777 }
1778 
1779 
1780 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1781 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1782 {
1783   int class = gelf_getclass (ebl->elf);
1784   GElf_Shdr glink_mem;
1785   GElf_Shdr *glink;
1786   Elf_Data *data;
1787   size_t cnt;
1788   size_t shstrndx;
1789   size_t sh_entsize;
1790 
1791   /* Get the data of the section.  */
1792   data = elf_getdata (scn, NULL);
1793   if (data == NULL)
1794     return;
1795 
1796   /* Get the section header string table index.  */
1797   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1798     error (EXIT_FAILURE, 0,
1799 	   gettext ("cannot get section header string table index"));
1800 
1801   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1802 
1803   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1804   if (glink == NULL)
1805     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1806 	   elf_ndxscn (scn));
1807 
1808   printf (ngettext ("\
1809 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1810 		    "\
1811 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1812 		    shdr->sh_size / sh_entsize),
1813 	  (unsigned long int) (shdr->sh_size / sh_entsize),
1814 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1815 	  shdr->sh_offset,
1816 	  (int) shdr->sh_link,
1817 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1818   fputs_unlocked (gettext ("  Type              Value\n"), stdout);
1819 
1820   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1821     {
1822       GElf_Dyn dynmem;
1823       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1824       if (dyn == NULL)
1825 	break;
1826 
1827       char buf[64];
1828       printf ("  %-17s ",
1829 	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1830 
1831       switch (dyn->d_tag)
1832 	{
1833 	case DT_NULL:
1834 	case DT_DEBUG:
1835 	case DT_BIND_NOW:
1836 	case DT_TEXTREL:
1837 	  /* No further output.  */
1838 	  fputc_unlocked ('\n', stdout);
1839 	  break;
1840 
1841 	case DT_NEEDED:
1842 	  printf (gettext ("Shared library: [%s]\n"),
1843 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1844 	  break;
1845 
1846 	case DT_SONAME:
1847 	  printf (gettext ("Library soname: [%s]\n"),
1848 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1849 	  break;
1850 
1851 	case DT_RPATH:
1852 	  printf (gettext ("Library rpath: [%s]\n"),
1853 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1854 	  break;
1855 
1856 	case DT_RUNPATH:
1857 	  printf (gettext ("Library runpath: [%s]\n"),
1858 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1859 	  break;
1860 
1861 	case DT_PLTRELSZ:
1862 	case DT_RELASZ:
1863 	case DT_STRSZ:
1864 	case DT_RELSZ:
1865 	case DT_RELAENT:
1866 	case DT_SYMENT:
1867 	case DT_RELENT:
1868 	case DT_PLTPADSZ:
1869 	case DT_MOVEENT:
1870 	case DT_MOVESZ:
1871 	case DT_INIT_ARRAYSZ:
1872 	case DT_FINI_ARRAYSZ:
1873 	case DT_SYMINSZ:
1874 	case DT_SYMINENT:
1875 	case DT_GNU_CONFLICTSZ:
1876 	case DT_GNU_LIBLISTSZ:
1877 	  printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1878 	  break;
1879 
1880 	case DT_VERDEFNUM:
1881 	case DT_VERNEEDNUM:
1882 	case DT_RELACOUNT:
1883 	case DT_RELCOUNT:
1884 	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
1885 	  break;
1886 
1887 	case DT_PLTREL:;
1888 	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1889 						      NULL, 0);
1890 	  puts (tagname ?: "???");
1891 	  break;
1892 
1893 	case DT_FLAGS:
1894 	  print_dt_flags (class, dyn->d_un.d_val);
1895 	  break;
1896 
1897 	case DT_FLAGS_1:
1898 	  print_dt_flags_1 (class, dyn->d_un.d_val);
1899 	  break;
1900 
1901 	case DT_FEATURE_1:
1902 	  print_dt_feature_1 (class, dyn->d_un.d_val);
1903 	  break;
1904 
1905 	case DT_POSFLAG_1:
1906 	  print_dt_posflag_1 (class, dyn->d_un.d_val);
1907 	  break;
1908 
1909 	default:
1910 	  printf ("%#0*" PRIx64 "\n",
1911 		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1912 	  break;
1913 	}
1914     }
1915 }
1916 
1917 
1918 /* Print the dynamic segment.  */
1919 static void
print_dynamic(Ebl * ebl)1920 print_dynamic (Ebl *ebl)
1921 {
1922   for (size_t i = 0; i < phnum; ++i)
1923     {
1924       GElf_Phdr phdr_mem;
1925       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1926 
1927       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1928 	{
1929 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1930 	  GElf_Shdr shdr_mem;
1931 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1932 	  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1933 	    handle_dynamic (ebl, scn, shdr);
1934 	  break;
1935 	}
1936     }
1937 }
1938 
1939 
1940 /* Print relocations.  */
1941 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1942 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1943 {
1944   /* Find all relocation sections and handle them.  */
1945   Elf_Scn *scn = NULL;
1946 
1947   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1948     {
1949        /* Handle the section if it is a symbol table.  */
1950       GElf_Shdr shdr_mem;
1951       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1952 
1953       if (likely (shdr != NULL))
1954 	{
1955 	  if (shdr->sh_type == SHT_REL)
1956 	    handle_relocs_rel (ebl, ehdr, scn, shdr);
1957 	  else if (shdr->sh_type == SHT_RELA)
1958 	    handle_relocs_rela (ebl, ehdr, scn, shdr);
1959 	}
1960     }
1961 }
1962 
1963 
1964 /* Handle a relocation section.  */
1965 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1966 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1967 {
1968   int class = gelf_getclass (ebl->elf);
1969   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1970   int nentries = shdr->sh_size / sh_entsize;
1971 
1972   /* Get the data of the section.  */
1973   Elf_Data *data = elf_getdata (scn, NULL);
1974   if (data == NULL)
1975     return;
1976 
1977   /* Get the symbol table information.  */
1978   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1979   GElf_Shdr symshdr_mem;
1980   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1981   Elf_Data *symdata = elf_getdata (symscn, NULL);
1982 
1983   /* Get the section header of the section the relocations are for.  */
1984   GElf_Shdr destshdr_mem;
1985   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1986 				      &destshdr_mem);
1987 
1988   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1989     {
1990       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1991 	      shdr->sh_offset);
1992       return;
1993     }
1994 
1995   /* Search for the optional extended section index table.  */
1996   Elf_Data *xndxdata = NULL;
1997   int xndxscnidx = elf_scnshndx (scn);
1998   if (unlikely (xndxscnidx > 0))
1999     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2000 
2001   /* Get the section header string table index.  */
2002   size_t shstrndx;
2003   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2004     error (EXIT_FAILURE, 0,
2005 	   gettext ("cannot get section header string table index"));
2006 
2007   if (shdr->sh_info != 0)
2008     printf (ngettext ("\
2009 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2010 		    "\
2011 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2012 		      nentries),
2013 	    elf_ndxscn (scn),
2014 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2015 	    (unsigned int) shdr->sh_info,
2016 	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2017 	    shdr->sh_offset,
2018 	    nentries);
2019   else
2020     /* The .rel.dyn section does not refer to a specific section but
2021        instead of section index zero.  Do not try to print a section
2022        name.  */
2023     printf (ngettext ("\
2024 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2025 		    "\
2026 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2027 		      nentries),
2028 	    (unsigned int) elf_ndxscn (scn),
2029 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2030 	    shdr->sh_offset,
2031 	    nentries);
2032   fputs_unlocked (class == ELFCLASS32
2033 		  ? gettext ("\
2034   Offset      Type                 Value       Name\n")
2035 		  : gettext ("\
2036   Offset              Type                 Value               Name\n"),
2037 	 stdout);
2038 
2039   int is_statically_linked = 0;
2040   for (int cnt = 0; cnt < nentries; ++cnt)
2041     {
2042       GElf_Rel relmem;
2043       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2044       if (likely (rel != NULL))
2045 	{
2046 	  char buf[128];
2047 	  GElf_Sym symmem;
2048 	  Elf32_Word xndx;
2049 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2050 					    GELF_R_SYM (rel->r_info),
2051 					    &symmem, &xndx);
2052 	  if (unlikely (sym == NULL))
2053 	    {
2054 	      /* As a special case we have to handle relocations in static
2055 		 executables.  This only happens for IRELATIVE relocations
2056 		 (so far).  There is no symbol table.  */
2057 	      if (is_statically_linked == 0)
2058 		{
2059 		  /* Find the program header and look for a PT_INTERP entry. */
2060 		  is_statically_linked = -1;
2061 		  if (ehdr->e_type == ET_EXEC)
2062 		    {
2063 		      is_statically_linked = 1;
2064 
2065 		      for (size_t inner = 0; inner < phnum; ++inner)
2066 			{
2067 			  GElf_Phdr phdr_mem;
2068 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2069 							  &phdr_mem);
2070 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2071 			    {
2072 			      is_statically_linked = -1;
2073 			      break;
2074 			    }
2075 			}
2076 		    }
2077 		}
2078 
2079 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2080 		printf ("\
2081   %#0*" PRIx64 "  %-20s %*s  %s\n",
2082 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2083 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2084 			/* Avoid the leading R_ which isn't carrying any
2085 			   information.  */
2086 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2087 					       buf, sizeof (buf)) + 2
2088 			: gettext ("<INVALID RELOC>"),
2089 			class == ELFCLASS32 ? 10 : 18, "",
2090 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2091 	      else
2092 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
2093 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2094 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2095 			/* Avoid the leading R_ which isn't carrying any
2096 			   information.  */
2097 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2098 					       buf, sizeof (buf)) + 2
2099 			: gettext ("<INVALID RELOC>"),
2100 			gettext ("INVALID SYMBOL"),
2101 			(long int) GELF_R_SYM (rel->r_info));
2102 	    }
2103 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2104 	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2105 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2106 		    likely (ebl_reloc_type_check (ebl,
2107 						  GELF_R_TYPE (rel->r_info)))
2108 		    /* Avoid the leading R_ which isn't carrying any
2109 		       information.  */
2110 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2111 					   buf, sizeof (buf)) + 2
2112 		    : gettext ("<INVALID RELOC>"),
2113 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2114 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2115 	  else
2116 	    {
2117 	      /* This is a relocation against a STT_SECTION symbol.  */
2118 	      GElf_Shdr secshdr_mem;
2119 	      GElf_Shdr *secshdr;
2120 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2121 						  sym->st_shndx == SHN_XINDEX
2122 						  ? xndx : sym->st_shndx),
2123 				      &secshdr_mem);
2124 
2125 	      if (unlikely (secshdr == NULL))
2126 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
2127 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2128 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2129 			/* Avoid the leading R_ which isn't carrying any
2130 			   information.  */
2131 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2132 					       buf, sizeof (buf)) + 2
2133 			: gettext ("<INVALID RELOC>"),
2134 			gettext ("INVALID SECTION"),
2135 			(long int) (sym->st_shndx == SHN_XINDEX
2136 				    ? xndx : sym->st_shndx));
2137 	      else
2138 		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2139 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2140 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2141 			/* Avoid the leading R_ which isn't carrying any
2142 			   information.  */
2143 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2144 					       buf, sizeof (buf)) + 2
2145 			: gettext ("<INVALID RELOC>"),
2146 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2147 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2148 	    }
2149 	}
2150     }
2151 }
2152 
2153 
2154 /* Handle a relocation section.  */
2155 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2156 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2157 {
2158   int class = gelf_getclass (ebl->elf);
2159   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2160   int nentries = shdr->sh_size / sh_entsize;
2161 
2162   /* Get the data of the section.  */
2163   Elf_Data *data = elf_getdata (scn, NULL);
2164   if (data == NULL)
2165     return;
2166 
2167   /* Get the symbol table information.  */
2168   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2169   GElf_Shdr symshdr_mem;
2170   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2171   Elf_Data *symdata = elf_getdata (symscn, NULL);
2172 
2173   /* Get the section header of the section the relocations are for.  */
2174   GElf_Shdr destshdr_mem;
2175   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2176 				      &destshdr_mem);
2177 
2178   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2179     {
2180       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2181 	      shdr->sh_offset);
2182       return;
2183     }
2184 
2185   /* Search for the optional extended section index table.  */
2186   Elf_Data *xndxdata = NULL;
2187   int xndxscnidx = elf_scnshndx (scn);
2188   if (unlikely (xndxscnidx > 0))
2189     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2190 
2191   /* Get the section header string table index.  */
2192   size_t shstrndx;
2193   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2194     error (EXIT_FAILURE, 0,
2195 	   gettext ("cannot get section header string table index"));
2196 
2197   if (shdr->sh_info != 0)
2198     printf (ngettext ("\
2199 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2200 		    "\
2201 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2202 		    nentries),
2203 	  elf_ndxscn (scn),
2204 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2205 	  (unsigned int) shdr->sh_info,
2206 	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2207 	  shdr->sh_offset,
2208 	  nentries);
2209   else
2210     /* The .rela.dyn section does not refer to a specific section but
2211        instead of section index zero.  Do not try to print a section
2212        name.  */
2213     printf (ngettext ("\
2214 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2215 		    "\
2216 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2217 		      nentries),
2218 	    (unsigned int) elf_ndxscn (scn),
2219 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2220 	    shdr->sh_offset,
2221 	    nentries);
2222   fputs_unlocked (class == ELFCLASS32
2223 		  ? gettext ("\
2224   Offset      Type            Value       Addend Name\n")
2225 		  : gettext ("\
2226   Offset              Type            Value               Addend Name\n"),
2227 		  stdout);
2228 
2229   int is_statically_linked = 0;
2230   for (int cnt = 0; cnt < nentries; ++cnt)
2231     {
2232       GElf_Rela relmem;
2233       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2234       if (likely (rel != NULL))
2235 	{
2236 	  char buf[64];
2237 	  GElf_Sym symmem;
2238 	  Elf32_Word xndx;
2239 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2240 					    GELF_R_SYM (rel->r_info),
2241 					    &symmem, &xndx);
2242 
2243 	  if (unlikely (sym == NULL))
2244 	    {
2245 	      /* As a special case we have to handle relocations in static
2246 		 executables.  This only happens for IRELATIVE relocations
2247 		 (so far).  There is no symbol table.  */
2248 	      if (is_statically_linked == 0)
2249 		{
2250 		  /* Find the program header and look for a PT_INTERP entry. */
2251 		  is_statically_linked = -1;
2252 		  if (ehdr->e_type == ET_EXEC)
2253 		    {
2254 		      is_statically_linked = 1;
2255 
2256 		      for (size_t inner = 0; inner < phnum; ++inner)
2257 			{
2258 			  GElf_Phdr phdr_mem;
2259 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2260 							  &phdr_mem);
2261 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2262 			    {
2263 			      is_statically_linked = -1;
2264 			      break;
2265 			    }
2266 			}
2267 		    }
2268 		}
2269 
2270 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2271 		printf ("\
2272   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
2273 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2274 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2275 			/* Avoid the leading R_ which isn't carrying any
2276 			   information.  */
2277 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2278 					       buf, sizeof (buf)) + 2
2279 			: gettext ("<INVALID RELOC>"),
2280 			class == ELFCLASS32 ? 10 : 18, "",
2281 			rel->r_addend,
2282 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2283 	      else
2284 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2285 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2286 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2287 			/* Avoid the leading R_ which isn't carrying any
2288 			   information.  */
2289 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2290 					       buf, sizeof (buf)) + 2
2291 			: gettext ("<INVALID RELOC>"),
2292 			gettext ("INVALID SYMBOL"),
2293 			(long int) GELF_R_SYM (rel->r_info));
2294 	    }
2295 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2296 	    printf ("\
2297   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2298 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2299 		    likely (ebl_reloc_type_check (ebl,
2300 						  GELF_R_TYPE (rel->r_info)))
2301 		    /* Avoid the leading R_ which isn't carrying any
2302 		       information.  */
2303 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2304 					   buf, sizeof (buf)) + 2
2305 		    : gettext ("<INVALID RELOC>"),
2306 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2307 		    rel->r_addend,
2308 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2309 	  else
2310 	    {
2311 	      /* This is a relocation against a STT_SECTION symbol.  */
2312 	      GElf_Shdr secshdr_mem;
2313 	      GElf_Shdr *secshdr;
2314 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2315 						  sym->st_shndx == SHN_XINDEX
2316 						  ? xndx : sym->st_shndx),
2317 				      &secshdr_mem);
2318 
2319 	      if (unlikely (secshdr == NULL))
2320 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2321 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2322 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2323 			/* Avoid the leading R_ which isn't carrying any
2324 			   information.  */
2325 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2326 					       buf, sizeof (buf)) + 2
2327 			: gettext ("<INVALID RELOC>"),
2328 			gettext ("INVALID SECTION"),
2329 			(long int) (sym->st_shndx == SHN_XINDEX
2330 				    ? xndx : sym->st_shndx));
2331 	      else
2332 		printf ("\
2333   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2334 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2335 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2336 			/* Avoid the leading R_ which isn't carrying any
2337 			   information.  */
2338 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2339 					       buf, sizeof (buf)) + 2
2340 			: gettext ("<INVALID RELOC>"),
2341 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2342 			rel->r_addend,
2343 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2344 	    }
2345 	}
2346     }
2347 }
2348 
2349 
2350 /* Print the program header.  */
2351 static void
print_symtab(Ebl * ebl,int type)2352 print_symtab (Ebl *ebl, int type)
2353 {
2354   /* Find the symbol table(s).  For this we have to search through the
2355      section table.  */
2356   Elf_Scn *scn = NULL;
2357 
2358   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2359     {
2360       /* Handle the section if it is a symbol table.  */
2361       GElf_Shdr shdr_mem;
2362       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2363 
2364       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2365 	{
2366 	  if (symbol_table_section != NULL)
2367 	    {
2368 	      /* Get the section header string table index.  */
2369 	      size_t shstrndx;
2370 	      const char *sname;
2371 	      if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2372 		error (EXIT_FAILURE, 0,
2373 		       gettext ("cannot get section header string table index"));
2374 	      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2375 	      if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2376 		continue;
2377 	    }
2378 
2379 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2380 	    {
2381 	      if (elf_compress (scn, 0, 0) < 0)
2382 		printf ("WARNING: %s [%zd]\n",
2383 			gettext ("Couldn't uncompress section"),
2384 			elf_ndxscn (scn));
2385 	      shdr = gelf_getshdr (scn, &shdr_mem);
2386 	      if (unlikely (shdr == NULL))
2387 		error (EXIT_FAILURE, 0,
2388 		       gettext ("cannot get section [%zd] header: %s"),
2389 		       elf_ndxscn (scn), elf_errmsg (-1));
2390 	    }
2391 	  handle_symtab (ebl, scn, shdr);
2392 	}
2393     }
2394 }
2395 
2396 
2397 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2398 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2399 {
2400   Elf_Data *versym_data = NULL;
2401   Elf_Data *verneed_data = NULL;
2402   Elf_Data *verdef_data = NULL;
2403   Elf_Data *xndx_data = NULL;
2404   int class = gelf_getclass (ebl->elf);
2405   Elf32_Word verneed_stridx = 0;
2406   Elf32_Word verdef_stridx = 0;
2407 
2408   /* Get the data of the section.  */
2409   Elf_Data *data = elf_getdata (scn, NULL);
2410   if (data == NULL)
2411     return;
2412 
2413   /* Find out whether we have other sections we might need.  */
2414   Elf_Scn *runscn = NULL;
2415   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2416     {
2417       GElf_Shdr runshdr_mem;
2418       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2419 
2420       if (likely (runshdr != NULL))
2421 	{
2422 	  if (runshdr->sh_type == SHT_GNU_versym
2423 	      && runshdr->sh_link == elf_ndxscn (scn))
2424 	    /* Bingo, found the version information.  Now get the data.  */
2425 	    versym_data = elf_getdata (runscn, NULL);
2426 	  else if (runshdr->sh_type == SHT_GNU_verneed)
2427 	    {
2428 	      /* This is the information about the needed versions.  */
2429 	      verneed_data = elf_getdata (runscn, NULL);
2430 	      verneed_stridx = runshdr->sh_link;
2431 	    }
2432 	  else if (runshdr->sh_type == SHT_GNU_verdef)
2433 	    {
2434 	      /* This is the information about the defined versions.  */
2435 	      verdef_data = elf_getdata (runscn, NULL);
2436 	      verdef_stridx = runshdr->sh_link;
2437 	    }
2438 	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2439 	      && runshdr->sh_link == elf_ndxscn (scn))
2440 	    /* Extended section index.  */
2441 	    xndx_data = elf_getdata (runscn, NULL);
2442 	}
2443     }
2444 
2445   /* Get the section header string table index.  */
2446   size_t shstrndx;
2447   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2448     error (EXIT_FAILURE, 0,
2449 	   gettext ("cannot get section header string table index"));
2450 
2451   GElf_Shdr glink_mem;
2452   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2453 				   &glink_mem);
2454   if (glink == NULL)
2455     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2456 	   elf_ndxscn (scn));
2457 
2458   /* Now we can compute the number of entries in the section.  */
2459   unsigned int nsyms = data->d_size / (class == ELFCLASS32
2460 				       ? sizeof (Elf32_Sym)
2461 				       : sizeof (Elf64_Sym));
2462 
2463   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2464 		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
2465 		    nsyms),
2466 	  (unsigned int) elf_ndxscn (scn),
2467 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2468   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
2469 		    " %lu local symbols  String table: [%2u] '%s'\n",
2470 		    shdr->sh_info),
2471 	  (unsigned long int) shdr->sh_info,
2472 	  (unsigned int) shdr->sh_link,
2473 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2474 
2475   fputs_unlocked (class == ELFCLASS32
2476 		  ? gettext ("\
2477   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
2478 		  : gettext ("\
2479   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
2480 		  stdout);
2481 
2482   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2483     {
2484       char typebuf[64];
2485       char bindbuf[64];
2486       char scnbuf[64];
2487       Elf32_Word xndx;
2488       GElf_Sym sym_mem;
2489       GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2490 
2491       if (unlikely (sym == NULL))
2492 	continue;
2493 
2494       /* Determine the real section index.  */
2495       if (likely (sym->st_shndx != SHN_XINDEX))
2496 	xndx = sym->st_shndx;
2497 
2498       printf (gettext ("\
2499 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2500 	      cnt,
2501 	      class == ELFCLASS32 ? 8 : 16,
2502 	      sym->st_value,
2503 	      sym->st_size,
2504 	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2505 				    typebuf, sizeof (typebuf)),
2506 	      ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2507 				       bindbuf, sizeof (bindbuf)),
2508 	      get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2509 	      ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2510 				sizeof (scnbuf), NULL, shnum),
2511 	      elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2512 
2513       if (versym_data != NULL)
2514 	{
2515 	  /* Get the version information.  */
2516 	  GElf_Versym versym_mem;
2517 	  GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2518 
2519 	  if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2520 	    {
2521 	      bool is_nobits = false;
2522 	      bool check_def = xndx != SHN_UNDEF;
2523 
2524 	      if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2525 		{
2526 		  GElf_Shdr symshdr_mem;
2527 		  GElf_Shdr *symshdr =
2528 		    gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2529 
2530 		  is_nobits = (symshdr != NULL
2531 			       && symshdr->sh_type == SHT_NOBITS);
2532 		}
2533 
2534 	      if (is_nobits || ! check_def)
2535 		{
2536 		  /* We must test both.  */
2537 		  GElf_Vernaux vernaux_mem;
2538 		  GElf_Vernaux *vernaux = NULL;
2539 		  size_t vn_offset = 0;
2540 
2541 		  GElf_Verneed verneed_mem;
2542 		  GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2543 							   &verneed_mem);
2544 		  while (verneed != NULL)
2545 		    {
2546 		      size_t vna_offset = vn_offset;
2547 
2548 		      vernaux = gelf_getvernaux (verneed_data,
2549 						 vna_offset += verneed->vn_aux,
2550 						 &vernaux_mem);
2551 		      while (vernaux != NULL
2552 			     && vernaux->vna_other != *versym
2553 			     && vernaux->vna_next != 0)
2554 			{
2555 			  /* Update the offset.  */
2556 			  vna_offset += vernaux->vna_next;
2557 
2558 			  vernaux = (vernaux->vna_next == 0
2559 				     ? NULL
2560 				     : gelf_getvernaux (verneed_data,
2561 							vna_offset,
2562 							&vernaux_mem));
2563 			}
2564 
2565 		      /* Check whether we found the version.  */
2566 		      if (vernaux != NULL && vernaux->vna_other == *versym)
2567 			/* Found it.  */
2568 			break;
2569 
2570 		      vn_offset += verneed->vn_next;
2571 		      verneed = (verneed->vn_next == 0
2572 				 ? NULL
2573 				 : gelf_getverneed (verneed_data, vn_offset,
2574 						    &verneed_mem));
2575 		    }
2576 
2577 		  if (vernaux != NULL && vernaux->vna_other == *versym)
2578 		    {
2579 		      printf ("@%s (%u)",
2580 			      elf_strptr (ebl->elf, verneed_stridx,
2581 					  vernaux->vna_name),
2582 			      (unsigned int) vernaux->vna_other);
2583 		      check_def = 0;
2584 		    }
2585 		  else if (unlikely (! is_nobits))
2586 		    error (0, 0, gettext ("bad dynamic symbol"));
2587 		  else
2588 		    check_def = 1;
2589 		}
2590 
2591 	      if (check_def && *versym != 0x8001)
2592 		{
2593 		  /* We must test both.  */
2594 		  size_t vd_offset = 0;
2595 
2596 		  GElf_Verdef verdef_mem;
2597 		  GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2598 							&verdef_mem);
2599 		  while (verdef != NULL)
2600 		    {
2601 		      if (verdef->vd_ndx == (*versym & 0x7fff))
2602 			/* Found the definition.  */
2603 			break;
2604 
2605 		      vd_offset += verdef->vd_next;
2606 		      verdef = (verdef->vd_next == 0
2607 				? NULL
2608 				: gelf_getverdef (verdef_data, vd_offset,
2609 						  &verdef_mem));
2610 		    }
2611 
2612 		  if (verdef != NULL)
2613 		    {
2614 		      GElf_Verdaux verdaux_mem;
2615 		      GElf_Verdaux *verdaux
2616 			= gelf_getverdaux (verdef_data,
2617 					   vd_offset + verdef->vd_aux,
2618 					   &verdaux_mem);
2619 
2620 		      if (verdaux != NULL)
2621 			printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2622 				elf_strptr (ebl->elf, verdef_stridx,
2623 					    verdaux->vda_name));
2624 		    }
2625 		}
2626 	    }
2627 	}
2628 
2629       putchar_unlocked ('\n');
2630     }
2631 }
2632 
2633 
2634 /* Print version information.  */
2635 static void
print_verinfo(Ebl * ebl)2636 print_verinfo (Ebl *ebl)
2637 {
2638   /* Find the version information sections.  For this we have to
2639      search through the section table.  */
2640   Elf_Scn *scn = NULL;
2641 
2642   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2643     {
2644       /* Handle the section if it is part of the versioning handling.  */
2645       GElf_Shdr shdr_mem;
2646       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2647 
2648       if (likely (shdr != NULL))
2649 	{
2650 	  if (shdr->sh_type == SHT_GNU_verneed)
2651 	    handle_verneed (ebl, scn, shdr);
2652 	  else if (shdr->sh_type == SHT_GNU_verdef)
2653 	    handle_verdef (ebl, scn, shdr);
2654 	  else if (shdr->sh_type == SHT_GNU_versym)
2655 	    handle_versym (ebl, scn, shdr);
2656 	}
2657     }
2658 }
2659 
2660 
2661 static const char *
get_ver_flags(unsigned int flags)2662 get_ver_flags (unsigned int flags)
2663 {
2664   static char buf[32];
2665   char *endp;
2666 
2667   if (flags == 0)
2668     return gettext ("none");
2669 
2670   if (flags & VER_FLG_BASE)
2671     endp = stpcpy (buf, "BASE ");
2672   else
2673     endp = buf;
2674 
2675   if (flags & VER_FLG_WEAK)
2676     {
2677       if (endp != buf)
2678 	endp = stpcpy (endp, "| ");
2679 
2680       endp = stpcpy (endp, "WEAK ");
2681     }
2682 
2683   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2684     {
2685       strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2686       buf[sizeof (buf) - 1] = '\0';
2687     }
2688 
2689   return buf;
2690 }
2691 
2692 
2693 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2694 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2695 {
2696   int class = gelf_getclass (ebl->elf);
2697 
2698   /* Get the data of the section.  */
2699   Elf_Data *data = elf_getdata (scn, NULL);
2700   if (data == NULL)
2701     return;
2702 
2703   /* Get the section header string table index.  */
2704   size_t shstrndx;
2705   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2706     error (EXIT_FAILURE, 0,
2707 	   gettext ("cannot get section header string table index"));
2708 
2709   GElf_Shdr glink_mem;
2710   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2711 				   &glink_mem);
2712   if (glink == NULL)
2713     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2714 	   elf_ndxscn (scn));
2715 
2716   printf (ngettext ("\
2717 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2718 		    "\
2719 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2720 		    shdr->sh_info),
2721 	  (unsigned int) elf_ndxscn (scn),
2722 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2723 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2724 	  shdr->sh_offset,
2725 	  (unsigned int) shdr->sh_link,
2726 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2727 
2728   unsigned int offset = 0;
2729   for (int cnt = shdr->sh_info; --cnt >= 0; )
2730     {
2731       /* Get the data at the next offset.  */
2732       GElf_Verneed needmem;
2733       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2734       if (unlikely (need == NULL))
2735 	break;
2736 
2737       printf (gettext ("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
2738 	      offset, (unsigned short int) need->vn_version,
2739 	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2740 	      (unsigned short int) need->vn_cnt);
2741 
2742       unsigned int auxoffset = offset + need->vn_aux;
2743       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2744 	{
2745 	  GElf_Vernaux auxmem;
2746 	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2747 	  if (unlikely (aux == NULL))
2748 	    break;
2749 
2750 	  printf (gettext ("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
2751 		  auxoffset,
2752 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2753 		  get_ver_flags (aux->vna_flags),
2754 		  (unsigned short int) aux->vna_other);
2755 
2756 	  if (aux->vna_next == 0)
2757 	    break;
2758 
2759 	  auxoffset += aux->vna_next;
2760 	}
2761 
2762       /* Find the next offset.  */
2763       if (need->vn_next == 0)
2764 	break;
2765 
2766       offset += need->vn_next;
2767     }
2768 }
2769 
2770 
2771 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2772 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2773 {
2774   /* Get the data of the section.  */
2775   Elf_Data *data = elf_getdata (scn, NULL);
2776   if (data == NULL)
2777     return;
2778 
2779   /* Get the section header string table index.  */
2780   size_t shstrndx;
2781   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2782     error (EXIT_FAILURE, 0,
2783 	   gettext ("cannot get section header string table index"));
2784 
2785   GElf_Shdr glink_mem;
2786   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2787 				   &glink_mem);
2788   if (glink == NULL)
2789     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2790 	   elf_ndxscn (scn));
2791 
2792   int class = gelf_getclass (ebl->elf);
2793   printf (ngettext ("\
2794 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2795 		    "\
2796 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2797 		    shdr->sh_info),
2798 	  (unsigned int) elf_ndxscn (scn),
2799 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2800 	  shdr->sh_info,
2801 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2802 	  shdr->sh_offset,
2803 	  (unsigned int) shdr->sh_link,
2804 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2805 
2806   unsigned int offset = 0;
2807   for (int cnt = shdr->sh_info; --cnt >= 0; )
2808     {
2809       /* Get the data at the next offset.  */
2810       GElf_Verdef defmem;
2811       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2812       if (unlikely (def == NULL))
2813 	break;
2814 
2815       unsigned int auxoffset = offset + def->vd_aux;
2816       GElf_Verdaux auxmem;
2817       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2818       if (unlikely (aux == NULL))
2819 	break;
2820 
2821       printf (gettext ("\
2822   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
2823 	      offset, def->vd_version,
2824 	      get_ver_flags (def->vd_flags),
2825 	      def->vd_ndx,
2826 	      def->vd_cnt,
2827 	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2828 
2829       auxoffset += aux->vda_next;
2830       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2831 	{
2832 	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
2833 	  if (unlikely (aux == NULL))
2834 	    break;
2835 
2836 	  printf (gettext ("  %#06x: Parent %d: %s\n"),
2837 		  auxoffset, cnt2,
2838 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2839 
2840 	  if (aux->vda_next == 0)
2841 	    break;
2842 
2843 	  auxoffset += aux->vda_next;
2844 	}
2845 
2846       /* Find the next offset.  */
2847       if (def->vd_next == 0)
2848 	break;
2849       offset += def->vd_next;
2850     }
2851 }
2852 
2853 
2854 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2855 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2856 {
2857   int class = gelf_getclass (ebl->elf);
2858   const char **vername;
2859   const char **filename;
2860 
2861   /* Get the data of the section.  */
2862   Elf_Data *data = elf_getdata (scn, NULL);
2863   if (data == NULL)
2864     return;
2865 
2866   /* Get the section header string table index.  */
2867   size_t shstrndx;
2868   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2869     error (EXIT_FAILURE, 0,
2870 	   gettext ("cannot get section header string table index"));
2871 
2872   /* We have to find the version definition section and extract the
2873      version names.  */
2874   Elf_Scn *defscn = NULL;
2875   Elf_Scn *needscn = NULL;
2876 
2877   Elf_Scn *verscn = NULL;
2878   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2879     {
2880       GElf_Shdr vershdr_mem;
2881       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2882 
2883       if (likely (vershdr != NULL))
2884 	{
2885 	  if (vershdr->sh_type == SHT_GNU_verdef)
2886 	    defscn = verscn;
2887 	  else if (vershdr->sh_type == SHT_GNU_verneed)
2888 	    needscn = verscn;
2889 	}
2890     }
2891 
2892   size_t nvername;
2893   if (defscn != NULL || needscn != NULL)
2894     {
2895       /* We have a version information (better should have).  Now get
2896 	 the version names.  First find the maximum version number.  */
2897       nvername = 0;
2898       if (defscn != NULL)
2899 	{
2900 	  /* Run through the version definitions and find the highest
2901 	     index.  */
2902 	  unsigned int offset = 0;
2903 	  Elf_Data *defdata;
2904 	  GElf_Shdr defshdrmem;
2905 	  GElf_Shdr *defshdr;
2906 
2907 	  defdata = elf_getdata (defscn, NULL);
2908 	  if (unlikely (defdata == NULL))
2909 	    return;
2910 
2911 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
2912 	  if (unlikely (defshdr == NULL))
2913 	    return;
2914 
2915 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2916 	    {
2917 	      GElf_Verdef defmem;
2918 	      GElf_Verdef *def;
2919 
2920 	      /* Get the data at the next offset.  */
2921 	      def = gelf_getverdef (defdata, offset, &defmem);
2922 	      if (unlikely (def == NULL))
2923 		break;
2924 
2925 	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2926 
2927 	      if (def->vd_next == 0)
2928 		break;
2929 	      offset += def->vd_next;
2930 	    }
2931 	}
2932       if (needscn != NULL)
2933 	{
2934 	  unsigned int offset = 0;
2935 	  Elf_Data *needdata;
2936 	  GElf_Shdr needshdrmem;
2937 	  GElf_Shdr *needshdr;
2938 
2939 	  needdata = elf_getdata (needscn, NULL);
2940 	  if (unlikely (needdata == NULL))
2941 	    return;
2942 
2943 	  needshdr = gelf_getshdr (needscn, &needshdrmem);
2944 	  if (unlikely (needshdr == NULL))
2945 	    return;
2946 
2947 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2948 	    {
2949 	      GElf_Verneed needmem;
2950 	      GElf_Verneed *need;
2951 	      unsigned int auxoffset;
2952 	      int cnt2;
2953 
2954 	      /* Get the data at the next offset.  */
2955 	      need = gelf_getverneed (needdata, offset, &needmem);
2956 	      if (unlikely (need == NULL))
2957 		break;
2958 
2959 	      /* Run through the auxiliary entries.  */
2960 	      auxoffset = offset + need->vn_aux;
2961 	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2962 		{
2963 		  GElf_Vernaux auxmem;
2964 		  GElf_Vernaux *aux;
2965 
2966 		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2967 		  if (unlikely (aux == NULL))
2968 		    break;
2969 
2970 		  nvername = MAX (nvername,
2971 				  (size_t) (aux->vna_other & 0x7fff));
2972 
2973 		  if (aux->vna_next == 0)
2974 		    break;
2975 		  auxoffset += aux->vna_next;
2976 		}
2977 
2978 	      if (need->vn_next == 0)
2979 		break;
2980 	      offset += need->vn_next;
2981 	    }
2982 	}
2983 
2984       /* This is the number of versions we know about.  */
2985       ++nvername;
2986 
2987       /* Allocate the array.  */
2988       vername = (const char **) alloca (nvername * sizeof (const char *));
2989       memset(vername, 0, nvername * sizeof (const char *));
2990       filename = (const char **) alloca (nvername * sizeof (const char *));
2991       memset(filename, 0, nvername * sizeof (const char *));
2992 
2993       /* Run through the data structures again and collect the strings.  */
2994       if (defscn != NULL)
2995 	{
2996 	  /* Run through the version definitions and find the highest
2997 	     index.  */
2998 	  unsigned int offset = 0;
2999 	  Elf_Data *defdata;
3000 	  GElf_Shdr defshdrmem;
3001 	  GElf_Shdr *defshdr;
3002 
3003 	  defdata = elf_getdata (defscn, NULL);
3004 	  if (unlikely (defdata == NULL))
3005 	    return;
3006 
3007 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
3008 	  if (unlikely (defshdr == NULL))
3009 	    return;
3010 
3011 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3012 	    {
3013 
3014 	      /* Get the data at the next offset.  */
3015 	      GElf_Verdef defmem;
3016 	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3017 	      if (unlikely (def == NULL))
3018 		break;
3019 
3020 	      GElf_Verdaux auxmem;
3021 	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
3022 						   offset + def->vd_aux,
3023 						   &auxmem);
3024 	      if (unlikely (aux == NULL))
3025 		break;
3026 
3027 	      vername[def->vd_ndx & 0x7fff]
3028 		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3029 	      filename[def->vd_ndx & 0x7fff] = NULL;
3030 
3031 	      if (def->vd_next == 0)
3032 		break;
3033 	      offset += def->vd_next;
3034 	    }
3035 	}
3036       if (needscn != NULL)
3037 	{
3038 	  unsigned int offset = 0;
3039 
3040 	  Elf_Data *needdata = elf_getdata (needscn, NULL);
3041 	  GElf_Shdr needshdrmem;
3042 	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3043 	  if (unlikely (needdata == NULL || needshdr == NULL))
3044 	    return;
3045 
3046 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3047 	    {
3048 	      /* Get the data at the next offset.  */
3049 	      GElf_Verneed needmem;
3050 	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
3051 						    &needmem);
3052 	      if (unlikely (need == NULL))
3053 		break;
3054 
3055 	      /* Run through the auxiliary entries.  */
3056 	      unsigned int auxoffset = offset + need->vn_aux;
3057 	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3058 		{
3059 		  GElf_Vernaux auxmem;
3060 		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3061 						       &auxmem);
3062 		  if (unlikely (aux == NULL))
3063 		    break;
3064 
3065 		  vername[aux->vna_other & 0x7fff]
3066 		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3067 		  filename[aux->vna_other & 0x7fff]
3068 		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3069 
3070 		  if (aux->vna_next == 0)
3071 		    break;
3072 		  auxoffset += aux->vna_next;
3073 		}
3074 
3075 	      if (need->vn_next == 0)
3076 		break;
3077 	      offset += need->vn_next;
3078 	    }
3079 	}
3080     }
3081   else
3082     {
3083       vername = NULL;
3084       nvername = 1;
3085       filename = NULL;
3086     }
3087 
3088   GElf_Shdr glink_mem;
3089   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3090 				   &glink_mem);
3091   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3092   if (glink == NULL)
3093     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
3094 	   elf_ndxscn (scn));
3095 
3096   /* Print the header.  */
3097   printf (ngettext ("\
3098 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
3099 		    "\
3100 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
3101 		    shdr->sh_size / sh_entsize),
3102 	  (unsigned int) elf_ndxscn (scn),
3103 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3104 	  (int) (shdr->sh_size / sh_entsize),
3105 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3106 	  shdr->sh_offset,
3107 	  (unsigned int) shdr->sh_link,
3108 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3109 
3110   /* Now we can finally look at the actual contents of this section.  */
3111   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3112     {
3113       if (cnt % 2 == 0)
3114 	printf ("\n %4d:", cnt);
3115 
3116       GElf_Versym symmem;
3117       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3118       if (sym == NULL)
3119 	break;
3120 
3121       switch (*sym)
3122 	{
3123 	  ssize_t n;
3124 	case 0:
3125 	  fputs_unlocked (gettext ("   0 *local*                     "),
3126 			  stdout);
3127 	  break;
3128 
3129 	case 1:
3130 	  fputs_unlocked (gettext ("   1 *global*                    "),
3131 			  stdout);
3132 	  break;
3133 
3134 	default:
3135 	  n = printf ("%4d%c%s",
3136 		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3137 		      (vername != NULL
3138 		       && (unsigned int) (*sym & 0x7fff) < nvername)
3139 		      ? vername[*sym & 0x7fff] : "???");
3140 	  if ((unsigned int) (*sym & 0x7fff) < nvername
3141 	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
3142 	    n += printf ("(%s)", filename[*sym & 0x7fff]);
3143 	  printf ("%*s", MAX (0, 33 - (int) n), " ");
3144 	  break;
3145 	}
3146     }
3147   putchar_unlocked ('\n');
3148 }
3149 
3150 
3151 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)3152 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3153 		 uint_fast32_t maxlength, Elf32_Word nbucket,
3154 		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3155 {
3156   uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3157 
3158   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3159     ++counts[lengths[cnt]];
3160 
3161   GElf_Shdr glink_mem;
3162   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3163 					       shdr->sh_link),
3164 				   &glink_mem);
3165   if (glink == NULL)
3166     {
3167       error (0, 0, gettext ("invalid sh_link value in section %zu"),
3168 	     elf_ndxscn (scn));
3169       return;
3170     }
3171 
3172   printf (ngettext ("\
3173 \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",
3174 		    "\
3175 \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",
3176 		    nbucket),
3177 	  (unsigned int) elf_ndxscn (scn),
3178 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3179 	  (int) nbucket,
3180 	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3181 	  shdr->sh_addr,
3182 	  shdr->sh_offset,
3183 	  (unsigned int) shdr->sh_link,
3184 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3185 
3186   if (extrastr != NULL)
3187     fputs (extrastr, stdout);
3188 
3189   if (likely (nbucket > 0))
3190     {
3191       uint64_t success = 0;
3192 
3193       /* xgettext:no-c-format */
3194       fputs_unlocked (gettext ("\
3195  Length  Number  % of total  Coverage\n"), stdout);
3196       printf (gettext ("      0  %6" PRIu32 "      %5.1f%%\n"),
3197 	      counts[0], (counts[0] * 100.0) / nbucket);
3198 
3199       uint64_t nzero_counts = 0;
3200       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3201 	{
3202 	  nzero_counts += counts[cnt] * cnt;
3203 	  printf (gettext ("\
3204 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
3205 		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3206 		  (nzero_counts * 100.0) / nsyms);
3207 	}
3208 
3209       Elf32_Word acc = 0;
3210       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3211 	{
3212 	  acc += cnt;
3213 	  success += counts[cnt] * acc;
3214 	}
3215 
3216       printf (gettext ("\
3217  Average number of tests:   successful lookup: %f\n\
3218 			  unsuccessful lookup: %f\n"),
3219 	      (double) success / (double) nzero_counts,
3220 	      (double) nzero_counts / (double) nbucket);
3221     }
3222 
3223   free (counts);
3224 }
3225 
3226 
3227 /* This function handles the traditional System V-style hash table format.  */
3228 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3229 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3230 {
3231   Elf_Data *data = elf_getdata (scn, NULL);
3232   if (unlikely (data == NULL))
3233     {
3234       error (0, 0, gettext ("cannot get data for section %d: %s"),
3235 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3236       return;
3237     }
3238 
3239   if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3240     {
3241     invalid_data:
3242       error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3243 	     (int) elf_ndxscn (scn));
3244       return;
3245     }
3246 
3247   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3248   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3249 
3250   uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3251   if (used_buf > data->d_size)
3252     goto invalid_data;
3253 
3254   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3255   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3256 
3257   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3258 
3259   uint_fast32_t maxlength = 0;
3260   uint_fast32_t nsyms = 0;
3261   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3262     {
3263       Elf32_Word inner = bucket[cnt];
3264       Elf32_Word chain_len = 0;
3265       while (inner > 0 && inner < nchain)
3266 	{
3267 	  ++nsyms;
3268 	  ++chain_len;
3269 	  if (chain_len > nchain)
3270 	    {
3271 	      error (0, 0, gettext ("invalid chain in sysv.hash section %d"),
3272 		     (int) elf_ndxscn (scn));
3273 	      free (lengths);
3274 	      return;
3275 	    }
3276 	  if (maxlength < ++lengths[cnt])
3277 	    ++maxlength;
3278 
3279 	  inner = chain[inner];
3280 	}
3281     }
3282 
3283   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3284 		   lengths, NULL);
3285 
3286   free (lengths);
3287 }
3288 
3289 
3290 /* This function handles the incorrect, System V-style hash table
3291    format some 64-bit architectures use.  */
3292 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3293 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3294 {
3295   Elf_Data *data = elf_getdata (scn, NULL);
3296   if (unlikely (data == NULL))
3297     {
3298       error (0, 0, gettext ("cannot get data for section %d: %s"),
3299 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3300       return;
3301     }
3302 
3303   if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3304     {
3305     invalid_data:
3306       error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3307 	     (int) elf_ndxscn (scn));
3308       return;
3309     }
3310 
3311   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3312   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3313 
3314   uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3315   if (maxwords < 2
3316       || maxwords - 2 < nbucket
3317       || maxwords - 2 - nbucket < nchain)
3318     goto invalid_data;
3319 
3320   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3321   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3322 
3323   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3324 
3325   uint_fast32_t maxlength = 0;
3326   uint_fast32_t nsyms = 0;
3327   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3328     {
3329       Elf64_Xword inner = bucket[cnt];
3330       Elf64_Xword chain_len = 0;
3331       while (inner > 0 && inner < nchain)
3332 	{
3333 	  ++nsyms;
3334 	  ++chain_len;
3335 	  if (chain_len > nchain)
3336 	    {
3337 	      error (0, 0, gettext ("invalid chain in sysv.hash64 section %d"),
3338 		     (int) elf_ndxscn (scn));
3339 	      free (lengths);
3340 	      return;
3341 	    }
3342 	  if (maxlength < ++lengths[cnt])
3343 	    ++maxlength;
3344 
3345 	  inner = chain[inner];
3346 	}
3347     }
3348 
3349   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3350 		   lengths, NULL);
3351 
3352   free (lengths);
3353 }
3354 
3355 
3356 /* This function handles the GNU-style hash table format.  */
3357 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3358 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3359 {
3360   uint32_t *lengths = NULL;
3361   Elf_Data *data = elf_getdata (scn, NULL);
3362   if (unlikely (data == NULL))
3363     {
3364       error (0, 0, gettext ("cannot get data for section %d: %s"),
3365 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3366       return;
3367     }
3368 
3369   if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3370     {
3371     invalid_data:
3372       free (lengths);
3373       error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3374 	     (int) elf_ndxscn (scn));
3375       return;
3376     }
3377 
3378   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3379   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3380 
3381   /* Next comes the size of the bitmap.  It's measured in words for
3382      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
3383      64 bit archs.  There is always a bloom filter present, so zero is
3384      an invalid value.  */
3385   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3386   if (gelf_getclass (ebl->elf) == ELFCLASS64)
3387     bitmask_words *= 2;
3388 
3389   if (bitmask_words == 0)
3390     goto invalid_data;
3391 
3392   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3393 
3394   /* Is there still room for the sym chain?
3395      Use uint64_t calculation to prevent 32bit overlow.  */
3396   uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3397   uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3398   if (used_buf > data->d_size)
3399     goto invalid_data;
3400 
3401   lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3402 
3403   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3404   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3405   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3406 						    + nbucket];
3407 
3408   /* Compute distribution of chain lengths.  */
3409   uint_fast32_t maxlength = 0;
3410   uint_fast32_t nsyms = 0;
3411   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3412     if (bucket[cnt] != 0)
3413       {
3414 	Elf32_Word inner = bucket[cnt] - symbias;
3415 	do
3416 	  {
3417 	    ++nsyms;
3418 	    if (maxlength < ++lengths[cnt])
3419 	      ++maxlength;
3420 	    if (inner >= max_nsyms)
3421 	      goto invalid_data;
3422 	  }
3423 	while ((chain[inner++] & 1) == 0);
3424       }
3425 
3426   /* Count bits in bitmask.  */
3427   uint_fast32_t nbits = 0;
3428   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3429     {
3430       uint_fast32_t word = bitmask[cnt];
3431 
3432       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3433       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3434       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3435       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3436       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3437     }
3438 
3439   char *str;
3440   if (unlikely (asprintf (&str, gettext ("\
3441  Symbol Bias: %u\n\
3442  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
3443 			  (unsigned int) symbias,
3444 			  bitmask_words * sizeof (Elf32_Word),
3445 			  ((nbits * 100 + 50)
3446 			   / (uint_fast32_t) (bitmask_words
3447 					      * sizeof (Elf32_Word) * 8)),
3448 			  (unsigned int) shift) == -1))
3449     error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3450 
3451   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3452 		   lengths, str);
3453 
3454   free (str);
3455   free (lengths);
3456 }
3457 
3458 
3459 /* Find the symbol table(s).  For this we have to search through the
3460    section table.  */
3461 static void
handle_hash(Ebl * ebl)3462 handle_hash (Ebl *ebl)
3463 {
3464   /* Get the section header string table index.  */
3465   size_t shstrndx;
3466   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3467     error (EXIT_FAILURE, 0,
3468 	   gettext ("cannot get section header string table index"));
3469 
3470   Elf_Scn *scn = NULL;
3471   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3472     {
3473       /* Handle the section if it is a symbol table.  */
3474       GElf_Shdr shdr_mem;
3475       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3476 
3477       if (likely (shdr != NULL))
3478 	{
3479 	  if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3480 	      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3481 	    {
3482 	      if (elf_compress (scn, 0, 0) < 0)
3483 		printf ("WARNING: %s [%zd]\n",
3484 			gettext ("Couldn't uncompress section"),
3485 			elf_ndxscn (scn));
3486 	      shdr = gelf_getshdr (scn, &shdr_mem);
3487 	      if (unlikely (shdr == NULL))
3488 		error (EXIT_FAILURE, 0,
3489 		       gettext ("cannot get section [%zd] header: %s"),
3490 		       elf_ndxscn (scn), elf_errmsg (-1));
3491 	    }
3492 
3493 	  if (shdr->sh_type == SHT_HASH)
3494 	    {
3495 	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3496 		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3497 	      else
3498 		handle_sysv_hash (ebl, scn, shdr, shstrndx);
3499 	    }
3500 	  else if (shdr->sh_type == SHT_GNU_HASH)
3501 	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
3502 	}
3503     }
3504 }
3505 
3506 
3507 static void
print_liblist(Ebl * ebl)3508 print_liblist (Ebl *ebl)
3509 {
3510   /* Find the library list sections.  For this we have to search
3511      through the section table.  */
3512   Elf_Scn *scn = NULL;
3513 
3514   /* Get the section header string table index.  */
3515   size_t shstrndx;
3516   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3517     error (EXIT_FAILURE, 0,
3518 	   gettext ("cannot get section header string table index"));
3519 
3520   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3521     {
3522       GElf_Shdr shdr_mem;
3523       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3524 
3525       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3526 	{
3527 	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3528 	  int nentries = shdr->sh_size / sh_entsize;
3529 	  printf (ngettext ("\
3530 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3531 			    "\
3532 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3533 			    nentries),
3534 		  elf_ndxscn (scn),
3535 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3536 		  shdr->sh_offset,
3537 		  nentries);
3538 
3539 	  Elf_Data *data = elf_getdata (scn, NULL);
3540 	  if (data == NULL)
3541 	    return;
3542 
3543 	  puts (gettext ("\
3544        Library                       Time Stamp          Checksum Version Flags"));
3545 
3546 	  for (int cnt = 0; cnt < nentries; ++cnt)
3547 	    {
3548 	      GElf_Lib lib_mem;
3549 	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3550 	      if (unlikely (lib == NULL))
3551 		continue;
3552 
3553 	      time_t t = (time_t) lib->l_time_stamp;
3554 	      struct tm *tm = gmtime (&t);
3555 	      if (unlikely (tm == NULL))
3556 		continue;
3557 
3558 	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3559 		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3560 		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3561 		      tm->tm_hour, tm->tm_min, tm->tm_sec,
3562 		      (unsigned int) lib->l_checksum,
3563 		      (unsigned int) lib->l_version,
3564 		      (unsigned int) lib->l_flags);
3565 	    }
3566 	}
3567     }
3568 }
3569 
3570 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3571 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3572 {
3573   /* Find the object attributes sections.  For this we have to search
3574      through the section table.  */
3575   Elf_Scn *scn = NULL;
3576 
3577   /* Get the section header string table index.  */
3578   size_t shstrndx;
3579   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3580     error (EXIT_FAILURE, 0,
3581 	   gettext ("cannot get section header string table index"));
3582 
3583   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3584     {
3585       GElf_Shdr shdr_mem;
3586       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3587 
3588       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3589 			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3590 			       || ehdr->e_machine != EM_ARM)
3591 			   && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
3592 			       || ehdr->e_machine != EM_CSKY)))
3593 	continue;
3594 
3595       printf (gettext ("\
3596 \nObject attributes section [%2zu] '%s' of %" PRIu64
3597 		       " bytes at offset %#0" PRIx64 ":\n"),
3598 	      elf_ndxscn (scn),
3599 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3600 	      shdr->sh_size, shdr->sh_offset);
3601 
3602       Elf_Data *data = elf_rawdata (scn, NULL);
3603       if (unlikely (data == NULL || data->d_size == 0))
3604 	return;
3605 
3606       const unsigned char *p = data->d_buf;
3607 
3608       /* There is only one 'version', A.  */
3609       if (unlikely (*p++ != 'A'))
3610 	return;
3611 
3612       fputs_unlocked (gettext ("  Owner          Size\n"), stdout);
3613 
3614       inline size_t left (void)
3615       {
3616 	return (const unsigned char *) data->d_buf + data->d_size - p;
3617       }
3618 
3619       /* Loop over the sections.  */
3620       while (left () >= 4)
3621 	{
3622 	  /* Section length.  */
3623 	  uint32_t len;
3624 	  memcpy (&len, p, sizeof len);
3625 
3626 	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3627 	    CONVERT (len);
3628 
3629 	  if (unlikely (len > left ()))
3630 	    break;
3631 
3632 	  /* Section vendor name.  */
3633 	  const unsigned char *name = p + sizeof len;
3634 	  p += len;
3635 
3636 	  unsigned const char *q = memchr (name, '\0', len);
3637 	  if (unlikely (q == NULL))
3638 	    break;
3639 	  ++q;
3640 
3641 	  printf (gettext ("  %-13s  %4" PRIu32 "\n"), name, len);
3642 
3643 	  bool gnu_vendor = (q - name == sizeof "gnu"
3644 			     && !memcmp (name, "gnu", sizeof "gnu"));
3645 
3646 	  /* Loop over subsections.  */
3647 	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3648 	      || gnu_vendor)
3649 	    while (q < p)
3650 	      {
3651 		const unsigned char *const sub = q;
3652 
3653 		unsigned int subsection_tag;
3654 		get_uleb128 (subsection_tag, q, p);
3655 		if (unlikely (q >= p))
3656 		  break;
3657 
3658 		uint32_t subsection_len;
3659 		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3660 		  break;
3661 
3662 		memcpy (&subsection_len, q, sizeof subsection_len);
3663 
3664 		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3665 		  CONVERT (subsection_len);
3666 
3667 		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
3668 		if (unlikely (subsection_len == 0
3669 			      || subsection_len >= (uint32_t) PTRDIFF_MAX
3670 			      || p - sub < (ptrdiff_t) subsection_len))
3671 		  break;
3672 
3673 		const unsigned char *r = q + sizeof subsection_len;
3674 		q = sub + subsection_len;
3675 
3676 		switch (subsection_tag)
3677 		  {
3678 		  default:
3679 		    /* Unknown subsection, print and skip.  */
3680 		    printf (gettext ("    %-4u %12" PRIu32 "\n"),
3681 			    subsection_tag, subsection_len);
3682 		    break;
3683 
3684 		  case 1:	/* Tag_File */
3685 		    printf (gettext ("    File: %11" PRIu32 "\n"),
3686 			    subsection_len);
3687 
3688 		    while (r < q)
3689 		      {
3690 			unsigned int tag;
3691 			get_uleb128 (tag, r, q);
3692 			if (unlikely (r >= q))
3693 			  break;
3694 
3695 			/* GNU style tags have either a uleb128 value,
3696 			   when lowest bit is not set, or a string
3697 			   when the lowest bit is set.
3698 			   "compatibility" (32) is special.  It has
3699 			   both a string and a uleb128 value.  For
3700 			   non-gnu we assume 6 till 31 only take ints.
3701 			   XXX see arm backend, do we need a separate
3702 			   hook?  */
3703 			uint64_t value = 0;
3704 			const char *string = NULL;
3705 			if (tag == 32 || (tag & 1) == 0
3706 			    || (! gnu_vendor && (tag > 5 && tag < 32)))
3707 			  {
3708 			    get_uleb128 (value, r, q);
3709 			    if (r > q)
3710 			      break;
3711 			  }
3712 			if (tag == 32
3713 			    || ((tag & 1) != 0
3714 				&& (gnu_vendor
3715 				    || (! gnu_vendor && tag > 32)))
3716 			    || (! gnu_vendor && tag > 3 && tag < 6))
3717 			  {
3718 			    string = (const char *) r;
3719 			    r = memchr (r, '\0', q - r);
3720 			    if (r == NULL)
3721 			      break;
3722 			    ++r;
3723 			  }
3724 
3725 			const char *tag_name = NULL;
3726 			const char *value_name = NULL;
3727 			ebl_check_object_attribute (ebl, (const char *) name,
3728 						    tag, value,
3729 						    &tag_name, &value_name);
3730 
3731 			if (tag_name != NULL)
3732 			  {
3733 			    if (tag == 32)
3734 			      printf (gettext ("      %s: %" PRId64 ", %s\n"),
3735 				      tag_name, value, string);
3736 			    else if (string == NULL && value_name == NULL)
3737 			      printf (gettext ("      %s: %" PRId64 "\n"),
3738 				      tag_name, value);
3739 			    else
3740 			      printf (gettext ("      %s: %s\n"),
3741 				      tag_name, string ?: value_name);
3742 			  }
3743 			else
3744 			  {
3745 			    /* For "gnu" vendor 32 "compatibility" has
3746 			       already been handled above.  */
3747 			    assert (tag != 32
3748 				    || strcmp ((const char *) name, "gnu"));
3749 			    if (string == NULL)
3750 			      printf (gettext ("      %u: %" PRId64 "\n"),
3751 				      tag, value);
3752 			    else
3753 			      printf (gettext ("      %u: %s\n"),
3754 				      tag, string);
3755 			  }
3756 		      }
3757 		  }
3758 	      }
3759 	}
3760     }
3761 }
3762 
3763 
3764 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3765 print_dwarf_addr (Dwfl_Module *dwflmod,
3766 		  int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3767 {
3768   /* See if there is a name we can give for this address.  */
3769   GElf_Sym sym;
3770   GElf_Off off = 0;
3771   const char *name = (print_address_names && ! print_unresolved_addresses)
3772     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3773     : NULL;
3774 
3775   const char *scn;
3776   if (print_unresolved_addresses)
3777     {
3778       address = raw;
3779       scn = NULL;
3780     }
3781   else
3782     {
3783       /* Relativize the address.  */
3784       int n = dwfl_module_relocations (dwflmod);
3785       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3786 
3787       /* In an ET_REL file there is a section name to refer to.  */
3788       scn = (i < 0 ? NULL
3789 	     : dwfl_module_relocation_info (dwflmod, i, NULL));
3790     }
3791 
3792   if ((name != NULL
3793        ? (off != 0
3794 	  ? (scn != NULL
3795 	     ? (address_size == 0
3796 		? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3797 			  scn, address, name, off)
3798 		: printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3799 			  scn, 2 + address_size * 2, address,
3800 			  name, off))
3801 	     : (address_size == 0
3802 		? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3803 			  address, name, off)
3804 		: printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3805 			  2 + address_size * 2, address,
3806 			  name, off)))
3807 	  : (scn != NULL
3808 	     ? (address_size == 0
3809 		? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3810 		: printf ("%s+%#0*" PRIx64 " <%s>",
3811 			   scn, 2 + address_size * 2, address, name))
3812 	     : (address_size == 0
3813 		? printf ("%#" PRIx64 " <%s>", address, name)
3814 		: printf ("%#0*" PRIx64 " <%s>",
3815 			  2 + address_size * 2, address, name))))
3816        : (scn != NULL
3817 	  ? (address_size == 0
3818 	     ? printf ("%s+%#" PRIx64, scn, address)
3819 	     : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3820 	  : (address_size == 0
3821 	     ? printf ("%#" PRIx64, address)
3822 	     : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3823     error (EXIT_FAILURE, 0, _("sprintf failure"));
3824 }
3825 
3826 
3827 static const char *
dwarf_tag_string(unsigned int tag)3828 dwarf_tag_string (unsigned int tag)
3829 {
3830   switch (tag)
3831     {
3832 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3833       DWARF_ALL_KNOWN_DW_TAG
3834 #undef DWARF_ONE_KNOWN_DW_TAG
3835     default:
3836       return NULL;
3837     }
3838 }
3839 
3840 
3841 static const char *
dwarf_attr_string(unsigned int attrnum)3842 dwarf_attr_string (unsigned int attrnum)
3843 {
3844   switch (attrnum)
3845     {
3846 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3847       DWARF_ALL_KNOWN_DW_AT
3848 #undef DWARF_ONE_KNOWN_DW_AT
3849     default:
3850       return NULL;
3851     }
3852 }
3853 
3854 
3855 static const char *
dwarf_form_string(unsigned int form)3856 dwarf_form_string (unsigned int form)
3857 {
3858   switch (form)
3859     {
3860 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3861       DWARF_ALL_KNOWN_DW_FORM
3862 #undef DWARF_ONE_KNOWN_DW_FORM
3863     default:
3864       return NULL;
3865     }
3866 }
3867 
3868 
3869 static const char *
dwarf_lang_string(unsigned int lang)3870 dwarf_lang_string (unsigned int lang)
3871 {
3872   switch (lang)
3873     {
3874 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3875       DWARF_ALL_KNOWN_DW_LANG
3876 #undef DWARF_ONE_KNOWN_DW_LANG
3877     default:
3878       return NULL;
3879     }
3880 }
3881 
3882 
3883 static const char *
dwarf_inline_string(unsigned int code)3884 dwarf_inline_string (unsigned int code)
3885 {
3886   static const char *const known[] =
3887     {
3888 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3889       DWARF_ALL_KNOWN_DW_INL
3890 #undef DWARF_ONE_KNOWN_DW_INL
3891     };
3892 
3893   if (likely (code < sizeof (known) / sizeof (known[0])))
3894     return known[code];
3895 
3896   return NULL;
3897 }
3898 
3899 
3900 static const char *
dwarf_encoding_string(unsigned int code)3901 dwarf_encoding_string (unsigned int code)
3902 {
3903   static const char *const known[] =
3904     {
3905 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3906       DWARF_ALL_KNOWN_DW_ATE
3907 #undef DWARF_ONE_KNOWN_DW_ATE
3908     };
3909 
3910   if (likely (code < sizeof (known) / sizeof (known[0])))
3911     return known[code];
3912 
3913   return NULL;
3914 }
3915 
3916 
3917 static const char *
dwarf_access_string(unsigned int code)3918 dwarf_access_string (unsigned int code)
3919 {
3920   static const char *const known[] =
3921     {
3922 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3923       DWARF_ALL_KNOWN_DW_ACCESS
3924 #undef DWARF_ONE_KNOWN_DW_ACCESS
3925     };
3926 
3927   if (likely (code < sizeof (known) / sizeof (known[0])))
3928     return known[code];
3929 
3930   return NULL;
3931 }
3932 
3933 
3934 static const char *
dwarf_defaulted_string(unsigned int code)3935 dwarf_defaulted_string (unsigned int code)
3936 {
3937   static const char *const known[] =
3938     {
3939 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3940       DWARF_ALL_KNOWN_DW_DEFAULTED
3941 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3942     };
3943 
3944   if (likely (code < sizeof (known) / sizeof (known[0])))
3945     return known[code];
3946 
3947   return NULL;
3948 }
3949 
3950 
3951 static const char *
dwarf_visibility_string(unsigned int code)3952 dwarf_visibility_string (unsigned int code)
3953 {
3954   static const char *const known[] =
3955     {
3956 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3957       DWARF_ALL_KNOWN_DW_VIS
3958 #undef DWARF_ONE_KNOWN_DW_VIS
3959     };
3960 
3961   if (likely (code < sizeof (known) / sizeof (known[0])))
3962     return known[code];
3963 
3964   return NULL;
3965 }
3966 
3967 
3968 static const char *
dwarf_virtuality_string(unsigned int code)3969 dwarf_virtuality_string (unsigned int code)
3970 {
3971   static const char *const known[] =
3972     {
3973 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3974       DWARF_ALL_KNOWN_DW_VIRTUALITY
3975 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3976     };
3977 
3978   if (likely (code < sizeof (known) / sizeof (known[0])))
3979     return known[code];
3980 
3981   return NULL;
3982 }
3983 
3984 
3985 static const char *
dwarf_identifier_case_string(unsigned int code)3986 dwarf_identifier_case_string (unsigned int code)
3987 {
3988   static const char *const known[] =
3989     {
3990 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3991       DWARF_ALL_KNOWN_DW_ID
3992 #undef DWARF_ONE_KNOWN_DW_ID
3993     };
3994 
3995   if (likely (code < sizeof (known) / sizeof (known[0])))
3996     return known[code];
3997 
3998   return NULL;
3999 }
4000 
4001 
4002 static const char *
dwarf_calling_convention_string(unsigned int code)4003 dwarf_calling_convention_string (unsigned int code)
4004 {
4005   static const char *const known[] =
4006     {
4007 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4008       DWARF_ALL_KNOWN_DW_CC
4009 #undef DWARF_ONE_KNOWN_DW_CC
4010     };
4011 
4012   if (likely (code < sizeof (known) / sizeof (known[0])))
4013     return known[code];
4014 
4015   return NULL;
4016 }
4017 
4018 
4019 static const char *
dwarf_ordering_string(unsigned int code)4020 dwarf_ordering_string (unsigned int code)
4021 {
4022   static const char *const known[] =
4023     {
4024 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4025       DWARF_ALL_KNOWN_DW_ORD
4026 #undef DWARF_ONE_KNOWN_DW_ORD
4027     };
4028 
4029   if (likely (code < sizeof (known) / sizeof (known[0])))
4030     return known[code];
4031 
4032   return NULL;
4033 }
4034 
4035 
4036 static const char *
dwarf_discr_list_string(unsigned int code)4037 dwarf_discr_list_string (unsigned int code)
4038 {
4039   static const char *const known[] =
4040     {
4041 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4042       DWARF_ALL_KNOWN_DW_DSC
4043 #undef DWARF_ONE_KNOWN_DW_DSC
4044     };
4045 
4046   if (likely (code < sizeof (known) / sizeof (known[0])))
4047     return known[code];
4048 
4049   return NULL;
4050 }
4051 
4052 
4053 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4054 dwarf_locexpr_opcode_string (unsigned int code)
4055 {
4056   static const char *const known[] =
4057     {
4058       /* Normally we can't affort building huge table of 64K entries,
4059 	 most of them zero, just because there are a couple defined
4060 	 values at the far end.  In case of opcodes, it's OK.  */
4061 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4062       DWARF_ALL_KNOWN_DW_OP
4063 #undef DWARF_ONE_KNOWN_DW_OP
4064     };
4065 
4066   if (likely (code < sizeof (known) / sizeof (known[0])))
4067     return known[code];
4068 
4069   return NULL;
4070 }
4071 
4072 
4073 static const char *
dwarf_unit_string(unsigned int type)4074 dwarf_unit_string (unsigned int type)
4075 {
4076   switch (type)
4077     {
4078 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4079       DWARF_ALL_KNOWN_DW_UT
4080 #undef DWARF_ONE_KNOWN_DW_UT
4081     default:
4082       return NULL;
4083     }
4084 }
4085 
4086 
4087 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4088 dwarf_range_list_encoding_string (unsigned int kind)
4089 {
4090   switch (kind)
4091     {
4092 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4093       DWARF_ALL_KNOWN_DW_RLE
4094 #undef DWARF_ONE_KNOWN_DW_RLE
4095     default:
4096       return NULL;
4097     }
4098 }
4099 
4100 
4101 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4102 dwarf_loc_list_encoding_string (unsigned int kind)
4103 {
4104   switch (kind)
4105     {
4106 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4107       DWARF_ALL_KNOWN_DW_LLE
4108 #undef DWARF_ONE_KNOWN_DW_LLE
4109     default:
4110       return NULL;
4111     }
4112 }
4113 
4114 
4115 static const char *
dwarf_line_content_description_string(unsigned int kind)4116 dwarf_line_content_description_string (unsigned int kind)
4117 {
4118   switch (kind)
4119     {
4120 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4121       DWARF_ALL_KNOWN_DW_LNCT
4122 #undef DWARF_ONE_KNOWN_DW_LNCT
4123     default:
4124       return NULL;
4125     }
4126 }
4127 
4128 
4129 /* Used by all dwarf_foo_name functions.  */
4130 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4131 string_or_unknown (const char *known, unsigned int code,
4132                    unsigned int lo_user, unsigned int hi_user,
4133 		   bool print_unknown_num)
4134 {
4135   static char unknown_buf[20];
4136 
4137   if (likely (known != NULL))
4138     return known;
4139 
4140   if (lo_user != 0 && code >= lo_user && code <= hi_user)
4141     {
4142       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4143 		code - lo_user);
4144       return unknown_buf;
4145     }
4146 
4147   if (print_unknown_num)
4148     {
4149       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4150       return unknown_buf;
4151     }
4152 
4153   return "???";
4154 }
4155 
4156 
4157 static const char *
dwarf_tag_name(unsigned int tag)4158 dwarf_tag_name (unsigned int tag)
4159 {
4160   const char *ret = dwarf_tag_string (tag);
4161   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4162 }
4163 
4164 static const char *
dwarf_attr_name(unsigned int attr)4165 dwarf_attr_name (unsigned int attr)
4166 {
4167   const char *ret = dwarf_attr_string (attr);
4168   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4169 }
4170 
4171 
4172 static const char *
dwarf_form_name(unsigned int form)4173 dwarf_form_name (unsigned int form)
4174 {
4175   const char *ret = dwarf_form_string (form);
4176   return string_or_unknown (ret, form, 0, 0, true);
4177 }
4178 
4179 
4180 static const char *
dwarf_lang_name(unsigned int lang)4181 dwarf_lang_name (unsigned int lang)
4182 {
4183   const char *ret = dwarf_lang_string (lang);
4184   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4185 }
4186 
4187 
4188 static const char *
dwarf_inline_name(unsigned int code)4189 dwarf_inline_name (unsigned int code)
4190 {
4191   const char *ret = dwarf_inline_string (code);
4192   return string_or_unknown (ret, code, 0, 0, false);
4193 }
4194 
4195 
4196 static const char *
dwarf_encoding_name(unsigned int code)4197 dwarf_encoding_name (unsigned int code)
4198 {
4199   const char *ret = dwarf_encoding_string (code);
4200   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4201 }
4202 
4203 
4204 static const char *
dwarf_access_name(unsigned int code)4205 dwarf_access_name (unsigned int code)
4206 {
4207   const char *ret = dwarf_access_string (code);
4208   return string_or_unknown (ret, code, 0, 0, false);
4209 }
4210 
4211 
4212 static const char *
dwarf_defaulted_name(unsigned int code)4213 dwarf_defaulted_name (unsigned int code)
4214 {
4215   const char *ret = dwarf_defaulted_string (code);
4216   return string_or_unknown (ret, code, 0, 0, false);
4217 }
4218 
4219 
4220 static const char *
dwarf_visibility_name(unsigned int code)4221 dwarf_visibility_name (unsigned int code)
4222 {
4223   const char *ret = dwarf_visibility_string (code);
4224   return string_or_unknown (ret, code, 0, 0, false);
4225 }
4226 
4227 
4228 static const char *
dwarf_virtuality_name(unsigned int code)4229 dwarf_virtuality_name (unsigned int code)
4230 {
4231   const char *ret = dwarf_virtuality_string (code);
4232   return string_or_unknown (ret, code, 0, 0, false);
4233 }
4234 
4235 
4236 static const char *
dwarf_identifier_case_name(unsigned int code)4237 dwarf_identifier_case_name (unsigned int code)
4238 {
4239   const char *ret = dwarf_identifier_case_string (code);
4240   return string_or_unknown (ret, code, 0, 0, false);
4241 }
4242 
4243 
4244 static const char *
dwarf_calling_convention_name(unsigned int code)4245 dwarf_calling_convention_name (unsigned int code)
4246 {
4247   const char *ret = dwarf_calling_convention_string (code);
4248   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4249 }
4250 
4251 
4252 static const char *
dwarf_ordering_name(unsigned int code)4253 dwarf_ordering_name (unsigned int code)
4254 {
4255   const char *ret = dwarf_ordering_string (code);
4256   return string_or_unknown (ret, code, 0, 0, false);
4257 }
4258 
4259 
4260 static const char *
dwarf_discr_list_name(unsigned int code)4261 dwarf_discr_list_name (unsigned int code)
4262 {
4263   const char *ret = dwarf_discr_list_string (code);
4264   return string_or_unknown (ret, code, 0, 0, false);
4265 }
4266 
4267 
4268 static const char *
dwarf_unit_name(unsigned int type)4269 dwarf_unit_name (unsigned int type)
4270 {
4271   const char *ret = dwarf_unit_string (type);
4272   return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4273 }
4274 
4275 
4276 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4277 dwarf_range_list_encoding_name (unsigned int kind)
4278 {
4279   const char *ret = dwarf_range_list_encoding_string (kind);
4280   return string_or_unknown (ret, kind, 0, 0, false);
4281 }
4282 
4283 
4284 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4285 dwarf_loc_list_encoding_name (unsigned int kind)
4286 {
4287   const char *ret = dwarf_loc_list_encoding_string (kind);
4288   return string_or_unknown (ret, kind, 0, 0, false);
4289 }
4290 
4291 
4292 static const char *
dwarf_line_content_description_name(unsigned int kind)4293 dwarf_line_content_description_name (unsigned int kind)
4294 {
4295   const char *ret = dwarf_line_content_description_string (kind);
4296   return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4297 			    false);
4298 }
4299 
4300 
4301 static void
print_block(size_t n,const void * block)4302 print_block (size_t n, const void *block)
4303 {
4304   if (n == 0)
4305     puts (_("empty block"));
4306   else
4307     {
4308       printf (_("%zu byte block:"), n);
4309       const unsigned char *data = block;
4310       do
4311 	printf (" %02x", *data++);
4312       while (--n > 0);
4313       putchar ('\n');
4314     }
4315 }
4316 
4317 static void
print_bytes(size_t n,const unsigned char * bytes)4318 print_bytes (size_t n, const unsigned char *bytes)
4319 {
4320   while (n-- > 0)
4321     {
4322       printf ("%02x", *bytes++);
4323       if (n > 0)
4324 	printf (" ");
4325     }
4326 }
4327 
4328 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4329 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4330 {
4331   if (cu == NULL)
4332     return -1;
4333 
4334   Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4335   if (debug_addr == NULL)
4336     return -1;
4337 
4338   Dwarf_Off base = __libdw_cu_addr_base (cu);
4339   Dwarf_Word off = idx * cu->address_size;
4340   if (base > debug_addr->d_size
4341       || off > debug_addr->d_size - base
4342       || cu->address_size > debug_addr->d_size - base - off)
4343     return -1;
4344 
4345   const unsigned char *addrp = debug_addr->d_buf + base + off;
4346   if (cu->address_size == 4)
4347     *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4348   else
4349     *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4350 
4351   return 0;
4352 }
4353 
4354 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)4355 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4356 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4357 	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4358 {
4359   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4360 
4361   if (len == 0)
4362     {
4363       printf ("%*s(empty)\n", indent, "");
4364       return;
4365     }
4366 
4367 #define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
4368 #define CONSUME(n)	NEED (n); else len -= (n)
4369 
4370   Dwarf_Word offset = 0;
4371   while (len-- > 0)
4372     {
4373       uint_fast8_t op = *data++;
4374 
4375       const char *op_name = dwarf_locexpr_opcode_string (op);
4376       if (unlikely (op_name == NULL))
4377 	{
4378 	  static char buf[20];
4379 	  if (op >= DW_OP_lo_user)
4380 	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4381 	  else
4382 	    snprintf (buf, sizeof buf, "??? (%#x)", op);
4383 	  op_name = buf;
4384 	}
4385 
4386       switch (op)
4387 	{
4388 	case DW_OP_addr:;
4389 	  /* Address operand.  */
4390 	  Dwarf_Word addr;
4391 	  NEED (addrsize);
4392 	  if (addrsize == 4)
4393 	    addr = read_4ubyte_unaligned (dbg, data);
4394 	  else if (addrsize == 8)
4395 	    addr = read_8ubyte_unaligned (dbg, data);
4396 	  else
4397 	    goto invalid;
4398 	  data += addrsize;
4399 	  CONSUME (addrsize);
4400 
4401 	  printf ("%*s[%2" PRIuMAX "] %s ",
4402 		  indent, "", (uintmax_t) offset, op_name);
4403 	  print_dwarf_addr (dwflmod, 0, addr, addr);
4404 	  printf ("\n");
4405 
4406 	  offset += 1 + addrsize;
4407 	  break;
4408 
4409 	case DW_OP_call_ref:
4410 	case DW_OP_GNU_variable_value:
4411 	  /* Offset operand.  */
4412 	  if (ref_size != 4 && ref_size != 8)
4413 	    goto invalid; /* Cannot be used in CFA.  */
4414 	  NEED (ref_size);
4415 	  if (ref_size == 4)
4416 	    addr = read_4ubyte_unaligned (dbg, data);
4417 	  else
4418 	    addr = read_8ubyte_unaligned (dbg, data);
4419 	  data += ref_size;
4420 	  CONSUME (ref_size);
4421 	  /* addr is a DIE offset, so format it as one.  */
4422 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4423 		  indent, "", (uintmax_t) offset,
4424 		  op_name, (uintmax_t) addr);
4425 	  offset += 1 + ref_size;
4426 	  break;
4427 
4428 	case DW_OP_deref_size:
4429 	case DW_OP_xderef_size:
4430 	case DW_OP_pick:
4431 	case DW_OP_const1u:
4432 	  // XXX value might be modified by relocation
4433 	  NEED (1);
4434 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4435 		  indent, "", (uintmax_t) offset,
4436 		  op_name, *((uint8_t *) data));
4437 	  ++data;
4438 	  --len;
4439 	  offset += 2;
4440 	  break;
4441 
4442 	case DW_OP_const2u:
4443 	  NEED (2);
4444 	  // XXX value might be modified by relocation
4445 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4446 		  indent, "", (uintmax_t) offset,
4447 		  op_name, read_2ubyte_unaligned (dbg, data));
4448 	  CONSUME (2);
4449 	  data += 2;
4450 	  offset += 3;
4451 	  break;
4452 
4453 	case DW_OP_const4u:
4454 	  NEED (4);
4455 	  // XXX value might be modified by relocation
4456 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4457 		  indent, "", (uintmax_t) offset,
4458 		  op_name, read_4ubyte_unaligned (dbg, data));
4459 	  CONSUME (4);
4460 	  data += 4;
4461 	  offset += 5;
4462 	  break;
4463 
4464 	case DW_OP_const8u:
4465 	  NEED (8);
4466 	  // XXX value might be modified by relocation
4467 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4468 		  indent, "", (uintmax_t) offset,
4469 		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4470 	  CONSUME (8);
4471 	  data += 8;
4472 	  offset += 9;
4473 	  break;
4474 
4475 	case DW_OP_const1s:
4476 	  NEED (1);
4477 	  // XXX value might be modified by relocation
4478 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4479 		  indent, "", (uintmax_t) offset,
4480 		  op_name, *((int8_t *) data));
4481 	  ++data;
4482 	  --len;
4483 	  offset += 2;
4484 	  break;
4485 
4486 	case DW_OP_const2s:
4487 	  NEED (2);
4488 	  // XXX value might be modified by relocation
4489 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4490 		  indent, "", (uintmax_t) offset,
4491 		  op_name, read_2sbyte_unaligned (dbg, data));
4492 	  CONSUME (2);
4493 	  data += 2;
4494 	  offset += 3;
4495 	  break;
4496 
4497 	case DW_OP_const4s:
4498 	  NEED (4);
4499 	  // XXX value might be modified by relocation
4500 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4501 		  indent, "", (uintmax_t) offset,
4502 		  op_name, read_4sbyte_unaligned (dbg, data));
4503 	  CONSUME (4);
4504 	  data += 4;
4505 	  offset += 5;
4506 	  break;
4507 
4508 	case DW_OP_const8s:
4509 	  NEED (8);
4510 	  // XXX value might be modified by relocation
4511 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4512 		  indent, "", (uintmax_t) offset,
4513 		  op_name, read_8sbyte_unaligned (dbg, data));
4514 	  CONSUME (8);
4515 	  data += 8;
4516 	  offset += 9;
4517 	  break;
4518 
4519 	case DW_OP_piece:
4520 	case DW_OP_regx:
4521 	case DW_OP_plus_uconst:
4522 	case DW_OP_constu:;
4523 	  const unsigned char *start = data;
4524 	  uint64_t uleb;
4525 	  NEED (1);
4526 	  get_uleb128 (uleb, data, data + len);
4527 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4528 		  indent, "", (uintmax_t) offset, op_name, uleb);
4529 	  CONSUME (data - start);
4530 	  offset += 1 + (data - start);
4531 	  break;
4532 
4533 	case DW_OP_addrx:
4534 	case DW_OP_GNU_addr_index:
4535 	case DW_OP_constx:
4536 	case DW_OP_GNU_const_index:;
4537 	  start = data;
4538 	  NEED (1);
4539 	  get_uleb128 (uleb, data, data + len);
4540 	  printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4541 		  indent, "", (uintmax_t) offset, op_name, uleb);
4542 	  CONSUME (data - start);
4543 	  offset += 1 + (data - start);
4544 	  if (get_indexed_addr (cu, uleb, &addr) != 0)
4545 	    printf ("???\n");
4546 	  else
4547 	    {
4548 	      print_dwarf_addr (dwflmod, 0, addr, addr);
4549 	      printf ("\n");
4550 	    }
4551 	  break;
4552 
4553 	case DW_OP_bit_piece:
4554 	  start = data;
4555 	  uint64_t uleb2;
4556 	  NEED (1);
4557 	  get_uleb128 (uleb, data, data + len);
4558 	  NEED (1);
4559 	  get_uleb128 (uleb2, data, data + len);
4560 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4561 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4562 	  CONSUME (data - start);
4563 	  offset += 1 + (data - start);
4564 	  break;
4565 
4566 	case DW_OP_fbreg:
4567 	case DW_OP_breg0 ... DW_OP_breg31:
4568 	case DW_OP_consts:
4569 	  start = data;
4570 	  int64_t sleb;
4571 	  NEED (1);
4572 	  get_sleb128 (sleb, data, data + len);
4573 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4574 		  indent, "", (uintmax_t) offset, op_name, sleb);
4575 	  CONSUME (data - start);
4576 	  offset += 1 + (data - start);
4577 	  break;
4578 
4579 	case DW_OP_bregx:
4580 	  start = data;
4581 	  NEED (1);
4582 	  get_uleb128 (uleb, data, data + len);
4583 	  NEED (1);
4584 	  get_sleb128 (sleb, data, data + len);
4585 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4586 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4587 	  CONSUME (data - start);
4588 	  offset += 1 + (data - start);
4589 	  break;
4590 
4591 	case DW_OP_call2:
4592 	  NEED (2);
4593 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4594 		  indent, "", (uintmax_t) offset, op_name,
4595 		  read_2ubyte_unaligned (dbg, data));
4596 	  CONSUME (2);
4597 	  data += 2;
4598 	  offset += 3;
4599 	  break;
4600 
4601 	case DW_OP_call4:
4602 	  NEED (4);
4603 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4604 		  indent, "", (uintmax_t) offset, op_name,
4605 		  read_4ubyte_unaligned (dbg, data));
4606 	  CONSUME (4);
4607 	  data += 4;
4608 	  offset += 5;
4609 	  break;
4610 
4611 	case DW_OP_skip:
4612 	case DW_OP_bra:
4613 	  NEED (2);
4614 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4615 		  indent, "", (uintmax_t) offset, op_name,
4616 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4617 	  CONSUME (2);
4618 	  data += 2;
4619 	  offset += 3;
4620 	  break;
4621 
4622 	case DW_OP_implicit_value:
4623 	  start = data;
4624 	  NEED (1);
4625 	  get_uleb128 (uleb, data, data + len);
4626 	  printf ("%*s[%2" PRIuMAX "] %s: ",
4627 		  indent, "", (uintmax_t) offset, op_name);
4628 	  NEED (uleb);
4629 	  print_block (uleb, data);
4630 	  data += uleb;
4631 	  CONSUME (data - start);
4632 	  offset += 1 + (data - start);
4633 	  break;
4634 
4635 	case DW_OP_implicit_pointer:
4636 	case DW_OP_GNU_implicit_pointer:
4637 	  /* DIE offset operand.  */
4638 	  start = data;
4639 	  NEED (ref_size);
4640 	  if (ref_size != 4 && ref_size != 8)
4641 	    goto invalid; /* Cannot be used in CFA.  */
4642 	  if (ref_size == 4)
4643 	    addr = read_4ubyte_unaligned (dbg, data);
4644 	  else
4645 	    addr = read_8ubyte_unaligned (dbg, data);
4646 	  data += ref_size;
4647 	  /* Byte offset operand.  */
4648 	  NEED (1);
4649 	  get_sleb128 (sleb, data, data + len);
4650 
4651 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4652 		  indent, "", (intmax_t) offset,
4653 		  op_name, (uintmax_t) addr, sleb);
4654 	  CONSUME (data - start);
4655 	  offset += 1 + (data - start);
4656 	  break;
4657 
4658 	case DW_OP_entry_value:
4659 	case DW_OP_GNU_entry_value:
4660 	  /* Size plus expression block.  */
4661 	  start = data;
4662 	  NEED (1);
4663 	  get_uleb128 (uleb, data, data + len);
4664 	  printf ("%*s[%2" PRIuMAX "] %s:\n",
4665 		  indent, "", (uintmax_t) offset, op_name);
4666 	  NEED (uleb);
4667 	  print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4668 		     addrsize, offset_size, cu, uleb, data);
4669 	  data += uleb;
4670 	  CONSUME (data - start);
4671 	  offset += 1 + (data - start);
4672 	  break;
4673 
4674 	case DW_OP_const_type:
4675 	case DW_OP_GNU_const_type:
4676 	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4677 	     unsigned size plus block.  */
4678 	  start = data;
4679 	  NEED (1);
4680 	  get_uleb128 (uleb, data, data + len);
4681 	  if (! print_unresolved_addresses && cu != NULL)
4682 	    uleb += cu->start;
4683 	  NEED (1);
4684 	  uint8_t usize = *(uint8_t *) data++;
4685 	  NEED (usize);
4686 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4687 		  indent, "", (uintmax_t) offset, op_name, uleb);
4688 	  print_block (usize, data);
4689 	  data += usize;
4690 	  CONSUME (data - start);
4691 	  offset += 1 + (data - start);
4692 	  break;
4693 
4694 	case DW_OP_regval_type:
4695 	case DW_OP_GNU_regval_type:
4696 	  /* uleb128 register number, uleb128 CU relative
4697 	     DW_TAG_base_type DIE offset.  */
4698 	  start = data;
4699 	  NEED (1);
4700 	  get_uleb128 (uleb, data, data + len);
4701 	  NEED (1);
4702 	  get_uleb128 (uleb2, data, data + len);
4703 	  if (! print_unresolved_addresses && cu != NULL)
4704 	    uleb2 += cu->start;
4705 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4706 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4707 	  CONSUME (data - start);
4708 	  offset += 1 + (data - start);
4709 	  break;
4710 
4711 	case DW_OP_deref_type:
4712 	case DW_OP_GNU_deref_type:
4713 	  /* 1-byte unsigned size of value, uleb128 CU relative
4714 	     DW_TAG_base_type DIE offset.  */
4715 	  start = data;
4716 	  NEED (1);
4717 	  usize = *(uint8_t *) data++;
4718 	  NEED (1);
4719 	  get_uleb128 (uleb, data, data + len);
4720 	  if (! print_unresolved_addresses && cu != NULL)
4721 	    uleb += cu->start;
4722 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4723 		  indent, "", (uintmax_t) offset,
4724 		  op_name, usize, uleb);
4725 	  CONSUME (data - start);
4726 	  offset += 1 + (data - start);
4727 	  break;
4728 
4729 	case DW_OP_xderef_type:
4730 	  /* 1-byte unsigned size of value, uleb128 base_type DIE offset.  */
4731 	  start = data;
4732 	  NEED (1);
4733 	  usize = *(uint8_t *) data++;
4734 	  NEED (1);
4735 	  get_uleb128 (uleb, data, data + len);
4736 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4737 		  indent, "", (uintmax_t) offset,
4738 		  op_name, usize, uleb);
4739 	  CONSUME (data - start);
4740 	  offset += 1 + (data - start);
4741 	  break;
4742 
4743 	case DW_OP_convert:
4744 	case DW_OP_GNU_convert:
4745 	case DW_OP_reinterpret:
4746 	case DW_OP_GNU_reinterpret:
4747 	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4748 	     for conversion to untyped.  */
4749 	  start = data;
4750 	  NEED (1);
4751 	  get_uleb128 (uleb, data, data + len);
4752 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4753 	    uleb += cu->start;
4754 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4755 		  indent, "", (uintmax_t) offset, op_name, uleb);
4756 	  CONSUME (data - start);
4757 	  offset += 1 + (data - start);
4758 	  break;
4759 
4760 	case DW_OP_GNU_parameter_ref:
4761 	  /* 4 byte CU relative reference to the abstract optimized away
4762 	     DW_TAG_formal_parameter.  */
4763 	  NEED (4);
4764 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4765 	  if (! print_unresolved_addresses && cu != NULL)
4766 	    param_off += cu->start;
4767 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4768 		  indent, "", (uintmax_t) offset, op_name, param_off);
4769 	  CONSUME (4);
4770 	  data += 4;
4771 	  offset += 5;
4772 	  break;
4773 
4774 	default:
4775 	  /* No Operand.  */
4776 	  printf ("%*s[%2" PRIuMAX "] %s\n",
4777 		  indent, "", (uintmax_t) offset, op_name);
4778 	  ++offset;
4779 	  break;
4780 	}
4781 
4782       indent = indentrest;
4783       continue;
4784 
4785     invalid:
4786       printf (gettext ("%*s[%2" PRIuMAX "] %s  <TRUNCATED>\n"),
4787 	      indent, "", (uintmax_t) offset, op_name);
4788       break;
4789     }
4790 }
4791 
4792 
4793 struct listptr
4794 {
4795   Dwarf_Off offset:(64 - 3);
4796   bool addr64:1;
4797   bool dwarf64:1;
4798   bool warned:1;
4799   struct Dwarf_CU *cu;
4800   unsigned int attr;
4801 };
4802 
4803 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
4804 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
4805 
4806 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4807 cudie_base (Dwarf_Die *cudie)
4808 {
4809   Dwarf_Addr base;
4810   /* Find the base address of the compilation unit.  It will normally
4811      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
4812      address could be overridden by DW_AT_entry_pc.  It's been
4813      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4814      compilation units with discontinuous ranges.  */
4815   if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4816     {
4817       Dwarf_Attribute attr_mem;
4818       if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4819 			  &base) != 0)
4820 	base = 0;
4821     }
4822   return base;
4823 }
4824 
4825 static Dwarf_Addr
listptr_base(struct listptr * p)4826 listptr_base (struct listptr *p)
4827 {
4828   Dwarf_Die cu = CUDIE (p->cu);
4829   return cudie_base (&cu);
4830 }
4831 
4832 static int
compare_listptr(const void * a,const void * b,void * arg)4833 compare_listptr (const void *a, const void *b, void *arg)
4834 {
4835   const char *name = arg;
4836   struct listptr *p1 = (void *) a;
4837   struct listptr *p2 = (void *) b;
4838 
4839   if (p1->offset < p2->offset)
4840     return -1;
4841   if (p1->offset > p2->offset)
4842     return 1;
4843 
4844   if (!p1->warned && !p2->warned)
4845     {
4846       if (p1->addr64 != p2->addr64)
4847 	{
4848 	  p1->warned = p2->warned = true;
4849 	  error (0, 0,
4850 		 gettext ("%s %#" PRIx64 " used with different address sizes"),
4851 		 name, (uint64_t) p1->offset);
4852 	}
4853       if (p1->dwarf64 != p2->dwarf64)
4854 	{
4855 	  p1->warned = p2->warned = true;
4856 	  error (0, 0,
4857 		 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4858 		 name, (uint64_t) p1->offset);
4859 	}
4860       if (listptr_base (p1) != listptr_base (p2))
4861 	{
4862 	  p1->warned = p2->warned = true;
4863 	  error (0, 0,
4864 		 gettext ("%s %#" PRIx64 " used with different base addresses"),
4865 		 name, (uint64_t) p1->offset);
4866 	}
4867       if (p1->attr != p2 ->attr)
4868 	{
4869 	  p1->warned = p2->warned = true;
4870 	  error (0, 0,
4871 		 gettext ("%s %#" PRIx64
4872 			  " used with different attribute %s and %s"),
4873 		 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
4874 		 dwarf_attr_name (p2->attr));
4875 	}
4876     }
4877 
4878   return 0;
4879 }
4880 
4881 struct listptr_table
4882 {
4883   size_t n;
4884   size_t alloc;
4885   struct listptr *table;
4886 };
4887 
4888 static struct listptr_table known_locsptr;
4889 static struct listptr_table known_loclistsptr;
4890 static struct listptr_table known_rangelistptr;
4891 static struct listptr_table known_rnglistptr;
4892 static struct listptr_table known_addrbases;
4893 static struct listptr_table known_stroffbases;
4894 
4895 static void
reset_listptr(struct listptr_table * table)4896 reset_listptr (struct listptr_table *table)
4897 {
4898   free (table->table);
4899   table->table = NULL;
4900   table->n = table->alloc = 0;
4901 }
4902 
4903 /* Returns false if offset doesn't fit.  See struct listptr.  */
4904 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)4905 notice_listptr (enum section_e section, struct listptr_table *table,
4906 		uint_fast8_t address_size, uint_fast8_t offset_size,
4907 		struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4908 {
4909   if (print_debug_sections & section)
4910     {
4911       if (table->n == table->alloc)
4912 	{
4913 	  if (table->alloc == 0)
4914 	    table->alloc = 128;
4915 	  else
4916 	    table->alloc *= 2;
4917 	  table->table = xrealloc (table->table,
4918 				   table->alloc * sizeof table->table[0]);
4919 	}
4920 
4921       struct listptr *p = &table->table[table->n++];
4922 
4923       *p = (struct listptr)
4924 	{
4925 	  .addr64 = address_size == 8,
4926 	  .dwarf64 = offset_size == 8,
4927 	  .offset = offset,
4928 	  .cu = cu,
4929 	  .attr = attr
4930 	};
4931 
4932       if (p->offset != offset)
4933 	{
4934 	  table->n--;
4935 	  return false;
4936 	}
4937     }
4938   return true;
4939 }
4940 
4941 static void
sort_listptr(struct listptr_table * table,const char * name)4942 sort_listptr (struct listptr_table *table, const char *name)
4943 {
4944   if (table->n > 0)
4945     qsort_r (table->table, table->n, sizeof table->table[0],
4946 	     &compare_listptr, (void *) name);
4947 }
4948 
4949 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)4950 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4951 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4952 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4953 		   unsigned char **readp, unsigned char *endp,
4954 		   unsigned int *attr)
4955 {
4956   if (table->n == 0)
4957     return false;
4958 
4959   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4960     ++*idxp;
4961 
4962   struct listptr *p = &table->table[*idxp];
4963 
4964   if (*idxp == table->n
4965       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4966     {
4967       *readp = endp;
4968       printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
4969 	      offset);
4970       return true;
4971     }
4972 
4973   if (p->offset != (Dwarf_Off) offset)
4974     {
4975       *readp += p->offset - offset;
4976       printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4977 	      offset, (Dwarf_Off) p->offset - offset);
4978       return true;
4979     }
4980 
4981   if (address_sizep != NULL)
4982     *address_sizep = listptr_address_size (p);
4983   if (offset_sizep != NULL)
4984     *offset_sizep = listptr_offset_size (p);
4985   if (base != NULL)
4986     *base = listptr_base (p);
4987   if (cu != NULL)
4988     *cu = p->cu;
4989   if (attr != NULL)
4990     *attr = p->attr;
4991 
4992   return false;
4993 }
4994 
4995 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t idx)4996 next_listptr_offset (struct listptr_table *table, size_t idx)
4997 {
4998   /* Note that multiple attributes could in theory point to the same loclist
4999      offset, so make sure we pick one that is bigger than the current one.
5000      The table is sorted on offset.  */
5001   Dwarf_Off offset = table->table[idx].offset;
5002   while (++idx < table->n)
5003     {
5004       Dwarf_Off next = table->table[idx].offset;
5005       if (next > offset)
5006 	return next;
5007     }
5008   return 0;
5009 }
5010 
5011 /* Returns the listptr associated with the given index, or NULL.  */
5012 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5013 get_listptr (struct listptr_table *table, size_t idx)
5014 {
5015   if (idx >= table->n)
5016     return NULL;
5017   return &table->table[idx];
5018 }
5019 
5020 /* Returns the next index, base address and CU associated with the
5021    list unit offsets.  If there is none false is returned, otherwise
5022    true.  Assumes the table has been sorted.  */
5023 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5024 listptr_cu (struct listptr_table *table, size_t *idxp,
5025 	    Dwarf_Off start, Dwarf_Off end,
5026 	    Dwarf_Addr *base, struct Dwarf_CU **cu)
5027 {
5028   while (*idxp < table->n
5029 	 && table->table[*idxp].offset < start)
5030     ++*idxp;
5031 
5032   if (*idxp < table->n
5033       && table->table[*idxp].offset >= start
5034       && table->table[*idxp].offset < end)
5035     {
5036       struct listptr *p = &table->table[*idxp];
5037       *base = listptr_base (p);
5038       *cu = p->cu;
5039       ++*idxp;
5040       return true;
5041     }
5042 
5043   return false;
5044 }
5045 
5046 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5047 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5048 			    Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5049 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5050 {
5051   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5052 			  dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5053 
5054   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5055 		   " [ Code]\n"),
5056 	  elf_ndxscn (scn), section_name (ebl, shdr),
5057 	  (uint64_t) shdr->sh_offset);
5058 
5059   Dwarf_Off offset = 0;
5060   while (offset < sh_size)
5061     {
5062       printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
5063 	      offset);
5064 
5065       while (1)
5066 	{
5067 	  size_t length;
5068 	  Dwarf_Abbrev abbrev;
5069 
5070 	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5071 	  if (res != 0)
5072 	    {
5073 	      if (unlikely (res < 0))
5074 		{
5075 		  printf (gettext ("\
5076  *** error while reading abbreviation: %s\n"),
5077 			  dwarf_errmsg (-1));
5078 		  return;
5079 		}
5080 
5081 	      /* This is the NUL byte at the end of the section.  */
5082 	      ++offset;
5083 	      break;
5084 	    }
5085 
5086 	  /* We know these calls can never fail.  */
5087 	  unsigned int code = dwarf_getabbrevcode (&abbrev);
5088 	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
5089 	  int has_children = dwarf_abbrevhaschildren (&abbrev);
5090 
5091 	  printf (gettext (" [%5u] offset: %" PRId64
5092 			   ", children: %s, tag: %s\n"),
5093 		  code, (int64_t) offset,
5094 		  has_children ? yes_str : no_str,
5095 		  dwarf_tag_name (tag));
5096 
5097 	  size_t cnt = 0;
5098 	  unsigned int name;
5099 	  unsigned int form;
5100 	  Dwarf_Sword data;
5101 	  Dwarf_Off enoffset;
5102 	  while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5103 					   &data, &enoffset) == 0)
5104 	    {
5105 	      printf ("          attr: %s, form: %s",
5106 		      dwarf_attr_name (name), dwarf_form_name (form));
5107 	      if (form == DW_FORM_implicit_const)
5108 		printf (" (%" PRId64 ")", data);
5109 	      printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5110 	      ++cnt;
5111 	    }
5112 
5113 	  offset += length;
5114 	}
5115     }
5116 }
5117 
5118 
5119 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5120 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5121 			  Ebl *ebl, GElf_Ehdr *ehdr,
5122 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5123 {
5124   printf (gettext ("\
5125 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5126 	  elf_ndxscn (scn), section_name (ebl, shdr),
5127 	  (uint64_t) shdr->sh_offset);
5128 
5129   if (shdr->sh_size == 0)
5130     return;
5131 
5132   /* We like to get the section from libdw to make sure they are relocated.  */
5133   Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5134 		    ?: elf_rawdata (scn, NULL));
5135   if (unlikely (data == NULL))
5136     {
5137       error (0, 0, gettext ("cannot get .debug_addr section data: %s"),
5138 	     elf_errmsg (-1));
5139       return;
5140     }
5141 
5142   size_t idx = 0;
5143   sort_listptr (&known_addrbases, "addr_base");
5144 
5145   const unsigned char *start = (const unsigned char *) data->d_buf;
5146   const unsigned char *readp = start;
5147   const unsigned char *readendp = ((const unsigned char *) data->d_buf
5148 				   + data->d_size);
5149 
5150   while (readp < readendp)
5151     {
5152       /* We cannot really know whether or not there is an header.  The
5153 	 DebugFission extension to DWARF4 doesn't add one.  The DWARF5
5154 	 .debug_addr variant does.  Whether or not we have an header,
5155 	 DW_AT_[GNU_]addr_base points at "index 0".  So if the current
5156 	 offset equals the CU addr_base then we can just start
5157 	 printing addresses.  If there is no CU with an exact match
5158 	 then we'll try to parse the header first.  */
5159       Dwarf_Off off = (Dwarf_Off) (readp
5160 				   - (const unsigned char *) data->d_buf);
5161 
5162       printf ("Table at offset %" PRIx64 " ", off);
5163 
5164       struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5165       const unsigned char *next_unitp;
5166 
5167       uint64_t unit_length;
5168       uint16_t version;
5169       uint8_t address_size;
5170       uint8_t segment_size;
5171       if (listptr == NULL)
5172 	{
5173 	  error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5174 		 off);
5175 
5176 	  /* We will have to assume it is just addresses to the end... */
5177 	  address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5178 	  next_unitp = readendp;
5179 	  printf ("Unknown CU:\n");
5180 	}
5181       else
5182 	{
5183 	  Dwarf_Die cudie;
5184 	  if (dwarf_cu_die (listptr->cu, &cudie,
5185 			    NULL, NULL, NULL, NULL,
5186 			    NULL, NULL) == NULL)
5187 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5188 	  else
5189 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5190 
5191 	  if (listptr->offset == off)
5192 	    {
5193 	      address_size = listptr_address_size (listptr);
5194 	      segment_size = 0;
5195 	      version = 4;
5196 
5197 	      /* The addresses start here, but where do they end?  */
5198 	      listptr = get_listptr (&known_addrbases, idx);
5199 	      if (listptr == NULL)
5200 		next_unitp = readendp;
5201 	      else if (listptr->cu->version < 5)
5202 		{
5203 		  next_unitp = start + listptr->offset;
5204 		  if (listptr->offset < off || listptr->offset > data->d_size)
5205 		    {
5206 		      error (0, 0,
5207 			     "Warning: Bad address base for next unit at %"
5208 			     PRIx64, off);
5209 		      next_unitp = readendp;
5210 		    }
5211 		}
5212 	      else
5213 		{
5214 		  /* Tricky, we don't have a header for this unit, but
5215 		     there is one for the next.  We will have to
5216 		     "guess" how big it is and subtract it from the
5217 		     offset (because that points after the header).  */
5218 		  unsigned int offset_size = listptr_offset_size (listptr);
5219 		  Dwarf_Off next_off = (listptr->offset
5220 					- (offset_size == 4 ? 4 : 12) /* len */
5221 					- 2 /* version */
5222 					- 1 /* address size */
5223 					- 1); /* segment selector size */
5224 		  next_unitp = start + next_off;
5225 		  if (next_off < off || next_off > data->d_size)
5226 		    {
5227 		      error (0, 0,
5228 			     "Warning: Couldn't calculate .debug_addr "
5229 			     " unit lenght at %" PRIx64, off);
5230 		      next_unitp = readendp;
5231 		    }
5232 		}
5233 	      unit_length = (uint64_t) (next_unitp - readp);
5234 
5235 	      /* Pretend we have a header.  */
5236 	      printf ("\n");
5237 	      printf (gettext (" Length:         %8" PRIu64 "\n"),
5238 		      unit_length);
5239 	      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
5240 	      printf (gettext (" Address size:   %8" PRIu64 "\n"),
5241 		      (uint64_t) address_size);
5242 	      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
5243 		      (uint64_t) segment_size);
5244 	      printf ("\n");
5245 	    }
5246 	  else
5247 	    {
5248 	      /* OK, we have to parse an header first.  */
5249 	      unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5250 	      if (unlikely (unit_length == 0xffffffff))
5251 		{
5252 		  if (unlikely (readp > readendp - 8))
5253 		    {
5254 		    invalid_data:
5255 		      error (0, 0, "Invalid data");
5256 		      return;
5257 		    }
5258 		  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5259 		}
5260 	      printf ("\n");
5261 	      printf (gettext (" Length:         %8" PRIu64 "\n"),
5262 		      unit_length);
5263 
5264 	      /* We need at least 2-bytes (version) + 1-byte
5265 		 (addr_size) + 1-byte (segment_size) = 4 bytes to
5266 		 complete the header.  And this unit cannot go beyond
5267 		 the section data.  */
5268 	      if (readp > readendp - 4
5269 		  || unit_length < 4
5270 		  || unit_length > (uint64_t) (readendp - readp))
5271 		goto invalid_data;
5272 
5273 	      next_unitp = readp + unit_length;
5274 
5275 	      version = read_2ubyte_unaligned_inc (dbg, readp);
5276 	      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
5277 
5278 	      if (version != 5)
5279 		{
5280 		  error (0, 0, gettext ("Unknown version"));
5281 		  goto next_unit;
5282 		}
5283 
5284 	      address_size = *readp++;
5285 	      printf (gettext (" Address size:   %8" PRIu64 "\n"),
5286 		      (uint64_t) address_size);
5287 
5288 	      if (address_size != 4 && address_size != 8)
5289 		{
5290 		  error (0, 0, gettext ("unsupported address size"));
5291 		  goto next_unit;
5292 		}
5293 
5294 	      segment_size = *readp++;
5295 	      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
5296 		      (uint64_t) segment_size);
5297 	      printf ("\n");
5298 
5299 	      if (segment_size != 0)
5300 		{
5301 		  error (0, 0, gettext ("unsupported segment size"));
5302 		  goto next_unit;
5303 		}
5304 
5305 	      if (listptr->offset != (Dwarf_Off) (readp - start))
5306 		{
5307 		  error (0, 0, "Address index doesn't start after header");
5308 		  goto next_unit;
5309 		}
5310 	    }
5311 	}
5312 
5313       int digits = 1;
5314       size_t addresses = (next_unitp - readp) / address_size;
5315       while (addresses >= 10)
5316 	{
5317 	  ++digits;
5318 	  addresses /= 10;
5319 	}
5320 
5321       unsigned int uidx = 0;
5322       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
5323       printf (" Addresses start at offset 0x%zx:\n", index_offset);
5324       while (readp <= next_unitp - address_size)
5325 	{
5326 	  Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5327 						     readp);
5328 	  printf (" [%*u] ", digits, uidx++);
5329 	  print_dwarf_addr (dwflmod, address_size, addr, addr);
5330 	  printf ("\n");
5331 	}
5332       printf ("\n");
5333 
5334       if (readp != next_unitp)
5335 	error (0, 0, "extra %zd bytes at end of unit",
5336 	       (size_t) (next_unitp - readp));
5337 
5338     next_unit:
5339       readp = next_unitp;
5340     }
5341 }
5342 
5343 /* Print content of DWARF .debug_aranges section.  We fortunately do
5344    not have to know a bit about the structure of the section, libdwarf
5345    takes care of it.  */
5346 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5347 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5348 			       GElf_Shdr *shdr, Dwarf *dbg)
5349 {
5350   Dwarf_Aranges *aranges;
5351   size_t cnt;
5352   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5353     {
5354       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5355 	     dwarf_errmsg (-1));
5356       return;
5357     }
5358 
5359   GElf_Shdr glink_mem;
5360   GElf_Shdr *glink;
5361   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5362   if (glink == NULL)
5363     {
5364       error (0, 0, gettext ("invalid sh_link value in section %zu"),
5365 	     elf_ndxscn (scn));
5366       return;
5367     }
5368 
5369   printf (ngettext ("\
5370 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5371 		    "\
5372 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5373 		    cnt),
5374 	  elf_ndxscn (scn), section_name (ebl, shdr),
5375 	  (uint64_t) shdr->sh_offset, cnt);
5376 
5377   /* Compute floor(log16(cnt)).  */
5378   size_t tmp = cnt;
5379   int digits = 1;
5380   while (tmp >= 16)
5381     {
5382       ++digits;
5383       tmp >>= 4;
5384     }
5385 
5386   for (size_t n = 0; n < cnt; ++n)
5387     {
5388       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5389       if (unlikely (runp == NULL))
5390 	{
5391 	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5392 	  return;
5393 	}
5394 
5395       Dwarf_Addr start;
5396       Dwarf_Word length;
5397       Dwarf_Off offset;
5398 
5399       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5400 	printf (gettext (" [%*zu] ???\n"), digits, n);
5401       else
5402 	printf (gettext (" [%*zu] start: %0#*" PRIx64
5403 			 ", length: %5" PRIu64 ", CU DIE offset: %6"
5404 			 PRId64 "\n"),
5405 		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5406 		(uint64_t) start, (uint64_t) length, (int64_t) offset);
5407     }
5408 }
5409 
5410 
5411 /* Print content of DWARF .debug_aranges section.  */
5412 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5413 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5414 			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5415 			     GElf_Shdr *shdr, Dwarf *dbg)
5416 {
5417   if (decodedaranges)
5418     {
5419       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5420       return;
5421     }
5422 
5423   Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5424 		    ?: elf_rawdata (scn, NULL));
5425 
5426   if (unlikely (data == NULL))
5427     {
5428       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5429 	     elf_errmsg (-1));
5430       return;
5431     }
5432 
5433   printf (gettext ("\
5434 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5435 	  elf_ndxscn (scn), section_name (ebl, shdr),
5436 	  (uint64_t) shdr->sh_offset);
5437 
5438   const unsigned char *readp = data->d_buf;
5439   const unsigned char *readendp = readp + data->d_size;
5440 
5441   while (readp < readendp)
5442     {
5443       const unsigned char *hdrstart = readp;
5444       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5445 
5446       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
5447       if (readp + 4 > readendp)
5448 	{
5449 	invalid_data:
5450 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5451 		 elf_ndxscn (scn), section_name (ebl, shdr));
5452 	  return;
5453 	}
5454 
5455       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5456       unsigned int length_bytes = 4;
5457       if (length == DWARF3_LENGTH_64_BIT)
5458 	{
5459 	  if (readp + 8 > readendp)
5460 	    goto invalid_data;
5461 	  length = read_8ubyte_unaligned_inc (dbg, readp);
5462 	  length_bytes = 8;
5463 	}
5464 
5465       const unsigned char *nexthdr = readp + length;
5466       printf (gettext ("\n Length:        %6" PRIu64 "\n"),
5467 	      (uint64_t) length);
5468 
5469       if (unlikely (length > (size_t) (readendp - readp)))
5470 	goto invalid_data;
5471 
5472       if (length == 0)
5473 	continue;
5474 
5475       if (readp + 2 > readendp)
5476 	goto invalid_data;
5477       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5478       printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
5479 	      version);
5480       if (version != 2)
5481 	{
5482 	  error (0, 0, gettext ("unsupported aranges version"));
5483 	  goto next_table;
5484 	}
5485 
5486       Dwarf_Word offset;
5487       if (readp + length_bytes > readendp)
5488 	goto invalid_data;
5489       if (length_bytes == 8)
5490 	offset = read_8ubyte_unaligned_inc (dbg, readp);
5491       else
5492 	offset = read_4ubyte_unaligned_inc (dbg, readp);
5493       printf (gettext (" CU offset:     %6" PRIx64 "\n"),
5494 	      (uint64_t) offset);
5495 
5496       if (readp + 1 > readendp)
5497 	goto invalid_data;
5498       unsigned int address_size = *readp++;
5499       printf (gettext (" Address size:  %6" PRIu64 "\n"),
5500 	      (uint64_t) address_size);
5501       if (address_size != 4 && address_size != 8)
5502 	{
5503 	  error (0, 0, gettext ("unsupported address size"));
5504 	  goto next_table;
5505 	}
5506 
5507       if (readp + 1 > readendp)
5508 	goto invalid_data;
5509       unsigned int segment_size = *readp++;
5510       printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
5511 	      (uint64_t) segment_size);
5512       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5513 	{
5514 	  error (0, 0, gettext ("unsupported segment size"));
5515 	  goto next_table;
5516 	}
5517 
5518       /* Round the address to the next multiple of 2*address_size.  */
5519       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5520 		% (2 * address_size));
5521 
5522       while (readp < nexthdr)
5523 	{
5524 	  Dwarf_Word range_address;
5525 	  Dwarf_Word range_length;
5526 	  Dwarf_Word segment = 0;
5527 	  if (readp + 2 * address_size + segment_size > readendp)
5528 	    goto invalid_data;
5529 	  if (address_size == 4)
5530 	    {
5531 	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
5532 	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
5533 	    }
5534 	  else
5535 	    {
5536 	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
5537 	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
5538 	    }
5539 
5540 	  if (segment_size == 4)
5541 	    segment = read_4ubyte_unaligned_inc (dbg, readp);
5542 	  else if (segment_size == 8)
5543 	    segment = read_8ubyte_unaligned_inc (dbg, readp);
5544 
5545 	  if (range_address == 0 && range_length == 0 && segment == 0)
5546 	    break;
5547 
5548 	  printf ("   ");
5549 	  print_dwarf_addr (dwflmod, address_size, range_address,
5550 			    range_address);
5551 	  printf ("..");
5552 	  print_dwarf_addr (dwflmod, address_size,
5553 			    range_address + range_length - 1,
5554 			    range_length);
5555 	  if (segment_size != 0)
5556 	    printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5557 	  else
5558 	    printf ("\n");
5559 	}
5560 
5561     next_table:
5562       if (readp != nexthdr)
5563 	{
5564 	  size_t padding = nexthdr - readp;
5565 	  printf (gettext ("   %zu padding bytes\n"), padding);
5566 	  readp = nexthdr;
5567 	}
5568     }
5569 }
5570 
5571 
5572 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5573 
5574 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5575    DWARF (.dwo) file.  */
5576 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5577 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5578 {
5579   uint64_t id;
5580   if (is_split_dwarf (dbg, &id, cu))
5581     {
5582       Dwarf_Die cudie;
5583       if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5584 	{
5585 	  *cu_base = cudie_base (&cudie);
5586 	  return true;
5587 	}
5588     }
5589   return false;
5590 }
5591 
5592 /* Print content of DWARF .debug_rnglists section.  */
5593 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5594 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5595 			      Ebl *ebl,
5596 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
5597 			      Elf_Scn *scn, GElf_Shdr *shdr,
5598 			      Dwarf *dbg __attribute__((unused)))
5599 {
5600   printf (gettext ("\
5601 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5602 	  elf_ndxscn (scn), section_name (ebl, shdr),
5603 	  (uint64_t) shdr->sh_offset);
5604 
5605   Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5606 		   ?: elf_rawdata (scn, NULL));
5607   if (unlikely (data == NULL))
5608     {
5609       error (0, 0, gettext ("cannot get .debug_rnglists content: %s"),
5610 	     elf_errmsg (-1));
5611       return;
5612     }
5613 
5614   /* For the listptr to get the base address/CU.  */
5615   sort_listptr (&known_rnglistptr, "rnglistptr");
5616   size_t listptr_idx = 0;
5617 
5618   const unsigned char *readp = data->d_buf;
5619   const unsigned char *const dataend = ((unsigned char *) data->d_buf
5620 					+ data->d_size);
5621   while (readp < dataend)
5622     {
5623       if (unlikely (readp > dataend - 4))
5624 	{
5625 	invalid_data:
5626 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5627 		 elf_ndxscn (scn), section_name (ebl, shdr));
5628 	  return;
5629 	}
5630 
5631       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5632       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
5633 	      (uint64_t) offset);
5634 
5635       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5636       unsigned int offset_size = 4;
5637       if (unlikely (unit_length == 0xffffffff))
5638 	{
5639 	  if (unlikely (readp > dataend - 8))
5640 	    goto invalid_data;
5641 
5642 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5643 	  offset_size = 8;
5644 	}
5645       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
5646 
5647       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5648 	 bytes to complete the header.  And this unit cannot go beyond
5649 	 the section data.  */
5650       if (readp > dataend - 8
5651 	  || unit_length < 8
5652 	  || unit_length > (uint64_t) (dataend - readp))
5653 	goto invalid_data;
5654 
5655       const unsigned char *nexthdr = readp + unit_length;
5656 
5657       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5658       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
5659 
5660       if (version != 5)
5661 	{
5662 	  error (0, 0, gettext ("Unknown version"));
5663 	  goto next_table;
5664 	}
5665 
5666       uint8_t address_size = *readp++;
5667       printf (gettext (" Address size:   %8" PRIu64 "\n"),
5668 	      (uint64_t) address_size);
5669 
5670       if (address_size != 4 && address_size != 8)
5671 	{
5672 	  error (0, 0, gettext ("unsupported address size"));
5673 	  goto next_table;
5674 	}
5675 
5676       uint8_t segment_size = *readp++;
5677       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
5678 	      (uint64_t) segment_size);
5679 
5680       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5681         {
5682           error (0, 0, gettext ("unsupported segment size"));
5683           goto next_table;
5684         }
5685 
5686       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5687       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
5688 	      (uint64_t) offset_entry_count);
5689 
5690       /* We need the CU that uses this unit to get the initial base address. */
5691       Dwarf_Addr cu_base = 0;
5692       struct Dwarf_CU *cu = NULL;
5693       if (listptr_cu (&known_rnglistptr, &listptr_idx,
5694 		      (Dwarf_Off) offset,
5695 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5696 		      &cu_base, &cu)
5697 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
5698 	{
5699 	  Dwarf_Die cudie;
5700 	  if (dwarf_cu_die (cu, &cudie,
5701 			    NULL, NULL, NULL, NULL,
5702 			    NULL, NULL) == NULL)
5703 	    printf (gettext (" Unknown CU base: "));
5704 	  else
5705 	    printf (gettext (" CU [%6" PRIx64 "] base: "),
5706 		    dwarf_dieoffset (&cudie));
5707 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5708 	  printf ("\n");
5709 	}
5710       else
5711 	printf (gettext (" Not associated with a CU.\n"));
5712 
5713       printf ("\n");
5714 
5715       const unsigned char *offset_array_start = readp;
5716       if (offset_entry_count > 0)
5717 	{
5718 	  uint64_t max_entries = (unit_length - 8) / offset_size;
5719 	  if (offset_entry_count > max_entries)
5720 	    {
5721 	      error (0, 0,
5722 		     gettext ("too many offset entries for unit length"));
5723 	      offset_entry_count = max_entries;
5724 	    }
5725 
5726 	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
5727 		  (uint64_t) (offset_array_start
5728 			      - (unsigned char *) data->d_buf));
5729 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5730 	    {
5731 	      printf ("   [%6" PRIu32 "] ", idx);
5732 	      if (offset_size == 4)
5733 		{
5734 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5735 		  printf ("0x%" PRIx32 "\n", off);
5736 		}
5737 	      else
5738 		{
5739 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5740 		  printf ("0x%" PRIx64 "\n", off);
5741 		}
5742 	    }
5743 	  printf ("\n");
5744 	}
5745 
5746       Dwarf_Addr base = cu_base;
5747       bool start_of_list = true;
5748       while (readp < nexthdr)
5749 	{
5750 	  uint8_t kind = *readp++;
5751 	  uint64_t op1, op2;
5752 
5753 	  /* Skip padding.  */
5754 	  if (start_of_list && kind == DW_RLE_end_of_list)
5755 	    continue;
5756 
5757 	  if (start_of_list)
5758 	    {
5759 	      base = cu_base;
5760 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5761 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5762 		      (uint64_t) (readp - offset_array_start - 1));
5763 	      start_of_list = false;
5764 	    }
5765 
5766 	  printf ("    %s", dwarf_range_list_encoding_name (kind));
5767 	  switch (kind)
5768 	    {
5769 	    case DW_RLE_end_of_list:
5770 	      start_of_list = true;
5771 	      printf ("\n\n");
5772 	      break;
5773 
5774 	    case DW_RLE_base_addressx:
5775 	      if ((uint64_t) (nexthdr - readp) < 1)
5776 		{
5777 		invalid_range:
5778 		  error (0, 0, gettext ("invalid range list data"));
5779 		  goto next_table;
5780 		}
5781 	      get_uleb128 (op1, readp, nexthdr);
5782 	      printf (" %" PRIx64 "\n", op1);
5783 	      if (! print_unresolved_addresses)
5784 		{
5785 		  Dwarf_Addr addr;
5786 		  if (get_indexed_addr (cu, op1, &addr) != 0)
5787 		    printf ("      ???\n");
5788 		  else
5789 		    {
5790 		      printf ("      ");
5791 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
5792 		      printf ("\n");
5793 		    }
5794 		}
5795 	      break;
5796 
5797 	    case DW_RLE_startx_endx:
5798 	      if ((uint64_t) (nexthdr - readp) < 1)
5799 		goto invalid_range;
5800 	      get_uleb128 (op1, readp, nexthdr);
5801 	      if ((uint64_t) (nexthdr - readp) < 1)
5802 		goto invalid_range;
5803 	      get_uleb128 (op2, readp, nexthdr);
5804 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5805 	      if (! print_unresolved_addresses)
5806 		{
5807 		  Dwarf_Addr addr1;
5808 		  Dwarf_Addr addr2;
5809 		  if (get_indexed_addr (cu, op1, &addr1) != 0
5810 		      || get_indexed_addr (cu, op2, &addr2) != 0)
5811 		    {
5812 		      printf ("      ???..\n");
5813 		      printf ("      ???\n");
5814 		    }
5815 		  else
5816 		    {
5817 		      printf ("      ");
5818 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5819 		      printf ("..\n      ");
5820 		      print_dwarf_addr (dwflmod, address_size,
5821 					addr2 - 1, addr2);
5822 		      printf ("\n");
5823 		    }
5824 		}
5825 	      break;
5826 
5827 	    case DW_RLE_startx_length:
5828 	      if ((uint64_t) (nexthdr - readp) < 1)
5829 		goto invalid_range;
5830 	      get_uleb128 (op1, readp, nexthdr);
5831 	      if ((uint64_t) (nexthdr - readp) < 1)
5832 		goto invalid_range;
5833 	      get_uleb128 (op2, readp, nexthdr);
5834 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5835 	      if (! print_unresolved_addresses)
5836 		{
5837 		  Dwarf_Addr addr1;
5838 		  Dwarf_Addr addr2;
5839 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
5840 		    {
5841 		      printf ("      ???..\n");
5842 		      printf ("      ???\n");
5843 		    }
5844 		  else
5845 		    {
5846 		      addr2 = addr1 + op2;
5847 		      printf ("      ");
5848 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5849 		      printf ("..\n      ");
5850 		      print_dwarf_addr (dwflmod, address_size,
5851 					addr2 - 1, addr2);
5852 		      printf ("\n");
5853 		    }
5854 		}
5855 	      break;
5856 
5857 	    case DW_RLE_offset_pair:
5858 	      if ((uint64_t) (nexthdr - readp) < 1)
5859 		goto invalid_range;
5860 	      get_uleb128 (op1, readp, nexthdr);
5861 	      if ((uint64_t) (nexthdr - readp) < 1)
5862 		goto invalid_range;
5863 	      get_uleb128 (op2, readp, nexthdr);
5864 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5865 	      if (! print_unresolved_addresses)
5866 		{
5867 		  op1 += base;
5868 		  op2 += base;
5869 		  printf ("      ");
5870 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5871 		  printf ("..\n      ");
5872 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5873 		  printf ("\n");
5874 		}
5875 	      break;
5876 
5877 	    case DW_RLE_base_address:
5878 	      if (address_size == 4)
5879 		{
5880 		  if ((uint64_t) (nexthdr - readp) < 4)
5881 		    goto invalid_range;
5882 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5883 		}
5884 	      else
5885 		{
5886 		  if ((uint64_t) (nexthdr - readp) < 8)
5887 		    goto invalid_range;
5888 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5889 		}
5890 	      base = op1;
5891 	      printf (" 0x%" PRIx64 "\n", base);
5892 	      if (! print_unresolved_addresses)
5893 		{
5894 		  printf ("      ");
5895 		  print_dwarf_addr (dwflmod, address_size, base, base);
5896 		  printf ("\n");
5897 		}
5898 	      break;
5899 
5900 	    case DW_RLE_start_end:
5901 	      if (address_size == 4)
5902 		{
5903 		  if ((uint64_t) (nexthdr - readp) < 8)
5904 		    goto invalid_range;
5905 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5906 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
5907 		}
5908 	      else
5909 		{
5910 		  if ((uint64_t) (nexthdr - readp) < 16)
5911 		    goto invalid_range;
5912 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5913 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
5914 		}
5915 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5916 	      if (! print_unresolved_addresses)
5917 		{
5918 		  printf ("      ");
5919 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5920 		  printf ("..\n      ");
5921 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5922 		  printf ("\n");
5923 		}
5924 	      break;
5925 
5926 	    case DW_RLE_start_length:
5927 	      if (address_size == 4)
5928 		{
5929 		  if ((uint64_t) (nexthdr - readp) < 4)
5930 		    goto invalid_range;
5931 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5932 		}
5933 	      else
5934 		{
5935 		  if ((uint64_t) (nexthdr - readp) < 8)
5936 		    goto invalid_range;
5937 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5938 		}
5939 	      if ((uint64_t) (nexthdr - readp) < 1)
5940 		goto invalid_range;
5941 	      get_uleb128 (op2, readp, nexthdr);
5942 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5943 	      if (! print_unresolved_addresses)
5944 		{
5945 		  op2 = op1 + op2;
5946 		  printf ("      ");
5947 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5948 		  printf ("..\n      ");
5949 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5950 		  printf ("\n");
5951 		}
5952 	      break;
5953 
5954 	    default:
5955 	      goto invalid_range;
5956 	    }
5957 	}
5958 
5959     next_table:
5960       if (readp != nexthdr)
5961 	{
5962           size_t padding = nexthdr - readp;
5963           printf (gettext ("   %zu padding bytes\n\n"), padding);
5964 	  readp = nexthdr;
5965 	}
5966     }
5967 }
5968 
5969 /* Print content of DWARF .debug_ranges section.  */
5970 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5971 print_debug_ranges_section (Dwfl_Module *dwflmod,
5972 			    Ebl *ebl, GElf_Ehdr *ehdr,
5973 			    Elf_Scn *scn, GElf_Shdr *shdr,
5974 			    Dwarf *dbg)
5975 {
5976   Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
5977 		    ?: elf_rawdata (scn, NULL));
5978   if (unlikely (data == NULL))
5979     {
5980       error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
5981 	     elf_errmsg (-1));
5982       return;
5983     }
5984 
5985   printf (gettext ("\
5986 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5987 	  elf_ndxscn (scn), section_name (ebl, shdr),
5988 	  (uint64_t) shdr->sh_offset);
5989 
5990   sort_listptr (&known_rangelistptr, "rangelistptr");
5991   size_t listptr_idx = 0;
5992 
5993   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5994 
5995   bool first = true;
5996   Dwarf_Addr base = 0;
5997   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
5998   unsigned char *readp = data->d_buf;
5999   Dwarf_CU *last_cu = NULL;
6000   while (readp < endp)
6001     {
6002       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6003       Dwarf_CU *cu = last_cu;
6004 
6005       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6006 				      &address_size, NULL, &base, &cu,
6007 				      offset, &readp, endp, NULL))
6008 	continue;
6009 
6010       if (last_cu != cu)
6011 	{
6012 	  Dwarf_Die cudie;
6013 	  if (dwarf_cu_die (cu, &cudie,
6014 			    NULL, NULL, NULL, NULL,
6015 			    NULL, NULL) == NULL)
6016 	    printf (gettext ("\n Unknown CU base: "));
6017 	  else
6018 	    printf (gettext ("\n CU [%6" PRIx64 "] base: "),
6019 		    dwarf_dieoffset (&cudie));
6020 	  print_dwarf_addr (dwflmod, address_size, base, base);
6021 	  printf ("\n");
6022 	}
6023       last_cu = cu;
6024 
6025       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6026 	{
6027 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
6028 	  break;
6029 	}
6030 
6031       Dwarf_Addr begin;
6032       Dwarf_Addr end;
6033       if (address_size == 8)
6034 	{
6035 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
6036 	  end = read_8ubyte_unaligned_inc (dbg, readp);
6037 	}
6038       else
6039 	{
6040 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
6041 	  end = read_4ubyte_unaligned_inc (dbg, readp);
6042 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
6043 	    begin = (Dwarf_Addr) -1l;
6044 	}
6045 
6046       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
6047 	{
6048 	  printf (gettext (" [%6tx] base address\n          "), offset);
6049 	  print_dwarf_addr (dwflmod, address_size, end, end);
6050 	  printf ("\n");
6051 	  base = end;
6052 	}
6053       else if (begin == 0 && end == 0) /* End of list entry.  */
6054 	{
6055 	  if (first)
6056 	    printf (gettext (" [%6tx] empty list\n"), offset);
6057 	  first = true;
6058 	}
6059       else
6060 	{
6061 	  /* We have an address range entry.  */
6062 	  if (first)		/* First address range entry in a list.  */
6063 	    printf (" [%6tx] ", offset);
6064 	  else
6065 	    printf ("          ");
6066 
6067 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6068 	  if (! print_unresolved_addresses)
6069 	    {
6070 	      printf ("          ");
6071 	      print_dwarf_addr (dwflmod, address_size, base + begin,
6072 			        base + begin);
6073 	      printf ("..\n          ");
6074 	      print_dwarf_addr (dwflmod, address_size,
6075 				base + end - 1, base + end);
6076 	      printf ("\n");
6077 	    }
6078 
6079 	  first = false;
6080 	}
6081     }
6082 }
6083 
6084 #define REGNAMESZ 16
6085 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6086 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6087 	       char name[REGNAMESZ], int *bits, int *type)
6088 {
6089   const char *set;
6090   const char *pfx;
6091   int ignore;
6092   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6093 				 bits ?: &ignore, type ?: &ignore);
6094   if (n <= 0)
6095     {
6096       if (loc != NULL)
6097 	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6098       else
6099 	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6100       if (bits != NULL)
6101 	*bits = loc != NULL ? loc->bits : 0;
6102       if (type != NULL)
6103 	*type = DW_ATE_unsigned;
6104       set = "??? unrecognized";
6105     }
6106   else
6107     {
6108       if (bits != NULL && *bits <= 0)
6109 	*bits = loc != NULL ? loc->bits : 0;
6110       if (type != NULL && *type == DW_ATE_void)
6111 	*type = DW_ATE_unsigned;
6112 
6113     }
6114   return set;
6115 }
6116 
6117 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6118 read_encoded (unsigned int encoding, const unsigned char *readp,
6119 	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6120 {
6121   if ((encoding & 0xf) == DW_EH_PE_absptr)
6122     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6123       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6124 
6125   switch (encoding & 0xf)
6126     {
6127     case DW_EH_PE_uleb128:
6128       get_uleb128 (*res, readp, endp);
6129       break;
6130     case DW_EH_PE_sleb128:
6131       get_sleb128 (*res, readp, endp);
6132       break;
6133     case DW_EH_PE_udata2:
6134       if (readp + 2 > endp)
6135 	goto invalid;
6136       *res = read_2ubyte_unaligned_inc (dbg, readp);
6137       break;
6138     case DW_EH_PE_udata4:
6139       if (readp + 4 > endp)
6140 	goto invalid;
6141       *res = read_4ubyte_unaligned_inc (dbg, readp);
6142       break;
6143     case DW_EH_PE_udata8:
6144       if (readp + 8 > endp)
6145 	goto invalid;
6146       *res = read_8ubyte_unaligned_inc (dbg, readp);
6147       break;
6148     case DW_EH_PE_sdata2:
6149       if (readp + 2 > endp)
6150 	goto invalid;
6151       *res = read_2sbyte_unaligned_inc (dbg, readp);
6152       break;
6153     case DW_EH_PE_sdata4:
6154       if (readp + 4 > endp)
6155 	goto invalid;
6156       *res = read_4sbyte_unaligned_inc (dbg, readp);
6157       break;
6158     case DW_EH_PE_sdata8:
6159       if (readp + 8 > endp)
6160 	goto invalid;
6161       *res = read_8sbyte_unaligned_inc (dbg, readp);
6162       break;
6163     default:
6164     invalid:
6165       error (1, 0,
6166 	     gettext ("invalid encoding"));
6167     }
6168 
6169   return readp;
6170 }
6171 
6172 
6173 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)6174 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6175 		   Dwarf_Word vma_base, unsigned int code_align,
6176 		   int data_align,
6177 		   unsigned int version, unsigned int ptr_size,
6178 		   unsigned int encoding,
6179 		   Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
6180 {
6181   char regnamebuf[REGNAMESZ];
6182   const char *regname (unsigned int regno)
6183   {
6184     register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6185     return regnamebuf;
6186   }
6187 
6188   puts ("\n   Program:");
6189   Dwarf_Word pc = vma_base;
6190   while (readp < endp)
6191     {
6192       unsigned int opcode = *readp++;
6193 
6194       if (opcode < DW_CFA_advance_loc)
6195 	/* Extended opcode.  */
6196 	switch (opcode)
6197 	  {
6198 	    uint64_t op1;
6199 	    int64_t sop1;
6200 	    uint64_t op2;
6201 	    int64_t sop2;
6202 
6203 	  case DW_CFA_nop:
6204 	    puts ("     nop");
6205 	    break;
6206 	  case DW_CFA_set_loc:
6207 	    if ((uint64_t) (endp - readp) < 1)
6208 	      goto invalid;
6209 	    readp = read_encoded (encoding, readp, endp, &op1, dbg);
6210 	    printf ("     set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6211 		    op1, pc = vma_base + op1);
6212 	    break;
6213 	  case DW_CFA_advance_loc1:
6214 	    if ((uint64_t) (endp - readp) < 1)
6215 	      goto invalid;
6216 	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
6217 		    *readp, pc += *readp * code_align);
6218 	    ++readp;
6219 	    break;
6220 	  case DW_CFA_advance_loc2:
6221 	    if ((uint64_t) (endp - readp) < 2)
6222 	      goto invalid;
6223 	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
6224 	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6225 		    op1, pc += op1 * code_align);
6226 	    break;
6227 	  case DW_CFA_advance_loc4:
6228 	    if ((uint64_t) (endp - readp) < 4)
6229 	      goto invalid;
6230 	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
6231 	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6232 		    op1, pc += op1 * code_align);
6233 	    break;
6234 	  case DW_CFA_offset_extended:
6235 	    if ((uint64_t) (endp - readp) < 1)
6236 	      goto invalid;
6237 	    get_uleb128 (op1, readp, endp);
6238 	    if ((uint64_t) (endp - readp) < 1)
6239 	      goto invalid;
6240 	    get_uleb128 (op2, readp, endp);
6241 	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6242 		    "\n",
6243 		    op1, regname (op1), op2 * data_align);
6244 	    break;
6245 	  case DW_CFA_restore_extended:
6246 	    if ((uint64_t) (endp - readp) < 1)
6247 	      goto invalid;
6248 	    get_uleb128 (op1, readp, endp);
6249 	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
6250 		    op1, regname (op1));
6251 	    break;
6252 	  case DW_CFA_undefined:
6253 	    if ((uint64_t) (endp - readp) < 1)
6254 	      goto invalid;
6255 	    get_uleb128 (op1, readp, endp);
6256 	    printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
6257 	    break;
6258 	  case DW_CFA_same_value:
6259 	    if ((uint64_t) (endp - readp) < 1)
6260 	      goto invalid;
6261 	    get_uleb128 (op1, readp, endp);
6262 	    printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
6263 	    break;
6264 	  case DW_CFA_register:
6265 	    if ((uint64_t) (endp - readp) < 1)
6266 	      goto invalid;
6267 	    get_uleb128 (op1, readp, endp);
6268 	    if ((uint64_t) (endp - readp) < 1)
6269 	      goto invalid;
6270 	    get_uleb128 (op2, readp, endp);
6271 	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6272 		    op1, regname (op1), op2, regname (op2));
6273 	    break;
6274 	  case DW_CFA_remember_state:
6275 	    puts ("     remember_state");
6276 	    break;
6277 	  case DW_CFA_restore_state:
6278 	    puts ("     restore_state");
6279 	    break;
6280 	  case DW_CFA_def_cfa:
6281 	    if ((uint64_t) (endp - readp) < 1)
6282 	      goto invalid;
6283 	    get_uleb128 (op1, readp, endp);
6284 	    if ((uint64_t) (endp - readp) < 1)
6285 	      goto invalid;
6286 	    get_uleb128 (op2, readp, endp);
6287 	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6288 		    op1, regname (op1), op2);
6289 	    break;
6290 	  case DW_CFA_def_cfa_register:
6291 	    if ((uint64_t) (endp - readp) < 1)
6292 	      goto invalid;
6293 	    get_uleb128 (op1, readp, endp);
6294 	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
6295 		    op1, regname (op1));
6296 	    break;
6297 	  case DW_CFA_def_cfa_offset:
6298 	    if ((uint64_t) (endp - readp) < 1)
6299 	      goto invalid;
6300 	    get_uleb128 (op1, readp, endp);
6301 	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
6302 	    break;
6303 	  case DW_CFA_def_cfa_expression:
6304 	    if ((uint64_t) (endp - readp) < 1)
6305 	      goto invalid;
6306 	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
6307 	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
6308 	    if ((uint64_t) (endp - readp) < op1)
6309 	      {
6310 	    invalid:
6311 	        fputs (gettext ("         <INVALID DATA>\n"), stdout);
6312 		return;
6313 	      }
6314 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6315 		       op1, readp);
6316 	    readp += op1;
6317 	    break;
6318 	  case DW_CFA_expression:
6319 	    if ((uint64_t) (endp - readp) < 1)
6320 	      goto invalid;
6321 	    get_uleb128 (op1, readp, endp);
6322 	    if ((uint64_t) (endp - readp) < 1)
6323 	      goto invalid;
6324 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6325 	    printf ("     expression r%" PRIu64 " (%s) \n",
6326 		    op1, regname (op1));
6327 	    if ((uint64_t) (endp - readp) < op2)
6328 	      goto invalid;
6329 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6330 		       op2, readp);
6331 	    readp += op2;
6332 	    break;
6333 	  case DW_CFA_offset_extended_sf:
6334 	    if ((uint64_t) (endp - readp) < 1)
6335 	      goto invalid;
6336 	    get_uleb128 (op1, readp, endp);
6337 	    if ((uint64_t) (endp - readp) < 1)
6338 	      goto invalid;
6339 	    get_sleb128 (sop2, readp, endp);
6340 	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6341 		    PRId64 "\n",
6342 		    op1, regname (op1), sop2 * data_align);
6343 	    break;
6344 	  case DW_CFA_def_cfa_sf:
6345 	    if ((uint64_t) (endp - readp) < 1)
6346 	      goto invalid;
6347 	    get_uleb128 (op1, readp, endp);
6348 	    if ((uint64_t) (endp - readp) < 1)
6349 	      goto invalid;
6350 	    get_sleb128 (sop2, readp, endp);
6351 	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6352 		    op1, regname (op1), sop2 * data_align);
6353 	    break;
6354 	  case DW_CFA_def_cfa_offset_sf:
6355 	    if ((uint64_t) (endp - readp) < 1)
6356 	      goto invalid;
6357 	    get_sleb128 (sop1, readp, endp);
6358 	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6359 	    break;
6360 	  case DW_CFA_val_offset:
6361 	    if ((uint64_t) (endp - readp) < 1)
6362 	      goto invalid;
6363 	    get_uleb128 (op1, readp, endp);
6364 	    if ((uint64_t) (endp - readp) < 1)
6365 	      goto invalid;
6366 	    get_uleb128 (op2, readp, endp);
6367 	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6368 		    op1, op2 * data_align);
6369 	    break;
6370 	  case DW_CFA_val_offset_sf:
6371 	    if ((uint64_t) (endp - readp) < 1)
6372 	      goto invalid;
6373 	    get_uleb128 (op1, readp, endp);
6374 	    if ((uint64_t) (endp - readp) < 1)
6375 	      goto invalid;
6376 	    get_sleb128 (sop2, readp, endp);
6377 	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6378 		    op1, sop2 * data_align);
6379 	    break;
6380 	  case DW_CFA_val_expression:
6381 	    if ((uint64_t) (endp - readp) < 1)
6382 	      goto invalid;
6383 	    get_uleb128 (op1, readp, endp);
6384 	    if ((uint64_t) (endp - readp) < 1)
6385 	      goto invalid;
6386 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6387 	    printf ("     val_expression r%" PRIu64 " (%s)\n",
6388 		    op1, regname (op1));
6389 	    if ((uint64_t) (endp - readp) < op2)
6390 	      goto invalid;
6391 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6392 		       NULL, op2, readp);
6393 	    readp += op2;
6394 	    break;
6395 	  case DW_CFA_MIPS_advance_loc8:
6396 	    if ((uint64_t) (endp - readp) < 8)
6397 	      goto invalid;
6398 	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
6399 	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6400 		    op1, pc += op1 * code_align);
6401 	    break;
6402 	  case DW_CFA_GNU_window_save:
6403 	    puts ("     GNU_window_save");
6404 	    break;
6405 	  case DW_CFA_GNU_args_size:
6406 	    if ((uint64_t) (endp - readp) < 1)
6407 	      goto invalid;
6408 	    get_uleb128 (op1, readp, endp);
6409 	    printf ("     args_size %" PRIu64 "\n", op1);
6410 	    break;
6411 	  default:
6412 	    printf ("     ??? (%u)\n", opcode);
6413 	    break;
6414 	  }
6415       else if (opcode < DW_CFA_offset)
6416 	printf ("     advance_loc %u to %#" PRIx64 "\n",
6417 		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6418       else if (opcode < DW_CFA_restore)
6419 	{
6420 	  uint64_t offset;
6421 	  if ((uint64_t) (endp - readp) < 1)
6422 	    goto invalid;
6423 	  get_uleb128 (offset, readp, endp);
6424 	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
6425 		  opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
6426 	}
6427       else
6428 	printf ("     restore r%u (%s)\n",
6429 		opcode & 0x3f, regname (opcode & 0x3f));
6430     }
6431 }
6432 
6433 
6434 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6435 encoded_ptr_size (int encoding, unsigned int ptr_size)
6436 {
6437   switch (encoding & 7)
6438     {
6439     case DW_EH_PE_udata4:
6440       return 4;
6441     case DW_EH_PE_udata8:
6442       return 8;
6443     case 0:
6444       return ptr_size;
6445     }
6446 
6447   fprintf (stderr, "Unsupported pointer encoding: %#x, "
6448 	   "assuming pointer size of %d.\n", encoding, ptr_size);
6449   return ptr_size;
6450 }
6451 
6452 
6453 static unsigned int
print_encoding(unsigned int val)6454 print_encoding (unsigned int val)
6455 {
6456   switch (val & 0xf)
6457     {
6458     case DW_EH_PE_absptr:
6459       fputs ("absptr", stdout);
6460       break;
6461     case DW_EH_PE_uleb128:
6462       fputs ("uleb128", stdout);
6463       break;
6464     case DW_EH_PE_udata2:
6465       fputs ("udata2", stdout);
6466       break;
6467     case DW_EH_PE_udata4:
6468       fputs ("udata4", stdout);
6469       break;
6470     case DW_EH_PE_udata8:
6471       fputs ("udata8", stdout);
6472       break;
6473     case DW_EH_PE_sleb128:
6474       fputs ("sleb128", stdout);
6475       break;
6476     case DW_EH_PE_sdata2:
6477       fputs ("sdata2", stdout);
6478       break;
6479     case DW_EH_PE_sdata4:
6480       fputs ("sdata4", stdout);
6481       break;
6482     case DW_EH_PE_sdata8:
6483       fputs ("sdata8", stdout);
6484       break;
6485     default:
6486       /* We did not use any of the bits after all.  */
6487       return val;
6488     }
6489 
6490   return val & ~0xf;
6491 }
6492 
6493 
6494 static unsigned int
print_relinfo(unsigned int val)6495 print_relinfo (unsigned int val)
6496 {
6497   switch (val & 0x70)
6498     {
6499     case DW_EH_PE_pcrel:
6500       fputs ("pcrel", stdout);
6501       break;
6502     case DW_EH_PE_textrel:
6503       fputs ("textrel", stdout);
6504       break;
6505     case DW_EH_PE_datarel:
6506       fputs ("datarel", stdout);
6507       break;
6508     case DW_EH_PE_funcrel:
6509       fputs ("funcrel", stdout);
6510       break;
6511     case DW_EH_PE_aligned:
6512       fputs ("aligned", stdout);
6513       break;
6514     default:
6515       return val;
6516     }
6517 
6518   return val & ~0x70;
6519 }
6520 
6521 
6522 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6523 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6524 {
6525   printf ("(%s", pfx);
6526 
6527   if (fde_encoding == DW_EH_PE_omit)
6528     puts ("omit)");
6529   else
6530     {
6531       unsigned int w = fde_encoding;
6532 
6533       w = print_encoding (w);
6534 
6535       if (w & 0x70)
6536 	{
6537 	  if (w != fde_encoding)
6538 	    fputc_unlocked (' ', stdout);
6539 
6540 	  w = print_relinfo (w);
6541 	}
6542 
6543       if (w != 0)
6544 	printf ("%s%x", w != fde_encoding ? " " : "", w);
6545 
6546       puts (")");
6547     }
6548 }
6549 
6550 
6551 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6552 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6553 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6554 {
6555   size_t shstrndx;
6556   /* We know this call will succeed since it did in the caller.  */
6557   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6558   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6559 
6560   /* Needed if we find PC-relative addresses.  */
6561   GElf_Addr bias;
6562   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6563     {
6564       error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
6565       return;
6566     }
6567 
6568   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6569   Elf_Data *data = (is_eh_frame
6570 		    ? elf_rawdata (scn, NULL)
6571 		    : (dbg->sectiondata[IDX_debug_frame]
6572 		       ?: elf_rawdata (scn, NULL)));
6573 
6574   if (unlikely (data == NULL))
6575     {
6576       error (0, 0, gettext ("cannot get %s content: %s"),
6577 	     scnname, elf_errmsg (-1));
6578       return;
6579     }
6580 
6581   if (is_eh_frame)
6582     printf (gettext ("\
6583 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6584 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6585   else
6586     printf (gettext ("\
6587 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6588 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6589 
6590   struct cieinfo
6591   {
6592     ptrdiff_t cie_offset;
6593     const char *augmentation;
6594     unsigned int code_alignment_factor;
6595     unsigned int data_alignment_factor;
6596     uint8_t address_size;
6597     uint8_t fde_encoding;
6598     uint8_t lsda_encoding;
6599     struct cieinfo *next;
6600   } *cies = NULL;
6601 
6602   const unsigned char *readp = data->d_buf;
6603   const unsigned char *const dataend = ((unsigned char *) data->d_buf
6604 					+ data->d_size);
6605   while (readp < dataend)
6606     {
6607       if (unlikely (readp + 4 > dataend))
6608 	{
6609 	invalid_data:
6610 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6611 		     elf_ndxscn (scn), scnname);
6612 	      return;
6613 	}
6614 
6615       /* At the beginning there must be a CIE.  There can be multiple,
6616 	 hence we test tis in a loop.  */
6617       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6618 
6619       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6620       unsigned int length = 4;
6621       if (unlikely (unit_length == 0xffffffff))
6622 	{
6623 	  if (unlikely (readp + 8 > dataend))
6624 	    goto invalid_data;
6625 
6626 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6627 	  length = 8;
6628 	}
6629 
6630       if (unlikely (unit_length == 0))
6631 	{
6632 	  printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
6633 	  continue;
6634 	}
6635 
6636       Dwarf_Word maxsize = dataend - readp;
6637       if (unlikely (unit_length > maxsize))
6638 	goto invalid_data;
6639 
6640       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6641 
6642       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6643       const unsigned char *const cieend = readp + unit_length;
6644       if (unlikely (cieend > dataend))
6645 	goto invalid_data;
6646 
6647       Dwarf_Off cie_id;
6648       if (length == 4)
6649 	{
6650 	  if (unlikely (cieend - readp < 4))
6651 	    goto invalid_data;
6652 	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6653 	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6654 	    cie_id = DW_CIE_ID_64;
6655 	}
6656       else
6657 	{
6658 	  if (unlikely (cieend - readp < 8))
6659 	    goto invalid_data;
6660 	  cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6661 	}
6662 
6663       uint_fast8_t version = 2;
6664       unsigned int code_alignment_factor;
6665       int data_alignment_factor;
6666       unsigned int fde_encoding = 0;
6667       unsigned int lsda_encoding = 0;
6668       Dwarf_Word initial_location = 0;
6669       Dwarf_Word vma_base = 0;
6670 
6671       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6672 	{
6673 	  if (unlikely (cieend - readp < 2))
6674 	    goto invalid_data;
6675 	  version = *readp++;
6676 	  const char *const augmentation = (const char *) readp;
6677 	  readp = memchr (readp, '\0', cieend - readp);
6678 	  if (unlikely (readp == NULL))
6679 	    goto invalid_data;
6680 	  ++readp;
6681 
6682 	  uint_fast8_t segment_size = 0;
6683 	  if (version >= 4)
6684 	    {
6685 	      if (cieend - readp < 5)
6686 		goto invalid_data;
6687 	      ptr_size = *readp++;
6688 	      segment_size = *readp++;
6689 	    }
6690 
6691 	  if (cieend - readp < 1)
6692 	    goto invalid_data;
6693 	  get_uleb128 (code_alignment_factor, readp, cieend);
6694 	  if (cieend - readp < 1)
6695 	    goto invalid_data;
6696 	  get_sleb128 (data_alignment_factor, readp, cieend);
6697 
6698 	  /* In some variant for unwind data there is another field.  */
6699 	  if (strcmp (augmentation, "eh") == 0)
6700 	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6701 
6702 	  unsigned int return_address_register;
6703 	  if (cieend - readp < 1)
6704 	    goto invalid_data;
6705 	  if (unlikely (version == 1))
6706 	    return_address_register = *readp++;
6707 	  else
6708 	    get_uleb128 (return_address_register, readp, cieend);
6709 
6710 	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6711 		  "   CIE_id:                   %" PRIu64 "\n"
6712 		  "   version:                  %u\n"
6713 		  "   augmentation:             \"%s\"\n",
6714 		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
6715 		  version, augmentation);
6716 	  if (version >= 4)
6717 	    printf ("   address_size:             %u\n"
6718 		    "   segment_size:             %u\n",
6719 		    ptr_size, segment_size);
6720 	  printf ("   code_alignment_factor:    %u\n"
6721 		  "   data_alignment_factor:    %d\n"
6722 		  "   return_address_register:  %u\n",
6723 		  code_alignment_factor,
6724 		  data_alignment_factor, return_address_register);
6725 
6726 	  if (augmentation[0] == 'z')
6727 	    {
6728 	      unsigned int augmentationlen;
6729 	      get_uleb128 (augmentationlen, readp, cieend);
6730 
6731 	      if (augmentationlen > (size_t) (cieend - readp))
6732 		{
6733 		  error (0, 0, gettext ("invalid augmentation length"));
6734 		  readp = cieend;
6735 		  continue;
6736 		}
6737 
6738 	      const char *hdr = "Augmentation data:";
6739 	      const char *cp = augmentation + 1;
6740 	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6741 		{
6742 		  printf ("   %-26s%#x ", hdr, *readp);
6743 		  hdr = "";
6744 
6745 		  if (*cp == 'R')
6746 		    {
6747 		      fde_encoding = *readp++;
6748 		      print_encoding_base (gettext ("FDE address encoding: "),
6749 					   fde_encoding);
6750 		    }
6751 		  else if (*cp == 'L')
6752 		    {
6753 		      lsda_encoding = *readp++;
6754 		      print_encoding_base (gettext ("LSDA pointer encoding: "),
6755 					   lsda_encoding);
6756 		    }
6757 		  else if (*cp == 'P')
6758 		    {
6759 		      /* Personality.  This field usually has a relocation
6760 			 attached pointing to __gcc_personality_v0.  */
6761 		      const unsigned char *startp = readp;
6762 		      unsigned int encoding = *readp++;
6763 		      uint64_t val = 0;
6764 		      readp = read_encoded (encoding, readp,
6765 					    readp - 1 + augmentationlen,
6766 					    &val, dbg);
6767 
6768 		      while (++startp < readp)
6769 			printf ("%#x ", *startp);
6770 
6771 		      putchar ('(');
6772 		      print_encoding (encoding);
6773 		      putchar (' ');
6774 		      switch (encoding & 0xf)
6775 			{
6776 			case DW_EH_PE_sleb128:
6777 			case DW_EH_PE_sdata2:
6778 			case DW_EH_PE_sdata4:
6779 			  printf ("%" PRId64 ")\n", val);
6780 			  break;
6781 			default:
6782 			  printf ("%#" PRIx64 ")\n", val);
6783 			  break;
6784 			}
6785 		    }
6786 		  else
6787 		    printf ("(%x)\n", *readp++);
6788 
6789 		  ++cp;
6790 		}
6791 	    }
6792 
6793 	  if (likely (ptr_size == 4 || ptr_size == 8))
6794 	    {
6795 	      struct cieinfo *newp = alloca (sizeof (*newp));
6796 	      newp->cie_offset = offset;
6797 	      newp->augmentation = augmentation;
6798 	      newp->fde_encoding = fde_encoding;
6799 	      newp->lsda_encoding = lsda_encoding;
6800 	      newp->address_size = ptr_size;
6801 	      newp->code_alignment_factor = code_alignment_factor;
6802 	      newp->data_alignment_factor = data_alignment_factor;
6803 	      newp->next = cies;
6804 	      cies = newp;
6805 	    }
6806 	}
6807       else
6808 	{
6809 	  struct cieinfo *cie = cies;
6810 	  while (cie != NULL)
6811 	    if (is_eh_frame
6812 		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6813 		: cie_id == (Dwarf_Off) cie->cie_offset)
6814 	      break;
6815 	    else
6816 	      cie = cie->next;
6817 	  if (unlikely (cie == NULL))
6818 	    {
6819 	      puts ("invalid CIE reference in FDE");
6820 	      return;
6821 	    }
6822 
6823 	  /* Initialize from CIE data.  */
6824 	  fde_encoding = cie->fde_encoding;
6825 	  lsda_encoding = cie->lsda_encoding;
6826 	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6827 	  code_alignment_factor = cie->code_alignment_factor;
6828 	  data_alignment_factor = cie->data_alignment_factor;
6829 
6830 	  const unsigned char *base = readp;
6831 	  // XXX There are sometimes relocations for this value
6832 	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6833 	  Dwarf_Word address_range
6834 	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
6835 
6836 	  /* pcrel for an FDE address is relative to the runtime
6837 	     address of the start_address field itself.  Sign extend
6838 	     if necessary to make sure the calculation is done on the
6839 	     full 64 bit address even when initial_location only holds
6840 	     the lower 32 bits.  */
6841 	  Dwarf_Addr pc_start = initial_location;
6842 	  if (ptr_size == 4)
6843 	    pc_start = (uint64_t) (int32_t) pc_start;
6844 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6845 	    pc_start += ((uint64_t) shdr->sh_addr
6846 			 + (base - (const unsigned char *) data->d_buf)
6847 			 - bias);
6848 
6849 	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6850 		  "   CIE_pointer:              %" PRIu64 "\n"
6851 		  "   initial_location:         ",
6852 		  offset, (uint64_t) unit_length,
6853 		  cie->cie_offset, (uint64_t) cie_id);
6854 	  print_dwarf_addr (dwflmod, cie->address_size,
6855 			    pc_start, initial_location);
6856 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6857 	    {
6858 	      vma_base = (((uint64_t) shdr->sh_offset
6859 			   + (base - (const unsigned char *) data->d_buf)
6860 			   + (uint64_t) initial_location)
6861 			  & (ptr_size == 4
6862 			     ? UINT64_C (0xffffffff)
6863 			     : UINT64_C (0xffffffffffffffff)));
6864 	      printf (gettext (" (offset: %#" PRIx64 ")"),
6865 		      (uint64_t) vma_base);
6866 	    }
6867 
6868 	  printf ("\n   address_range:            %#" PRIx64,
6869 		  (uint64_t) address_range);
6870 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6871 	    printf (gettext (" (end offset: %#" PRIx64 ")"),
6872 		    ((uint64_t) vma_base + (uint64_t) address_range)
6873 		    & (ptr_size == 4
6874 		       ? UINT64_C (0xffffffff)
6875 		       : UINT64_C (0xffffffffffffffff)));
6876 	  putchar ('\n');
6877 
6878 	  if (cie->augmentation[0] == 'z')
6879 	    {
6880 	      unsigned int augmentationlen;
6881 	      if (cieend - readp < 1)
6882 		goto invalid_data;
6883 	      get_uleb128 (augmentationlen, readp, cieend);
6884 
6885 	      if (augmentationlen > (size_t) (cieend - readp))
6886 		{
6887 		  error (0, 0, gettext ("invalid augmentation length"));
6888 		  readp = cieend;
6889 		  continue;
6890 		}
6891 
6892 	      if (augmentationlen > 0)
6893 		{
6894 		  const char *hdr = "Augmentation data:";
6895 		  const char *cp = cie->augmentation + 1;
6896 		  unsigned int u = 0;
6897 		  while (*cp != '\0'
6898 			 && cp < cie->augmentation + augmentationlen + 1)
6899 		    {
6900 		      if (*cp == 'L')
6901 			{
6902 			  uint64_t lsda_pointer;
6903 			  const unsigned char *p
6904 			    = read_encoded (lsda_encoding, &readp[u],
6905 					    &readp[augmentationlen],
6906 					    &lsda_pointer, dbg);
6907 			  u = p - readp;
6908 			  printf (gettext ("\
6909    %-26sLSDA pointer: %#" PRIx64 "\n"),
6910 				  hdr, lsda_pointer);
6911 			  hdr = "";
6912 			}
6913 		      ++cp;
6914 		    }
6915 
6916 		  while (u < augmentationlen)
6917 		    {
6918 		      printf ("   %-26s%#x\n", hdr, readp[u++]);
6919 		      hdr = "";
6920 		    }
6921 		}
6922 
6923 	      readp += augmentationlen;
6924 	    }
6925 	}
6926 
6927       /* Handle the initialization instructions.  */
6928       if (ptr_size != 4 && ptr_size !=8)
6929 	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6930       else
6931 	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6932 			   data_alignment_factor, version, ptr_size,
6933 			   fde_encoding, dwflmod, ebl, dbg);
6934       readp = cieend;
6935     }
6936 }
6937 
6938 
6939 /* Returns the signedness (or false if it cannot be determined) and
6940    the byte size (or zero if it cannot be gotten) of the given DIE
6941    DW_AT_type attribute.  Uses dwarf_peel_type and dwarf_aggregate_size.  */
6942 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)6943 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
6944 {
6945   Dwarf_Attribute attr;
6946   Dwarf_Die type;
6947 
6948   *bytes = 0;
6949   *is_signed = false;
6950 
6951   if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
6952 								DW_AT_type,
6953 								&attr), &type),
6954 		       &type) == 0)
6955     {
6956       Dwarf_Word val;
6957       *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
6958 						 &attr), &val) == 0
6959 		    && (val == DW_ATE_signed || val == DW_ATE_signed_char));
6960 
6961       if (dwarf_aggregate_size (&type, &val) == 0)
6962 	*bytes = val;
6963     }
6964 }
6965 
6966 struct attrcb_args
6967 {
6968   Dwfl_Module *dwflmod;
6969   Dwarf *dbg;
6970   Dwarf_Die *dies;
6971   int level;
6972   bool silent;
6973   bool is_split;
6974   unsigned int version;
6975   unsigned int addrsize;
6976   unsigned int offset_size;
6977   struct Dwarf_CU *cu;
6978 };
6979 
6980 
6981 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)6982 attr_callback (Dwarf_Attribute *attrp, void *arg)
6983 {
6984   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
6985   const int level = cbargs->level;
6986   Dwarf_Die *die = &cbargs->dies[level];
6987   bool is_split = cbargs->is_split;
6988 
6989   unsigned int attr = dwarf_whatattr (attrp);
6990   if (unlikely (attr == 0))
6991     {
6992       if (!cbargs->silent)
6993 	error (0, 0, gettext ("DIE [%" PRIx64 "] "
6994 			      "cannot get attribute code: %s"),
6995 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
6996       return DWARF_CB_ABORT;
6997     }
6998 
6999   unsigned int form = dwarf_whatform (attrp);
7000   if (unlikely (form == 0))
7001     {
7002       if (!cbargs->silent)
7003 	error (0, 0, gettext ("DIE [%" PRIx64 "] "
7004 			      "cannot get attribute form: %s"),
7005 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7006       return DWARF_CB_ABORT;
7007     }
7008 
7009   switch (form)
7010     {
7011     case DW_FORM_addr:
7012     case DW_FORM_addrx:
7013     case DW_FORM_addrx1:
7014     case DW_FORM_addrx2:
7015     case DW_FORM_addrx3:
7016     case DW_FORM_addrx4:
7017     case DW_FORM_GNU_addr_index:
7018       if (!cbargs->silent)
7019 	{
7020 	  Dwarf_Addr addr;
7021 	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7022 	    {
7023 	    attrval_out:
7024 	      if (!cbargs->silent)
7025 		error (0, 0, gettext ("DIE [%" PRIx64 "] "
7026 				      "cannot get attribute '%s' (%s) value: "
7027 				      "%s"),
7028 		       dwarf_dieoffset (die),
7029 		       dwarf_attr_name (attr),
7030 		       dwarf_form_name (form),
7031 		       dwarf_errmsg (-1));
7032 	      /* Don't ABORT, it might be other attributes can be resolved.  */
7033 	      return DWARF_CB_OK;
7034 	    }
7035 	  if (form != DW_FORM_addr )
7036 	    {
7037 	      Dwarf_Word word;
7038 	      if (dwarf_formudata (attrp, &word) != 0)
7039 		goto attrval_out;
7040 	      printf ("           %*s%-20s (%s) [%" PRIx64 "] ",
7041 		      (int) (level * 2), "", dwarf_attr_name (attr),
7042 		      dwarf_form_name (form), word);
7043 	    }
7044 	  else
7045 	    printf ("           %*s%-20s (%s) ",
7046 		    (int) (level * 2), "", dwarf_attr_name (attr),
7047 		    dwarf_form_name (form));
7048 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7049 	  printf ("\n");
7050 	}
7051       break;
7052 
7053     case DW_FORM_indirect:
7054     case DW_FORM_strp:
7055     case DW_FORM_line_strp:
7056     case DW_FORM_strx:
7057     case DW_FORM_strx1:
7058     case DW_FORM_strx2:
7059     case DW_FORM_strx3:
7060     case DW_FORM_strx4:
7061     case DW_FORM_string:
7062     case DW_FORM_GNU_strp_alt:
7063     case DW_FORM_GNU_str_index:
7064       if (cbargs->silent)
7065 	break;
7066       const char *str = dwarf_formstring (attrp);
7067       if (unlikely (str == NULL))
7068 	goto attrval_out;
7069       printf ("           %*s%-20s (%s) \"%s\"\n",
7070 	      (int) (level * 2), "", dwarf_attr_name (attr),
7071 	      dwarf_form_name (form), str);
7072       break;
7073 
7074     case DW_FORM_ref_addr:
7075     case DW_FORM_ref_udata:
7076     case DW_FORM_ref8:
7077     case DW_FORM_ref4:
7078     case DW_FORM_ref2:
7079     case DW_FORM_ref1:
7080     case DW_FORM_GNU_ref_alt:
7081     case DW_FORM_ref_sup4:
7082     case DW_FORM_ref_sup8:
7083       if (cbargs->silent)
7084 	break;
7085       Dwarf_Die ref;
7086       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7087 	goto attrval_out;
7088 
7089       printf ("           %*s%-20s (%s) ",
7090 	      (int) (level * 2), "", dwarf_attr_name (attr),
7091 	      dwarf_form_name (form));
7092       if (is_split)
7093 	printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7094       else
7095 	printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7096       break;
7097 
7098     case DW_FORM_ref_sig8:
7099       if (cbargs->silent)
7100 	break;
7101       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
7102 	      (int) (level * 2), "", dwarf_attr_name (attr),
7103 	      dwarf_form_name (form),
7104 	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7105       break;
7106 
7107     case DW_FORM_sec_offset:
7108     case DW_FORM_rnglistx:
7109     case DW_FORM_loclistx:
7110     case DW_FORM_implicit_const:
7111     case DW_FORM_udata:
7112     case DW_FORM_sdata:
7113     case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7114     case DW_FORM_data4:
7115     case DW_FORM_data2:
7116     case DW_FORM_data1:;
7117       Dwarf_Word num;
7118       if (unlikely (dwarf_formudata (attrp, &num) != 0))
7119 	goto attrval_out;
7120 
7121       const char *valuestr = NULL;
7122       bool as_hex_id = false;
7123       switch (attr)
7124 	{
7125 	  /* This case can take either a constant or a loclistptr.  */
7126 	case DW_AT_data_member_location:
7127 	  if (form != DW_FORM_sec_offset
7128 	      && (cbargs->version >= 4
7129 		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7130 	    {
7131 	      if (!cbargs->silent)
7132 		printf ("           %*s%-20s (%s) %" PRIuMAX "\n",
7133 			(int) (level * 2), "", dwarf_attr_name (attr),
7134 			dwarf_form_name (form), (uintmax_t) num);
7135 	      return DWARF_CB_OK;
7136 	    }
7137 	  FALLTHROUGH;
7138 
7139 	/* These cases always take a loclist[ptr] and no constant. */
7140 	case DW_AT_location:
7141 	case DW_AT_data_location:
7142 	case DW_AT_vtable_elem_location:
7143 	case DW_AT_string_length:
7144 	case DW_AT_use_location:
7145 	case DW_AT_frame_base:
7146 	case DW_AT_return_addr:
7147 	case DW_AT_static_link:
7148 	case DW_AT_segment:
7149 	case DW_AT_GNU_call_site_value:
7150 	case DW_AT_GNU_call_site_data_value:
7151 	case DW_AT_GNU_call_site_target:
7152 	case DW_AT_GNU_call_site_target_clobbered:
7153 	case DW_AT_GNU_locviews:
7154 	  {
7155 	    bool nlpt;
7156 	    if (cbargs->cu->version < 5)
7157 	      {
7158 		if (! cbargs->is_split)
7159 		  {
7160 		    nlpt = notice_listptr (section_loc, &known_locsptr,
7161 					   cbargs->addrsize,
7162 					   cbargs->offset_size,
7163 					   cbargs->cu, num, attr);
7164 		  }
7165 		else
7166 		  nlpt = true;
7167 	      }
7168 	    else
7169 	      {
7170 		/* Only register for a real section offset.  Otherwise
7171 		   it is a DW_FORM_loclistx which is just an index
7172 		   number and we should already have registered the
7173 		   section offset for the index when we saw the
7174 		   DW_AT_loclists_base CU attribute.  */
7175 		if (form == DW_FORM_sec_offset)
7176 		  nlpt = notice_listptr (section_loc, &known_loclistsptr,
7177 					 cbargs->addrsize, cbargs->offset_size,
7178 					 cbargs->cu, num, attr);
7179 		else
7180 		  nlpt = true;
7181 
7182 	      }
7183 
7184 	    if (!cbargs->silent)
7185 	      {
7186 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7187 		  printf ("           %*s%-20s (%s) location list [%6"
7188 			  PRIxMAX "]%s\n",
7189 			  (int) (level * 2), "", dwarf_attr_name (attr),
7190 			  dwarf_form_name (form), (uintmax_t) num,
7191 			  nlpt ? "" : " <WARNING offset too big>");
7192 		else
7193 		  printf ("           %*s%-20s (%s) location index [%6"
7194 			  PRIxMAX "]\n",
7195 			  (int) (level * 2), "", dwarf_attr_name (attr),
7196 			  dwarf_form_name (form), (uintmax_t) num);
7197 	      }
7198 	  }
7199 	  return DWARF_CB_OK;
7200 
7201 	case DW_AT_loclists_base:
7202 	  {
7203 	    bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7204                                         cbargs->addrsize, cbargs->offset_size,
7205                                         cbargs->cu, num, attr);
7206 
7207 	    if (!cbargs->silent)
7208 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7209 		      (int) (level * 2), "", dwarf_attr_name (attr),
7210 		      dwarf_form_name (form), (uintmax_t) num,
7211 		      nlpt ? "" : " <WARNING offset too big>");
7212 	  }
7213 	  return DWARF_CB_OK;
7214 
7215 	case DW_AT_ranges:
7216 	case DW_AT_start_scope:
7217 	  {
7218 	    bool nlpt;
7219 	    if (cbargs->cu->version < 5)
7220 	      nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7221 				     cbargs->addrsize, cbargs->offset_size,
7222 				     cbargs->cu, num, attr);
7223 	    else
7224 	      {
7225 		/* Only register for a real section offset.  Otherwise
7226 		   it is a DW_FORM_rangelistx which is just an index
7227 		   number and we should already have registered the
7228 		   section offset for the index when we saw the
7229 		   DW_AT_rnglists_base CU attribute.  */
7230 		if (form == DW_FORM_sec_offset)
7231 		  nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7232 					 cbargs->addrsize, cbargs->offset_size,
7233 					 cbargs->cu, num, attr);
7234 		else
7235 		  nlpt = true;
7236 	      }
7237 
7238 	    if (!cbargs->silent)
7239 	      {
7240 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7241 		  printf ("           %*s%-20s (%s) range list [%6"
7242 			  PRIxMAX "]%s\n",
7243 			  (int) (level * 2), "", dwarf_attr_name (attr),
7244 			  dwarf_form_name (form), (uintmax_t) num,
7245 			  nlpt ? "" : " <WARNING offset too big>");
7246 		else
7247 		  printf ("           %*s%-20s (%s) range index [%6"
7248 			  PRIxMAX "]\n",
7249 			  (int) (level * 2), "", dwarf_attr_name (attr),
7250 			  dwarf_form_name (form), (uintmax_t) num);
7251 	      }
7252 	  }
7253 	  return DWARF_CB_OK;
7254 
7255 	case DW_AT_rnglists_base:
7256 	  {
7257 	    bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7258 					cbargs->addrsize, cbargs->offset_size,
7259 					cbargs->cu, num, attr);
7260 	    if (!cbargs->silent)
7261 	      printf ("           %*s%-20s (%s) range list [%6"
7262 		      PRIxMAX "]%s\n",
7263 		      (int) (level * 2), "", dwarf_attr_name (attr),
7264 		      dwarf_form_name (form), (uintmax_t) num,
7265 		      nlpt ? "" : " <WARNING offset too big>");
7266 	  }
7267 	  return DWARF_CB_OK;
7268 
7269 	case DW_AT_addr_base:
7270 	case DW_AT_GNU_addr_base:
7271 	  {
7272 	    bool addrbase = notice_listptr (section_addr, &known_addrbases,
7273 					    cbargs->addrsize,
7274 					    cbargs->offset_size,
7275 					    cbargs->cu, num, attr);
7276 	    if (!cbargs->silent)
7277 	      printf ("           %*s%-20s (%s) address base [%6"
7278 		      PRIxMAX "]%s\n",
7279 		      (int) (level * 2), "", dwarf_attr_name (attr),
7280 		      dwarf_form_name (form), (uintmax_t) num,
7281 		      addrbase ? "" : " <WARNING offset too big>");
7282 	  }
7283 	  return DWARF_CB_OK;
7284 
7285 	case DW_AT_str_offsets_base:
7286 	  {
7287 	    bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7288 					      cbargs->addrsize,
7289 					      cbargs->offset_size,
7290 					      cbargs->cu, num, attr);
7291 	    if (!cbargs->silent)
7292 	      printf ("           %*s%-20s (%s) str offsets base [%6"
7293 		      PRIxMAX "]%s\n",
7294 		      (int) (level * 2), "", dwarf_attr_name (attr),
7295 		      dwarf_form_name (form), (uintmax_t) num,
7296 		      stroffbase ? "" : " <WARNING offset too big>");
7297 	  }
7298 	  return DWARF_CB_OK;
7299 
7300 	case DW_AT_language:
7301 	  valuestr = dwarf_lang_name (num);
7302 	  break;
7303 	case DW_AT_encoding:
7304 	  valuestr = dwarf_encoding_name (num);
7305 	  break;
7306 	case DW_AT_accessibility:
7307 	  valuestr = dwarf_access_name (num);
7308 	  break;
7309 	case DW_AT_defaulted:
7310 	  valuestr = dwarf_defaulted_name (num);
7311 	  break;
7312 	case DW_AT_visibility:
7313 	  valuestr = dwarf_visibility_name (num);
7314 	  break;
7315 	case DW_AT_virtuality:
7316 	  valuestr = dwarf_virtuality_name (num);
7317 	  break;
7318 	case DW_AT_identifier_case:
7319 	  valuestr = dwarf_identifier_case_name (num);
7320 	  break;
7321 	case DW_AT_calling_convention:
7322 	  valuestr = dwarf_calling_convention_name (num);
7323 	  break;
7324 	case DW_AT_inline:
7325 	  valuestr = dwarf_inline_name (num);
7326 	  break;
7327 	case DW_AT_ordering:
7328 	  valuestr = dwarf_ordering_name (num);
7329 	  break;
7330 	case DW_AT_decl_file:
7331 	case DW_AT_call_file:
7332 	  {
7333 	    if (cbargs->silent)
7334 	      break;
7335 
7336 	    /* Try to get the actual file, the current interface only
7337 	       gives us full paths, but we only want to show the file
7338 	       name for now.  */
7339 	    Dwarf_Die cudie;
7340 	    if (dwarf_cu_die (cbargs->cu, &cudie,
7341 			      NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7342 	      {
7343 		Dwarf_Files *files;
7344 		size_t nfiles;
7345 		if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7346 		  {
7347 		    valuestr = dwarf_filesrc (files, num, NULL, NULL);
7348 		    if (valuestr != NULL)
7349 		      {
7350 			char *filename = strrchr (valuestr, '/');
7351 			if (filename != NULL)
7352 			  valuestr = filename + 1;
7353 		      }
7354 		    else
7355 		      error (0, 0, gettext ("invalid file (%" PRId64 "): %s"),
7356 			     num, dwarf_errmsg (-1));
7357 		  }
7358 		else
7359 		  error (0, 0, gettext ("no srcfiles for CU [%" PRIx64 "]"),
7360 			 dwarf_dieoffset (&cudie));
7361 	      }
7362 	    else
7363 	     error (0, 0, gettext ("couldn't get DWARF CU: %s"),
7364 		    dwarf_errmsg (-1));
7365 	    if (valuestr == NULL)
7366 	      valuestr = "???";
7367 	  }
7368 	  break;
7369 	case DW_AT_GNU_dwo_id:
7370 	  as_hex_id = true;
7371 	  break;
7372 
7373 	default:
7374 	  /* Nothing.  */
7375 	  break;
7376 	}
7377 
7378       if (cbargs->silent)
7379 	break;
7380 
7381       /* When highpc is in constant form it is relative to lowpc.
7382 	 In that case also show the address.  */
7383       Dwarf_Addr highpc;
7384       if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7385 	{
7386 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (",
7387 		  (int) (level * 2), "", dwarf_attr_name (attr),
7388 		  dwarf_form_name (form), (uintmax_t) num);
7389 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7390 	  printf (")\n");
7391 	}
7392       else
7393 	{
7394 	  if (as_hex_id)
7395 	    {
7396 	      printf ("           %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7397 		      (int) (level * 2), "", dwarf_attr_name (attr),
7398 		      dwarf_form_name (form), num);
7399 	    }
7400 	  else
7401 	    {
7402 	      Dwarf_Sword snum = 0;
7403 	      bool is_signed;
7404 	      int bytes = 0;
7405 	      if (attr == DW_AT_const_value)
7406 		die_type_sign_bytes (die, &is_signed, &bytes);
7407 	      else
7408 		is_signed = (form == DW_FORM_sdata
7409 			     || form == DW_FORM_implicit_const);
7410 
7411 	      if (is_signed)
7412 		if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7413 		  goto attrval_out;
7414 
7415 	      if (valuestr == NULL)
7416 		{
7417 		  printf ("           %*s%-20s (%s) ",
7418 			  (int) (level * 2), "", dwarf_attr_name (attr),
7419 			  dwarf_form_name (form));
7420 		}
7421 	      else
7422 		{
7423 		  printf ("           %*s%-20s (%s) %s (",
7424 			  (int) (level * 2), "", dwarf_attr_name (attr),
7425 			  dwarf_form_name (form), valuestr);
7426 		}
7427 
7428 	      switch (bytes)
7429 		{
7430 		case 1:
7431 		  if (is_signed)
7432 		    printf ("%" PRId8, (int8_t) snum);
7433 		  else
7434 		    printf ("%" PRIu8, (uint8_t) num);
7435 		  break;
7436 
7437 		case 2:
7438 		  if (is_signed)
7439 		    printf ("%" PRId16, (int16_t) snum);
7440 		  else
7441 		    printf ("%" PRIu16, (uint16_t) num);
7442 		  break;
7443 
7444 		case 4:
7445 		  if (is_signed)
7446 		    printf ("%" PRId32, (int32_t) snum);
7447 		  else
7448 		    printf ("%" PRIu32, (uint32_t) num);
7449 		  break;
7450 
7451 		case 8:
7452 		  if (is_signed)
7453 		    printf ("%" PRId64, (int64_t) snum);
7454 		  else
7455 		    printf ("%" PRIu64, (uint64_t) num);
7456 		  break;
7457 
7458 		default:
7459 		  if (is_signed)
7460 		    printf ("%" PRIdMAX, (intmax_t) snum);
7461 		  else
7462 		    printf ("%" PRIuMAX, (uintmax_t) num);
7463 		  break;
7464 		}
7465 
7466 	      /* Make clear if we switched from a signed encoding to
7467 		 an unsigned value.  */
7468 	      if (attr == DW_AT_const_value
7469 		  && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7470 		  && !is_signed)
7471 		printf (" (%" PRIdMAX ")", (intmax_t) num);
7472 
7473 	      if (valuestr == NULL)
7474 		printf ("\n");
7475 	      else
7476 		printf (")\n");
7477 	    }
7478 	}
7479       break;
7480 
7481     case DW_FORM_flag:
7482       if (cbargs->silent)
7483 	break;
7484       bool flag;
7485       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7486 	goto attrval_out;
7487 
7488       printf ("           %*s%-20s (%s) %s\n",
7489 	      (int) (level * 2), "", dwarf_attr_name (attr),
7490 	      dwarf_form_name (form), flag ? yes_str : no_str);
7491       break;
7492 
7493     case DW_FORM_flag_present:
7494       if (cbargs->silent)
7495 	break;
7496       printf ("           %*s%-20s (%s) %s\n",
7497 	      (int) (level * 2), "", dwarf_attr_name (attr),
7498 	      dwarf_form_name (form), yes_str);
7499       break;
7500 
7501     case DW_FORM_exprloc:
7502     case DW_FORM_block4:
7503     case DW_FORM_block2:
7504     case DW_FORM_block1:
7505     case DW_FORM_block:
7506     case DW_FORM_data16: /* DWARF5 calls this a constant class.  */
7507       if (cbargs->silent)
7508 	break;
7509       Dwarf_Block block;
7510       if (unlikely (dwarf_formblock (attrp, &block) != 0))
7511 	goto attrval_out;
7512 
7513       printf ("           %*s%-20s (%s) ",
7514 	      (int) (level * 2), "", dwarf_attr_name (attr),
7515 	      dwarf_form_name (form));
7516 
7517       switch (attr)
7518 	{
7519 	default:
7520 	  if (form != DW_FORM_exprloc)
7521 	    {
7522 	      print_block (block.length, block.data);
7523 	      break;
7524 	    }
7525 	  FALLTHROUGH;
7526 
7527 	case DW_AT_location:
7528 	case DW_AT_data_location:
7529 	case DW_AT_data_member_location:
7530 	case DW_AT_vtable_elem_location:
7531 	case DW_AT_string_length:
7532 	case DW_AT_use_location:
7533 	case DW_AT_frame_base:
7534 	case DW_AT_return_addr:
7535 	case DW_AT_static_link:
7536 	case DW_AT_allocated:
7537 	case DW_AT_associated:
7538 	case DW_AT_bit_size:
7539 	case DW_AT_bit_offset:
7540 	case DW_AT_bit_stride:
7541 	case DW_AT_byte_size:
7542 	case DW_AT_byte_stride:
7543 	case DW_AT_count:
7544 	case DW_AT_lower_bound:
7545 	case DW_AT_upper_bound:
7546 	case DW_AT_GNU_call_site_value:
7547 	case DW_AT_GNU_call_site_data_value:
7548 	case DW_AT_GNU_call_site_target:
7549 	case DW_AT_GNU_call_site_target_clobbered:
7550 	  if (form != DW_FORM_data16)
7551 	    {
7552 	      putchar ('\n');
7553 	      print_ops (cbargs->dwflmod, cbargs->dbg,
7554 			 12 + level * 2, 12 + level * 2,
7555 			 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7556 			 attrp->cu, block.length, block.data);
7557 	    }
7558 	  else
7559 	    print_block (block.length, block.data);
7560 	  break;
7561 
7562 	case DW_AT_discr_list:
7563 	  if (block.length == 0)
7564 	    puts ("<default>");
7565 	  else if (form != DW_FORM_data16)
7566 	    {
7567 	      const unsigned char *readp = block.data;
7568 	      const unsigned char *readendp = readp + block.length;
7569 
7570 	      /* See if we are dealing with a signed or unsigned
7571 		 values.  If the parent of this variant DIE is a
7572 		 variant_part then it will either have a discriminant
7573 		 which points to the member which type is the
7574 		 discriminant type.  Or the variant_part itself has a
7575 		 type representing the discriminant.  */
7576 	      bool is_signed = false;
7577 	      if (level > 0)
7578 		{
7579 		  Dwarf_Die *parent = &cbargs->dies[level - 1];
7580 		  if (dwarf_tag (die) == DW_TAG_variant
7581 		      && dwarf_tag (parent) == DW_TAG_variant_part)
7582 		    {
7583 		      Dwarf_Die member;
7584 		      Dwarf_Attribute discr_attr;
7585 		      int bytes;
7586 		      if (dwarf_formref_die (dwarf_attr (parent,
7587 							 DW_AT_discr,
7588 							 &discr_attr),
7589 					     &member) != NULL)
7590 			die_type_sign_bytes (&member, &is_signed, &bytes);
7591 		      else
7592 			die_type_sign_bytes (parent, &is_signed, &bytes);
7593 		    }
7594 		}
7595 	      while (readp < readendp)
7596 		{
7597 		  int d = (int) *readp++;
7598 		  printf ("%s ", dwarf_discr_list_name (d));
7599 		  if (readp >= readendp)
7600 		    goto attrval_out;
7601 
7602 		  Dwarf_Word val;
7603 		  Dwarf_Sword sval;
7604 		  if (d == DW_DSC_label)
7605 		    {
7606 		      if (is_signed)
7607 			{
7608 			  get_sleb128 (sval, readp, readendp);
7609 			  printf ("%" PRId64 "", sval);
7610 			}
7611 		      else
7612 			{
7613 			  get_uleb128 (val, readp, readendp);
7614 			  printf ("%" PRIu64 "", val);
7615 			}
7616 		    }
7617 		  else if (d == DW_DSC_range)
7618 		    {
7619 		      if (is_signed)
7620 			{
7621 			  get_sleb128 (sval, readp, readendp);
7622 			  printf ("%" PRId64 "..", sval);
7623 			  if (readp >= readendp)
7624 			    goto attrval_out;
7625 			  get_sleb128 (sval, readp, readendp);
7626 			  printf ("%" PRId64 "", sval);
7627 			}
7628 		      else
7629 			{
7630 			  get_uleb128 (val, readp, readendp);
7631 			  printf ("%" PRIu64 "..", val);
7632 			  if (readp >= readendp)
7633 			    goto attrval_out;
7634 			  get_uleb128 (val, readp, readendp);
7635 			  printf ("%" PRIu64 "", val);
7636 			}
7637 		    }
7638 		  else
7639 		    {
7640 		      print_block (readendp - readp, readp);
7641 		      break;
7642 		    }
7643 		  if (readp < readendp)
7644 		    printf (", ");
7645 		}
7646 	      putchar ('\n');
7647 	    }
7648 	  else
7649 	    print_block (block.length, block.data);
7650 	  break;
7651 	}
7652       break;
7653 
7654     default:
7655       if (cbargs->silent)
7656 	break;
7657       printf ("           %*s%-20s (%s) ???\n",
7658 	      (int) (level * 2), "", dwarf_attr_name (attr),
7659 	      dwarf_form_name (form));
7660       break;
7661     }
7662 
7663   return DWARF_CB_OK;
7664 }
7665 
7666 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7667 print_debug_units (Dwfl_Module *dwflmod,
7668 		   Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7669 		   Elf_Scn *scn, GElf_Shdr *shdr,
7670 		   Dwarf *dbg, bool debug_types)
7671 {
7672   const bool silent = !(print_debug_sections & section_info) && !debug_types;
7673   const char *secname = section_name (ebl, shdr);
7674 
7675   if (!silent)
7676     printf (gettext ("\
7677 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7678 	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7679 
7680   /* If the section is empty we don't have to do anything.  */
7681   if (!silent && shdr->sh_size == 0)
7682     return;
7683 
7684   int maxdies = 20;
7685   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
7686 
7687   /* New compilation unit.  */
7688   Dwarf_Half version;
7689 
7690   Dwarf_Die result;
7691   Dwarf_Off abbroffset;
7692   uint8_t addrsize;
7693   uint8_t offsize;
7694   uint64_t unit_id;
7695   Dwarf_Off subdie_off;
7696 
7697   int unit_res;
7698   Dwarf_CU *cu;
7699   Dwarf_CU cu_mem;
7700   uint8_t unit_type;
7701   Dwarf_Die cudie;
7702 
7703   /* We cheat a little because we want to see only the CUs from .debug_info
7704      or .debug_types.  We know the Dwarf_CU struct layout.  Set it up at
7705      the end of .debug_info if we want .debug_types only.  Check the returned
7706      Dwarf_CU is still in the expected section.  */
7707   if (debug_types)
7708     {
7709       cu_mem.dbg = dbg;
7710       cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7711       cu_mem.sec_idx = IDX_debug_info;
7712       cu = &cu_mem;
7713     }
7714   else
7715     cu = NULL;
7716 
7717  next_cu:
7718   unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7719 			      &cudie, NULL);
7720   if (unit_res == 1)
7721     goto do_return;
7722 
7723   if (unit_res == -1)
7724     {
7725       if (!silent)
7726 	error (0, 0, gettext ("cannot get next unit: %s"), dwarf_errmsg (-1));
7727       goto do_return;
7728     }
7729 
7730   if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7731     goto do_return;
7732 
7733   dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7734 		&unit_id, &subdie_off);
7735 
7736   if (!silent)
7737     {
7738       Dwarf_Off offset = cu->start;
7739       if (debug_types && version < 5)
7740 	{
7741 	  Dwarf_Die typedie;
7742 	  Dwarf_Off dieoffset;
7743 	  dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
7744 							   &typedie));
7745 	  printf (gettext (" Type unit at offset %" PRIu64 ":\n"
7746 			   " Version: %" PRIu16
7747 			   ", Abbreviation section offset: %" PRIu64
7748 			   ", Address size: %" PRIu8
7749 			   ", Offset size: %" PRIu8
7750 			   "\n Type signature: %#" PRIx64
7751 			   ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7752 		  (uint64_t) offset, version, abbroffset, addrsize, offsize,
7753 		  unit_id, (uint64_t) subdie_off, dieoffset);
7754 	}
7755       else
7756 	{
7757 	  printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
7758 			   " Version: %" PRIu16
7759 			   ", Abbreviation section offset: %" PRIu64
7760 			   ", Address size: %" PRIu8
7761 			   ", Offset size: %" PRIu8 "\n"),
7762 		  (uint64_t) offset, version, abbroffset, addrsize, offsize);
7763 
7764 	  if (version >= 5 || (unit_type != DW_UT_compile
7765 			       && unit_type != DW_UT_partial))
7766 	    {
7767 	      printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7768 			       dwarf_unit_name (unit_type), unit_type);
7769 	      if (unit_type == DW_UT_type
7770 		  || unit_type == DW_UT_skeleton
7771 		  || unit_type == DW_UT_split_compile
7772 		  || unit_type == DW_UT_split_type)
7773 		printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7774 	      if (unit_type == DW_UT_type
7775 		  || unit_type == DW_UT_split_type)
7776 		{
7777 		  Dwarf_Die typedie;
7778 		  Dwarf_Off dieoffset;
7779 		  dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7780 				 NULL, NULL, NULL);
7781 		  dieoffset = dwarf_dieoffset (&typedie);
7782 		  printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7783 			  subdie_off, dieoffset);
7784 		}
7785 	      printf ("\n");
7786 	    }
7787 	}
7788     }
7789 
7790   if (version < 2 || version > 5
7791       || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7792     {
7793       if (!silent)
7794 	error (0, 0, gettext ("unknown version (%d) or unit type (%d)"),
7795 	       version, unit_type);
7796       goto next_cu;
7797     }
7798 
7799   struct attrcb_args args =
7800     {
7801       .dwflmod = dwflmod,
7802       .silent = silent,
7803       .version = version,
7804       .addrsize = addrsize,
7805       .offset_size = offsize
7806     };
7807 
7808   bool is_split = false;
7809   int level = 0;
7810   dies[0] = cudie;
7811   args.cu = dies[0].cu;
7812   args.dbg = dbg;
7813   args.is_split = is_split;
7814 
7815   /* We might return here again for the split CU subdie.  */
7816   do_cu:
7817   do
7818     {
7819       Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7820       if (unlikely (offset == (Dwarf_Off) -1))
7821 	{
7822 	  if (!silent)
7823 	    error (0, 0, gettext ("cannot get DIE offset: %s"),
7824 		   dwarf_errmsg (-1));
7825 	  goto do_return;
7826 	}
7827 
7828       int tag = dwarf_tag (&dies[level]);
7829       if (unlikely (tag == DW_TAG_invalid))
7830 	{
7831 	  if (!silent)
7832 	    error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
7833 				  "] in section '%s': %s"),
7834 		   (uint64_t) offset, secname, dwarf_errmsg (-1));
7835 	  goto do_return;
7836 	}
7837 
7838       if (!silent)
7839 	{
7840 	  unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7841 	  if (is_split)
7842 	    printf (" {%6" PRIx64 "}  ", (uint64_t) offset);
7843 	  else
7844 	    printf (" [%6" PRIx64 "]  ", (uint64_t) offset);
7845 	  printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7846 		  dwarf_tag_name (tag), code);
7847 	}
7848 
7849       /* Print the attribute values.  */
7850       args.level = level;
7851       args.dies = dies;
7852       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7853 
7854       /* Make room for the next level's DIE.  */
7855       if (level + 1 == maxdies)
7856 	dies = (Dwarf_Die *) xrealloc (dies,
7857 				       (maxdies += 10)
7858 				       * sizeof (Dwarf_Die));
7859 
7860       int res = dwarf_child (&dies[level], &dies[level + 1]);
7861       if (res > 0)
7862 	{
7863 	  while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7864 	    if (level-- == 0)
7865 	      break;
7866 
7867 	  if (unlikely (res == -1))
7868 	    {
7869 	      if (!silent)
7870 		error (0, 0, gettext ("cannot get next DIE: %s\n"),
7871 		       dwarf_errmsg (-1));
7872 	      goto do_return;
7873 	    }
7874 	}
7875       else if (unlikely (res < 0))
7876 	{
7877 	  if (!silent)
7878 	    error (0, 0, gettext ("cannot get next DIE: %s"),
7879 		   dwarf_errmsg (-1));
7880 	  goto do_return;
7881 	}
7882       else
7883 	++level;
7884     }
7885   while (level >= 0);
7886 
7887   /* We might want to show the split compile unit if this was a skeleton.
7888      We need to scan it if we are requesting printing .debug_ranges for
7889      DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7890      section.  */
7891   if (unit_type == DW_UT_skeleton
7892       && ((!silent && show_split_units)
7893 	  || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7894     {
7895       Dwarf_Die subdie;
7896       if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7897 	  || dwarf_tag (&subdie) == DW_TAG_invalid)
7898 	{
7899 	  if (!silent)
7900 	    {
7901 	      Dwarf_Attribute dwo_at;
7902 	      const char *dwo_name =
7903 		(dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7904 					       &dwo_at))
7905 		 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7906 						   &dwo_at))
7907 		     ?: "<unknown>"));
7908 	      fprintf (stderr,
7909 		       "Could not find split unit '%s', id: %" PRIx64 "\n",
7910 		       dwo_name, unit_id);
7911 	    }
7912 	}
7913       else
7914 	{
7915 	  Dwarf_CU *split_cu = subdie.cu;
7916 	  dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7917 			&addrsize, &offsize, &unit_id, &subdie_off);
7918 	  Dwarf_Off offset = cu->start;
7919 
7920 	  if (!silent)
7921 	    {
7922 	      printf (gettext (" Split compilation unit at offset %"
7923 			       PRIu64 ":\n"
7924 			       " Version: %" PRIu16
7925 			       ", Abbreviation section offset: %" PRIu64
7926 			       ", Address size: %" PRIu8
7927 			       ", Offset size: %" PRIu8 "\n"),
7928 		      (uint64_t) offset, version, abbroffset,
7929 		      addrsize, offsize);
7930 	      printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7931 		      dwarf_unit_name (unit_type), unit_type);
7932 	      printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7933 	      printf ("\n");
7934 	    }
7935 
7936 	  unit_type = DW_UT_split_compile;
7937 	  is_split = true;
7938 	  level = 0;
7939 	  dies[0] = subdie;
7940 	  args.cu = dies[0].cu;
7941 	  args.dbg = split_cu->dbg;
7942 	  args.is_split = is_split;
7943 	  goto do_cu;
7944 	}
7945     }
7946 
7947   /* And again... */
7948   goto next_cu;
7949 
7950  do_return:
7951   free (dies);
7952 }
7953 
7954 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7955 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7956 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7957 {
7958   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
7959 }
7960 
7961 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7962 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7963 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7964 {
7965   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
7966 }
7967 
7968 
7969 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7970 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
7971 			    GElf_Ehdr *ehdr __attribute__ ((unused)),
7972 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7973 {
7974   printf (gettext ("\
7975 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
7976 	  elf_ndxscn (scn), section_name (ebl, shdr),
7977 	  (uint64_t) shdr->sh_offset);
7978 
7979   size_t address_size
7980     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7981 
7982   Dwarf_Lines *lines;
7983   size_t nlines;
7984   Dwarf_Off off, next_off = 0;
7985   Dwarf_CU *cu = NULL;
7986   while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
7987 			   &lines, &nlines) == 0)
7988     {
7989       Dwarf_Die cudie;
7990       if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
7991 				       NULL, NULL, NULL, NULL) == 0)
7992 	printf (" CU [%" PRIx64 "] %s\n",
7993 		dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
7994       else
7995 	{
7996 	  /* DWARF5 lines can be independent of any CU, but they probably
7997 	     are used by some CU.  Determine the CU this block is for.  */
7998 	  Dwarf_Off cuoffset;
7999 	  Dwarf_Off ncuoffset = 0;
8000 	  size_t hsize;
8001 	  while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8002 			       NULL, NULL, NULL) == 0)
8003 	    {
8004 	      if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8005 		continue;
8006 	      Dwarf_Attribute stmt_list;
8007 	      if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8008 		continue;
8009 	      Dwarf_Word lineoff;
8010 	      if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8011 		continue;
8012 	      if (lineoff == off)
8013 		{
8014 		  /* Found the CU.  */
8015 		  cu = cudie.cu;
8016 		  break;
8017 		}
8018 	    }
8019 
8020 	  if (cu != NULL)
8021 	    printf (" CU [%" PRIx64 "] %s\n",
8022 		    dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8023 	  else
8024 	    printf (" No CU\n");
8025 	}
8026 
8027       printf ("  line:col SBPE* disc isa op address"
8028 	      " (Statement Block Prologue Epilogue *End)\n");
8029       const char *last_file = "";
8030       for (size_t n = 0; n < nlines; n++)
8031 	{
8032 	  Dwarf_Line *line = dwarf_onesrcline (lines, n);
8033 	  if (line == NULL)
8034 	    {
8035 	      printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8036 	      continue;
8037 	    }
8038 	  Dwarf_Word mtime, length;
8039 	  const char *file = dwarf_linesrc (line, &mtime, &length);
8040 	  if (file == NULL)
8041 	    {
8042 	      printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8043 	      last_file = "";
8044 	    }
8045 	  else if (strcmp (last_file, file) != 0)
8046 	    {
8047 	      printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8048 		      file, mtime, length);
8049 	      last_file = file;
8050 	    }
8051 
8052 	  int lineno, colno;
8053 	  bool statement, endseq, block, prologue_end, epilogue_begin;
8054 	  unsigned int lineop, isa, disc;
8055 	  Dwarf_Addr address;
8056 	  dwarf_lineaddr (line, &address);
8057 	  dwarf_lineno (line, &lineno);
8058 	  dwarf_linecol (line, &colno);
8059 	  dwarf_lineop_index (line, &lineop);
8060 	  dwarf_linebeginstatement (line, &statement);
8061 	  dwarf_lineendsequence (line, &endseq);
8062 	  dwarf_lineblock (line, &block);
8063 	  dwarf_lineprologueend (line, &prologue_end);
8064 	  dwarf_lineepiloguebegin (line, &epilogue_begin);
8065 	  dwarf_lineisa (line, &isa);
8066 	  dwarf_linediscriminator (line, &disc);
8067 
8068 	  /* End sequence is special, it is one byte past.  */
8069 	  printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8070 		  lineno, colno,
8071 		  (statement ? 'S' : ' '),
8072 		  (block ? 'B' : ' '),
8073 		  (prologue_end ? 'P' : ' '),
8074 		  (epilogue_begin ? 'E' : ' '),
8075 		  (endseq ? '*' : ' '),
8076 		  disc, isa, lineop);
8077 	  print_dwarf_addr (dwflmod, address_size,
8078 			    address - (endseq ? 1 : 0), address);
8079 	  printf ("\n");
8080 
8081 	  if (endseq)
8082 	    printf("\n");
8083 	}
8084     }
8085 }
8086 
8087 
8088 /* Print the value of a form.
8089    Returns new value of readp, or readendp on failure.  */
8090 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)8091 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8092 		 const unsigned char *readendp, unsigned int offset_len,
8093 		 Dwarf_Off str_offsets_base)
8094 {
8095   Dwarf_Word val;
8096   unsigned char *endp;
8097   Elf_Data *data;
8098   char *str;
8099   switch (form)
8100     {
8101     case DW_FORM_data1:
8102       if (readendp - readp < 1)
8103 	{
8104 	invalid_data:
8105 	  error (0, 0, "invalid data");
8106 	  return readendp;
8107 	}
8108       val = *readp++;
8109       printf (" %" PRIx8, (unsigned int) val);
8110       break;
8111 
8112     case DW_FORM_data2:
8113       if (readendp - readp < 2)
8114 	goto invalid_data;
8115       val = read_2ubyte_unaligned_inc (dbg, readp);
8116       printf(" %" PRIx16, (unsigned int) val);
8117       break;
8118 
8119     case DW_FORM_data4:
8120       if (readendp - readp < 4)
8121 	goto invalid_data;
8122       val = read_4ubyte_unaligned_inc (dbg, readp);
8123       printf (" %" PRIx32, (unsigned int) val);
8124       break;
8125 
8126     case DW_FORM_data8:
8127       if (readendp - readp < 8)
8128 	goto invalid_data;
8129       val = read_8ubyte_unaligned_inc (dbg, readp);
8130       printf (" %" PRIx64, val);
8131       break;
8132 
8133     case DW_FORM_sdata:
8134       if (readendp - readp < 1)
8135 	goto invalid_data;
8136       get_sleb128 (val, readp, readendp);
8137       printf (" %" PRIx64, val);
8138       break;
8139 
8140     case DW_FORM_udata:
8141       if (readendp - readp < 1)
8142 	goto invalid_data;
8143       get_uleb128 (val, readp, readendp);
8144       printf (" %" PRIx64, val);
8145       break;
8146 
8147     case DW_FORM_block:
8148       if (readendp - readp < 1)
8149 	goto invalid_data;
8150       get_uleb128 (val, readp, readendp);
8151       if ((size_t) (readendp - readp) < val)
8152 	goto invalid_data;
8153       print_bytes (val, readp);
8154       readp += val;
8155       break;
8156 
8157     case DW_FORM_block1:
8158       if (readendp - readp < 1)
8159 	goto invalid_data;
8160       val = *readp++;
8161       if ((size_t) (readendp - readp) < val)
8162 	goto invalid_data;
8163       print_bytes (val, readp);
8164       readp += val;
8165       break;
8166 
8167     case DW_FORM_block2:
8168       if (readendp - readp < 2)
8169 	goto invalid_data;
8170       val = read_2ubyte_unaligned_inc (dbg, readp);
8171       if ((size_t) (readendp - readp) < val)
8172 	goto invalid_data;
8173       print_bytes (val, readp);
8174       readp += val;
8175       break;
8176 
8177     case DW_FORM_block4:
8178       if (readendp - readp < 4)
8179 	goto invalid_data;
8180       val = read_4ubyte_unaligned_inc (dbg, readp);
8181       if ((size_t) (readendp - readp) < val)
8182 	goto invalid_data;
8183       print_bytes (val, readp);
8184       readp += val;
8185       break;
8186 
8187     case DW_FORM_data16:
8188       if (readendp - readp < 16)
8189 	goto invalid_data;
8190       print_bytes (16, readp);
8191       readp += 16;
8192       break;
8193 
8194     case DW_FORM_flag:
8195       if (readendp - readp < 1)
8196 	goto invalid_data;
8197       val = *readp++;
8198       printf ("%s", val != 0 ? yes_str : no_str);
8199       break;
8200 
8201     case DW_FORM_string:
8202       endp = memchr (readp, '\0', readendp - readp);
8203       if (endp == NULL)
8204 	goto invalid_data;
8205       printf ("%s", readp);
8206       readp = endp + 1;
8207       break;
8208 
8209     case DW_FORM_strp:
8210     case DW_FORM_line_strp:
8211     case DW_FORM_strp_sup:
8212       if ((size_t) (readendp - readp) < offset_len)
8213 	goto invalid_data;
8214       if (offset_len == 8)
8215 	val = read_8ubyte_unaligned_inc (dbg, readp);
8216       else
8217 	val = read_4ubyte_unaligned_inc (dbg, readp);
8218       if (form == DW_FORM_strp)
8219 	data = dbg->sectiondata[IDX_debug_str];
8220       else if (form == DW_FORM_line_strp)
8221 	data = dbg->sectiondata[IDX_debug_line_str];
8222       else /* form == DW_FORM_strp_sup */
8223 	{
8224 	  Dwarf *alt = dwarf_getalt (dbg);
8225 	  data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8226 	}
8227       if (data == NULL || val >= data->d_size
8228 	  || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8229 	str = "???";
8230       else
8231 	str = (char *) data->d_buf + val;
8232       printf ("%s (%" PRIu64 ")", str, val);
8233       break;
8234 
8235     case DW_FORM_sec_offset:
8236       if ((size_t) (readendp - readp) < offset_len)
8237 	goto invalid_data;
8238       if (offset_len == 8)
8239 	val = read_8ubyte_unaligned_inc (dbg, readp);
8240       else
8241 	val = read_4ubyte_unaligned_inc (dbg, readp);
8242       printf ("[%" PRIx64 "]", val);
8243       break;
8244 
8245     case DW_FORM_strx:
8246     case DW_FORM_GNU_str_index:
8247       if (readendp - readp < 1)
8248 	goto invalid_data;
8249       get_uleb128 (val, readp, readendp);
8250     strx_val:
8251       data = dbg->sectiondata[IDX_debug_str_offsets];
8252       if (data == NULL
8253 	  || data->d_size - str_offsets_base < val)
8254 	str = "???";
8255       else
8256 	{
8257 	  const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8258 	  const unsigned char *strreadendp = data->d_buf + data->d_size;
8259 	  if ((size_t) (strreadendp - strreadp) < offset_len)
8260 	    str = "???";
8261 	  else
8262 	    {
8263 	      Dwarf_Off idx;
8264 	      if (offset_len == 8)
8265 		idx = read_8ubyte_unaligned (dbg, strreadp);
8266 	      else
8267 		idx = read_4ubyte_unaligned (dbg, strreadp);
8268 
8269 	      data = dbg->sectiondata[IDX_debug_str];
8270 	      if (data == NULL || idx >= data->d_size
8271 		  || memchr (data->d_buf + idx, '\0',
8272 			     data->d_size - idx) == NULL)
8273 		str = "???";
8274 	      else
8275 		str = (char *) data->d_buf + idx;
8276 	    }
8277 	}
8278       printf ("%s (%" PRIu64 ")", str, val);
8279       break;
8280 
8281     case DW_FORM_strx1:
8282       if (readendp - readp < 1)
8283 	goto invalid_data;
8284       val = *readp++;
8285       goto strx_val;
8286 
8287     case DW_FORM_strx2:
8288       if (readendp - readp < 2)
8289 	goto invalid_data;
8290       val = read_2ubyte_unaligned_inc (dbg, readp);
8291       goto strx_val;
8292 
8293     case DW_FORM_strx3:
8294       if (readendp - readp < 3)
8295 	goto invalid_data;
8296       val = read_3ubyte_unaligned_inc (dbg, readp);
8297       goto strx_val;
8298 
8299     case DW_FORM_strx4:
8300       if (readendp - readp < 4)
8301 	goto invalid_data;
8302       val = read_4ubyte_unaligned_inc (dbg, readp);
8303       goto strx_val;
8304 
8305     default:
8306       error (0, 0, gettext ("unknown form: %s"), dwarf_form_name (form));
8307       return readendp;
8308     }
8309 
8310   return readp;
8311 }
8312 
8313 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8314 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8315 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8316 {
8317   if (decodedline)
8318     {
8319       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8320       return;
8321     }
8322 
8323   printf (gettext ("\
8324 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8325 	  elf_ndxscn (scn), section_name (ebl, shdr),
8326 	  (uint64_t) shdr->sh_offset);
8327 
8328   if (shdr->sh_size == 0)
8329     return;
8330 
8331   /* There is no functionality in libdw to read the information in the
8332      way it is represented here.  Hardcode the decoder.  */
8333   Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8334 		    ?: elf_rawdata (scn, NULL));
8335   if (unlikely (data == NULL))
8336     {
8337       error (0, 0, gettext ("cannot get line data section data: %s"),
8338 	     elf_errmsg (-1));
8339       return;
8340     }
8341 
8342   const unsigned char *linep = (const unsigned char *) data->d_buf;
8343   const unsigned char *lineendp;
8344 
8345   while (linep
8346 	 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8347     {
8348       size_t start_offset = linep - (const unsigned char *) data->d_buf;
8349 
8350       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
8351 
8352       if (unlikely (linep + 4 > lineendp))
8353 	goto invalid_data;
8354       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8355       unsigned int length = 4;
8356       if (unlikely (unit_length == 0xffffffff))
8357 	{
8358 	  if (unlikely (linep + 8 > lineendp))
8359 	    {
8360 	    invalid_data:
8361 	      error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8362 		     elf_ndxscn (scn), section_name (ebl, shdr));
8363 	      return;
8364 	    }
8365 	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8366 	  length = 8;
8367 	}
8368 
8369       /* Check whether we have enough room in the section.  */
8370       if (unlikely (unit_length > (size_t) (lineendp - linep)))
8371 	goto invalid_data;
8372       lineendp = linep + unit_length;
8373 
8374       /* The next element of the header is the version identifier.  */
8375       if ((size_t) (lineendp - linep) < 2)
8376 	goto invalid_data;
8377       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8378 
8379       size_t address_size
8380 	= elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8381       unsigned char segment_selector_size = 0;
8382       if (version > 4)
8383 	{
8384 	  if ((size_t) (lineendp - linep) < 2)
8385 	    goto invalid_data;
8386 	  address_size = *linep++;
8387 	  segment_selector_size = *linep++;
8388 	}
8389 
8390       /* Next comes the header length.  */
8391       Dwarf_Word header_length;
8392       if (length == 4)
8393 	{
8394 	  if ((size_t) (lineendp - linep) < 4)
8395 	    goto invalid_data;
8396 	  header_length = read_4ubyte_unaligned_inc (dbg, linep);
8397 	}
8398       else
8399 	{
8400 	  if ((size_t) (lineendp - linep) < 8)
8401 	    goto invalid_data;
8402 	  header_length = read_8ubyte_unaligned_inc (dbg, linep);
8403 	}
8404 
8405       /* Next the minimum instruction length.  */
8406       if ((size_t) (lineendp - linep) < 1)
8407 	goto invalid_data;
8408       uint_fast8_t minimum_instr_len = *linep++;
8409 
8410       /* Next the maximum operations per instruction, in version 4 format.  */
8411       uint_fast8_t max_ops_per_instr;
8412       if (version < 4)
8413 	max_ops_per_instr = 1;
8414       else
8415 	{
8416 	  if ((size_t) (lineendp - linep) < 1)
8417 	    goto invalid_data;
8418 	  max_ops_per_instr = *linep++;
8419 	}
8420 
8421       /* We need at least 4 more bytes.  */
8422       if ((size_t) (lineendp - linep) < 4)
8423 	goto invalid_data;
8424 
8425       /* Then the flag determining the default value of the is_stmt
8426 	 register.  */
8427       uint_fast8_t default_is_stmt = *linep++;
8428 
8429       /* Now the line base.  */
8430       int_fast8_t line_base = *linep++;
8431 
8432       /* And the line range.  */
8433       uint_fast8_t line_range = *linep++;
8434 
8435       /* The opcode base.  */
8436       uint_fast8_t opcode_base = *linep++;
8437 
8438       /* Print what we got so far.  */
8439       printf (gettext ("\n"
8440 		       " Length:                         %" PRIu64 "\n"
8441 		       " DWARF version:                  %" PRIuFAST16 "\n"
8442 		       " Prologue length:                %" PRIu64 "\n"
8443 		       " Address size:                   %zd\n"
8444 		       " Segment selector size:          %zd\n"
8445 		       " Min instruction length:         %" PRIuFAST8 "\n"
8446 		       " Max operations per instruction: %" PRIuFAST8 "\n"
8447 		       " Initial value if 'is_stmt':     %" PRIuFAST8 "\n"
8448 		       " Line base:                      %" PRIdFAST8 "\n"
8449 		       " Line range:                     %" PRIuFAST8 "\n"
8450 		       " Opcode base:                    %" PRIuFAST8 "\n"
8451 		       "\n"
8452 		       "Opcodes:\n"),
8453 	      (uint64_t) unit_length, version, (uint64_t) header_length,
8454 	      address_size, (size_t) segment_selector_size,
8455 	      minimum_instr_len, max_ops_per_instr,
8456 	      default_is_stmt, line_base,
8457 	      line_range, opcode_base);
8458 
8459       if (version < 2 || version > 5)
8460 	{
8461 	  error (0, 0, gettext ("cannot handle .debug_line version: %u\n"),
8462 		 (unsigned int) version);
8463 	  linep = lineendp;
8464 	  continue;
8465 	}
8466 
8467       if (address_size != 4 && address_size != 8)
8468 	{
8469 	  error (0, 0, gettext ("cannot handle address size: %u\n"),
8470 		 (unsigned int) address_size);
8471 	  linep = lineendp;
8472 	  continue;
8473 	}
8474 
8475       if (segment_selector_size != 0)
8476 	{
8477 	  error (0, 0, gettext ("cannot handle segment selector size: %u\n"),
8478 		 (unsigned int) segment_selector_size);
8479 	  linep = lineendp;
8480 	  continue;
8481 	}
8482 
8483       if (unlikely (linep + opcode_base - 1 >= lineendp))
8484 	{
8485 	invalid_unit:
8486 	  error (0, 0,
8487 		 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
8488 		 linep - (const unsigned char *) data->d_buf,
8489 		 elf_ndxscn (scn), section_name (ebl, shdr));
8490 	  linep = lineendp;
8491 	  continue;
8492 	}
8493       int opcode_base_l10 = 1;
8494       unsigned int tmp = opcode_base;
8495       while (tmp > 10)
8496 	{
8497 	  tmp /= 10;
8498 	  ++opcode_base_l10;
8499 	}
8500       const uint8_t *standard_opcode_lengths = linep - 1;
8501       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8502 	printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
8503 			  "  [%*" PRIuFAST8 "]  %hhu arguments\n",
8504 			  (int) linep[cnt - 1]),
8505 		opcode_base_l10, cnt, linep[cnt - 1]);
8506       linep += opcode_base - 1;
8507 
8508       if (unlikely (linep >= lineendp))
8509 	goto invalid_unit;
8510 
8511       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8512 
8513       puts (gettext ("\nDirectory table:"));
8514       if (version > 4)
8515 	{
8516 	  struct encpair { uint16_t desc; uint16_t form; };
8517 	  struct encpair enc[256];
8518 
8519 	  printf (gettext ("      ["));
8520 	  if ((size_t) (lineendp - linep) < 1)
8521 	    goto invalid_data;
8522 	  unsigned char directory_entry_format_count = *linep++;
8523 	  for (int i = 0; i < directory_entry_format_count; i++)
8524 	    {
8525 	      uint16_t desc, form;
8526 	      if ((size_t) (lineendp - linep) < 1)
8527 		goto invalid_data;
8528 	      get_uleb128 (desc, linep, lineendp);
8529 	      if ((size_t) (lineendp - linep) < 1)
8530 		goto invalid_data;
8531 	      get_uleb128 (form, linep, lineendp);
8532 
8533 	      enc[i].desc = desc;
8534 	      enc[i].form = form;
8535 
8536 	      printf ("%s(%s)",
8537 		      dwarf_line_content_description_name (desc),
8538 		      dwarf_form_name (form));
8539 	      if (i + 1 < directory_entry_format_count)
8540 		printf (", ");
8541 	    }
8542 	  printf ("]\n");
8543 
8544 	  uint64_t directories_count;
8545 	  if ((size_t) (lineendp - linep) < 1)
8546             goto invalid_data;
8547 	  get_uleb128 (directories_count, linep, lineendp);
8548 
8549 	  if (directory_entry_format_count == 0
8550 	      && directories_count != 0)
8551 	    goto invalid_data;
8552 
8553 	  for (uint64_t i = 0; i < directories_count; i++)
8554 	    {
8555 	      printf (" %-5" PRIu64 " ", i);
8556 	      for (int j = 0; j < directory_entry_format_count; j++)
8557 		{
8558 		  linep = print_form_data (dbg, enc[j].form,
8559 					   linep, lineendp, length,
8560 					   str_offsets_base);
8561 		  if (j + 1 < directory_entry_format_count)
8562 		    printf (", ");
8563 		}
8564 	      printf ("\n");
8565 	      if (linep >= lineendp)
8566 		goto invalid_unit;
8567 	    }
8568 	}
8569       else
8570 	{
8571 	  while (linep < lineendp && *linep != 0)
8572 	    {
8573 	      unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8574 	      if (unlikely (endp == NULL))
8575 		goto invalid_unit;
8576 
8577 	      printf (" %s\n", (char *) linep);
8578 
8579 	      linep = endp + 1;
8580 	    }
8581 	  if (linep >= lineendp || *linep != 0)
8582 	    goto invalid_unit;
8583 	  /* Skip the final NUL byte.  */
8584 	  ++linep;
8585 	}
8586 
8587       if (unlikely (linep >= lineendp))
8588 	goto invalid_unit;
8589 
8590       puts (gettext ("\nFile name table:"));
8591       if (version > 4)
8592 	{
8593 	  struct encpair { uint16_t desc; uint16_t form; };
8594 	  struct encpair enc[256];
8595 
8596 	  printf (gettext ("      ["));
8597 	  if ((size_t) (lineendp - linep) < 1)
8598 	    goto invalid_data;
8599 	  unsigned char file_name_format_count = *linep++;
8600 	  for (int i = 0; i < file_name_format_count; i++)
8601 	    {
8602 	      uint64_t desc, form;
8603 	      if ((size_t) (lineendp - linep) < 1)
8604 		goto invalid_data;
8605 	      get_uleb128 (desc, linep, lineendp);
8606 	      if ((size_t) (lineendp - linep) < 1)
8607 		goto invalid_data;
8608 	      get_uleb128 (form, linep, lineendp);
8609 
8610 	      if (! libdw_valid_user_form (form))
8611 		goto invalid_data;
8612 
8613 	      enc[i].desc = desc;
8614 	      enc[i].form = form;
8615 
8616 	      printf ("%s(%s)",
8617 		      dwarf_line_content_description_name (desc),
8618 		      dwarf_form_name (form));
8619 	      if (i + 1 < file_name_format_count)
8620 		printf (", ");
8621 	    }
8622 	  printf ("]\n");
8623 
8624 	  uint64_t file_name_count;
8625 	  if ((size_t) (lineendp - linep) < 1)
8626             goto invalid_data;
8627 	  get_uleb128 (file_name_count, linep, lineendp);
8628 
8629 	  if (file_name_format_count == 0
8630 	      && file_name_count != 0)
8631 	    goto invalid_data;
8632 
8633 	  for (uint64_t i = 0; i < file_name_count; i++)
8634 	    {
8635 	      printf (" %-5" PRIu64 " ", i);
8636 	      for (int j = 0; j < file_name_format_count; j++)
8637 		{
8638 		  linep = print_form_data (dbg, enc[j].form,
8639 					   linep, lineendp, length,
8640 					   str_offsets_base);
8641 		  if (j + 1 < file_name_format_count)
8642 		    printf (", ");
8643 		}
8644 	      printf ("\n");
8645 	      if (linep >= lineendp)
8646 		goto invalid_unit;
8647 	    }
8648 	}
8649       else
8650 	{
8651 	  puts (gettext (" Entry Dir   Time      Size      Name"));
8652 	  for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8653 	    {
8654 	      /* First comes the file name.  */
8655 	      char *fname = (char *) linep;
8656 	      unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8657 	      if (unlikely (endp == NULL))
8658 		goto invalid_unit;
8659 	      linep = endp + 1;
8660 
8661 	      /* Then the index.  */
8662 	      unsigned int diridx;
8663 	      if (lineendp - linep < 1)
8664 		goto invalid_unit;
8665 	      get_uleb128 (diridx, linep, lineendp);
8666 
8667 	      /* Next comes the modification time.  */
8668 	      unsigned int mtime;
8669 	      if (lineendp - linep < 1)
8670 		goto invalid_unit;
8671 	      get_uleb128 (mtime, linep, lineendp);
8672 
8673 	      /* Finally the length of the file.  */
8674 	      unsigned int fsize;
8675 	      if (lineendp - linep < 1)
8676 		goto invalid_unit;
8677 	      get_uleb128 (fsize, linep, lineendp);
8678 
8679 	      printf (" %-5u %-5u %-9u %-9u %s\n",
8680 		      cnt, diridx, mtime, fsize, fname);
8681 	    }
8682 	  if (linep >= lineendp || *linep != '\0')
8683 	    goto invalid_unit;
8684 	  /* Skip the final NUL byte.  */
8685 	  ++linep;
8686 	}
8687 
8688       puts (gettext ("\nLine number statements:"));
8689       Dwarf_Word address = 0;
8690       unsigned int op_index = 0;
8691       size_t line = 1;
8692       uint_fast8_t is_stmt = default_is_stmt;
8693 
8694       /* Apply the "operation advance" from a special opcode
8695 	 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
8696       unsigned int op_addr_advance;
8697       bool show_op_index;
8698       inline void advance_pc (unsigned int op_advance)
8699       {
8700 	op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8701 					       / max_ops_per_instr);
8702 	address += op_addr_advance;
8703 	show_op_index = (op_index > 0 ||
8704 			 (op_index + op_advance) % max_ops_per_instr > 0);
8705 	op_index = (op_index + op_advance) % max_ops_per_instr;
8706       }
8707 
8708       if (max_ops_per_instr == 0)
8709 	{
8710 	  error (0, 0,
8711 		 gettext ("invalid maximum operations per instruction is zero"));
8712 	  linep = lineendp;
8713 	  continue;
8714 	}
8715 
8716       while (linep < lineendp)
8717 	{
8718 	  size_t offset = linep - (const unsigned char *) data->d_buf;
8719 	  unsigned int u128;
8720 	  int s128;
8721 
8722 	  /* Read the opcode.  */
8723 	  unsigned int opcode = *linep++;
8724 
8725 	  printf (" [%6" PRIx64 "]", (uint64_t)offset);
8726 	  /* Is this a special opcode?  */
8727 	  if (likely (opcode >= opcode_base))
8728 	    {
8729 	      if (unlikely (line_range == 0))
8730 		goto invalid_unit;
8731 
8732 	      /* Yes.  Handling this is quite easy since the opcode value
8733 		 is computed with
8734 
8735 		 opcode = (desired line increment - line_base)
8736 			   + (line_range * address advance) + opcode_base
8737 	      */
8738 	      int line_increment = (line_base
8739 				    + (opcode - opcode_base) % line_range);
8740 
8741 	      /* Perform the increments.  */
8742 	      line += line_increment;
8743 	      advance_pc ((opcode - opcode_base) / line_range);
8744 
8745 	      printf (gettext (" special opcode %u: address+%u = "),
8746 		      opcode, op_addr_advance);
8747 	      print_dwarf_addr (dwflmod, 0, address, address);
8748 	      if (show_op_index)
8749 		printf (gettext (", op_index = %u, line%+d = %zu\n"),
8750 			op_index, line_increment, line);
8751 	      else
8752 		printf (gettext (", line%+d = %zu\n"),
8753 			line_increment, line);
8754 	    }
8755 	  else if (opcode == 0)
8756 	    {
8757 	      /* This an extended opcode.  */
8758 	      if (unlikely (linep + 2 > lineendp))
8759 		goto invalid_unit;
8760 
8761 	      /* The length.  */
8762 	      unsigned int len = *linep++;
8763 
8764 	      if (unlikely (linep + len > lineendp))
8765 		goto invalid_unit;
8766 
8767 	      /* The sub-opcode.  */
8768 	      opcode = *linep++;
8769 
8770 	      printf (gettext (" extended opcode %u: "), opcode);
8771 
8772 	      switch (opcode)
8773 		{
8774 		case DW_LNE_end_sequence:
8775 		  puts (gettext (" end of sequence"));
8776 
8777 		  /* Reset the registers we care about.  */
8778 		  address = 0;
8779 		  op_index = 0;
8780 		  line = 1;
8781 		  is_stmt = default_is_stmt;
8782 		  break;
8783 
8784 		case DW_LNE_set_address:
8785 		  op_index = 0;
8786 		  if (unlikely ((size_t) (lineendp - linep) < address_size))
8787 		    goto invalid_unit;
8788 		  if (address_size == 4)
8789 		    address = read_4ubyte_unaligned_inc (dbg, linep);
8790 		  else
8791 		    address = read_8ubyte_unaligned_inc (dbg, linep);
8792 		  {
8793 		    printf (gettext (" set address to "));
8794 		    print_dwarf_addr (dwflmod, 0, address, address);
8795 		    printf ("\n");
8796 		  }
8797 		  break;
8798 
8799 		case DW_LNE_define_file:
8800 		  {
8801 		    char *fname = (char *) linep;
8802 		    unsigned char *endp = memchr (linep, '\0',
8803 						  lineendp - linep);
8804 		    if (unlikely (endp == NULL))
8805 		      goto invalid_unit;
8806 		    linep = endp + 1;
8807 
8808 		    unsigned int diridx;
8809 		    if (lineendp - linep < 1)
8810 		      goto invalid_unit;
8811 		    get_uleb128 (diridx, linep, lineendp);
8812 		    Dwarf_Word mtime;
8813 		    if (lineendp - linep < 1)
8814 		      goto invalid_unit;
8815 		    get_uleb128 (mtime, linep, lineendp);
8816 		    Dwarf_Word filelength;
8817 		    if (lineendp - linep < 1)
8818 		      goto invalid_unit;
8819 		    get_uleb128 (filelength, linep, lineendp);
8820 
8821 		    printf (gettext ("\
8822  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8823 			    diridx, (uint64_t) mtime, (uint64_t) filelength,
8824 			    fname);
8825 		  }
8826 		  break;
8827 
8828 		case DW_LNE_set_discriminator:
8829 		  /* Takes one ULEB128 parameter, the discriminator.  */
8830 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8831 				|| lineendp - linep < 1))
8832 		    goto invalid_unit;
8833 
8834 		  get_uleb128 (u128, linep, lineendp);
8835 		  printf (gettext (" set discriminator to %u\n"), u128);
8836 		  break;
8837 
8838 		default:
8839 		  /* Unknown, ignore it.  */
8840 		  puts (gettext (" unknown opcode"));
8841 		  linep += len - 1;
8842 		  break;
8843 		}
8844 	    }
8845 	  else if (opcode <= DW_LNS_set_isa)
8846 	    {
8847 	      /* This is a known standard opcode.  */
8848 	      switch (opcode)
8849 		{
8850 		case DW_LNS_copy:
8851 		  /* Takes no argument.  */
8852 		  puts (gettext (" copy"));
8853 		  break;
8854 
8855 		case DW_LNS_advance_pc:
8856 		  /* Takes one uleb128 parameter which is added to the
8857 		     address.  */
8858 		  if (lineendp - linep < 1)
8859 		    goto invalid_unit;
8860 		  get_uleb128 (u128, linep, lineendp);
8861 		  advance_pc (u128);
8862 		  {
8863 		    printf (gettext (" advance address by %u to "),
8864 			    op_addr_advance);
8865 		    print_dwarf_addr (dwflmod, 0, address, address);
8866 		    if (show_op_index)
8867 		      printf (gettext (", op_index to %u"), op_index);
8868 		    printf ("\n");
8869 		  }
8870 		  break;
8871 
8872 		case DW_LNS_advance_line:
8873 		  /* Takes one sleb128 parameter which is added to the
8874 		     line.  */
8875 		  if (lineendp - linep < 1)
8876 		    goto invalid_unit;
8877 		  get_sleb128 (s128, linep, lineendp);
8878 		  line += s128;
8879 		  printf (gettext ("\
8880  advance line by constant %d to %" PRId64 "\n"),
8881 			  s128, (int64_t) line);
8882 		  break;
8883 
8884 		case DW_LNS_set_file:
8885 		  /* Takes one uleb128 parameter which is stored in file.  */
8886 		  if (lineendp - linep < 1)
8887 		    goto invalid_unit;
8888 		  get_uleb128 (u128, linep, lineendp);
8889 		  printf (gettext (" set file to %" PRIu64 "\n"),
8890 			  (uint64_t) u128);
8891 		  break;
8892 
8893 		case DW_LNS_set_column:
8894 		  /* Takes one uleb128 parameter which is stored in column.  */
8895 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8896 				|| lineendp - linep < 1))
8897 		    goto invalid_unit;
8898 
8899 		  get_uleb128 (u128, linep, lineendp);
8900 		  printf (gettext (" set column to %" PRIu64 "\n"),
8901 			  (uint64_t) u128);
8902 		  break;
8903 
8904 		case DW_LNS_negate_stmt:
8905 		  /* Takes no argument.  */
8906 		  is_stmt = 1 - is_stmt;
8907 		  printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8908 			  "is_stmt", is_stmt);
8909 		  break;
8910 
8911 		case DW_LNS_set_basic_block:
8912 		  /* Takes no argument.  */
8913 		  puts (gettext (" set basic block flag"));
8914 		  break;
8915 
8916 		case DW_LNS_const_add_pc:
8917 		  /* Takes no argument.  */
8918 
8919 		  if (unlikely (line_range == 0))
8920 		    goto invalid_unit;
8921 
8922 		  advance_pc ((255 - opcode_base) / line_range);
8923 		  {
8924 		    printf (gettext (" advance address by constant %u to "),
8925 			    op_addr_advance);
8926 		    print_dwarf_addr (dwflmod, 0, address, address);
8927 		    if (show_op_index)
8928 		      printf (gettext (", op_index to %u"), op_index);
8929 		    printf ("\n");
8930 		  }
8931 		  break;
8932 
8933 		case DW_LNS_fixed_advance_pc:
8934 		  /* Takes one 16 bit parameter which is added to the
8935 		     address.  */
8936 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8937 				|| lineendp - linep < 2))
8938 		    goto invalid_unit;
8939 
8940 		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
8941 		  address += u128;
8942 		  op_index = 0;
8943 		  {
8944 		    printf (gettext ("\
8945  advance address by fixed value %u to \n"),
8946 			    u128);
8947 		    print_dwarf_addr (dwflmod, 0, address, address);
8948 		    printf ("\n");
8949 		  }
8950 		  break;
8951 
8952 		case DW_LNS_set_prologue_end:
8953 		  /* Takes no argument.  */
8954 		  puts (gettext (" set prologue end flag"));
8955 		  break;
8956 
8957 		case DW_LNS_set_epilogue_begin:
8958 		  /* Takes no argument.  */
8959 		  puts (gettext (" set epilogue begin flag"));
8960 		  break;
8961 
8962 		case DW_LNS_set_isa:
8963 		  /* Takes one uleb128 parameter which is stored in isa.  */
8964 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8965 				|| lineendp - linep < 1))
8966 		    goto invalid_unit;
8967 
8968 		  get_uleb128 (u128, linep, lineendp);
8969 		  printf (gettext (" set isa to %u\n"), u128);
8970 		  break;
8971 		}
8972 	    }
8973 	  else
8974 	    {
8975 	      /* This is a new opcode the generator but not we know about.
8976 		 Read the parameters associated with it but then discard
8977 		 everything.  Read all the parameters for this opcode.  */
8978 	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8979 				" unknown opcode with %" PRIu8 " parameters:",
8980 				standard_opcode_lengths[opcode]),
8981 		      standard_opcode_lengths[opcode]);
8982 	      for (int n = standard_opcode_lengths[opcode];
8983 		   n > 0 && linep < lineendp; --n)
8984 		{
8985 		  get_uleb128 (u128, linep, lineendp);
8986 		  if (n != standard_opcode_lengths[opcode])
8987 		    putc_unlocked (',', stdout);
8988 		  printf (" %u", u128);
8989 		}
8990 
8991 	      /* Next round, ignore this opcode.  */
8992 	      continue;
8993 	    }
8994 	}
8995     }
8996 
8997   /* There must only be one data block.  */
8998   assert (elf_getdata (scn, data) == NULL);
8999 }
9000 
9001 
9002 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9003 print_debug_loclists_section (Dwfl_Module *dwflmod,
9004 			      Ebl *ebl,
9005 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
9006 			      Elf_Scn *scn, GElf_Shdr *shdr,
9007 			      Dwarf *dbg)
9008 {
9009   printf (gettext ("\
9010 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9011 	  elf_ndxscn (scn), section_name (ebl, shdr),
9012 	  (uint64_t) shdr->sh_offset);
9013 
9014   Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9015 		    ?: elf_rawdata (scn, NULL));
9016   if (unlikely (data == NULL))
9017     {
9018       error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
9019 	     elf_errmsg (-1));
9020       return;
9021     }
9022 
9023   /* For the listptr to get the base address/CU.  */
9024   sort_listptr (&known_loclistsptr, "loclistsptr");
9025   size_t listptr_idx = 0;
9026 
9027   const unsigned char *readp = data->d_buf;
9028   const unsigned char *const dataend = ((unsigned char *) data->d_buf
9029 					+ data->d_size);
9030   while (readp < dataend)
9031     {
9032       if (unlikely (readp > dataend - 4))
9033 	{
9034 	invalid_data:
9035 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
9036 		 elf_ndxscn (scn), section_name (ebl, shdr));
9037 	  return;
9038 	}
9039 
9040       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9041       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
9042 	      (uint64_t) offset);
9043 
9044       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9045       unsigned int offset_size = 4;
9046       if (unlikely (unit_length == 0xffffffff))
9047 	{
9048 	  if (unlikely (readp > dataend - 8))
9049 	    goto invalid_data;
9050 
9051 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9052 	  offset_size = 8;
9053 	}
9054       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
9055 
9056       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9057 	 bytes to complete the header.  And this unit cannot go beyond
9058 	 the section data.  */
9059       if (readp > dataend - 8
9060 	  || unit_length < 8
9061 	  || unit_length > (uint64_t) (dataend - readp))
9062 	goto invalid_data;
9063 
9064       const unsigned char *nexthdr = readp + unit_length;
9065 
9066       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9067       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
9068 
9069       if (version != 5)
9070 	{
9071 	  error (0, 0, gettext ("Unknown version"));
9072 	  goto next_table;
9073 	}
9074 
9075       uint8_t address_size = *readp++;
9076       printf (gettext (" Address size:   %8" PRIu64 "\n"),
9077 	      (uint64_t) address_size);
9078 
9079       if (address_size != 4 && address_size != 8)
9080 	{
9081 	  error (0, 0, gettext ("unsupported address size"));
9082 	  goto next_table;
9083 	}
9084 
9085       uint8_t segment_size = *readp++;
9086       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
9087 	      (uint64_t) segment_size);
9088 
9089       if (segment_size != 0)
9090         {
9091           error (0, 0, gettext ("unsupported segment size"));
9092           goto next_table;
9093         }
9094 
9095       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9096       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
9097 	      (uint64_t) offset_entry_count);
9098 
9099       /* We need the CU that uses this unit to get the initial base address. */
9100       Dwarf_Addr cu_base = 0;
9101       struct Dwarf_CU *cu = NULL;
9102       if (listptr_cu (&known_loclistsptr, &listptr_idx,
9103 		      (Dwarf_Off) offset,
9104 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9105 		      &cu_base, &cu)
9106 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
9107 	{
9108 	  Dwarf_Die cudie;
9109 	  if (dwarf_cu_die (cu, &cudie,
9110 			    NULL, NULL, NULL, NULL,
9111 			    NULL, NULL) == NULL)
9112 	    printf (gettext (" Unknown CU base: "));
9113 	  else
9114 	    printf (gettext (" CU [%6" PRIx64 "] base: "),
9115 		    dwarf_dieoffset (&cudie));
9116 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9117 	  printf ("\n");
9118 	}
9119       else
9120 	printf (gettext (" Not associated with a CU.\n"));
9121 
9122       printf ("\n");
9123 
9124       const unsigned char *offset_array_start = readp;
9125       if (offset_entry_count > 0)
9126 	{
9127 	  uint64_t max_entries = (unit_length - 8) / offset_size;
9128 	  if (offset_entry_count > max_entries)
9129 	    {
9130 	      error (0, 0,
9131 		     gettext ("too many offset entries for unit length"));
9132 	      offset_entry_count = max_entries;
9133 	    }
9134 
9135 	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
9136 		  (uint64_t) (offset_array_start
9137 			      - (unsigned char *) data->d_buf));
9138 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9139 	    {
9140 	      printf ("   [%6" PRIu32 "] ", idx);
9141 	      if (offset_size == 4)
9142 		{
9143 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9144 		  printf ("0x%" PRIx32 "\n", off);
9145 		}
9146 	      else
9147 		{
9148 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9149 		  printf ("0x%" PRIx64 "\n", off);
9150 		}
9151 	    }
9152 	  printf ("\n");
9153 	}
9154 
9155       Dwarf_Addr base = cu_base;
9156       bool start_of_list = true;
9157       while (readp < nexthdr)
9158 	{
9159 	  uint8_t kind = *readp++;
9160 	  uint64_t op1, op2, len;
9161 
9162 	  /* Skip padding.  */
9163 	  if (start_of_list && kind == DW_LLE_end_of_list)
9164 	    continue;
9165 
9166 	  if (start_of_list)
9167 	    {
9168 	      base = cu_base;
9169 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9170 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9171 		      (uint64_t) (readp - offset_array_start - 1));
9172 	      start_of_list = false;
9173 	    }
9174 
9175 	  printf ("    %s", dwarf_loc_list_encoding_name (kind));
9176 	  switch (kind)
9177 	    {
9178 	    case DW_LLE_end_of_list:
9179 	      start_of_list = true;
9180 	      printf ("\n\n");
9181 	      break;
9182 
9183 	    case DW_LLE_base_addressx:
9184 	      if ((uint64_t) (nexthdr - readp) < 1)
9185 		{
9186 		invalid_entry:
9187 		  error (0, 0, gettext ("invalid loclists data"));
9188 		  goto next_table;
9189 		}
9190 	      get_uleb128 (op1, readp, nexthdr);
9191 	      printf (" %" PRIx64 "\n", op1);
9192 	      if (! print_unresolved_addresses)
9193 		{
9194 		  Dwarf_Addr addr;
9195 		  if (get_indexed_addr (cu, op1, &addr) != 0)
9196 		    printf ("      ???\n");
9197 		  else
9198 		    {
9199 		      printf ("      ");
9200 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
9201 		      printf ("\n");
9202 		    }
9203 		}
9204 	      break;
9205 
9206 	    case DW_LLE_startx_endx:
9207 	      if ((uint64_t) (nexthdr - readp) < 1)
9208 		goto invalid_entry;
9209 	      get_uleb128 (op1, readp, nexthdr);
9210 	      if ((uint64_t) (nexthdr - readp) < 1)
9211 		goto invalid_entry;
9212 	      get_uleb128 (op2, readp, nexthdr);
9213 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9214 	      if (! print_unresolved_addresses)
9215 		{
9216 		  Dwarf_Addr addr1;
9217 		  Dwarf_Addr addr2;
9218 		  if (get_indexed_addr (cu, op1, &addr1) != 0
9219 		      || get_indexed_addr (cu, op2, &addr2) != 0)
9220 		    {
9221 		      printf ("      ???..\n");
9222 		      printf ("      ???\n");
9223 		    }
9224 		  else
9225 		    {
9226 		      printf ("      ");
9227 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9228 		      printf ("..\n      ");
9229 		      print_dwarf_addr (dwflmod, address_size,
9230 					addr2 - 1, addr2);
9231 		      printf ("\n");
9232 		    }
9233 		}
9234 	      if ((uint64_t) (nexthdr - readp) < 1)
9235 		goto invalid_entry;
9236 	      get_uleb128 (len, readp, nexthdr);
9237 	      if ((uint64_t) (nexthdr - readp) < len)
9238 		goto invalid_entry;
9239 	      print_ops (dwflmod, dbg, 8, 8, version,
9240 			 address_size, offset_size, cu, len, readp);
9241 	      readp += len;
9242 	      break;
9243 
9244 	    case DW_LLE_startx_length:
9245 	      if ((uint64_t) (nexthdr - readp) < 1)
9246 		goto invalid_entry;
9247 	      get_uleb128 (op1, readp, nexthdr);
9248 	      if ((uint64_t) (nexthdr - readp) < 1)
9249 		goto invalid_entry;
9250 	      get_uleb128 (op2, readp, nexthdr);
9251 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9252 	      if (! print_unresolved_addresses)
9253 		{
9254 		  Dwarf_Addr addr1;
9255 		  Dwarf_Addr addr2;
9256 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
9257 		    {
9258 		      printf ("      ???..\n");
9259 		      printf ("      ???\n");
9260 		    }
9261 		  else
9262 		    {
9263 		      addr2 = addr1 + op2;
9264 		      printf ("      ");
9265 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9266 		      printf ("..\n      ");
9267 		      print_dwarf_addr (dwflmod, address_size,
9268 					addr2 - 1, addr2);
9269 		      printf ("\n");
9270 		    }
9271 		}
9272 	      if ((uint64_t) (nexthdr - readp) < 1)
9273 		goto invalid_entry;
9274 	      get_uleb128 (len, readp, nexthdr);
9275 	      if ((uint64_t) (nexthdr - readp) < len)
9276 		goto invalid_entry;
9277 	      print_ops (dwflmod, dbg, 8, 8, version,
9278 			 address_size, offset_size, cu, len, readp);
9279 	      readp += len;
9280 	      break;
9281 
9282 	    case DW_LLE_offset_pair:
9283 	      if ((uint64_t) (nexthdr - readp) < 1)
9284 		goto invalid_entry;
9285 	      get_uleb128 (op1, readp, nexthdr);
9286 	      if ((uint64_t) (nexthdr - readp) < 1)
9287 		goto invalid_entry;
9288 	      get_uleb128 (op2, readp, nexthdr);
9289 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9290 	      if (! print_unresolved_addresses)
9291 		{
9292 		  op1 += base;
9293 		  op2 += base;
9294 		  printf ("      ");
9295 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9296 		  printf ("..\n      ");
9297 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9298 		  printf ("\n");
9299 		}
9300 	      if ((uint64_t) (nexthdr - readp) < 1)
9301 		goto invalid_entry;
9302 	      get_uleb128 (len, readp, nexthdr);
9303 	      if ((uint64_t) (nexthdr - readp) < len)
9304 		goto invalid_entry;
9305 	      print_ops (dwflmod, dbg, 8, 8, version,
9306 			 address_size, offset_size, cu, len, readp);
9307 	      readp += len;
9308 	      break;
9309 
9310 	    case DW_LLE_default_location:
9311 	      if ((uint64_t) (nexthdr - readp) < 1)
9312 		goto invalid_entry;
9313 	      get_uleb128 (len, readp, nexthdr);
9314 	      if ((uint64_t) (nexthdr - readp) < len)
9315 		goto invalid_entry;
9316 	      print_ops (dwflmod, dbg, 8, 8, version,
9317 			 address_size, offset_size, cu, len, readp);
9318 	      readp += len;
9319 	      break;
9320 
9321 	    case DW_LLE_base_address:
9322 	      if (address_size == 4)
9323 		{
9324 		  if ((uint64_t) (nexthdr - readp) < 4)
9325 		    goto invalid_entry;
9326 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9327 		}
9328 	      else
9329 		{
9330 		  if ((uint64_t) (nexthdr - readp) < 8)
9331 		    goto invalid_entry;
9332 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9333 		}
9334 	      base = op1;
9335 	      printf (" 0x%" PRIx64 "\n", base);
9336 	      if (! print_unresolved_addresses)
9337 		{
9338 		  printf ("      ");
9339 		  print_dwarf_addr (dwflmod, address_size, base, base);
9340 		  printf ("\n");
9341 		}
9342 	      break;
9343 
9344 	    case DW_LLE_start_end:
9345 	      if (address_size == 4)
9346 		{
9347 		  if ((uint64_t) (nexthdr - readp) < 8)
9348 		    goto invalid_entry;
9349 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9350 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
9351 		}
9352 	      else
9353 		{
9354 		  if ((uint64_t) (nexthdr - readp) < 16)
9355 		    goto invalid_entry;
9356 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9357 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
9358 		}
9359 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9360 	      if (! print_unresolved_addresses)
9361 		{
9362 		  printf ("      ");
9363 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9364 		  printf ("..\n      ");
9365 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9366 		  printf ("\n");
9367 		}
9368 	      if ((uint64_t) (nexthdr - readp) < 1)
9369 		goto invalid_entry;
9370 	      get_uleb128 (len, readp, nexthdr);
9371 	      if ((uint64_t) (nexthdr - readp) < len)
9372 		goto invalid_entry;
9373 	      print_ops (dwflmod, dbg, 8, 8, version,
9374 			 address_size, offset_size, cu, len, readp);
9375 	      readp += len;
9376 	      break;
9377 
9378 	    case DW_LLE_start_length:
9379 	      if (address_size == 4)
9380 		{
9381 		  if ((uint64_t) (nexthdr - readp) < 4)
9382 		    goto invalid_entry;
9383 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9384 		}
9385 	      else
9386 		{
9387 		  if ((uint64_t) (nexthdr - readp) < 8)
9388 		    goto invalid_entry;
9389 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9390 		}
9391 	      if ((uint64_t) (nexthdr - readp) < 1)
9392 		goto invalid_entry;
9393 	      get_uleb128 (op2, readp, nexthdr);
9394 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9395 	      if (! print_unresolved_addresses)
9396 		{
9397 		  op2 = op1 + op2;
9398 		  printf ("      ");
9399 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9400 		  printf ("..\n      ");
9401 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9402 		  printf ("\n");
9403 		}
9404 	      if ((uint64_t) (nexthdr - readp) < 1)
9405 		goto invalid_entry;
9406 	      get_uleb128 (len, readp, nexthdr);
9407 	      if ((uint64_t) (nexthdr - readp) < len)
9408 		goto invalid_entry;
9409 	      print_ops (dwflmod, dbg, 8, 8, version,
9410 			 address_size, offset_size, cu, len, readp);
9411 	      readp += len;
9412 	      break;
9413 
9414 	    default:
9415 	      goto invalid_entry;
9416 	    }
9417 	}
9418 
9419     next_table:
9420       if (readp != nexthdr)
9421 	{
9422           size_t padding = nexthdr - readp;
9423           printf (gettext ("   %zu padding bytes\n\n"), padding);
9424 	  readp = nexthdr;
9425 	}
9426     }
9427 }
9428 
9429 
9430 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9431 print_debug_loc_section (Dwfl_Module *dwflmod,
9432 			 Ebl *ebl, GElf_Ehdr *ehdr,
9433 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9434 {
9435   Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9436 		    ?: elf_rawdata (scn, NULL));
9437 
9438   if (unlikely (data == NULL))
9439     {
9440       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9441 	     elf_errmsg (-1));
9442       return;
9443     }
9444 
9445   printf (gettext ("\
9446 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9447 	  elf_ndxscn (scn), section_name (ebl, shdr),
9448 	  (uint64_t) shdr->sh_offset);
9449 
9450   sort_listptr (&known_locsptr, "loclistptr");
9451   size_t listptr_idx = 0;
9452 
9453   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9454   uint_fast8_t offset_size = 4;
9455 
9456   bool first = true;
9457   Dwarf_Addr base = 0;
9458   unsigned char *readp = data->d_buf;
9459   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9460   Dwarf_CU *last_cu = NULL;
9461   while (readp < endp)
9462     {
9463       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9464       Dwarf_CU *cu = last_cu;
9465       unsigned int attr = 0;
9466 
9467       if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9468 				      &address_size, &offset_size, &base,
9469 				      &cu, offset, &readp, endp, &attr))
9470 	continue;
9471 
9472       if (last_cu != cu)
9473        {
9474 	Dwarf_Die cudie;
9475 	if (dwarf_cu_die (cu, &cudie,
9476 			  NULL, NULL, NULL, NULL,
9477 			  NULL, NULL) == NULL)
9478 	  printf (gettext ("\n Unknown CU base: "));
9479 	else
9480 	  printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9481 		  dwarf_dieoffset (&cudie));
9482 	print_dwarf_addr (dwflmod, address_size, base, base);
9483 	printf ("\n");
9484        }
9485       last_cu = cu;
9486 
9487       if (attr == DW_AT_GNU_locviews)
9488 	{
9489 	  Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9490 						    listptr_idx);
9491 	  const unsigned char *locp = readp;
9492 	  const unsigned char *locendp;
9493 	  if (next_off == 0
9494 	      || next_off > (size_t) (endp
9495 				      - (const unsigned char *) data->d_buf))
9496 	    locendp = endp;
9497 	  else
9498 	    locendp = (const unsigned char *) data->d_buf + next_off;
9499 
9500 	  while (locp < locendp)
9501 	    {
9502 	      uint64_t v1, v2;
9503 	      get_uleb128 (v1, locp, locendp);
9504 	      if (locp >= locendp)
9505 		{
9506 		  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9507 		  break;
9508 		}
9509 	      get_uleb128 (v2, locp, locendp);
9510 	      if (first)		/* First view pair in a list.  */
9511 		printf (" [%6tx] ", offset);
9512 	      else
9513 		printf ("          ");
9514 	      printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9515 	      first = false;
9516 	    }
9517 
9518 	  first = true;
9519 	  readp = (unsigned char *) locendp;
9520 	  continue;
9521 	}
9522 
9523       /* GNU DebugFission encoded addresses as addrx.  */
9524       bool is_debugfission = ((cu != NULL
9525 			       || split_dwarf_cu_base (dbg, &cu, &base))
9526 			      && (cu->version < 5
9527 				  && cu->unit_type == DW_UT_split_compile));
9528       if (!is_debugfission
9529 	  && unlikely (data->d_size - offset < (size_t) address_size * 2))
9530         {
9531 	invalid_data:
9532 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9533 	  break;
9534 	}
9535 
9536       Dwarf_Addr begin;
9537       Dwarf_Addr end;
9538       bool use_base = true;
9539       if (is_debugfission)
9540 	{
9541 	  const unsigned char *locp = readp;
9542 	  const unsigned char *locendp = readp + data->d_size;
9543 	  if (locp >= locendp)
9544 	    goto invalid_data;
9545 
9546 	  Dwarf_Word idx;
9547 	  unsigned char code = *locp++;
9548 	  switch (code)
9549 	    {
9550 	    case DW_LLE_GNU_end_of_list_entry:
9551 	      begin = 0;
9552 	      end = 0;
9553 	      break;
9554 
9555 	    case DW_LLE_GNU_base_address_selection_entry:
9556 	      if (locp >= locendp)
9557 		goto invalid_data;
9558 	      begin = (Dwarf_Addr) -1;
9559 	      get_uleb128 (idx, locp, locendp);
9560 	      if (get_indexed_addr (cu, idx, &end) != 0)
9561 		end = idx; /* ... */
9562 	      break;
9563 
9564 	    case DW_LLE_GNU_start_end_entry:
9565 	      if (locp >= locendp)
9566 		goto invalid_data;
9567 	      get_uleb128 (idx, locp, locendp);
9568 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9569 		begin = idx; /* ... */
9570 	      if (locp >= locendp)
9571 		goto invalid_data;
9572 	      get_uleb128 (idx, locp, locendp);
9573 	      if (get_indexed_addr (cu, idx, &end) != 0)
9574 		end = idx; /* ... */
9575 	      use_base = false;
9576 	      break;
9577 
9578 	    case DW_LLE_GNU_start_length_entry:
9579 	      if (locp >= locendp)
9580 		goto invalid_data;
9581 	      get_uleb128 (idx, locp, locendp);
9582 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9583 		begin = idx; /* ... */
9584 	      if (locendp - locp < 4)
9585 		goto invalid_data;
9586 	      end = read_4ubyte_unaligned_inc (dbg, locp);
9587 	      end += begin;
9588 	      use_base = false;
9589 	      break;
9590 
9591 	    default:
9592 		goto invalid_data;
9593 	    }
9594 
9595 	  readp = (unsigned char *) locp;
9596 	}
9597       else if (address_size == 8)
9598 	{
9599 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
9600 	  end = read_8ubyte_unaligned_inc (dbg, readp);
9601 	}
9602       else
9603 	{
9604 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
9605 	  end = read_4ubyte_unaligned_inc (dbg, readp);
9606 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
9607 	    begin = (Dwarf_Addr) -1l;
9608 	}
9609 
9610       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
9611 	{
9612 	  printf (gettext (" [%6tx] base address\n          "), offset);
9613 	  print_dwarf_addr (dwflmod, address_size, end, end);
9614 	  printf ("\n");
9615 	  base = end;
9616 	}
9617       else if (begin == 0 && end == 0) /* End of list entry.  */
9618 	{
9619 	  if (first)
9620 	    printf (gettext (" [%6tx] empty list\n"), offset);
9621 	  first = true;
9622 	}
9623       else
9624 	{
9625 	  /* We have a location expression entry.  */
9626 	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9627 
9628 	  if (first)		/* First entry in a list.  */
9629 	    printf (" [%6tx] ", offset);
9630 	  else
9631 	    printf ("          ");
9632 
9633 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9634 	  if (! print_unresolved_addresses)
9635 	    {
9636 	      Dwarf_Addr dab = use_base ? base + begin : begin;
9637 	      Dwarf_Addr dae = use_base ? base + end : end;
9638 	      printf ("          ");
9639 	      print_dwarf_addr (dwflmod, address_size, dab, dab);
9640 	      printf ("..\n          ");
9641 	      print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9642 	      printf ("\n");
9643 	    }
9644 
9645 	  if (endp - readp <= (ptrdiff_t) len)
9646 	    {
9647 	      fputs (gettext ("   <INVALID DATA>\n"), stdout);
9648 	      break;
9649 	    }
9650 
9651 	  print_ops (dwflmod, dbg, 11, 11,
9652 		     cu != NULL ? cu->version : 3,
9653 		     address_size, offset_size, cu, len, readp);
9654 
9655 	  first = false;
9656 	  readp += len;
9657 	}
9658     }
9659 }
9660 
9661 struct mac_culist
9662 {
9663   Dwarf_Die die;
9664   Dwarf_Off offset;
9665   Dwarf_Files *files;
9666   struct mac_culist *next;
9667 };
9668 
9669 
9670 static int
mac_compare(const void * p1,const void * p2)9671 mac_compare (const void *p1, const void *p2)
9672 {
9673   struct mac_culist *m1 = (struct mac_culist *) p1;
9674   struct mac_culist *m2 = (struct mac_culist *) p2;
9675 
9676   if (m1->offset < m2->offset)
9677     return -1;
9678   if (m1->offset > m2->offset)
9679     return 1;
9680   return 0;
9681 }
9682 
9683 
9684 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9685 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9686 			     Ebl *ebl,
9687 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
9688 			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9689 {
9690   printf (gettext ("\
9691 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9692 	  elf_ndxscn (scn), section_name (ebl, shdr),
9693 	  (uint64_t) shdr->sh_offset);
9694   putc_unlocked ('\n', stdout);
9695 
9696   /* There is no function in libdw to iterate over the raw content of
9697      the section but it is easy enough to do.  */
9698   Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9699 		    ?: elf_rawdata (scn, NULL));
9700   if (unlikely (data == NULL))
9701     {
9702       error (0, 0, gettext ("cannot get macro information section data: %s"),
9703 	     elf_errmsg (-1));
9704       return;
9705     }
9706 
9707   /* Get the source file information for all CUs.  */
9708   Dwarf_Off offset;
9709   Dwarf_Off ncu = 0;
9710   size_t hsize;
9711   struct mac_culist *culist = NULL;
9712   size_t nculist = 0;
9713   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9714     {
9715       Dwarf_Die cudie;
9716       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9717 	continue;
9718 
9719       Dwarf_Attribute attr;
9720       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9721 	continue;
9722 
9723       Dwarf_Word macoff;
9724       if (dwarf_formudata (&attr, &macoff) != 0)
9725 	continue;
9726 
9727       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9728       newp->die = cudie;
9729       newp->offset = macoff;
9730       newp->files = NULL;
9731       newp->next = culist;
9732       culist = newp;
9733       ++nculist;
9734     }
9735 
9736   /* Convert the list into an array for easier consumption.  */
9737   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9738 							 * sizeof (*cus));
9739   /* Add sentinel.  */
9740   cus[nculist].offset = data->d_size;
9741   cus[nculist].files = (Dwarf_Files *) -1l;
9742   if (nculist > 0)
9743     {
9744       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9745 	{
9746 	  assert (cnt < nculist);
9747 	  cus[cnt] = *culist;
9748 	  culist = culist->next;
9749 	}
9750 
9751       /* Sort the array according to the offset in the .debug_macinfo
9752 	 section.  Note we keep the sentinel at the end.  */
9753       qsort (cus, nculist, sizeof (*cus), mac_compare);
9754     }
9755 
9756   const unsigned char *readp = (const unsigned char *) data->d_buf;
9757   const unsigned char *readendp = readp + data->d_size;
9758   int level = 1;
9759 
9760   while (readp < readendp)
9761     {
9762       unsigned int opcode = *readp++;
9763       unsigned int u128;
9764       unsigned int u128_2;
9765       const unsigned char *endp;
9766 
9767       switch (opcode)
9768 	{
9769 	case DW_MACINFO_define:
9770 	case DW_MACINFO_undef:
9771 	case DW_MACINFO_vendor_ext:
9772 	  /*  For the first two opcodes the parameters are
9773 		line, string
9774 	      For the latter
9775 		number, string.
9776 	      We can treat these cases together.  */
9777 	  get_uleb128 (u128, readp, readendp);
9778 
9779 	  endp = memchr (readp, '\0', readendp - readp);
9780 	  if (unlikely (endp == NULL))
9781 	    {
9782 	      printf (gettext ("\
9783 %*s*** non-terminated string at end of section"),
9784 		      level, "");
9785 	      return;
9786 	    }
9787 
9788 	  if (opcode == DW_MACINFO_define)
9789 	    printf ("%*s#define %s, line %u\n",
9790 		    level, "", (char *) readp, u128);
9791 	  else if (opcode == DW_MACINFO_undef)
9792 	    printf ("%*s#undef %s, line %u\n",
9793 		    level, "", (char *) readp, u128);
9794 	  else
9795 	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9796 
9797 	  readp = endp + 1;
9798 	  break;
9799 
9800 	case DW_MACINFO_start_file:
9801 	  /* The two parameters are line and file index, in this order.  */
9802 	  get_uleb128 (u128, readp, readendp);
9803 	  if (readendp - readp < 1)
9804 	    {
9805 	      printf (gettext ("\
9806 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9807 		      level, "");
9808 	      return;
9809 	    }
9810 	  get_uleb128 (u128_2, readp, readendp);
9811 
9812 	  /* Find the CU DIE for this file.  */
9813 	  size_t macoff = readp - (const unsigned char *) data->d_buf;
9814 	  const char *fname = "???";
9815 	  if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
9816 	    {
9817 	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9818 		++cus;
9819 
9820 	      if (cus[0].files == NULL
9821 		  && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9822 		cus[0].files = (Dwarf_Files *) -1l;
9823 
9824 	      if (cus[0].files != (Dwarf_Files *) -1l)
9825 		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9826 			 ?: "???");
9827 	    }
9828 
9829 	  printf ("%*sstart_file %u, [%u] %s\n",
9830 		  level, "", u128, u128_2, fname);
9831 	  ++level;
9832 	  break;
9833 
9834 	case DW_MACINFO_end_file:
9835 	  --level;
9836 	  printf ("%*send_file\n", level, "");
9837 	  /* Nothing more to do.  */
9838 	  break;
9839 
9840 	default:
9841 	  // XXX gcc seems to generate files with a trailing zero.
9842 	  if (unlikely (opcode != 0 || readp != readendp))
9843 	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9844 	  break;
9845 	}
9846     }
9847 }
9848 
9849 
9850 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9851 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9852 			   Ebl *ebl,
9853 			   GElf_Ehdr *ehdr __attribute__ ((unused)),
9854 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9855 {
9856   printf (gettext ("\
9857 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9858 	  elf_ndxscn (scn), section_name (ebl, shdr),
9859 	  (uint64_t) shdr->sh_offset);
9860   putc_unlocked ('\n', stdout);
9861 
9862   Elf_Data *data =  elf_getdata (scn, NULL);
9863   if (unlikely (data == NULL))
9864     {
9865       error (0, 0, gettext ("cannot get macro information section data: %s"),
9866 	     elf_errmsg (-1));
9867       return;
9868     }
9869 
9870   /* Get the source file information for all CUs.  Uses same
9871      datastructure as macinfo.  But uses offset field to directly
9872      match .debug_line offset.  And just stored in a list.  */
9873   Dwarf_Off offset;
9874   Dwarf_Off ncu = 0;
9875   size_t hsize;
9876   struct mac_culist *culist = NULL;
9877   size_t nculist = 0;
9878   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9879     {
9880       Dwarf_Die cudie;
9881       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9882 	continue;
9883 
9884       Dwarf_Attribute attr;
9885       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9886 	continue;
9887 
9888       Dwarf_Word lineoff;
9889       if (dwarf_formudata (&attr, &lineoff) != 0)
9890 	continue;
9891 
9892       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9893       newp->die = cudie;
9894       newp->offset = lineoff;
9895       newp->files = NULL;
9896       newp->next = culist;
9897       culist = newp;
9898       ++nculist;
9899     }
9900 
9901   const unsigned char *readp = (const unsigned char *) data->d_buf;
9902   const unsigned char *readendp = readp + data->d_size;
9903 
9904   while (readp < readendp)
9905     {
9906       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
9907 	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
9908 
9909       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9910       // optional vendor extension macro entry table.
9911       if (readp + 2 > readendp)
9912 	{
9913 	invalid_data:
9914 	  error (0, 0, gettext ("invalid data"));
9915 	  return;
9916 	}
9917       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9918       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
9919 
9920       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
9921       // 5 when it gets standardized.
9922       if (vers != 4 && vers != 5)
9923 	{
9924 	  printf (gettext ("  unknown version, cannot parse section\n"));
9925 	  return;
9926 	}
9927 
9928       if (readp + 1 > readendp)
9929 	goto invalid_data;
9930       const unsigned char flag = *readp++;
9931       printf (gettext (" Flag:               0x%" PRIx8), flag);
9932       if (flag != 0)
9933 	{
9934 	  printf (" (");
9935 	  if ((flag & 0x01) != 0)
9936 	    {
9937 	      printf ("offset_size");
9938 	      if ((flag & 0xFE) !=  0)
9939 		printf (", ");
9940 	    }
9941 	  if ((flag & 0x02) != 0)
9942 	    {
9943 	      printf ("debug_line_offset");
9944 	      if ((flag & 0xFC) !=  0)
9945 		printf (", ");
9946 	    }
9947 	  if ((flag & 0x04) != 0)
9948 	    {
9949 	      printf ("operands_table");
9950 	      if ((flag & 0xF8) !=  0)
9951 		printf (", ");
9952 	    }
9953 	  if ((flag & 0xF8) != 0)
9954 	    printf ("unknown");
9955 	  printf (")");
9956 	}
9957       printf ("\n");
9958 
9959       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9960       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
9961       Dwarf_Off line_offset = -1;
9962       if (flag & 0x02)
9963 	{
9964 	  if (offset_len == 8)
9965 	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9966 	  else
9967 	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9968 	  printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9969 		  line_offset);
9970 	}
9971 
9972       struct mac_culist *cu = NULL;
9973       if (line_offset != (Dwarf_Off) -1)
9974 	{
9975 	  cu = culist;
9976 	  while (cu != NULL && line_offset != cu->offset)
9977 	    cu = cu->next;
9978 	}
9979 
9980       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9981 							       ? cu->die.cu
9982 							       : NULL));
9983 
9984       const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9985       memset (vendor, 0, sizeof vendor);
9986       if (flag & 0x04)
9987 	{
9988 	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
9989 	  // of arguments, for each argument 1 byte form code.
9990 	  if (readp + 1 > readendp)
9991 	    goto invalid_data;
9992 	  unsigned int tlen = *readp++;
9993 	  printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
9994 		  tlen);
9995 	  for (unsigned int i = 0; i < tlen; i++)
9996 	    {
9997 	      if (readp + 1 > readendp)
9998 		goto invalid_data;
9999 	      unsigned int opcode = *readp++;
10000 	      printf (gettext ("    [%" PRIx8 "]"), opcode);
10001 	      if (opcode < DW_MACRO_lo_user
10002 		  || opcode > DW_MACRO_hi_user)
10003 		goto invalid_data;
10004 	      // Record the start of description for this vendor opcode.
10005 	      // uleb128 nr args, 1 byte per arg form.
10006 	      vendor[opcode - DW_MACRO_lo_user] = readp;
10007 	      if (readp + 1 > readendp)
10008 		goto invalid_data;
10009 	      unsigned int args = *readp++;
10010 	      if (args > 0)
10011 		{
10012 		  printf (gettext (" %" PRIu8 " arguments:"), args);
10013 		  while (args > 0)
10014 		    {
10015 		      if (readp + 1 > readendp)
10016 			goto invalid_data;
10017 		      unsigned int form = *readp++;
10018 		      printf (" %s", dwarf_form_name (form));
10019 		      if (! libdw_valid_user_form (form))
10020 			goto invalid_data;
10021 		      args--;
10022 		      if (args > 0)
10023 			putchar_unlocked (',');
10024 		    }
10025 		}
10026 	      else
10027 		printf (gettext (" no arguments."));
10028 	      putchar_unlocked ('\n');
10029 	    }
10030 	}
10031       putchar_unlocked ('\n');
10032 
10033       int level = 1;
10034       if (readp + 1 > readendp)
10035 	goto invalid_data;
10036       unsigned int opcode = *readp++;
10037       while (opcode != 0)
10038 	{
10039 	  unsigned int u128;
10040 	  unsigned int u128_2;
10041 	  const unsigned char *endp;
10042 	  uint64_t off;
10043 
10044           switch (opcode)
10045             {
10046             case DW_MACRO_start_file:
10047 	      get_uleb128 (u128, readp, readendp);
10048 	      if (readp >= readendp)
10049 		goto invalid_data;
10050 	      get_uleb128 (u128_2, readp, readendp);
10051 
10052 	      /* Find the CU DIE that matches this line offset.  */
10053 	      const char *fname = "???";
10054 	      if (cu != NULL)
10055 		{
10056 		  if (cu->files == NULL
10057 		      && dwarf_getsrcfiles (&cu->die, &cu->files,
10058 					    NULL) != 0)
10059 		    cu->files = (Dwarf_Files *) -1l;
10060 
10061 		  if (cu->files != (Dwarf_Files *) -1l)
10062 		    fname = (dwarf_filesrc (cu->files, u128_2,
10063 					    NULL, NULL) ?: "???");
10064 		}
10065 	      printf ("%*sstart_file %u, [%u] %s\n",
10066 		      level, "", u128, u128_2, fname);
10067 	      ++level;
10068 	      break;
10069 
10070 	    case DW_MACRO_end_file:
10071 	      --level;
10072 	      printf ("%*send_file\n", level, "");
10073 	      break;
10074 
10075 	    case DW_MACRO_define:
10076 	      get_uleb128 (u128, readp, readendp);
10077 	      endp = memchr (readp, '\0', readendp - readp);
10078 	      if (endp == NULL)
10079 		goto invalid_data;
10080 	      printf ("%*s#define %s, line %u\n",
10081 		      level, "", readp, u128);
10082 	      readp = endp + 1;
10083 	      break;
10084 
10085 	    case DW_MACRO_undef:
10086 	      get_uleb128 (u128, readp, readendp);
10087 	      endp = memchr (readp, '\0', readendp - readp);
10088 	      if (endp == NULL)
10089 		goto invalid_data;
10090 	      printf ("%*s#undef %s, line %u\n",
10091 		      level, "", readp, u128);
10092 	      readp = endp + 1;
10093 	      break;
10094 
10095 	    case DW_MACRO_define_strp:
10096 	      get_uleb128 (u128, readp, readendp);
10097 	      if (readp + offset_len > readendp)
10098 		goto invalid_data;
10099 	      if (offset_len == 8)
10100 		off = read_8ubyte_unaligned_inc (dbg, readp);
10101 	      else
10102 		off = read_4ubyte_unaligned_inc (dbg, readp);
10103 	      printf ("%*s#define %s, line %u (indirect)\n",
10104 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10105 	      break;
10106 
10107 	    case DW_MACRO_undef_strp:
10108 	      get_uleb128 (u128, readp, readendp);
10109 	      if (readp + offset_len > readendp)
10110 		goto invalid_data;
10111 	      if (offset_len == 8)
10112 		off = read_8ubyte_unaligned_inc (dbg, readp);
10113 	      else
10114 		off = read_4ubyte_unaligned_inc (dbg, readp);
10115 	      printf ("%*s#undef %s, line %u (indirect)\n",
10116 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10117 	      break;
10118 
10119 	    case DW_MACRO_import:
10120 	      if (readp + offset_len > readendp)
10121 		goto invalid_data;
10122 	      if (offset_len == 8)
10123 		off = read_8ubyte_unaligned_inc (dbg, readp);
10124 	      else
10125 		off = read_4ubyte_unaligned_inc (dbg, readp);
10126 	      printf ("%*s#include offset 0x%" PRIx64 "\n",
10127 		      level, "", off);
10128 	      break;
10129 
10130 	    case DW_MACRO_define_sup:
10131 	      get_uleb128 (u128, readp, readendp);
10132 	      if (readp + offset_len > readendp)
10133 		goto invalid_data;
10134 	      printf ("%*s#define ", level, "");
10135 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10136 					readp, readendp, offset_len,
10137 					str_offsets_base);
10138 	      printf (", line %u (sup)\n", u128);
10139 	      break;
10140 
10141 	    case DW_MACRO_undef_sup:
10142 	      get_uleb128 (u128, readp, readendp);
10143 	      if (readp + offset_len > readendp)
10144 		goto invalid_data;
10145 	      printf ("%*s#undef ", level, "");
10146 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10147 					readp, readendp, offset_len,
10148 					str_offsets_base);
10149 	      printf (", line %u (sup)\n", u128);
10150 	      break;
10151 
10152 	    case DW_MACRO_import_sup:
10153 	      if (readp + offset_len > readendp)
10154 		goto invalid_data;
10155 	      if (offset_len == 8)
10156 		off = read_8ubyte_unaligned_inc (dbg, readp);
10157 	      else
10158 		off = read_4ubyte_unaligned_inc (dbg, readp);
10159 	      // XXX Needs support for reading from supplementary object file.
10160 	      printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10161 		      level, "", off);
10162 	      break;
10163 
10164 	    case DW_MACRO_define_strx:
10165 	      get_uleb128 (u128, readp, readendp);
10166 	      if (readp + offset_len > readendp)
10167 		goto invalid_data;
10168 	      printf ("%*s#define ", level, "");
10169 	      readp =  print_form_data (dbg, DW_FORM_strx,
10170 					readp, readendp, offset_len,
10171 					str_offsets_base);
10172 	      printf (", line %u (strx)\n", u128);
10173 	      break;
10174 
10175 	    case DW_MACRO_undef_strx:
10176 	      get_uleb128 (u128, readp, readendp);
10177 	      if (readp + offset_len > readendp)
10178 		goto invalid_data;
10179 	      printf ("%*s#undef ", level, "");
10180 	      readp =  print_form_data (dbg, DW_FORM_strx,
10181 					readp, readendp, offset_len,
10182 					str_offsets_base);
10183 	      printf (", line %u (strx)\n", u128);
10184 	      break;
10185 
10186 	    default:
10187 	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10188 	      if (opcode < DW_MACRO_lo_user
10189 		  || opcode > DW_MACRO_lo_user
10190 		  || vendor[opcode - DW_MACRO_lo_user] == NULL)
10191 		goto invalid_data;
10192 
10193 	      const unsigned char *op_desc;
10194 	      op_desc = vendor[opcode - DW_MACRO_lo_user];
10195 
10196 	      // Just skip the arguments, we cannot really interpret them,
10197 	      // but print as much as we can.
10198 	      unsigned int args = *op_desc++;
10199 	      while (args > 0 && readp < readendp)
10200 		{
10201 		  unsigned int form = *op_desc++;
10202 		  readp = print_form_data (dbg, form, readp, readendp,
10203 					   offset_len, str_offsets_base);
10204 		  args--;
10205 		  if (args > 0)
10206 		    printf (", ");
10207 		}
10208 	      putchar_unlocked ('\n');
10209 	    }
10210 
10211 	  if (readp + 1 > readendp)
10212 	    goto invalid_data;
10213 	  opcode = *readp++;
10214 	  if (opcode == 0)
10215 	    putchar_unlocked ('\n');
10216 	}
10217     }
10218 }
10219 
10220 
10221 /* Callback for printing global names.  */
10222 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10223 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10224 		void *arg)
10225 {
10226   int *np = (int *) arg;
10227 
10228   printf (gettext (" [%5d] DIE offset: %6" PRId64
10229 		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10230 	  (*np)++, global->die_offset, global->cu_offset, global->name);
10231 
10232   return 0;
10233 }
10234 
10235 
10236 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
10237 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10238 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10239 			      Ebl *ebl,
10240 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
10241 			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10242 {
10243   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10244 	  elf_ndxscn (scn), section_name (ebl, shdr),
10245 	  (uint64_t) shdr->sh_offset);
10246 
10247   int n = 0;
10248   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10249 }
10250 
10251 /* Print the content of the DWARF string section '.debug_str'.  */
10252 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10253 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10254 			 Ebl *ebl,
10255 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10256 			 Elf_Scn *scn, GElf_Shdr *shdr,
10257 			 Dwarf *dbg __attribute__ ((unused)))
10258 {
10259   Elf_Data *data = elf_rawdata (scn, NULL);
10260   const size_t sh_size = data ? data->d_size : 0;
10261 
10262   /* Compute floor(log16(shdr->sh_size)).  */
10263   GElf_Addr tmp = sh_size;
10264   int digits = 1;
10265   while (tmp >= 16)
10266     {
10267       ++digits;
10268       tmp >>= 4;
10269     }
10270   digits = MAX (4, digits);
10271 
10272   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10273 		   " %*s  String\n"),
10274 	  elf_ndxscn (scn),
10275 	  section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10276 	  /* TRANS: the debugstr| prefix makes the string unique.  */
10277 	  digits + 2, sgettext ("debugstr|Offset"));
10278 
10279   Dwarf_Off offset = 0;
10280   while (offset < sh_size)
10281     {
10282       size_t len;
10283       const char *str = (const char *) data->d_buf + offset;
10284       const char *endp = memchr (str, '\0', sh_size - offset);
10285       if (unlikely (endp == NULL))
10286 	{
10287 	  printf (gettext (" *** error, missing string terminator\n"));
10288 	  break;
10289 	}
10290 
10291       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
10292       len = endp - str;
10293       offset += len + 1;
10294     }
10295 }
10296 
10297 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10298 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10299 				 Ebl *ebl,
10300 				 GElf_Ehdr *ehdr __attribute__ ((unused)),
10301 				 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10302 {
10303   printf (gettext ("\
10304 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10305 	  elf_ndxscn (scn), section_name (ebl, shdr),
10306 	  (uint64_t) shdr->sh_offset);
10307 
10308   if (shdr->sh_size == 0)
10309     return;
10310 
10311   /* We like to get the section from libdw to make sure they are relocated.  */
10312   Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10313 		    ?: elf_rawdata (scn, NULL));
10314   if (unlikely (data == NULL))
10315     {
10316       error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10317 	     elf_errmsg (-1));
10318       return;
10319     }
10320 
10321   size_t idx = 0;
10322   sort_listptr (&known_stroffbases, "str_offsets");
10323 
10324   const unsigned char *start = (const unsigned char *) data->d_buf;
10325   const unsigned char *readp = start;
10326   const unsigned char *readendp = ((const unsigned char *) data->d_buf
10327 				   + data->d_size);
10328 
10329   while (readp < readendp)
10330     {
10331       /* Most string offset tables will have a header.  For split
10332 	 dwarf unit GNU DebugFission didn't add one.  But they were
10333 	 also only defined for split units (main or skeleton units
10334 	 didn't have indirect strings).  So if we don't have a
10335 	 DW_AT_str_offsets_base at all and this is offset zero, then
10336 	 just start printing offsets immediately, if this is a .dwo
10337 	 section.  */
10338       Dwarf_Off off = (Dwarf_Off) (readp
10339 				   - (const unsigned char *) data->d_buf);
10340 
10341       printf ("Table at offset %" PRIx64 " ", off);
10342 
10343       struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10344       const unsigned char *next_unitp = readendp;
10345       uint8_t offset_size;
10346       bool has_header;
10347       if (listptr == NULL)
10348 	{
10349 	  /* This can happen for .dwo files.  There is only an header
10350 	     in the case this is a version 5 split DWARF file.  */
10351 	  Dwarf_CU *cu;
10352 	  uint8_t unit_type;
10353 	  if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10354 			       NULL, NULL) != 0)
10355 	    {
10356 	      error (0, 0, "Warning: Cannot find any DWARF unit.");
10357 	      /* Just guess some values.  */
10358 	      has_header = false;
10359 	      offset_size = 4;
10360 	    }
10361 	  else if (off == 0
10362 		   && (unit_type == DW_UT_split_type
10363 		       || unit_type == DW_UT_split_compile))
10364 	    {
10365 	      has_header = cu->version > 4;
10366 	      offset_size = cu->offset_size;
10367 	    }
10368 	  else
10369 	    {
10370 	      error (0, 0,
10371 		     "Warning: No CU references .debug_str_offsets after %"
10372 		     PRIx64, off);
10373 	      has_header = cu->version > 4;
10374 	      offset_size = cu->offset_size;
10375 	    }
10376 	  printf ("\n");
10377 	}
10378       else
10379 	{
10380 	  /* This must be DWARF5, since GNU DebugFission didn't define
10381 	     DW_AT_str_offsets_base.  */
10382 	  has_header = true;
10383 
10384 	  Dwarf_Die cudie;
10385 	  if (dwarf_cu_die (listptr->cu, &cudie,
10386 			    NULL, NULL, NULL, NULL,
10387 			    NULL, NULL) == NULL)
10388 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10389 	  else
10390 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10391 	}
10392 
10393       if (has_header)
10394 	{
10395 	  uint64_t unit_length;
10396 	  uint16_t version;
10397 	  uint16_t padding;
10398 
10399 	  unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10400 	  if (unlikely (unit_length == 0xffffffff))
10401 	    {
10402 	      if (unlikely (readp > readendp - 8))
10403 		{
10404 		invalid_data:
10405 		  error (0, 0, "Invalid data");
10406 		  return;
10407 		}
10408 	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10409 	      offset_size = 8;
10410 	    }
10411 	  else
10412 	    offset_size = 4;
10413 
10414 	  printf ("\n");
10415 	  printf (gettext (" Length:        %8" PRIu64 "\n"),
10416 		  unit_length);
10417 	  printf (gettext (" Offset size:   %8" PRIu8 "\n"),
10418 		  offset_size);
10419 
10420 	  /* We need at least 2-bytes (version) + 2-bytes (padding) =
10421 	     4 bytes to complete the header.  And this unit cannot go
10422 	     beyond the section data.  */
10423 	  if (readp > readendp - 4
10424 	      || unit_length < 4
10425 	      || unit_length > (uint64_t) (readendp - readp))
10426 	    goto invalid_data;
10427 
10428 	  next_unitp = readp + unit_length;
10429 
10430 	  version = read_2ubyte_unaligned_inc (dbg, readp);
10431 	  printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10432 
10433 	  if (version != 5)
10434 	    {
10435 	      error (0, 0, gettext ("Unknown version"));
10436 	      goto next_unit;
10437 	    }
10438 
10439 	  padding = read_2ubyte_unaligned_inc (dbg, readp);
10440 	  printf (gettext (" Padding:       %8" PRIx16 "\n"), padding);
10441 
10442 	  if (listptr != NULL
10443 	      && listptr->offset != (Dwarf_Off) (readp - start))
10444 	    {
10445 	      error (0, 0, "String offsets index doesn't start after header");
10446 	      goto next_unit;
10447 	    }
10448 
10449 	  printf ("\n");
10450 	}
10451 
10452       int digits = 1;
10453       size_t offsets = (next_unitp - readp) / offset_size;
10454       while (offsets >= 10)
10455 	{
10456 	  ++digits;
10457 	  offsets /= 10;
10458 	}
10459 
10460       unsigned int uidx = 0;
10461       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
10462       printf (" Offsets start at 0x%zx:\n", index_offset);
10463       while (readp <= next_unitp - offset_size)
10464 	{
10465 	  Dwarf_Word offset;
10466 	  if (offset_size == 4)
10467 	    offset = read_4ubyte_unaligned_inc (dbg, readp);
10468 	  else
10469 	    offset = read_8ubyte_unaligned_inc (dbg, readp);
10470 	  const char *str = dwarf_getstring (dbg, offset, NULL);
10471 	  printf (" [%*u] [%*" PRIx64 "]  \"%s\"\n",
10472 		  digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10473 	}
10474       printf ("\n");
10475 
10476       if (readp != next_unitp)
10477 	error (0, 0, "extra %zd bytes at end of unit",
10478 	       (size_t) (next_unitp - readp));
10479 
10480     next_unit:
10481       readp = next_unitp;
10482     }
10483 }
10484 
10485 
10486 /* Print the content of the call frame search table section
10487    '.eh_frame_hdr'.  */
10488 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10489 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10490 			       Ebl *ebl __attribute__ ((unused)),
10491 			       GElf_Ehdr *ehdr __attribute__ ((unused)),
10492 			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10493 {
10494   printf (gettext ("\
10495 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10496 	  elf_ndxscn (scn));
10497 
10498   Elf_Data *data = elf_rawdata (scn, NULL);
10499 
10500   if (unlikely (data == NULL))
10501     {
10502       error (0, 0, gettext ("cannot get %s content: %s"),
10503 	     ".eh_frame_hdr", elf_errmsg (-1));
10504       return;
10505     }
10506 
10507   const unsigned char *readp = data->d_buf;
10508   const unsigned char *const dataend = ((unsigned char *) data->d_buf
10509 					+ data->d_size);
10510 
10511   if (unlikely (readp + 4 > dataend))
10512     {
10513     invalid_data:
10514       error (0, 0, gettext ("invalid data"));
10515       return;
10516     }
10517 
10518   unsigned int version = *readp++;
10519   unsigned int eh_frame_ptr_enc = *readp++;
10520   unsigned int fde_count_enc = *readp++;
10521   unsigned int table_enc = *readp++;
10522 
10523   printf (" version:          %u\n"
10524 	  " eh_frame_ptr_enc: %#x ",
10525 	  version, eh_frame_ptr_enc);
10526   print_encoding_base ("", eh_frame_ptr_enc);
10527   printf (" fde_count_enc:    %#x ", fde_count_enc);
10528   print_encoding_base ("", fde_count_enc);
10529   printf (" table_enc:        %#x ", table_enc);
10530   print_encoding_base ("", table_enc);
10531 
10532   uint64_t eh_frame_ptr = 0;
10533   if (eh_frame_ptr_enc != DW_EH_PE_omit)
10534     {
10535       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10536 			    dbg);
10537       if (unlikely (readp == NULL))
10538 	goto invalid_data;
10539 
10540       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
10541       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10542 	printf (" (offset: %#" PRIx64 ")",
10543 		/* +4 because of the 4 byte header of the section.  */
10544 		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10545 
10546       putchar_unlocked ('\n');
10547     }
10548 
10549   uint64_t fde_count = 0;
10550   if (fde_count_enc != DW_EH_PE_omit)
10551     {
10552       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10553       if (unlikely (readp == NULL))
10554 	goto invalid_data;
10555 
10556       printf (" fde_count:        %" PRIu64 "\n", fde_count);
10557     }
10558 
10559   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10560     return;
10561 
10562   puts (" Table:");
10563 
10564   /* Optimize for the most common case.  */
10565   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10566     while (fde_count > 0 && readp + 8 <= dataend)
10567       {
10568 	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10569 	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10570 				   + (int64_t) initial_location);
10571 	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10572 	// XXX Possibly print symbol name or section offset for initial_offset
10573 	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10574 		" fde=[%6" PRIx64 "]\n",
10575 		initial_location, initial_offset,
10576 		address, address - (eh_frame_ptr + 4));
10577       }
10578   else
10579     while (0 && readp < dataend)
10580       {
10581 
10582       }
10583 }
10584 
10585 
10586 /* Print the content of the exception handling table section
10587    '.eh_frame_hdr'.  */
10588 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10589 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10590 			     Ebl *ebl __attribute__ ((unused)),
10591 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
10592 			     Elf_Scn *scn,
10593 			     GElf_Shdr *shdr __attribute__ ((unused)),
10594 			     Dwarf *dbg __attribute__ ((unused)))
10595 {
10596   printf (gettext ("\
10597 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10598 	  elf_ndxscn (scn));
10599 
10600   Elf_Data *data = elf_rawdata (scn, NULL);
10601 
10602   if (unlikely (data == NULL))
10603     {
10604       error (0, 0, gettext ("cannot get %s content: %s"),
10605 	     ".gcc_except_table", elf_errmsg (-1));
10606       return;
10607     }
10608 
10609   const unsigned char *readp = data->d_buf;
10610   const unsigned char *const dataend = readp + data->d_size;
10611 
10612   if (unlikely (readp + 1 > dataend))
10613     {
10614     invalid_data:
10615       error (0, 0, gettext ("invalid data"));
10616       return;
10617     }
10618   unsigned int lpstart_encoding = *readp++;
10619   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
10620   print_encoding_base ("", lpstart_encoding);
10621   if (lpstart_encoding != DW_EH_PE_omit)
10622     {
10623       uint64_t lpstart;
10624       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10625       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
10626     }
10627 
10628   if (unlikely (readp + 1 > dataend))
10629     goto invalid_data;
10630   unsigned int ttype_encoding = *readp++;
10631   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
10632   print_encoding_base ("", ttype_encoding);
10633   const unsigned char *ttype_base = NULL;
10634   if (ttype_encoding != DW_EH_PE_omit)
10635     {
10636       unsigned int ttype_base_offset;
10637       get_uleb128 (ttype_base_offset, readp, dataend);
10638       printf (" TType base offset:   %#x\n", ttype_base_offset);
10639       if ((size_t) (dataend - readp) > ttype_base_offset)
10640         ttype_base = readp + ttype_base_offset;
10641     }
10642 
10643   if (unlikely (readp + 1 > dataend))
10644     goto invalid_data;
10645   unsigned int call_site_encoding = *readp++;
10646   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
10647   print_encoding_base ("", call_site_encoding);
10648   unsigned int call_site_table_len;
10649   get_uleb128 (call_site_table_len, readp, dataend);
10650 
10651   const unsigned char *const action_table = readp + call_site_table_len;
10652   if (unlikely (action_table > dataend))
10653     goto invalid_data;
10654   unsigned int u = 0;
10655   unsigned int max_action = 0;
10656   while (readp < action_table)
10657     {
10658       if (u == 0)
10659 	puts (gettext ("\n Call site table:"));
10660 
10661       uint64_t call_site_start;
10662       readp = read_encoded (call_site_encoding, readp, dataend,
10663 			    &call_site_start, dbg);
10664       uint64_t call_site_length;
10665       readp = read_encoded (call_site_encoding, readp, dataend,
10666 			    &call_site_length, dbg);
10667       uint64_t landing_pad;
10668       readp = read_encoded (call_site_encoding, readp, dataend,
10669 			    &landing_pad, dbg);
10670       unsigned int action;
10671       get_uleb128 (action, readp, dataend);
10672       max_action = MAX (action, max_action);
10673       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
10674 		       "        Call site length:  %" PRIu64 "\n"
10675 		       "        Landing pad:       %#" PRIx64 "\n"
10676 		       "        Action:            %u\n"),
10677 	      u++, call_site_start, call_site_length, landing_pad, action);
10678     }
10679   if (readp != action_table)
10680     goto invalid_data;
10681 
10682   unsigned int max_ar_filter = 0;
10683   if (max_action > 0)
10684     {
10685       puts ("\n Action table:");
10686 
10687       size_t maxdata = (size_t) (dataend - action_table);
10688       if (max_action > maxdata || maxdata - max_action < 1)
10689 	{
10690 	invalid_action_table:
10691 	  fputs (gettext ("   <INVALID DATA>\n"), stdout);
10692 	  return;
10693 	}
10694 
10695       const unsigned char *const action_table_end
10696 	= action_table + max_action + 1;
10697 
10698       u = 0;
10699       do
10700 	{
10701 	  int ar_filter;
10702 	  get_sleb128 (ar_filter, readp, action_table_end);
10703 	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10704 	    max_ar_filter = ar_filter;
10705 	  int ar_disp;
10706 	  if (readp >= action_table_end)
10707 	    goto invalid_action_table;
10708 	  get_sleb128 (ar_disp, readp, action_table_end);
10709 
10710 	  printf (" [%4u] ar_filter:  % d\n"
10711 		  "        ar_disp:    % -5d",
10712 		  u, ar_filter, ar_disp);
10713 	  if (abs (ar_disp) & 1)
10714 	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10715 	  else if (ar_disp != 0)
10716 	    puts (" -> ???");
10717 	  else
10718 	    putchar_unlocked ('\n');
10719 	  ++u;
10720 	}
10721       while (readp < action_table_end);
10722     }
10723 
10724   if (max_ar_filter > 0 && ttype_base != NULL)
10725     {
10726       unsigned char dsize;
10727       puts ("\n TType table:");
10728 
10729       // XXX Not *4, size of encoding;
10730       switch (ttype_encoding & 7)
10731 	{
10732 	case DW_EH_PE_udata2:
10733 	case DW_EH_PE_sdata2:
10734 	  dsize = 2;
10735 	  break;
10736 	case DW_EH_PE_udata4:
10737 	case DW_EH_PE_sdata4:
10738 	  dsize = 4;
10739 	  break;
10740 	case DW_EH_PE_udata8:
10741 	case DW_EH_PE_sdata8:
10742 	  dsize = 8;
10743 	  break;
10744 	default:
10745 	  dsize = 0;
10746 	  error (1, 0, gettext ("invalid TType encoding"));
10747 	}
10748 
10749       if (max_ar_filter
10750 	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10751 	goto invalid_data;
10752 
10753       readp = ttype_base - max_ar_filter * dsize;
10754       do
10755 	{
10756 	  uint64_t ttype;
10757 	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10758 				dbg);
10759 	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10760 	}
10761       while (readp < ttype_base);
10762     }
10763 }
10764 
10765 /* Print the content of the '.gdb_index' section.
10766    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10767 */
10768 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10769 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10770 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10771 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10772 {
10773   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10774 		   " contains %" PRId64 " bytes :\n"),
10775 	  elf_ndxscn (scn), section_name (ebl, shdr),
10776 	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10777 
10778   Elf_Data *data = elf_rawdata (scn, NULL);
10779 
10780   if (unlikely (data == NULL))
10781     {
10782       error (0, 0, gettext ("cannot get %s content: %s"),
10783 	     ".gdb_index", elf_errmsg (-1));
10784       return;
10785     }
10786 
10787   // .gdb_index is always in little endian.
10788   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10789   dbg = &dummy_dbg;
10790 
10791   const unsigned char *readp = data->d_buf;
10792   const unsigned char *const dataend = readp + data->d_size;
10793 
10794   if (unlikely (readp + 4 > dataend))
10795     {
10796     invalid_data:
10797       error (0, 0, gettext ("invalid data"));
10798       return;
10799     }
10800 
10801   int32_t vers = read_4ubyte_unaligned (dbg, readp);
10802   printf (gettext (" Version:         %" PRId32 "\n"), vers);
10803 
10804   // The only difference between version 4 and version 5 is the
10805   // hash used for generating the table.  Version 6 contains symbols
10806   // for inlined functions, older versions didn't.  Version 7 adds
10807   // symbol kinds.  Version 8 just indicates that it correctly includes
10808   // TUs for symbols.
10809   if (vers < 4 || vers > 8)
10810     {
10811       printf (gettext ("  unknown version, cannot parse section\n"));
10812       return;
10813     }
10814 
10815   readp += 4;
10816   if (unlikely (readp + 4 > dataend))
10817     goto invalid_data;
10818 
10819   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10820   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
10821 
10822   readp += 4;
10823   if (unlikely (readp + 4 > dataend))
10824     goto invalid_data;
10825 
10826   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10827   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
10828 
10829   readp += 4;
10830   if (unlikely (readp + 4 > dataend))
10831     goto invalid_data;
10832 
10833   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10834   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
10835 
10836   readp += 4;
10837   if (unlikely (readp + 4 > dataend))
10838     goto invalid_data;
10839 
10840   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10841   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
10842 
10843   readp += 4;
10844   if (unlikely (readp + 4 > dataend))
10845     goto invalid_data;
10846 
10847   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10848   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10849 
10850   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10851 		< const_off))
10852     goto invalid_data;
10853 
10854   readp = data->d_buf + cu_off;
10855 
10856   const unsigned char *nextp = data->d_buf + tu_off;
10857   if (tu_off >= data->d_size)
10858     goto invalid_data;
10859 
10860   size_t cu_nr = (nextp - readp) / 16;
10861 
10862   printf (gettext ("\n CU list at offset %#" PRIx32
10863 		   " contains %zu entries:\n"),
10864 	  cu_off, cu_nr);
10865 
10866   size_t n = 0;
10867   while (dataend - readp >= 16 && n < cu_nr)
10868     {
10869       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10870       readp += 8;
10871 
10872       uint64_t len = read_8ubyte_unaligned (dbg, readp);
10873       readp += 8;
10874 
10875       printf (" [%4zu] start: %0#8" PRIx64
10876 	      ", length: %5" PRIu64 "\n", n, off, len);
10877       n++;
10878     }
10879 
10880   readp = data->d_buf + tu_off;
10881   nextp = data->d_buf + addr_off;
10882   if (addr_off >= data->d_size)
10883     goto invalid_data;
10884 
10885   size_t tu_nr = (nextp - readp) / 24;
10886 
10887   printf (gettext ("\n TU list at offset %#" PRIx32
10888 		   " contains %zu entries:\n"),
10889 	  tu_off, tu_nr);
10890 
10891   n = 0;
10892   while (dataend - readp >= 24 && n < tu_nr)
10893     {
10894       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10895       readp += 8;
10896 
10897       uint64_t type = read_8ubyte_unaligned (dbg, readp);
10898       readp += 8;
10899 
10900       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10901       readp += 8;
10902 
10903       printf (" [%4zu] CU offset: %5" PRId64
10904 	      ", type offset: %5" PRId64
10905 	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10906       n++;
10907     }
10908 
10909   readp = data->d_buf + addr_off;
10910   nextp = data->d_buf + sym_off;
10911   if (sym_off >= data->d_size)
10912     goto invalid_data;
10913 
10914   size_t addr_nr = (nextp - readp) / 20;
10915 
10916   printf (gettext ("\n Address list at offset %#" PRIx32
10917 		   " contains %zu entries:\n"),
10918 	  addr_off, addr_nr);
10919 
10920   n = 0;
10921   while (dataend - readp >= 20 && n < addr_nr)
10922     {
10923       uint64_t low = read_8ubyte_unaligned (dbg, readp);
10924       readp += 8;
10925 
10926       uint64_t high = read_8ubyte_unaligned (dbg, readp);
10927       readp += 8;
10928 
10929       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10930       readp += 4;
10931 
10932       printf (" [%4zu] ", n);
10933       print_dwarf_addr (dwflmod, 8, low, low);
10934       printf ("..");
10935       print_dwarf_addr (dwflmod, 8, high - 1, high);
10936       printf (", CU index: %5" PRId32 "\n", idx);
10937       n++;
10938     }
10939 
10940   const unsigned char *const_start = data->d_buf + const_off;
10941   if (const_off >= data->d_size)
10942     goto invalid_data;
10943 
10944   readp = data->d_buf + sym_off;
10945   nextp = const_start;
10946   size_t sym_nr = (nextp - readp) / 8;
10947 
10948   printf (gettext ("\n Symbol table at offset %#" PRIx32
10949 		   " contains %zu slots:\n"),
10950 	  addr_off, sym_nr);
10951 
10952   n = 0;
10953   while (dataend - readp >= 8 && n < sym_nr)
10954     {
10955       uint32_t name = read_4ubyte_unaligned (dbg, readp);
10956       readp += 4;
10957 
10958       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10959       readp += 4;
10960 
10961       if (name != 0 || vector != 0)
10962 	{
10963 	  const unsigned char *sym = const_start + name;
10964 	  if (unlikely ((size_t) (dataend - const_start) < name
10965 			|| memchr (sym, '\0', dataend - sym) == NULL))
10966 	    goto invalid_data;
10967 
10968 	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10969 
10970 	  const unsigned char *readcus = const_start + vector;
10971 	  if (unlikely ((size_t) (dataend - const_start) < vector))
10972 	    goto invalid_data;
10973 	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10974 	  while (cus--)
10975 	    {
10976 	      uint32_t cu_kind, cu, kind;
10977 	      bool is_static;
10978 	      readcus += 4;
10979 	      if (unlikely (readcus + 4 > dataend))
10980 		goto invalid_data;
10981 	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
10982 	      cu = cu_kind & ((1 << 24) - 1);
10983 	      kind = (cu_kind >> 28) & 7;
10984 	      is_static = cu_kind & (1U << 31);
10985 	      if (cu > cu_nr - 1)
10986 		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10987 	      else
10988 		printf ("%" PRId32, cu);
10989 	      if (kind != 0)
10990 		{
10991 		  printf (" (");
10992 		  switch (kind)
10993 		    {
10994 		    case 1:
10995 		      printf ("type");
10996 		      break;
10997 		    case 2:
10998 		      printf ("var");
10999 		      break;
11000 		    case 3:
11001 		      printf ("func");
11002 		      break;
11003 		    case 4:
11004 		      printf ("other");
11005 		      break;
11006 		    default:
11007 		      printf ("unknown-0x%" PRIx32, kind);
11008 		      break;
11009 		    }
11010 		  printf (":%c)", (is_static ? 'S' : 'G'));
11011 		}
11012 	      if (cus > 0)
11013 		printf (", ");
11014 	    }
11015 	  printf ("\n");
11016 	}
11017       n++;
11018     }
11019 }
11020 
11021 /* Returns true and sets split DWARF CU id if there is a split compile
11022    unit in the given Dwarf, and no non-split units are found (before it).  */
11023 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11024 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11025 {
11026   Dwarf_CU *cu = NULL;
11027   while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11028     {
11029       uint8_t unit_type;
11030       if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11031 			 id, NULL, NULL) != 0)
11032 	return false;
11033 
11034       if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11035 	return false;
11036 
11037       /* We really only care about the split compile unit, the types
11038 	 should be fine and self sufficient.  Also they don't have an
11039 	 id that we can match with a skeleton unit.  */
11040       if (unit_type == DW_UT_split_compile)
11041 	{
11042 	  *split_cu = cu;
11043 	  return true;
11044 	}
11045     }
11046 
11047   return false;
11048 }
11049 
11050 /* Check that there is one and only one Dwfl_Module, return in arg.  */
11051 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11052 getone_dwflmod (Dwfl_Module *dwflmod,
11053 	       void **userdata __attribute__ ((unused)),
11054 	       const char *name __attribute__ ((unused)),
11055 	       Dwarf_Addr base __attribute__ ((unused)),
11056 	       void *arg)
11057 {
11058   Dwfl_Module **m = (Dwfl_Module **) arg;
11059   if (*m != NULL)
11060     return DWARF_CB_ABORT;
11061   *m = dwflmod;
11062   return DWARF_CB_OK;
11063 }
11064 
11065 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11066 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11067 {
11068   /* Used for skeleton file, if necessary for split DWARF.  */
11069   Dwfl *skel_dwfl = NULL;
11070   Dwfl_Module *skel_mod = NULL;
11071   char *skel_name = NULL;
11072   Dwarf *split_dbg = NULL;
11073   Dwarf_CU *split_cu = NULL;
11074 
11075   /* Before we start the real work get a debug context descriptor.  */
11076   Dwarf_Addr dwbias;
11077   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11078   Dwarf dummy_dbg =
11079     {
11080       .elf = ebl->elf,
11081       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11082     };
11083   if (dbg == NULL)
11084     {
11085       if ((print_debug_sections & ~section_exception) != 0)
11086 	error (0, 0, gettext ("cannot get debug context descriptor: %s"),
11087 	       dwfl_errmsg (-1));
11088       dbg = &dummy_dbg;
11089     }
11090   else
11091     {
11092       /* If we are asked about a split dwarf (.dwo) file, use the user
11093 	 provided, or find the corresponding skeleton file. If we got
11094 	 a skeleton file, replace the given dwflmod and dbg, with one
11095 	 derived from the skeleton file to provide enough context.  */
11096       uint64_t split_id;
11097       if (is_split_dwarf (dbg, &split_id, &split_cu))
11098 	{
11099 	  if (dwarf_skeleton != NULL)
11100 	    skel_name = strdup (dwarf_skeleton);
11101 	  else
11102 	    {
11103 	      /* Replace file.dwo with file.o and see if that matches. */
11104 	      const char *fname;
11105 	      dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11106 				&fname, NULL);
11107 	      if (fname != NULL)
11108 		{
11109 		  size_t flen = strlen (fname);
11110 		  if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11111 		    {
11112 		      skel_name = strdup (fname);
11113 		      if (skel_name != NULL)
11114 			{
11115 			  skel_name[flen - 3] = 'o';
11116 			  skel_name[flen - 2] = '\0';
11117 			}
11118 		    }
11119 		}
11120 	    }
11121 
11122 	  if (skel_name != NULL)
11123 	    {
11124 	      int skel_fd = open (skel_name, O_RDONLY);
11125 	      if (skel_fd == -1)
11126 		fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11127 			 " '%s'\n", skel_name);
11128 	      else
11129 		skel_dwfl = create_dwfl (skel_fd, skel_name);
11130 
11131 	      if (skel_dwfl != NULL)
11132 		{
11133 		  if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11134 				       &skel_mod, 0) != 0)
11135 		    {
11136 		      fprintf (stderr, "Warning: Bad DWARF skeleton,"
11137 			       " multiple modules '%s'\n", skel_name);
11138 		      dwfl_end (skel_dwfl);
11139 		      skel_mod = NULL;
11140 		    }
11141 		}
11142 	      else if (skel_fd != -1)
11143 		fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11144 			 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11145 
11146 	      if (skel_mod != NULL)
11147 		{
11148 		  Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11149 		  if (skel_dbg != NULL)
11150 		    {
11151 		      /* First check the skeleton CU DIE, only fetch
11152 			 the split DIE if we know the id matches to
11153 			 not unnecessary search for any split DIEs we
11154 			 don't need. */
11155 		      Dwarf_CU *cu = NULL;
11156 		      while (dwarf_get_units (skel_dbg, cu, &cu,
11157 					      NULL, NULL, NULL, NULL) == 0)
11158 			{
11159 			  uint8_t unit_type;
11160 			  uint64_t skel_id;
11161 			  if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11162 					     &skel_id, NULL, NULL) == 0
11163 			      && unit_type == DW_UT_skeleton
11164 			      && split_id == skel_id)
11165 			    {
11166 			      Dwarf_Die subdie;
11167 			      if (dwarf_cu_info (cu, NULL, NULL, NULL,
11168 						 &subdie,
11169 						 NULL, NULL, NULL) == 0
11170 				  && dwarf_tag (&subdie) != DW_TAG_invalid)
11171 				{
11172 				  split_dbg = dwarf_cu_getdwarf (subdie.cu);
11173 				  if (split_dbg == NULL)
11174 				    fprintf (stderr,
11175 					     "Warning: Couldn't get split_dbg:"
11176 					     " %s\n", dwarf_errmsg (-1));
11177 				  break;
11178 				}
11179 			      else
11180 				{
11181 				  /* Everything matches up, but not
11182 				     according to libdw. Which means
11183 				     the user knew better.  So...
11184 				     Terrible hack... We can never
11185 				     destroy the underlying dwfl
11186 				     because it would free the wrong
11187 				     Dwarfs... So we leak memory...*/
11188 				  if (cu->split == NULL
11189 				      && dwarf_skeleton != NULL)
11190 				    {
11191 				      do_not_close_dwfl = true;
11192 				      __libdw_link_skel_split (cu, split_cu);
11193 				      split_dbg = dwarf_cu_getdwarf (split_cu);
11194 				      break;
11195 				    }
11196 				  else
11197 				    fprintf (stderr, "Warning: Couldn't get"
11198 					     " skeleton subdie: %s\n",
11199 					     dwarf_errmsg (-1));
11200 				}
11201 			    }
11202 			}
11203 		      if (split_dbg == NULL)
11204 			fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11205 		    }
11206 		  else
11207 		    fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11208 			     " %s\n", dwfl_errmsg (-1));
11209 		}
11210 	    }
11211 
11212 	  if (split_dbg != NULL)
11213 	    {
11214 	      dbg = split_dbg;
11215 	      dwflmod = skel_mod;
11216 	    }
11217 	  else if (skel_name == NULL)
11218 	    fprintf (stderr,
11219 		     "Warning: split DWARF file, but no skeleton found.\n");
11220 	}
11221       else if (dwarf_skeleton != NULL)
11222 	fprintf (stderr, "Warning: DWARF skeleton given,"
11223 		 " but not a split DWARF file\n");
11224     }
11225 
11226   /* Get the section header string table index.  */
11227   size_t shstrndx;
11228   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11229     error (EXIT_FAILURE, 0,
11230 	   gettext ("cannot get section header string table index"));
11231 
11232   /* If the .debug_info section is listed as implicitly required then
11233      we must make sure to handle it before handling any other debug
11234      section.  Various other sections depend on the CU DIEs being
11235      scanned (silently) first.  */
11236   bool implicit_info = (implicit_debug_sections & section_info) != 0;
11237   bool explicit_info = (print_debug_sections & section_info) != 0;
11238   if (implicit_info)
11239     {
11240       Elf_Scn *scn = NULL;
11241       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11242 	{
11243 	  GElf_Shdr shdr_mem;
11244 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11245 
11246 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11247 	    {
11248 	      const char *name = elf_strptr (ebl->elf, shstrndx,
11249 					     shdr->sh_name);
11250 	      if (name == NULL)
11251 		continue;
11252 
11253 	      if (strcmp (name, ".debug_info") == 0
11254 		  || strcmp (name, ".debug_info.dwo") == 0
11255 		  || strcmp (name, ".zdebug_info") == 0
11256 		  || strcmp (name, ".zdebug_info.dwo") == 0)
11257 		{
11258 		  print_debug_info_section (dwflmod, ebl, ehdr,
11259 					    scn, shdr, dbg);
11260 		  break;
11261 		}
11262 	    }
11263 	}
11264       print_debug_sections &= ~section_info;
11265       implicit_debug_sections &= ~section_info;
11266     }
11267 
11268   /* Look through all the sections for the debugging sections to print.  */
11269   Elf_Scn *scn = NULL;
11270   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11271     {
11272       GElf_Shdr shdr_mem;
11273       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11274 
11275       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11276 	{
11277 	  static const struct
11278 	  {
11279 	    const char *name;
11280 	    enum section_e bitmask;
11281 	    void (*fp) (Dwfl_Module *, Ebl *,
11282 			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11283 	  } debug_sections[] =
11284 	    {
11285 #define NEW_SECTION(name) \
11286 	      { ".debug_" #name, section_##name, print_debug_##name##_section }
11287 	      NEW_SECTION (abbrev),
11288 	      NEW_SECTION (addr),
11289 	      NEW_SECTION (aranges),
11290 	      NEW_SECTION (frame),
11291 	      NEW_SECTION (info),
11292 	      NEW_SECTION (types),
11293 	      NEW_SECTION (line),
11294 	      NEW_SECTION (loc),
11295 	      /* loclists is loc for DWARF5.  */
11296 	      { ".debug_loclists", section_loc,
11297 		print_debug_loclists_section },
11298 	      NEW_SECTION (pubnames),
11299 	      NEW_SECTION (str),
11300 	      /* A DWARF5 specialised debug string section.  */
11301 	      { ".debug_line_str", section_str,
11302 		print_debug_str_section },
11303 	      /* DWARF5 string offsets table.  */
11304 	      { ".debug_str_offsets", section_str,
11305 		print_debug_str_offsets_section },
11306 	      NEW_SECTION (macinfo),
11307 	      NEW_SECTION (macro),
11308 	      NEW_SECTION (ranges),
11309 	      /* rnglists is ranges for DWARF5.  */
11310 	      { ".debug_rnglists", section_ranges,
11311 		print_debug_rnglists_section },
11312 	      { ".eh_frame", section_frame | section_exception,
11313 		print_debug_frame_section },
11314 	      { ".eh_frame_hdr", section_frame | section_exception,
11315 		print_debug_frame_hdr_section },
11316 	      { ".gcc_except_table", section_frame | section_exception,
11317 		print_debug_exception_table },
11318 	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
11319 	    };
11320 	  const int ndebug_sections = (sizeof (debug_sections)
11321 				       / sizeof (debug_sections[0]));
11322 	  const char *name = elf_strptr (ebl->elf, shstrndx,
11323 					 shdr->sh_name);
11324 	  if (name == NULL)
11325 	    continue;
11326 
11327 	  int n;
11328 	  for (n = 0; n < ndebug_sections; ++n)
11329 	    {
11330 	      size_t dbglen = strlen (debug_sections[n].name);
11331 	      size_t scnlen = strlen (name);
11332 	      if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11333 		   && (dbglen == scnlen
11334 		       || (scnlen == dbglen + 4
11335 			   && strstr (name, ".dwo") == name + dbglen)))
11336 		  || (name[0] == '.' && name[1] == 'z'
11337 		      && debug_sections[n].name[1] == 'd'
11338 		      && strncmp (&name[2], &debug_sections[n].name[1],
11339 				  dbglen - 1) == 0
11340 		      && (scnlen == dbglen + 1
11341 			  || (scnlen == dbglen + 5
11342 			      && strstr (name, ".dwo") == name + dbglen + 1))))
11343 		{
11344 		  if ((print_debug_sections | implicit_debug_sections)
11345 		      & debug_sections[n].bitmask)
11346 		    debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11347 		  break;
11348 		}
11349 	    }
11350 	}
11351     }
11352 
11353   dwfl_end (skel_dwfl);
11354   free (skel_name);
11355 
11356   /* Turn implicit and/or explicit back on in case we go over another file.  */
11357   if (implicit_info)
11358     implicit_debug_sections |= section_info;
11359   if (explicit_info)
11360     print_debug_sections |= section_info;
11361 
11362   reset_listptr (&known_locsptr);
11363   reset_listptr (&known_loclistsptr);
11364   reset_listptr (&known_rangelistptr);
11365   reset_listptr (&known_rnglistptr);
11366   reset_listptr (&known_addrbases);
11367   reset_listptr (&known_stroffbases);
11368 }
11369 
11370 
11371 #define ITEM_INDENT		4
11372 #define WRAP_COLUMN		75
11373 
11374 /* Print "NAME: FORMAT", wrapping when output text would make the line
11375    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
11376    but this function is also used for registers which should be printed
11377    aligned.  Fortunately registers output uses fixed fields width (such
11378    as %11d) for the alignment.
11379 
11380    Line breaks should not depend on the particular values although that
11381    may happen in some cases of the core items.  */
11382 
11383 static unsigned int
11384 __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,...)11385 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11386 		 size_t name_width, const char *name, const char *format, ...)
11387 {
11388   size_t len = strlen (name);
11389   if (name_width < len)
11390     name_width = len;
11391 
11392   char *out;
11393   va_list ap;
11394   va_start (ap, format);
11395   int out_len = vasprintf (&out, format, ap);
11396   va_end (ap);
11397   if (out_len == -1)
11398     error (EXIT_FAILURE, 0, _("memory exhausted"));
11399 
11400   size_t n = name_width + sizeof ": " - 1 + out_len;
11401 
11402   if (colno == 0)
11403     {
11404       printf ("%*s", ITEM_INDENT, "");
11405       colno = ITEM_INDENT + n;
11406     }
11407   else if (colno + 2 + n < wrap)
11408     {
11409       printf ("%c ", sep);
11410       colno += 2 + n;
11411     }
11412   else
11413     {
11414       printf ("\n%*s", ITEM_INDENT, "");
11415       colno = ITEM_INDENT + n;
11416     }
11417 
11418   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11419 
11420   free (out);
11421 
11422   return colno;
11423 }
11424 
11425 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11426 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11427 	 void *value, const void *data, size_t size)
11428 {
11429   Elf_Data valuedata =
11430     {
11431       .d_type = type,
11432       .d_buf = value,
11433       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11434       .d_version = EV_CURRENT,
11435     };
11436   Elf_Data indata =
11437     {
11438       .d_type = type,
11439       .d_buf = (void *) data,
11440       .d_size = valuedata.d_size,
11441       .d_version = EV_CURRENT,
11442     };
11443 
11444   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11445 		 ? elf32_xlatetom : elf64_xlatetom)
11446     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11447   if (d == NULL)
11448     error (EXIT_FAILURE, 0,
11449 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11450 
11451   return data + indata.d_size;
11452 }
11453 
11454 typedef uint8_t GElf_Byte;
11455 
11456 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11457 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11458 		  unsigned int colno, size_t *repeated_size)
11459 {
11460   uint_fast16_t count = item->count ?: 1;
11461   /* Ebl_Core_Item count is always a small number.
11462      Make sure the backend didn't put in some large bogus value.  */
11463   assert (count < 128);
11464 
11465 #define TYPES								      \
11466   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
11467   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
11468   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
11469   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
11470   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
11471   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11472 
11473 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11474   typedef union { TYPES; } value_t;
11475   void *data = alloca (count * sizeof (value_t));
11476 #undef DO_TYPE
11477 
11478 #define DO_TYPE(NAME, Name, hex, dec) \
11479     GElf_##Name *value_##Name __attribute__((unused)) = data
11480   TYPES;
11481 #undef DO_TYPE
11482 
11483   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11484   size_t convsize = size;
11485   if (repeated_size != NULL)
11486     {
11487       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11488 	{
11489 	  data = alloca (*repeated_size);
11490 	  count *= *repeated_size / size;
11491 	  convsize = count * size;
11492 	  *repeated_size -= convsize;
11493 	}
11494       else if (item->count != 0 || item->format != '\n')
11495 	*repeated_size -= size;
11496     }
11497 
11498   convert (core, item->type, count, data, desc + item->offset, convsize);
11499 
11500   Elf_Type type = item->type;
11501   if (type == ELF_T_ADDR)
11502     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11503 
11504   switch (item->format)
11505     {
11506     case 'd':
11507       assert (count == 1);
11508       switch (type)
11509 	{
11510 #define DO_TYPE(NAME, Name, hex, dec)					      \
11511 	  case ELF_T_##NAME:						      \
11512 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11513 				     0, item->name, dec, value_##Name[0]); \
11514 	    break
11515 	  TYPES;
11516 #undef DO_TYPE
11517 	default:
11518 	  abort ();
11519 	}
11520       break;
11521 
11522     case 'x':
11523       assert (count == 1);
11524       switch (type)
11525 	{
11526 #define DO_TYPE(NAME, Name, hex, dec)					      \
11527 	  case ELF_T_##NAME:						      \
11528 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11529 				     0, item->name, hex, value_##Name[0]);      \
11530 	    break
11531 	  TYPES;
11532 #undef DO_TYPE
11533 	default:
11534 	  abort ();
11535 	}
11536       break;
11537 
11538     case 'b':
11539     case 'B':
11540       assert (size % sizeof (unsigned int) == 0);
11541       unsigned int nbits = count * size * 8;
11542       unsigned int pop = 0;
11543       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11544 	pop += __builtin_popcount (*i);
11545       bool negate = pop > nbits / 2;
11546       const unsigned int bias = item->format == 'b';
11547 
11548       {
11549 	char printed[(negate ? nbits - pop : pop) * 16 + 1];
11550 	char *p = printed;
11551 	*p = '\0';
11552 
11553 	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11554 	  {
11555 	    assert (size == sizeof (unsigned int) * 2);
11556 	    for (unsigned int *i = data;
11557 		 (void *) i < data + count * size; i += 2)
11558 	      {
11559 		unsigned int w = i[1];
11560 		i[1] = i[0];
11561 		i[0] = w;
11562 	      }
11563 	  }
11564 
11565 	unsigned int lastbit = 0;
11566 	unsigned int run = 0;
11567 	for (const unsigned int *i = data;
11568 	     (void *) i < data + count * size; ++i)
11569 	  {
11570 	    unsigned int bit = ((void *) i - data) * 8;
11571 	    unsigned int w = negate ? ~*i : *i;
11572 	    while (w != 0)
11573 	      {
11574 		/* Note that a right shift equal to (or greater than)
11575 		   the number of bits of w is undefined behaviour.  In
11576 		   particular when the least significant bit is bit 32
11577 		   (w = 0x8000000) then w >>= n is undefined.  So
11578 		   explicitly handle that case separately.  */
11579 		unsigned int n = ffs (w);
11580 		if (n < sizeof (w) * 8)
11581 		  w >>= n;
11582 		else
11583 		  w = 0;
11584 		bit += n;
11585 
11586 		if (lastbit != 0 && lastbit + 1 == bit)
11587 		  ++run;
11588 		else
11589 		  {
11590 		    if (lastbit == 0)
11591 		      p += sprintf (p, "%u", bit - bias);
11592 		    else if (run == 0)
11593 		      p += sprintf (p, ",%u", bit - bias);
11594 		    else
11595 		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11596 		    run = 0;
11597 		  }
11598 
11599 		lastbit = bit;
11600 	      }
11601 	  }
11602 	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11603 	  p += sprintf (p, "-%u", lastbit - bias);
11604 
11605 	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11606 				 negate ? "~<%s>" : "<%s>", printed);
11607       }
11608       break;
11609 
11610     case 'T':
11611     case (char) ('T'|0x80):
11612       assert (count == 2);
11613       Dwarf_Word sec;
11614       Dwarf_Word usec;
11615       switch (type)
11616 	{
11617 #define DO_TYPE(NAME, Name, hex, dec)					      \
11618 	  case ELF_T_##NAME:						      \
11619 	    sec = value_##Name[0];					      \
11620 	    usec = value_##Name[1];					      \
11621 	    break
11622 	  TYPES;
11623 #undef DO_TYPE
11624 	default:
11625 	  abort ();
11626 	}
11627       if (unlikely (item->format == (char) ('T'|0x80)))
11628 	{
11629 	  /* This is a hack for an ill-considered 64-bit ABI where
11630 	     tv_usec is actually a 32-bit field with 32 bits of padding
11631 	     rounding out struct timeval.  We've already converted it as
11632 	     a 64-bit field.  For little-endian, this just means the
11633 	     high half is the padding; it's presumably zero, but should
11634 	     be ignored anyway.  For big-endian, it means the 32-bit
11635 	     field went into the high half of USEC.  */
11636 	  GElf_Ehdr ehdr_mem;
11637 	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11638 	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11639 	    usec >>= 32;
11640 	  else
11641 	    usec &= UINT32_MAX;
11642 	}
11643       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11644 			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
11645       break;
11646 
11647     case 'c':
11648       assert (count == 1);
11649       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11650 			       "%c", value_Byte[0]);
11651       break;
11652 
11653     case 's':
11654       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11655 			       "%.*s", (int) count, value_Byte);
11656       break;
11657 
11658     case '\n':
11659       /* This is a list of strings separated by '\n'.  */
11660       assert (item->count == 0);
11661       assert (repeated_size != NULL);
11662       assert (item->name == NULL);
11663       if (unlikely (item->offset >= *repeated_size))
11664 	break;
11665 
11666       const char *s = desc + item->offset;
11667       size = *repeated_size - item->offset;
11668       *repeated_size = 0;
11669       while (size > 0)
11670 	{
11671 	  const char *eol = memchr (s, '\n', size);
11672 	  int len = size;
11673 	  if (eol != NULL)
11674 	    len = eol - s;
11675 	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11676 	  if (eol == NULL)
11677 	    break;
11678 	  size -= eol + 1 - s;
11679 	  s = eol + 1;
11680 	}
11681 
11682       colno = WRAP_COLUMN;
11683       break;
11684 
11685     case 'h':
11686       break;
11687 
11688     default:
11689       error (0, 0, "XXX not handling format '%c' for %s",
11690 	     item->format, item->name);
11691       break;
11692     }
11693 
11694 #undef TYPES
11695 
11696   return colno;
11697 }
11698 
11699 
11700 /* Sort items by group, and by layout offset within each group.  */
11701 static int
compare_core_items(const void * a,const void * b)11702 compare_core_items (const void *a, const void *b)
11703 {
11704   const Ebl_Core_Item *const *p1 = a;
11705   const Ebl_Core_Item *const *p2 = b;
11706   const Ebl_Core_Item *item1 = *p1;
11707   const Ebl_Core_Item *item2 = *p2;
11708 
11709   return ((item1->group == item2->group ? 0
11710 	   : strcmp (item1->group, item2->group))
11711 	  ?: (int) item1->offset - (int) item2->offset);
11712 }
11713 
11714 /* Sort item groups by layout offset of the first item in the group.  */
11715 static int
compare_core_item_groups(const void * a,const void * b)11716 compare_core_item_groups (const void *a, const void *b)
11717 {
11718   const Ebl_Core_Item *const *const *p1 = a;
11719   const Ebl_Core_Item *const *const *p2 = b;
11720   const Ebl_Core_Item *const *group1 = *p1;
11721   const Ebl_Core_Item *const *group2 = *p2;
11722   const Ebl_Core_Item *item1 = *group1;
11723   const Ebl_Core_Item *item2 = *group2;
11724 
11725   return (int) item1->offset - (int) item2->offset;
11726 }
11727 
11728 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11729 handle_core_items (Elf *core, const void *desc, size_t descsz,
11730 		   const Ebl_Core_Item *items, size_t nitems)
11731 {
11732   if (nitems == 0)
11733     return 0;
11734   unsigned int colno = 0;
11735 
11736   /* FORMAT '\n' makes sense to be present only as a single item as it
11737      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
11738      if present as a single item but they can be also processed with other
11739      items below.  */
11740   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11741 		      || items[0].format == 'B'))
11742     {
11743       assert (items[0].offset == 0);
11744       size_t size = descsz;
11745       colno = handle_core_item (core, items, desc, colno, &size);
11746       /* If SIZE is not zero here there is some remaining data.  But we do not
11747 	 know how to process it anyway.  */
11748       return colno;
11749     }
11750   for (size_t i = 0; i < nitems; ++i)
11751     assert (items[i].format != '\n');
11752 
11753   /* Sort to collect the groups together.  */
11754   const Ebl_Core_Item *sorted_items[nitems];
11755   for (size_t i = 0; i < nitems; ++i)
11756     sorted_items[i] = &items[i];
11757   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11758 
11759   /* Collect the unique groups and sort them.  */
11760   const Ebl_Core_Item **groups[nitems];
11761   groups[0] = &sorted_items[0];
11762   size_t ngroups = 1;
11763   for (size_t i = 1; i < nitems; ++i)
11764     if (sorted_items[i]->group != sorted_items[i - 1]->group
11765 	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11766       groups[ngroups++] = &sorted_items[i];
11767   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11768 
11769   /* Write out all the groups.  */
11770   const void *last = desc;
11771   do
11772     {
11773       for (size_t i = 0; i < ngroups; ++i)
11774 	{
11775 	  for (const Ebl_Core_Item **item = groups[i];
11776 	       (item < &sorted_items[nitems]
11777 		&& ((*item)->group == groups[i][0]->group
11778 		    || !strcmp ((*item)->group, groups[i][0]->group)));
11779 	       ++item)
11780 	    colno = handle_core_item (core, *item, desc, colno, NULL);
11781 
11782 	  /* Force a line break at the end of the group.  */
11783 	  colno = WRAP_COLUMN;
11784 	}
11785 
11786       if (descsz == 0)
11787 	break;
11788 
11789       /* This set of items consumed a certain amount of the note's data.
11790 	 If there is more data there, we have another unit of the same size.
11791 	 Loop to print that out too.  */
11792       const Ebl_Core_Item *item = &items[nitems - 1];
11793       size_t eltsz = item->offset + gelf_fsize (core, item->type,
11794 						item->count ?: 1, EV_CURRENT);
11795 
11796       int reps = -1;
11797       do
11798 	{
11799 	  ++reps;
11800 	  desc += eltsz;
11801 	  descsz -= eltsz;
11802 	}
11803       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11804 
11805       if (reps == 1)
11806 	{
11807 	  /* For just one repeat, print it unabridged twice.  */
11808 	  desc -= eltsz;
11809 	  descsz += eltsz;
11810 	}
11811       else if (reps > 1)
11812 	printf (gettext ("\n%*s... <repeats %u more times> ..."),
11813 		ITEM_INDENT, "", reps);
11814 
11815       last = desc;
11816     }
11817   while (descsz > 0);
11818 
11819   return colno;
11820 }
11821 
11822 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11823 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11824 		      unsigned int colno)
11825 {
11826   desc += regloc->offset;
11827 
11828   abort ();			/* XXX */
11829   return colno;
11830 }
11831 
11832 
11833 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11834 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11835 		      const Ebl_Register_Location *regloc, const void *desc,
11836 		      unsigned int colno)
11837 {
11838   if (regloc->bits % 8 != 0)
11839     return handle_bit_registers (regloc, desc, colno);
11840 
11841   desc += regloc->offset;
11842 
11843   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11844     {
11845       char name[REGNAMESZ];
11846       int bits;
11847       int type;
11848       register_info (ebl, reg, regloc, name, &bits, &type);
11849 
11850 #define TYPES								      \
11851       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
11852       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
11853       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
11854       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
11855 
11856 #define BITS(bits, xtype, sfmt, ufmt)				\
11857       uint##bits##_t b##bits; int##bits##_t b##bits##s
11858       union { TYPES; uint64_t b128[2]; } value;
11859 #undef	BITS
11860 
11861       switch (type)
11862 	{
11863 	case DW_ATE_unsigned:
11864 	case DW_ATE_signed:
11865 	case DW_ATE_address:
11866 	  switch (bits)
11867 	    {
11868 #define BITS(bits, xtype, sfmt, ufmt)					      \
11869 	    case bits:							      \
11870 	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
11871 	      if (type == DW_ATE_signed)				      \
11872 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11873 					 maxregname, name,		      \
11874 					 sfmt, value.b##bits##s);	      \
11875 	      else							      \
11876 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11877 					 maxregname, name,		      \
11878 					 ufmt, value.b##bits);		      \
11879 	      break
11880 
11881 	    TYPES;
11882 
11883 	    case 128:
11884 	      assert (type == DW_ATE_unsigned);
11885 	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11886 	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11887 	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
11888 				       maxregname, name,
11889 				       "0x%.16" PRIx64 "%.16" PRIx64,
11890 				       value.b128[!be], value.b128[be]);
11891 	      break;
11892 
11893 	    default:
11894 	      abort ();
11895 #undef	BITS
11896 	    }
11897 	  break;
11898 
11899 	default:
11900 	  /* Print each byte in hex, the whole thing in native byte order.  */
11901 	  assert (bits % 8 == 0);
11902 	  const uint8_t *bytes = desc;
11903 	  desc += bits / 8;
11904 	  char hex[bits / 4 + 1];
11905 	  hex[bits / 4] = '\0';
11906 	  int incr = 1;
11907 	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11908 	    {
11909 	      bytes += bits / 8 - 1;
11910 	      incr = -1;
11911 	    }
11912 	  size_t idx = 0;
11913 	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11914 	    {
11915 	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11916 	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11917 	    }
11918 	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
11919 				   maxregname, name, "0x%s", hex);
11920 	  break;
11921 	}
11922       desc += regloc->pad;
11923 
11924 #undef TYPES
11925     }
11926 
11927   return colno;
11928 }
11929 
11930 
11931 struct register_info
11932 {
11933   const Ebl_Register_Location *regloc;
11934   const char *set;
11935   char name[REGNAMESZ];
11936   int regno;
11937   int bits;
11938   int type;
11939 };
11940 
11941 static int
register_bitpos(const struct register_info * r)11942 register_bitpos (const struct register_info *r)
11943 {
11944   return (r->regloc->offset * 8
11945 	  + ((r->regno - r->regloc->regno)
11946 	     * (r->regloc->bits + r->regloc->pad * 8)));
11947 }
11948 
11949 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)11950 compare_sets_by_info (const struct register_info *r1,
11951 		      const struct register_info *r2)
11952 {
11953   return ((int) r2->bits - (int) r1->bits
11954 	  ?: register_bitpos (r1) - register_bitpos (r2));
11955 }
11956 
11957 /* Sort registers by set, and by size and layout offset within each set.  */
11958 static int
compare_registers(const void * a,const void * b)11959 compare_registers (const void *a, const void *b)
11960 {
11961   const struct register_info *r1 = a;
11962   const struct register_info *r2 = b;
11963 
11964   /* Unused elements sort last.  */
11965   if (r1->regloc == NULL)
11966     return r2->regloc == NULL ? 0 : 1;
11967   if (r2->regloc == NULL)
11968     return -1;
11969 
11970   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11971 	  ?: compare_sets_by_info (r1, r2));
11972 }
11973 
11974 /* Sort register sets by layout offset of the first register in the set.  */
11975 static int
compare_register_sets(const void * a,const void * b)11976 compare_register_sets (const void *a, const void *b)
11977 {
11978   const struct register_info *const *p1 = a;
11979   const struct register_info *const *p2 = b;
11980   return compare_sets_by_info (*p1, *p2);
11981 }
11982 
11983 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)11984 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11985 		       const Ebl_Register_Location *reglocs, size_t nregloc)
11986 {
11987   if (nregloc == 0)
11988     return 0;
11989 
11990   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
11991   if (maxnreg <= 0)
11992     {
11993       for (size_t i = 0; i < nregloc; ++i)
11994 	if (maxnreg < reglocs[i].regno + reglocs[i].count)
11995 	  maxnreg = reglocs[i].regno + reglocs[i].count;
11996       assert (maxnreg > 0);
11997     }
11998 
11999   struct register_info regs[maxnreg];
12000   memset (regs, 0, sizeof regs);
12001 
12002   /* Sort to collect the sets together.  */
12003   int maxreg = 0;
12004   for (size_t i = 0; i < nregloc; ++i)
12005     for (int reg = reglocs[i].regno;
12006 	 reg < reglocs[i].regno + reglocs[i].count;
12007 	 ++reg)
12008       {
12009 	assert (reg < maxnreg);
12010 	if (reg > maxreg)
12011 	  maxreg = reg;
12012 	struct register_info *info = &regs[reg];
12013 	info->regloc = &reglocs[i];
12014 	info->regno = reg;
12015 	info->set = register_info (ebl, reg, &reglocs[i],
12016 				   info->name, &info->bits, &info->type);
12017       }
12018   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12019 
12020   /* Collect the unique sets and sort them.  */
12021   inline bool same_set (const struct register_info *a,
12022 			const struct register_info *b)
12023   {
12024     return (a < &regs[maxnreg] && a->regloc != NULL
12025 	    && b < &regs[maxnreg] && b->regloc != NULL
12026 	    && a->bits == b->bits
12027 	    && (a->set == b->set || !strcmp (a->set, b->set)));
12028   }
12029   struct register_info *sets[maxreg + 1];
12030   sets[0] = &regs[0];
12031   size_t nsets = 1;
12032   for (int i = 1; i <= maxreg; ++i)
12033     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
12034       sets[nsets++] = &regs[i];
12035   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12036 
12037   /* Write out all the sets.  */
12038   unsigned int colno = 0;
12039   for (size_t i = 0; i < nsets; ++i)
12040     {
12041       /* Find the longest name of a register in this set.  */
12042       size_t maxname = 0;
12043       const struct register_info *end;
12044       for (end = sets[i]; same_set (sets[i], end); ++end)
12045 	{
12046 	  size_t len = strlen (end->name);
12047 	  if (len > maxname)
12048 	    maxname = len;
12049 	}
12050 
12051       for (const struct register_info *reg = sets[i];
12052 	   reg < end;
12053 	   reg += reg->regloc->count ?: 1)
12054 	colno = handle_core_register (ebl, core, maxname,
12055 				      reg->regloc, desc, colno);
12056 
12057       /* Force a line break at the end of the group.  */
12058       colno = WRAP_COLUMN;
12059     }
12060 
12061   return colno;
12062 }
12063 
12064 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12065 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12066 {
12067   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12068   if (data == NULL)
12069   elf_error:
12070     error (EXIT_FAILURE, 0,
12071 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12072 
12073   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12074   for (size_t i = 0; i < nauxv; ++i)
12075     {
12076       GElf_auxv_t av_mem;
12077       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12078       if (av == NULL)
12079 	goto elf_error;
12080 
12081       const char *name;
12082       const char *fmt;
12083       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12084 	{
12085 	  /* Unknown type.  */
12086 	  if (av->a_un.a_val == 0)
12087 	    printf ("    %" PRIu64 "\n", av->a_type);
12088 	  else
12089 	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
12090 		    av->a_type, av->a_un.a_val);
12091 	}
12092       else
12093 	switch (fmt[0])
12094 	  {
12095 	  case '\0':		/* Normally zero.  */
12096 	    if (av->a_un.a_val == 0)
12097 	      {
12098 		printf ("    %s\n", name);
12099 		break;
12100 	      }
12101 	    FALLTHROUGH;
12102 	  case 'x':		/* hex */
12103 	  case 'p':		/* address */
12104 	  case 's':		/* address of string */
12105 	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12106 	    break;
12107 	  case 'u':
12108 	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
12109 	    break;
12110 	  case 'd':
12111 	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
12112 	    break;
12113 
12114 	  case 'b':
12115 	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
12116 	    GElf_Xword bit = 1;
12117 	    const char *pfx = "<";
12118 	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12119 	      {
12120 		if (av->a_un.a_val & bit)
12121 		  {
12122 		    printf ("%s%s", pfx, p);
12123 		    pfx = " ";
12124 		  }
12125 		bit <<= 1;
12126 	      }
12127 	    printf (">\n");
12128 	    break;
12129 
12130 	  default:
12131 	    abort ();
12132 	  }
12133     }
12134 }
12135 
12136 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12137 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12138 {
12139   return ptr < end && (size_t) (end - ptr) >= sz;
12140 }
12141 
12142 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12143 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12144 	      int *retp)
12145 {
12146   if (! buf_has_data (*ptrp, end, 4))
12147     return false;
12148 
12149   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12150   return true;
12151 }
12152 
12153 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12154 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12155 		uint64_t *retp)
12156 {
12157   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12158   if (! buf_has_data (*ptrp, end, sz))
12159     return false;
12160 
12161   union
12162   {
12163     uint64_t u64;
12164     uint32_t u32;
12165   } u;
12166 
12167   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12168 
12169   if (sz == 4)
12170     *retp = u.u32;
12171   else
12172     *retp = u.u64;
12173   return true;
12174 }
12175 
12176 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12177 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12178 {
12179   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12180   if (data == NULL)
12181     error (EXIT_FAILURE, 0,
12182 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12183 
12184   unsigned char const *ptr = data->d_buf;
12185   unsigned char const *const end = data->d_buf + data->d_size;
12186 
12187   /* Siginfo head is three ints: signal number, error number, origin
12188      code.  */
12189   int si_signo, si_errno, si_code;
12190   if (! buf_read_int (core, &ptr, end, &si_signo)
12191       || ! buf_read_int (core, &ptr, end, &si_errno)
12192       || ! buf_read_int (core, &ptr, end, &si_code))
12193     {
12194     fail:
12195       printf ("    Not enough data in NT_SIGINFO note.\n");
12196       return;
12197     }
12198 
12199   /* Next is a pointer-aligned union of structures.  On 64-bit
12200      machines, that implies a word of padding.  */
12201   if (gelf_getclass (core) == ELFCLASS64)
12202     ptr += 4;
12203 
12204   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
12205 	  si_signo, si_errno, si_code);
12206 
12207   if (si_code > 0)
12208     switch (si_signo)
12209       {
12210       case CORE_SIGILL:
12211       case CORE_SIGFPE:
12212       case CORE_SIGSEGV:
12213       case CORE_SIGBUS:
12214 	{
12215 	  uint64_t addr;
12216 	  if (! buf_read_ulong (core, &ptr, end, &addr))
12217 	    goto fail;
12218 	  printf ("    fault address: %#" PRIx64 "\n", addr);
12219 	  break;
12220 	}
12221       default:
12222 	;
12223       }
12224   else if (si_code == CORE_SI_USER)
12225     {
12226       int pid, uid;
12227       if (! buf_read_int (core, &ptr, end, &pid)
12228 	  || ! buf_read_int (core, &ptr, end, &uid))
12229 	goto fail;
12230       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
12231     }
12232 }
12233 
12234 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12235 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12236 {
12237   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12238   if (data == NULL)
12239     error (EXIT_FAILURE, 0,
12240 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12241 
12242   unsigned char const *ptr = data->d_buf;
12243   unsigned char const *const end = data->d_buf + data->d_size;
12244 
12245   uint64_t count, page_size;
12246   if (! buf_read_ulong (core, &ptr, end, &count)
12247       || ! buf_read_ulong (core, &ptr, end, &page_size))
12248     {
12249     fail:
12250       printf ("    Not enough data in NT_FILE note.\n");
12251       return;
12252     }
12253 
12254   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12255   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12256   if (count > maxcount)
12257     goto fail;
12258 
12259   /* Where file names are stored.  */
12260   unsigned char const *const fstart = ptr + 3 * count * addrsize;
12261   char const *fptr = (char *) fstart;
12262 
12263   printf ("    %" PRId64 " files:\n", count);
12264   for (uint64_t i = 0; i < count; ++i)
12265     {
12266       uint64_t mstart, mend, moffset;
12267       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12268 	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
12269 	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12270 	goto fail;
12271 
12272       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12273       if (fnext == NULL)
12274 	goto fail;
12275 
12276       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
12277 		       " %08" PRIx64 " %" PRId64,
12278 		       mstart, mend, moffset * page_size, mend - mstart);
12279       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12280 
12281       fptr = fnext + 1;
12282     }
12283 }
12284 
12285 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12286 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12287 		  const char *name, const void *desc)
12288 {
12289   GElf_Word regs_offset;
12290   size_t nregloc;
12291   const Ebl_Register_Location *reglocs;
12292   size_t nitems;
12293   const Ebl_Core_Item *items;
12294 
12295   if (! ebl_core_note (ebl, nhdr, name, desc,
12296 		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
12297     return;
12298 
12299   /* Pass 0 for DESCSZ when there are registers in the note,
12300      so that the ITEMS array does not describe the whole thing.
12301      For non-register notes, the actual descsz might be a multiple
12302      of the unit size, not just exactly the unit size.  */
12303   unsigned int colno = handle_core_items (ebl->elf, desc,
12304 					  nregloc == 0 ? nhdr->n_descsz : 0,
12305 					  items, nitems);
12306   if (colno != 0)
12307     putchar_unlocked ('\n');
12308 
12309   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12310 				 reglocs, nregloc);
12311   if (colno != 0)
12312     putchar_unlocked ('\n');
12313 }
12314 
12315 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12316 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12317 		   GElf_Off start, Elf_Data *data)
12318 {
12319   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
12320 
12321   if (data == NULL)
12322     goto bad_note;
12323 
12324   size_t offset = 0;
12325   GElf_Nhdr nhdr;
12326   size_t name_offset;
12327   size_t desc_offset;
12328   while (offset < data->d_size
12329 	 && (offset = gelf_getnote (data, offset,
12330 				    &nhdr, &name_offset, &desc_offset)) > 0)
12331     {
12332       const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12333       const char *desc = data->d_buf + desc_offset;
12334 
12335       /* GNU Build Attributes are weird, they store most of their data
12336 	 into the owner name field.  Extract just the owner name
12337 	 prefix here, then use the rest later as data.  */
12338       bool is_gnu_build_attr
12339 	= strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12340 		   strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12341       const char *print_name = (is_gnu_build_attr
12342 				? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12343       size_t print_namesz = (is_gnu_build_attr
12344 			     ? strlen (print_name) : nhdr.n_namesz);
12345 
12346       char buf[100];
12347       char buf2[100];
12348       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
12349 	      (int) print_namesz, print_name, nhdr.n_descsz,
12350 	      ehdr->e_type == ET_CORE
12351 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
12352 					 buf, sizeof (buf))
12353 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12354 					   nhdr.n_descsz,
12355 					   buf2, sizeof (buf2)));
12356 
12357       /* Filter out invalid entries.  */
12358       if (memchr (name, '\0', nhdr.n_namesz) != NULL
12359 	  /* XXX For now help broken Linux kernels.  */
12360 	  || 1)
12361 	{
12362 	  if (ehdr->e_type == ET_CORE)
12363 	    {
12364 	      if (nhdr.n_type == NT_AUXV
12365 		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
12366 		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
12367 		  && !memcmp (name, "CORE", 4))
12368 		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12369 				  start + desc_offset);
12370 	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12371 		switch (nhdr.n_type)
12372 		  {
12373 		  case NT_SIGINFO:
12374 		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12375 					 start + desc_offset);
12376 		    break;
12377 
12378 		  case NT_FILE:
12379 		    handle_file_note (ebl->elf, nhdr.n_descsz,
12380 				      start + desc_offset);
12381 		    break;
12382 
12383 		  default:
12384 		    handle_core_note (ebl, &nhdr, name, desc);
12385 		  }
12386 	      else
12387 		handle_core_note (ebl, &nhdr, name, desc);
12388 	    }
12389 	  else
12390 	    ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12391 			     nhdr.n_descsz, desc);
12392 	}
12393     }
12394 
12395   if (offset == data->d_size)
12396     return;
12397 
12398  bad_note:
12399   error (0, 0,
12400 	 gettext ("cannot get content of note: %s"),
12401 	 data != NULL ? "garbage data" : elf_errmsg (-1));
12402 }
12403 
12404 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12405 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12406 {
12407   /* If we have section headers, just look for SHT_NOTE sections.
12408      In a debuginfo file, the program headers are not reliable.  */
12409   if (shnum != 0)
12410     {
12411       /* Get the section header string table index.  */
12412       size_t shstrndx;
12413       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12414 	error (EXIT_FAILURE, 0,
12415 	       gettext ("cannot get section header string table index"));
12416 
12417       Elf_Scn *scn = NULL;
12418       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12419 	{
12420 	  GElf_Shdr shdr_mem;
12421 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12422 
12423 	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12424 	    /* Not what we are looking for.  */
12425 	    continue;
12426 
12427 	  if (notes_section != NULL)
12428 	    {
12429 	      char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12430 	      if (sname == NULL || strcmp (sname, notes_section) != 0)
12431 		continue;
12432 	    }
12433 
12434 	  printf (gettext ("\
12435 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12436 		  elf_ndxscn (scn),
12437 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12438 		  shdr->sh_size, shdr->sh_offset);
12439 
12440 	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
12441 			     elf_getdata (scn, NULL));
12442 	}
12443       return;
12444     }
12445 
12446   /* We have to look through the program header to find the note
12447      sections.  There can be more than one.  */
12448   for (size_t cnt = 0; cnt < phnum; ++cnt)
12449     {
12450       GElf_Phdr mem;
12451       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12452 
12453       if (phdr == NULL || phdr->p_type != PT_NOTE)
12454 	/* Not what we are looking for.  */
12455 	continue;
12456 
12457       printf (gettext ("\
12458 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12459 	      phdr->p_filesz, phdr->p_offset);
12460 
12461       handle_notes_data (ebl, ehdr, phdr->p_offset,
12462 			 elf_getdata_rawchunk (ebl->elf,
12463 					       phdr->p_offset, phdr->p_filesz,
12464 					       (phdr->p_align == 8
12465 						? ELF_T_NHDR8 : ELF_T_NHDR)));
12466     }
12467 }
12468 
12469 
12470 static void
hex_dump(const uint8_t * data,size_t len)12471 hex_dump (const uint8_t *data, size_t len)
12472 {
12473   size_t pos = 0;
12474   while (pos < len)
12475     {
12476       printf ("  0x%08zx ", pos);
12477 
12478       const size_t chunk = MIN (len - pos, 16);
12479 
12480       for (size_t i = 0; i < chunk; ++i)
12481 	if (i % 4 == 3)
12482 	  printf ("%02x ", data[pos + i]);
12483 	else
12484 	  printf ("%02x", data[pos + i]);
12485 
12486       if (chunk < 16)
12487 	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12488 
12489       for (size_t i = 0; i < chunk; ++i)
12490 	{
12491 	  unsigned char b = data[pos + i];
12492 	  printf ("%c", isprint (b) ? b : '.');
12493 	}
12494 
12495       putchar ('\n');
12496       pos += chunk;
12497     }
12498 }
12499 
12500 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12501 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12502 {
12503   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12504     printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12505 	    elf_ndxscn (scn), name);
12506   else
12507     {
12508       if (print_decompress)
12509 	{
12510 	  /* We try to decompress the section, but keep the old shdr around
12511 	     so we can show both the original shdr size and the uncompressed
12512 	     data size.   */
12513 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12514 	    {
12515 	      if (elf_compress (scn, 0, 0) < 0)
12516 		printf ("WARNING: %s [%zd]\n",
12517 			gettext ("Couldn't uncompress section"),
12518 			elf_ndxscn (scn));
12519 	    }
12520 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12521 	    {
12522 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12523 		printf ("WARNING: %s [%zd]\n",
12524 			gettext ("Couldn't uncompress section"),
12525 			elf_ndxscn (scn));
12526 	    }
12527 	}
12528 
12529       Elf_Data *data = elf_rawdata (scn, NULL);
12530       if (data == NULL)
12531 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12532 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12533       else
12534 	{
12535 	  if (data->d_size == shdr->sh_size)
12536 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12537 			     " bytes at offset %#0" PRIx64 ":\n"),
12538 		    elf_ndxscn (scn), name,
12539 		    shdr->sh_size, shdr->sh_offset);
12540 	  else
12541 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12542 			     " bytes (%zd uncompressed) at offset %#0"
12543 			     PRIx64 ":\n"),
12544 		    elf_ndxscn (scn), name,
12545 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12546 	  hex_dump (data->d_buf, data->d_size);
12547 	}
12548     }
12549 }
12550 
12551 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12552 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12553 {
12554   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12555     printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12556 	    elf_ndxscn (scn), name);
12557   else
12558     {
12559       if (print_decompress)
12560 	{
12561 	  /* We try to decompress the section, but keep the old shdr around
12562 	     so we can show both the original shdr size and the uncompressed
12563 	     data size.  */
12564 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12565 	    {
12566 	      if (elf_compress (scn, 0, 0) < 0)
12567 		printf ("WARNING: %s [%zd]\n",
12568 			gettext ("Couldn't uncompress section"),
12569 			elf_ndxscn (scn));
12570 	    }
12571 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12572 	    {
12573 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12574 		printf ("WARNING: %s [%zd]\n",
12575 			gettext ("Couldn't uncompress section"),
12576 			elf_ndxscn (scn));
12577 	    }
12578 	}
12579 
12580       Elf_Data *data = elf_rawdata (scn, NULL);
12581       if (data == NULL)
12582 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12583 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12584       else
12585 	{
12586 	  if (data->d_size == shdr->sh_size)
12587 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12588 			     " bytes at offset %#0" PRIx64 ":\n"),
12589 		    elf_ndxscn (scn), name,
12590 		    shdr->sh_size, shdr->sh_offset);
12591 	  else
12592 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12593 			     " bytes (%zd uncompressed) at offset %#0"
12594 			     PRIx64 ":\n"),
12595 		    elf_ndxscn (scn), name,
12596 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12597 
12598 	  const char *start = data->d_buf;
12599 	  const char *const limit = start + data->d_size;
12600 	  do
12601 	    {
12602 	      const char *end = memchr (start, '\0', limit - start);
12603 	      const size_t pos = start - (const char *) data->d_buf;
12604 	      if (unlikely (end == NULL))
12605 		{
12606 		  printf ("  [%6zx]- %.*s\n",
12607 			  pos, (int) (limit - start), start);
12608 		  break;
12609 		}
12610 	      printf ("  [%6zx]  %s\n", pos, start);
12611 	      start = end + 1;
12612 	    } while (start < limit);
12613 	}
12614     }
12615 }
12616 
12617 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))12618 for_each_section_argument (Elf *elf, const struct section_argument *list,
12619 			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12620 					 const char *name))
12621 {
12622   /* Get the section header string table index.  */
12623   size_t shstrndx;
12624   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12625     error (EXIT_FAILURE, 0,
12626 	   gettext ("cannot get section header string table index"));
12627 
12628   for (const struct section_argument *a = list; a != NULL; a = a->next)
12629     {
12630       Elf_Scn *scn;
12631       GElf_Shdr shdr_mem;
12632       const char *name = NULL;
12633 
12634       char *endp = NULL;
12635       unsigned long int shndx = strtoul (a->arg, &endp, 0);
12636       if (endp != a->arg && *endp == '\0')
12637 	{
12638 	  scn = elf_getscn (elf, shndx);
12639 	  if (scn == NULL)
12640 	    {
12641 	      error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12642 	      continue;
12643 	    }
12644 
12645 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
12646 	    error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12647 		   elf_errmsg (-1));
12648 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12649 	  (*dump) (scn, &shdr_mem, name);
12650 	}
12651       else
12652 	{
12653 	  /* Need to look up the section by name.  */
12654 	  scn = NULL;
12655 	  bool found = false;
12656 	  while ((scn = elf_nextscn (elf, scn)) != NULL)
12657 	    {
12658 	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
12659 		continue;
12660 	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12661 	      if (name == NULL)
12662 		continue;
12663 	      if (!strcmp (name, a->arg))
12664 		{
12665 		  found = true;
12666 		  (*dump) (scn, &shdr_mem, name);
12667 		}
12668 	    }
12669 
12670 	  if (unlikely (!found) && !a->implicit)
12671 	    error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12672 	}
12673     }
12674 }
12675 
12676 static void
dump_data(Ebl * ebl)12677 dump_data (Ebl *ebl)
12678 {
12679   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12680 }
12681 
12682 static void
dump_strings(Ebl * ebl)12683 dump_strings (Ebl *ebl)
12684 {
12685   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12686 }
12687 
12688 static void
print_strings(Ebl * ebl)12689 print_strings (Ebl *ebl)
12690 {
12691   /* Get the section header string table index.  */
12692   size_t shstrndx;
12693   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12694     error (EXIT_FAILURE, 0,
12695 	   gettext ("cannot get section header string table index"));
12696 
12697   Elf_Scn *scn;
12698   GElf_Shdr shdr_mem;
12699   const char *name;
12700   scn = NULL;
12701   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12702     {
12703       if (gelf_getshdr (scn, &shdr_mem) == NULL)
12704 	continue;
12705 
12706       if (shdr_mem.sh_type != SHT_PROGBITS
12707 	  || !(shdr_mem.sh_flags & SHF_STRINGS))
12708 	continue;
12709 
12710       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12711       if (name == NULL)
12712 	continue;
12713 
12714       print_string_section (scn, &shdr_mem, name);
12715     }
12716 }
12717 
12718 static void
dump_archive_index(Elf * elf,const char * fname)12719 dump_archive_index (Elf *elf, const char *fname)
12720 {
12721   size_t narsym;
12722   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12723   if (arsym == NULL)
12724     {
12725       int result = elf_errno ();
12726       if (unlikely (result != ELF_E_NO_INDEX))
12727 	error (EXIT_FAILURE, 0,
12728 	       gettext ("cannot get symbol index of archive '%s': %s"),
12729 	       fname, elf_errmsg (result));
12730       else
12731 	printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12732       return;
12733     }
12734 
12735   printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12736 	  fname, narsym);
12737 
12738   size_t as_off = 0;
12739   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12740     {
12741       if (s->as_off != as_off)
12742 	{
12743 	  as_off = s->as_off;
12744 
12745 	  Elf *subelf = NULL;
12746 	  if (unlikely (elf_rand (elf, as_off) == 0)
12747 	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12748 			   == NULL))
12749 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12750 	    while (1)
12751 #endif
12752 	      error (EXIT_FAILURE, 0,
12753 		     gettext ("cannot extract member at offset %zu in '%s': %s"),
12754 		     as_off, fname, elf_errmsg (-1));
12755 
12756 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
12757 
12758 	  printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12759 
12760 	  elf_end (subelf);
12761 	}
12762 
12763       printf ("\t%s\n", s->as_name);
12764     }
12765 }
12766 
12767 #include "debugpred.h"
12768