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
4833 #if defined(__DragonFly__)
compare_listptr(void * arg,const void * a,const void * b)4834 compare_listptr (void *arg, const void *a, const void *b)
4835 #else
4836 compare_listptr (const void *a, const void *b, void *arg)
4837 #endif
4838 {
4839   const char *name = arg;
4840   struct listptr *p1 = (void *) a;
4841   struct listptr *p2 = (void *) b;
4842 
4843   if (p1->offset < p2->offset)
4844     return -1;
4845   if (p1->offset > p2->offset)
4846     return 1;
4847 
4848   if (!p1->warned && !p2->warned)
4849     {
4850       if (p1->addr64 != p2->addr64)
4851 	{
4852 	  p1->warned = p2->warned = true;
4853 	  error (0, 0,
4854 		 gettext ("%s %#" PRIx64 " used with different address sizes"),
4855 		 name, (uint64_t) p1->offset);
4856 	}
4857       if (p1->dwarf64 != p2->dwarf64)
4858 	{
4859 	  p1->warned = p2->warned = true;
4860 	  error (0, 0,
4861 		 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4862 		 name, (uint64_t) p1->offset);
4863 	}
4864       if (listptr_base (p1) != listptr_base (p2))
4865 	{
4866 	  p1->warned = p2->warned = true;
4867 	  error (0, 0,
4868 		 gettext ("%s %#" PRIx64 " used with different base addresses"),
4869 		 name, (uint64_t) p1->offset);
4870 	}
4871       if (p1->attr != p2 ->attr)
4872 	{
4873 	  p1->warned = p2->warned = true;
4874 	  error (0, 0,
4875 		 gettext ("%s %#" PRIx64
4876 			  " used with different attribute %s and %s"),
4877 		 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
4878 		 dwarf_attr_name (p2->attr));
4879 	}
4880     }
4881 
4882   return 0;
4883 }
4884 
4885 struct listptr_table
4886 {
4887   size_t n;
4888   size_t alloc;
4889   struct listptr *table;
4890 };
4891 
4892 static struct listptr_table known_locsptr;
4893 static struct listptr_table known_loclistsptr;
4894 static struct listptr_table known_rangelistptr;
4895 static struct listptr_table known_rnglistptr;
4896 static struct listptr_table known_addrbases;
4897 static struct listptr_table known_stroffbases;
4898 
4899 static void
reset_listptr(struct listptr_table * table)4900 reset_listptr (struct listptr_table *table)
4901 {
4902   free (table->table);
4903   table->table = NULL;
4904   table->n = table->alloc = 0;
4905 }
4906 
4907 /* Returns false if offset doesn't fit.  See struct listptr.  */
4908 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)4909 notice_listptr (enum section_e section, struct listptr_table *table,
4910 		uint_fast8_t address_size, uint_fast8_t offset_size,
4911 		struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4912 {
4913   if (print_debug_sections & section)
4914     {
4915       if (table->n == table->alloc)
4916 	{
4917 	  if (table->alloc == 0)
4918 	    table->alloc = 128;
4919 	  else
4920 	    table->alloc *= 2;
4921 	  table->table = xrealloc (table->table,
4922 				   table->alloc * sizeof table->table[0]);
4923 	}
4924 
4925       struct listptr *p = &table->table[table->n++];
4926 
4927       *p = (struct listptr)
4928 	{
4929 	  .addr64 = address_size == 8,
4930 	  .dwarf64 = offset_size == 8,
4931 	  .offset = offset,
4932 	  .cu = cu,
4933 	  .attr = attr
4934 	};
4935 
4936       if (p->offset != offset)
4937 	{
4938 	  table->n--;
4939 	  return false;
4940 	}
4941     }
4942   return true;
4943 }
4944 
4945 static void
sort_listptr(struct listptr_table * table,const char * name)4946 sort_listptr (struct listptr_table *table, const char *name)
4947 {
4948   if (table->n > 0)
4949 #if defined(__DragonFly__)
4950     qsort_r (table->table, table->n, sizeof table->table[0],
4951 	     (void *) name, &compare_listptr);
4952 #else
4953     qsort_r (table->table, table->n, sizeof table->table[0],
4954 	     &compare_listptr, (void *) name);
4955 #endif
4956 }
4957 
4958 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)4959 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4960 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4961 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4962 		   unsigned char **readp, unsigned char *endp,
4963 		   unsigned int *attr)
4964 {
4965   if (table->n == 0)
4966     return false;
4967 
4968   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4969     ++*idxp;
4970 
4971   struct listptr *p = &table->table[*idxp];
4972 
4973   if (*idxp == table->n
4974       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4975     {
4976       *readp = endp;
4977       printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
4978 	      offset);
4979       return true;
4980     }
4981 
4982   if (p->offset != (Dwarf_Off) offset)
4983     {
4984       *readp += p->offset - offset;
4985       printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4986 	      offset, (Dwarf_Off) p->offset - offset);
4987       return true;
4988     }
4989 
4990   if (address_sizep != NULL)
4991     *address_sizep = listptr_address_size (p);
4992   if (offset_sizep != NULL)
4993     *offset_sizep = listptr_offset_size (p);
4994   if (base != NULL)
4995     *base = listptr_base (p);
4996   if (cu != NULL)
4997     *cu = p->cu;
4998   if (attr != NULL)
4999     *attr = p->attr;
5000 
5001   return false;
5002 }
5003 
5004 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t idx)5005 next_listptr_offset (struct listptr_table *table, size_t idx)
5006 {
5007   /* Note that multiple attributes could in theory point to the same loclist
5008      offset, so make sure we pick one that is bigger than the current one.
5009      The table is sorted on offset.  */
5010   Dwarf_Off offset = table->table[idx].offset;
5011   while (++idx < table->n)
5012     {
5013       Dwarf_Off next = table->table[idx].offset;
5014       if (next > offset)
5015 	return next;
5016     }
5017   return 0;
5018 }
5019 
5020 /* Returns the listptr associated with the given index, or NULL.  */
5021 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5022 get_listptr (struct listptr_table *table, size_t idx)
5023 {
5024   if (idx >= table->n)
5025     return NULL;
5026   return &table->table[idx];
5027 }
5028 
5029 /* Returns the next index, base address and CU associated with the
5030    list unit offsets.  If there is none false is returned, otherwise
5031    true.  Assumes the table has been sorted.  */
5032 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5033 listptr_cu (struct listptr_table *table, size_t *idxp,
5034 	    Dwarf_Off start, Dwarf_Off end,
5035 	    Dwarf_Addr *base, struct Dwarf_CU **cu)
5036 {
5037   while (*idxp < table->n
5038 	 && table->table[*idxp].offset < start)
5039     ++*idxp;
5040 
5041   if (*idxp < table->n
5042       && table->table[*idxp].offset >= start
5043       && table->table[*idxp].offset < end)
5044     {
5045       struct listptr *p = &table->table[*idxp];
5046       *base = listptr_base (p);
5047       *cu = p->cu;
5048       ++*idxp;
5049       return true;
5050     }
5051 
5052   return false;
5053 }
5054 
5055 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5056 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5057 			    Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5058 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5059 {
5060   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5061 			  dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5062 
5063   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5064 		   " [ Code]\n"),
5065 	  elf_ndxscn (scn), section_name (ebl, shdr),
5066 	  (uint64_t) shdr->sh_offset);
5067 
5068   Dwarf_Off offset = 0;
5069   while (offset < sh_size)
5070     {
5071       printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
5072 	      offset);
5073 
5074       while (1)
5075 	{
5076 	  size_t length;
5077 	  Dwarf_Abbrev abbrev;
5078 
5079 	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5080 	  if (res != 0)
5081 	    {
5082 	      if (unlikely (res < 0))
5083 		{
5084 		  printf (gettext ("\
5085  *** error while reading abbreviation: %s\n"),
5086 			  dwarf_errmsg (-1));
5087 		  return;
5088 		}
5089 
5090 	      /* This is the NUL byte at the end of the section.  */
5091 	      ++offset;
5092 	      break;
5093 	    }
5094 
5095 	  /* We know these calls can never fail.  */
5096 	  unsigned int code = dwarf_getabbrevcode (&abbrev);
5097 	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
5098 	  int has_children = dwarf_abbrevhaschildren (&abbrev);
5099 
5100 	  printf (gettext (" [%5u] offset: %" PRId64
5101 			   ", children: %s, tag: %s\n"),
5102 		  code, (int64_t) offset,
5103 		  has_children ? yes_str : no_str,
5104 		  dwarf_tag_name (tag));
5105 
5106 	  size_t cnt = 0;
5107 	  unsigned int name;
5108 	  unsigned int form;
5109 	  Dwarf_Sword data;
5110 	  Dwarf_Off enoffset;
5111 	  while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5112 					   &data, &enoffset) == 0)
5113 	    {
5114 	      printf ("          attr: %s, form: %s",
5115 		      dwarf_attr_name (name), dwarf_form_name (form));
5116 	      if (form == DW_FORM_implicit_const)
5117 		printf (" (%" PRId64 ")", data);
5118 	      printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5119 	      ++cnt;
5120 	    }
5121 
5122 	  offset += length;
5123 	}
5124     }
5125 }
5126 
5127 
5128 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5129 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5130 			  Ebl *ebl, GElf_Ehdr *ehdr,
5131 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5132 {
5133   printf (gettext ("\
5134 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5135 	  elf_ndxscn (scn), section_name (ebl, shdr),
5136 	  (uint64_t) shdr->sh_offset);
5137 
5138   if (shdr->sh_size == 0)
5139     return;
5140 
5141   /* We like to get the section from libdw to make sure they are relocated.  */
5142   Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5143 		    ?: elf_rawdata (scn, NULL));
5144   if (unlikely (data == NULL))
5145     {
5146       error (0, 0, gettext ("cannot get .debug_addr section data: %s"),
5147 	     elf_errmsg (-1));
5148       return;
5149     }
5150 
5151   size_t idx = 0;
5152   sort_listptr (&known_addrbases, "addr_base");
5153 
5154   const unsigned char *start = (const unsigned char *) data->d_buf;
5155   const unsigned char *readp = start;
5156   const unsigned char *readendp = ((const unsigned char *) data->d_buf
5157 				   + data->d_size);
5158 
5159   while (readp < readendp)
5160     {
5161       /* We cannot really know whether or not there is an header.  The
5162 	 DebugFission extension to DWARF4 doesn't add one.  The DWARF5
5163 	 .debug_addr variant does.  Whether or not we have an header,
5164 	 DW_AT_[GNU_]addr_base points at "index 0".  So if the current
5165 	 offset equals the CU addr_base then we can just start
5166 	 printing addresses.  If there is no CU with an exact match
5167 	 then we'll try to parse the header first.  */
5168       Dwarf_Off off = (Dwarf_Off) (readp
5169 				   - (const unsigned char *) data->d_buf);
5170 
5171       printf ("Table at offset %" PRIx64 " ", off);
5172 
5173       struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5174       const unsigned char *next_unitp;
5175 
5176       uint64_t unit_length;
5177       uint16_t version;
5178       uint8_t address_size;
5179       uint8_t segment_size;
5180       if (listptr == NULL)
5181 	{
5182 	  error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5183 		 off);
5184 
5185 	  /* We will have to assume it is just addresses to the end... */
5186 	  address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5187 	  next_unitp = readendp;
5188 	  printf ("Unknown CU:\n");
5189 	}
5190       else
5191 	{
5192 	  Dwarf_Die cudie;
5193 	  if (dwarf_cu_die (listptr->cu, &cudie,
5194 			    NULL, NULL, NULL, NULL,
5195 			    NULL, NULL) == NULL)
5196 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5197 	  else
5198 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5199 
5200 	  if (listptr->offset == off)
5201 	    {
5202 	      address_size = listptr_address_size (listptr);
5203 	      segment_size = 0;
5204 	      version = 4;
5205 
5206 	      /* The addresses start here, but where do they end?  */
5207 	      listptr = get_listptr (&known_addrbases, idx);
5208 	      if (listptr == NULL)
5209 		next_unitp = readendp;
5210 	      else if (listptr->cu->version < 5)
5211 		{
5212 		  next_unitp = start + listptr->offset;
5213 		  if (listptr->offset < off || listptr->offset > data->d_size)
5214 		    {
5215 		      error (0, 0,
5216 			     "Warning: Bad address base for next unit at %"
5217 			     PRIx64, off);
5218 		      next_unitp = readendp;
5219 		    }
5220 		}
5221 	      else
5222 		{
5223 		  /* Tricky, we don't have a header for this unit, but
5224 		     there is one for the next.  We will have to
5225 		     "guess" how big it is and subtract it from the
5226 		     offset (because that points after the header).  */
5227 		  unsigned int offset_size = listptr_offset_size (listptr);
5228 		  Dwarf_Off next_off = (listptr->offset
5229 					- (offset_size == 4 ? 4 : 12) /* len */
5230 					- 2 /* version */
5231 					- 1 /* address size */
5232 					- 1); /* segment selector size */
5233 		  next_unitp = start + next_off;
5234 		  if (next_off < off || next_off > data->d_size)
5235 		    {
5236 		      error (0, 0,
5237 			     "Warning: Couldn't calculate .debug_addr "
5238 			     " unit lenght at %" PRIx64, off);
5239 		      next_unitp = readendp;
5240 		    }
5241 		}
5242 	      unit_length = (uint64_t) (next_unitp - readp);
5243 
5244 	      /* Pretend we have a header.  */
5245 	      printf ("\n");
5246 	      printf (gettext (" Length:         %8" PRIu64 "\n"),
5247 		      unit_length);
5248 	      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
5249 	      printf (gettext (" Address size:   %8" PRIu64 "\n"),
5250 		      (uint64_t) address_size);
5251 	      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
5252 		      (uint64_t) segment_size);
5253 	      printf ("\n");
5254 	    }
5255 	  else
5256 	    {
5257 	      /* OK, we have to parse an header first.  */
5258 	      unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5259 	      if (unlikely (unit_length == 0xffffffff))
5260 		{
5261 		  if (unlikely (readp > readendp - 8))
5262 		    {
5263 		    invalid_data:
5264 		      error (0, 0, "Invalid data");
5265 		      return;
5266 		    }
5267 		  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5268 		}
5269 	      printf ("\n");
5270 	      printf (gettext (" Length:         %8" PRIu64 "\n"),
5271 		      unit_length);
5272 
5273 	      /* We need at least 2-bytes (version) + 1-byte
5274 		 (addr_size) + 1-byte (segment_size) = 4 bytes to
5275 		 complete the header.  And this unit cannot go beyond
5276 		 the section data.  */
5277 	      if (readp > readendp - 4
5278 		  || unit_length < 4
5279 		  || unit_length > (uint64_t) (readendp - readp))
5280 		goto invalid_data;
5281 
5282 	      next_unitp = readp + unit_length;
5283 
5284 	      version = read_2ubyte_unaligned_inc (dbg, readp);
5285 	      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
5286 
5287 	      if (version != 5)
5288 		{
5289 		  error (0, 0, gettext ("Unknown version"));
5290 		  goto next_unit;
5291 		}
5292 
5293 	      address_size = *readp++;
5294 	      printf (gettext (" Address size:   %8" PRIu64 "\n"),
5295 		      (uint64_t) address_size);
5296 
5297 	      if (address_size != 4 && address_size != 8)
5298 		{
5299 		  error (0, 0, gettext ("unsupported address size"));
5300 		  goto next_unit;
5301 		}
5302 
5303 	      segment_size = *readp++;
5304 	      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
5305 		      (uint64_t) segment_size);
5306 	      printf ("\n");
5307 
5308 	      if (segment_size != 0)
5309 		{
5310 		  error (0, 0, gettext ("unsupported segment size"));
5311 		  goto next_unit;
5312 		}
5313 
5314 	      if (listptr->offset != (Dwarf_Off) (readp - start))
5315 		{
5316 		  error (0, 0, "Address index doesn't start after header");
5317 		  goto next_unit;
5318 		}
5319 	    }
5320 	}
5321 
5322       int digits = 1;
5323       size_t addresses = (next_unitp - readp) / address_size;
5324       while (addresses >= 10)
5325 	{
5326 	  ++digits;
5327 	  addresses /= 10;
5328 	}
5329 
5330       unsigned int uidx = 0;
5331       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
5332       printf (" Addresses start at offset 0x%zx:\n", index_offset);
5333       while (readp <= next_unitp - address_size)
5334 	{
5335 	  Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5336 						     readp);
5337 	  printf (" [%*u] ", digits, uidx++);
5338 	  print_dwarf_addr (dwflmod, address_size, addr, addr);
5339 	  printf ("\n");
5340 	}
5341       printf ("\n");
5342 
5343       if (readp != next_unitp)
5344 	error (0, 0, "extra %zd bytes at end of unit",
5345 	       (size_t) (next_unitp - readp));
5346 
5347     next_unit:
5348       readp = next_unitp;
5349     }
5350 }
5351 
5352 /* Print content of DWARF .debug_aranges section.  We fortunately do
5353    not have to know a bit about the structure of the section, libdwarf
5354    takes care of it.  */
5355 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5356 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5357 			       GElf_Shdr *shdr, Dwarf *dbg)
5358 {
5359   Dwarf_Aranges *aranges;
5360   size_t cnt;
5361   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5362     {
5363       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5364 	     dwarf_errmsg (-1));
5365       return;
5366     }
5367 
5368   GElf_Shdr glink_mem;
5369   GElf_Shdr *glink;
5370   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5371   if (glink == NULL)
5372     {
5373       error (0, 0, gettext ("invalid sh_link value in section %zu"),
5374 	     elf_ndxscn (scn));
5375       return;
5376     }
5377 
5378   printf (ngettext ("\
5379 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5380 		    "\
5381 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5382 		    cnt),
5383 	  elf_ndxscn (scn), section_name (ebl, shdr),
5384 	  (uint64_t) shdr->sh_offset, cnt);
5385 
5386   /* Compute floor(log16(cnt)).  */
5387   size_t tmp = cnt;
5388   int digits = 1;
5389   while (tmp >= 16)
5390     {
5391       ++digits;
5392       tmp >>= 4;
5393     }
5394 
5395   for (size_t n = 0; n < cnt; ++n)
5396     {
5397       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5398       if (unlikely (runp == NULL))
5399 	{
5400 	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5401 	  return;
5402 	}
5403 
5404       Dwarf_Addr start;
5405       Dwarf_Word length;
5406       Dwarf_Off offset;
5407 
5408       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5409 	printf (gettext (" [%*zu] ???\n"), digits, n);
5410       else
5411 	printf (gettext (" [%*zu] start: %0#*" PRIx64
5412 			 ", length: %5" PRIu64 ", CU DIE offset: %6"
5413 			 PRId64 "\n"),
5414 		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5415 		(uint64_t) start, (uint64_t) length, (int64_t) offset);
5416     }
5417 }
5418 
5419 
5420 /* Print content of DWARF .debug_aranges section.  */
5421 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5422 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5423 			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5424 			     GElf_Shdr *shdr, Dwarf *dbg)
5425 {
5426   if (decodedaranges)
5427     {
5428       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5429       return;
5430     }
5431 
5432   Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5433 		    ?: elf_rawdata (scn, NULL));
5434 
5435   if (unlikely (data == NULL))
5436     {
5437       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5438 	     elf_errmsg (-1));
5439       return;
5440     }
5441 
5442   printf (gettext ("\
5443 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5444 	  elf_ndxscn (scn), section_name (ebl, shdr),
5445 	  (uint64_t) shdr->sh_offset);
5446 
5447   const unsigned char *readp = data->d_buf;
5448   const unsigned char *readendp = readp + data->d_size;
5449 
5450   while (readp < readendp)
5451     {
5452       const unsigned char *hdrstart = readp;
5453       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5454 
5455       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
5456       if (readp + 4 > readendp)
5457 	{
5458 	invalid_data:
5459 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5460 		 elf_ndxscn (scn), section_name (ebl, shdr));
5461 	  return;
5462 	}
5463 
5464       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5465       unsigned int length_bytes = 4;
5466       if (length == DWARF3_LENGTH_64_BIT)
5467 	{
5468 	  if (readp + 8 > readendp)
5469 	    goto invalid_data;
5470 	  length = read_8ubyte_unaligned_inc (dbg, readp);
5471 	  length_bytes = 8;
5472 	}
5473 
5474       const unsigned char *nexthdr = readp + length;
5475       printf (gettext ("\n Length:        %6" PRIu64 "\n"),
5476 	      (uint64_t) length);
5477 
5478       if (unlikely (length > (size_t) (readendp - readp)))
5479 	goto invalid_data;
5480 
5481       if (length == 0)
5482 	continue;
5483 
5484       if (readp + 2 > readendp)
5485 	goto invalid_data;
5486       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5487       printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
5488 	      version);
5489       if (version != 2)
5490 	{
5491 	  error (0, 0, gettext ("unsupported aranges version"));
5492 	  goto next_table;
5493 	}
5494 
5495       Dwarf_Word offset;
5496       if (readp + length_bytes > readendp)
5497 	goto invalid_data;
5498       if (length_bytes == 8)
5499 	offset = read_8ubyte_unaligned_inc (dbg, readp);
5500       else
5501 	offset = read_4ubyte_unaligned_inc (dbg, readp);
5502       printf (gettext (" CU offset:     %6" PRIx64 "\n"),
5503 	      (uint64_t) offset);
5504 
5505       if (readp + 1 > readendp)
5506 	goto invalid_data;
5507       unsigned int address_size = *readp++;
5508       printf (gettext (" Address size:  %6" PRIu64 "\n"),
5509 	      (uint64_t) address_size);
5510       if (address_size != 4 && address_size != 8)
5511 	{
5512 	  error (0, 0, gettext ("unsupported address size"));
5513 	  goto next_table;
5514 	}
5515 
5516       if (readp + 1 > readendp)
5517 	goto invalid_data;
5518       unsigned int segment_size = *readp++;
5519       printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
5520 	      (uint64_t) segment_size);
5521       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5522 	{
5523 	  error (0, 0, gettext ("unsupported segment size"));
5524 	  goto next_table;
5525 	}
5526 
5527       /* Round the address to the next multiple of 2*address_size.  */
5528       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5529 		% (2 * address_size));
5530 
5531       while (readp < nexthdr)
5532 	{
5533 	  Dwarf_Word range_address;
5534 	  Dwarf_Word range_length;
5535 	  Dwarf_Word segment = 0;
5536 	  if (readp + 2 * address_size + segment_size > readendp)
5537 	    goto invalid_data;
5538 	  if (address_size == 4)
5539 	    {
5540 	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
5541 	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
5542 	    }
5543 	  else
5544 	    {
5545 	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
5546 	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
5547 	    }
5548 
5549 	  if (segment_size == 4)
5550 	    segment = read_4ubyte_unaligned_inc (dbg, readp);
5551 	  else if (segment_size == 8)
5552 	    segment = read_8ubyte_unaligned_inc (dbg, readp);
5553 
5554 	  if (range_address == 0 && range_length == 0 && segment == 0)
5555 	    break;
5556 
5557 	  printf ("   ");
5558 	  print_dwarf_addr (dwflmod, address_size, range_address,
5559 			    range_address);
5560 	  printf ("..");
5561 	  print_dwarf_addr (dwflmod, address_size,
5562 			    range_address + range_length - 1,
5563 			    range_length);
5564 	  if (segment_size != 0)
5565 	    printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5566 	  else
5567 	    printf ("\n");
5568 	}
5569 
5570     next_table:
5571       if (readp != nexthdr)
5572 	{
5573 	  size_t padding = nexthdr - readp;
5574 	  printf (gettext ("   %zu padding bytes\n"), padding);
5575 	  readp = nexthdr;
5576 	}
5577     }
5578 }
5579 
5580 
5581 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5582 
5583 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5584    DWARF (.dwo) file.  */
5585 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5586 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5587 {
5588   uint64_t id;
5589   if (is_split_dwarf (dbg, &id, cu))
5590     {
5591       Dwarf_Die cudie;
5592       if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5593 	{
5594 	  *cu_base = cudie_base (&cudie);
5595 	  return true;
5596 	}
5597     }
5598   return false;
5599 }
5600 
5601 /* Print content of DWARF .debug_rnglists section.  */
5602 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5603 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5604 			      Ebl *ebl,
5605 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
5606 			      Elf_Scn *scn, GElf_Shdr *shdr,
5607 			      Dwarf *dbg __attribute__((unused)))
5608 {
5609   printf (gettext ("\
5610 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5611 	  elf_ndxscn (scn), section_name (ebl, shdr),
5612 	  (uint64_t) shdr->sh_offset);
5613 
5614   Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5615 		   ?: elf_rawdata (scn, NULL));
5616   if (unlikely (data == NULL))
5617     {
5618       error (0, 0, gettext ("cannot get .debug_rnglists content: %s"),
5619 	     elf_errmsg (-1));
5620       return;
5621     }
5622 
5623   /* For the listptr to get the base address/CU.  */
5624   sort_listptr (&known_rnglistptr, "rnglistptr");
5625   size_t listptr_idx = 0;
5626 
5627   const unsigned char *readp = data->d_buf;
5628   const unsigned char *const dataend = ((unsigned char *) data->d_buf
5629 					+ data->d_size);
5630   while (readp < dataend)
5631     {
5632       if (unlikely (readp > dataend - 4))
5633 	{
5634 	invalid_data:
5635 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5636 		 elf_ndxscn (scn), section_name (ebl, shdr));
5637 	  return;
5638 	}
5639 
5640       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5641       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
5642 	      (uint64_t) offset);
5643 
5644       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5645       unsigned int offset_size = 4;
5646       if (unlikely (unit_length == 0xffffffff))
5647 	{
5648 	  if (unlikely (readp > dataend - 8))
5649 	    goto invalid_data;
5650 
5651 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5652 	  offset_size = 8;
5653 	}
5654       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
5655 
5656       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5657 	 bytes to complete the header.  And this unit cannot go beyond
5658 	 the section data.  */
5659       if (readp > dataend - 8
5660 	  || unit_length < 8
5661 	  || unit_length > (uint64_t) (dataend - readp))
5662 	goto invalid_data;
5663 
5664       const unsigned char *nexthdr = readp + unit_length;
5665 
5666       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5667       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
5668 
5669       if (version != 5)
5670 	{
5671 	  error (0, 0, gettext ("Unknown version"));
5672 	  goto next_table;
5673 	}
5674 
5675       uint8_t address_size = *readp++;
5676       printf (gettext (" Address size:   %8" PRIu64 "\n"),
5677 	      (uint64_t) address_size);
5678 
5679       if (address_size != 4 && address_size != 8)
5680 	{
5681 	  error (0, 0, gettext ("unsupported address size"));
5682 	  goto next_table;
5683 	}
5684 
5685       uint8_t segment_size = *readp++;
5686       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
5687 	      (uint64_t) segment_size);
5688 
5689       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5690         {
5691           error (0, 0, gettext ("unsupported segment size"));
5692           goto next_table;
5693         }
5694 
5695       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5696       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
5697 	      (uint64_t) offset_entry_count);
5698 
5699       /* We need the CU that uses this unit to get the initial base address. */
5700       Dwarf_Addr cu_base = 0;
5701       struct Dwarf_CU *cu = NULL;
5702       if (listptr_cu (&known_rnglistptr, &listptr_idx,
5703 		      (Dwarf_Off) offset,
5704 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5705 		      &cu_base, &cu)
5706 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
5707 	{
5708 	  Dwarf_Die cudie;
5709 	  if (dwarf_cu_die (cu, &cudie,
5710 			    NULL, NULL, NULL, NULL,
5711 			    NULL, NULL) == NULL)
5712 	    printf (gettext (" Unknown CU base: "));
5713 	  else
5714 	    printf (gettext (" CU [%6" PRIx64 "] base: "),
5715 		    dwarf_dieoffset (&cudie));
5716 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5717 	  printf ("\n");
5718 	}
5719       else
5720 	printf (gettext (" Not associated with a CU.\n"));
5721 
5722       printf ("\n");
5723 
5724       const unsigned char *offset_array_start = readp;
5725       if (offset_entry_count > 0)
5726 	{
5727 	  uint64_t max_entries = (unit_length - 8) / offset_size;
5728 	  if (offset_entry_count > max_entries)
5729 	    {
5730 	      error (0, 0,
5731 		     gettext ("too many offset entries for unit length"));
5732 	      offset_entry_count = max_entries;
5733 	    }
5734 
5735 	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
5736 		  (uint64_t) (offset_array_start
5737 			      - (unsigned char *) data->d_buf));
5738 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5739 	    {
5740 	      printf ("   [%6" PRIu32 "] ", idx);
5741 	      if (offset_size == 4)
5742 		{
5743 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5744 		  printf ("0x%" PRIx32 "\n", off);
5745 		}
5746 	      else
5747 		{
5748 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5749 		  printf ("0x%" PRIx64 "\n", off);
5750 		}
5751 	    }
5752 	  printf ("\n");
5753 	}
5754 
5755       Dwarf_Addr base = cu_base;
5756       bool start_of_list = true;
5757       while (readp < nexthdr)
5758 	{
5759 	  uint8_t kind = *readp++;
5760 	  uint64_t op1, op2;
5761 
5762 	  /* Skip padding.  */
5763 	  if (start_of_list && kind == DW_RLE_end_of_list)
5764 	    continue;
5765 
5766 	  if (start_of_list)
5767 	    {
5768 	      base = cu_base;
5769 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5770 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5771 		      (uint64_t) (readp - offset_array_start - 1));
5772 	      start_of_list = false;
5773 	    }
5774 
5775 	  printf ("    %s", dwarf_range_list_encoding_name (kind));
5776 	  switch (kind)
5777 	    {
5778 	    case DW_RLE_end_of_list:
5779 	      start_of_list = true;
5780 	      printf ("\n\n");
5781 	      break;
5782 
5783 	    case DW_RLE_base_addressx:
5784 	      if ((uint64_t) (nexthdr - readp) < 1)
5785 		{
5786 		invalid_range:
5787 		  error (0, 0, gettext ("invalid range list data"));
5788 		  goto next_table;
5789 		}
5790 	      get_uleb128 (op1, readp, nexthdr);
5791 	      printf (" %" PRIx64 "\n", op1);
5792 	      if (! print_unresolved_addresses)
5793 		{
5794 		  Dwarf_Addr addr;
5795 		  if (get_indexed_addr (cu, op1, &addr) != 0)
5796 		    printf ("      ???\n");
5797 		  else
5798 		    {
5799 		      printf ("      ");
5800 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
5801 		      printf ("\n");
5802 		    }
5803 		}
5804 	      break;
5805 
5806 	    case DW_RLE_startx_endx:
5807 	      if ((uint64_t) (nexthdr - readp) < 1)
5808 		goto invalid_range;
5809 	      get_uleb128 (op1, readp, nexthdr);
5810 	      if ((uint64_t) (nexthdr - readp) < 1)
5811 		goto invalid_range;
5812 	      get_uleb128 (op2, readp, nexthdr);
5813 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5814 	      if (! print_unresolved_addresses)
5815 		{
5816 		  Dwarf_Addr addr1;
5817 		  Dwarf_Addr addr2;
5818 		  if (get_indexed_addr (cu, op1, &addr1) != 0
5819 		      || get_indexed_addr (cu, op2, &addr2) != 0)
5820 		    {
5821 		      printf ("      ???..\n");
5822 		      printf ("      ???\n");
5823 		    }
5824 		  else
5825 		    {
5826 		      printf ("      ");
5827 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5828 		      printf ("..\n      ");
5829 		      print_dwarf_addr (dwflmod, address_size,
5830 					addr2 - 1, addr2);
5831 		      printf ("\n");
5832 		    }
5833 		}
5834 	      break;
5835 
5836 	    case DW_RLE_startx_length:
5837 	      if ((uint64_t) (nexthdr - readp) < 1)
5838 		goto invalid_range;
5839 	      get_uleb128 (op1, readp, nexthdr);
5840 	      if ((uint64_t) (nexthdr - readp) < 1)
5841 		goto invalid_range;
5842 	      get_uleb128 (op2, readp, nexthdr);
5843 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5844 	      if (! print_unresolved_addresses)
5845 		{
5846 		  Dwarf_Addr addr1;
5847 		  Dwarf_Addr addr2;
5848 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
5849 		    {
5850 		      printf ("      ???..\n");
5851 		      printf ("      ???\n");
5852 		    }
5853 		  else
5854 		    {
5855 		      addr2 = addr1 + op2;
5856 		      printf ("      ");
5857 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5858 		      printf ("..\n      ");
5859 		      print_dwarf_addr (dwflmod, address_size,
5860 					addr2 - 1, addr2);
5861 		      printf ("\n");
5862 		    }
5863 		}
5864 	      break;
5865 
5866 	    case DW_RLE_offset_pair:
5867 	      if ((uint64_t) (nexthdr - readp) < 1)
5868 		goto invalid_range;
5869 	      get_uleb128 (op1, readp, nexthdr);
5870 	      if ((uint64_t) (nexthdr - readp) < 1)
5871 		goto invalid_range;
5872 	      get_uleb128 (op2, readp, nexthdr);
5873 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5874 	      if (! print_unresolved_addresses)
5875 		{
5876 		  op1 += base;
5877 		  op2 += base;
5878 		  printf ("      ");
5879 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5880 		  printf ("..\n      ");
5881 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5882 		  printf ("\n");
5883 		}
5884 	      break;
5885 
5886 	    case DW_RLE_base_address:
5887 	      if (address_size == 4)
5888 		{
5889 		  if ((uint64_t) (nexthdr - readp) < 4)
5890 		    goto invalid_range;
5891 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5892 		}
5893 	      else
5894 		{
5895 		  if ((uint64_t) (nexthdr - readp) < 8)
5896 		    goto invalid_range;
5897 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5898 		}
5899 	      base = op1;
5900 	      printf (" 0x%" PRIx64 "\n", base);
5901 	      if (! print_unresolved_addresses)
5902 		{
5903 		  printf ("      ");
5904 		  print_dwarf_addr (dwflmod, address_size, base, base);
5905 		  printf ("\n");
5906 		}
5907 	      break;
5908 
5909 	    case DW_RLE_start_end:
5910 	      if (address_size == 4)
5911 		{
5912 		  if ((uint64_t) (nexthdr - readp) < 8)
5913 		    goto invalid_range;
5914 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5915 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
5916 		}
5917 	      else
5918 		{
5919 		  if ((uint64_t) (nexthdr - readp) < 16)
5920 		    goto invalid_range;
5921 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5922 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
5923 		}
5924 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5925 	      if (! print_unresolved_addresses)
5926 		{
5927 		  printf ("      ");
5928 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5929 		  printf ("..\n      ");
5930 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5931 		  printf ("\n");
5932 		}
5933 	      break;
5934 
5935 	    case DW_RLE_start_length:
5936 	      if (address_size == 4)
5937 		{
5938 		  if ((uint64_t) (nexthdr - readp) < 4)
5939 		    goto invalid_range;
5940 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
5941 		}
5942 	      else
5943 		{
5944 		  if ((uint64_t) (nexthdr - readp) < 8)
5945 		    goto invalid_range;
5946 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
5947 		}
5948 	      if ((uint64_t) (nexthdr - readp) < 1)
5949 		goto invalid_range;
5950 	      get_uleb128 (op2, readp, nexthdr);
5951 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5952 	      if (! print_unresolved_addresses)
5953 		{
5954 		  op2 = op1 + op2;
5955 		  printf ("      ");
5956 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
5957 		  printf ("..\n      ");
5958 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5959 		  printf ("\n");
5960 		}
5961 	      break;
5962 
5963 	    default:
5964 	      goto invalid_range;
5965 	    }
5966 	}
5967 
5968     next_table:
5969       if (readp != nexthdr)
5970 	{
5971           size_t padding = nexthdr - readp;
5972           printf (gettext ("   %zu padding bytes\n\n"), padding);
5973 	  readp = nexthdr;
5974 	}
5975     }
5976 }
5977 
5978 /* Print content of DWARF .debug_ranges section.  */
5979 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5980 print_debug_ranges_section (Dwfl_Module *dwflmod,
5981 			    Ebl *ebl, GElf_Ehdr *ehdr,
5982 			    Elf_Scn *scn, GElf_Shdr *shdr,
5983 			    Dwarf *dbg)
5984 {
5985   Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
5986 		    ?: elf_rawdata (scn, NULL));
5987   if (unlikely (data == NULL))
5988     {
5989       error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
5990 	     elf_errmsg (-1));
5991       return;
5992     }
5993 
5994   printf (gettext ("\
5995 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5996 	  elf_ndxscn (scn), section_name (ebl, shdr),
5997 	  (uint64_t) shdr->sh_offset);
5998 
5999   sort_listptr (&known_rangelistptr, "rangelistptr");
6000   size_t listptr_idx = 0;
6001 
6002   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6003 
6004   bool first = true;
6005   Dwarf_Addr base = 0;
6006   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6007   unsigned char *readp = data->d_buf;
6008   Dwarf_CU *last_cu = NULL;
6009   while (readp < endp)
6010     {
6011       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6012       Dwarf_CU *cu = last_cu;
6013 
6014       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6015 				      &address_size, NULL, &base, &cu,
6016 				      offset, &readp, endp, NULL))
6017 	continue;
6018 
6019       if (last_cu != cu)
6020 	{
6021 	  Dwarf_Die cudie;
6022 	  if (dwarf_cu_die (cu, &cudie,
6023 			    NULL, NULL, NULL, NULL,
6024 			    NULL, NULL) == NULL)
6025 	    printf (gettext ("\n Unknown CU base: "));
6026 	  else
6027 	    printf (gettext ("\n CU [%6" PRIx64 "] base: "),
6028 		    dwarf_dieoffset (&cudie));
6029 	  print_dwarf_addr (dwflmod, address_size, base, base);
6030 	  printf ("\n");
6031 	}
6032       last_cu = cu;
6033 
6034       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6035 	{
6036 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
6037 	  break;
6038 	}
6039 
6040       Dwarf_Addr begin;
6041       Dwarf_Addr end;
6042       if (address_size == 8)
6043 	{
6044 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
6045 	  end = read_8ubyte_unaligned_inc (dbg, readp);
6046 	}
6047       else
6048 	{
6049 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
6050 	  end = read_4ubyte_unaligned_inc (dbg, readp);
6051 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
6052 	    begin = (Dwarf_Addr) -1l;
6053 	}
6054 
6055       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
6056 	{
6057 	  printf (gettext (" [%6tx] base address\n          "), offset);
6058 	  print_dwarf_addr (dwflmod, address_size, end, end);
6059 	  printf ("\n");
6060 	  base = end;
6061 	}
6062       else if (begin == 0 && end == 0) /* End of list entry.  */
6063 	{
6064 	  if (first)
6065 	    printf (gettext (" [%6tx] empty list\n"), offset);
6066 	  first = true;
6067 	}
6068       else
6069 	{
6070 	  /* We have an address range entry.  */
6071 	  if (first)		/* First address range entry in a list.  */
6072 	    printf (" [%6tx] ", offset);
6073 	  else
6074 	    printf ("          ");
6075 
6076 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6077 	  if (! print_unresolved_addresses)
6078 	    {
6079 	      printf ("          ");
6080 	      print_dwarf_addr (dwflmod, address_size, base + begin,
6081 			        base + begin);
6082 	      printf ("..\n          ");
6083 	      print_dwarf_addr (dwflmod, address_size,
6084 				base + end - 1, base + end);
6085 	      printf ("\n");
6086 	    }
6087 
6088 	  first = false;
6089 	}
6090     }
6091 }
6092 
6093 #define REGNAMESZ 16
6094 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6095 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6096 	       char name[REGNAMESZ], int *bits, int *type)
6097 {
6098   const char *set;
6099   const char *pfx;
6100   int ignore;
6101   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6102 				 bits ?: &ignore, type ?: &ignore);
6103   if (n <= 0)
6104     {
6105       if (loc != NULL)
6106 	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6107       else
6108 	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6109       if (bits != NULL)
6110 	*bits = loc != NULL ? loc->bits : 0;
6111       if (type != NULL)
6112 	*type = DW_ATE_unsigned;
6113       set = "??? unrecognized";
6114     }
6115   else
6116     {
6117       if (bits != NULL && *bits <= 0)
6118 	*bits = loc != NULL ? loc->bits : 0;
6119       if (type != NULL && *type == DW_ATE_void)
6120 	*type = DW_ATE_unsigned;
6121 
6122     }
6123   return set;
6124 }
6125 
6126 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6127 read_encoded (unsigned int encoding, const unsigned char *readp,
6128 	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6129 {
6130   if ((encoding & 0xf) == DW_EH_PE_absptr)
6131     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6132       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6133 
6134   switch (encoding & 0xf)
6135     {
6136     case DW_EH_PE_uleb128:
6137       get_uleb128 (*res, readp, endp);
6138       break;
6139     case DW_EH_PE_sleb128:
6140       get_sleb128 (*res, readp, endp);
6141       break;
6142     case DW_EH_PE_udata2:
6143       if (readp + 2 > endp)
6144 	goto invalid;
6145       *res = read_2ubyte_unaligned_inc (dbg, readp);
6146       break;
6147     case DW_EH_PE_udata4:
6148       if (readp + 4 > endp)
6149 	goto invalid;
6150       *res = read_4ubyte_unaligned_inc (dbg, readp);
6151       break;
6152     case DW_EH_PE_udata8:
6153       if (readp + 8 > endp)
6154 	goto invalid;
6155       *res = read_8ubyte_unaligned_inc (dbg, readp);
6156       break;
6157     case DW_EH_PE_sdata2:
6158       if (readp + 2 > endp)
6159 	goto invalid;
6160       *res = read_2sbyte_unaligned_inc (dbg, readp);
6161       break;
6162     case DW_EH_PE_sdata4:
6163       if (readp + 4 > endp)
6164 	goto invalid;
6165       *res = read_4sbyte_unaligned_inc (dbg, readp);
6166       break;
6167     case DW_EH_PE_sdata8:
6168       if (readp + 8 > endp)
6169 	goto invalid;
6170       *res = read_8sbyte_unaligned_inc (dbg, readp);
6171       break;
6172     default:
6173     invalid:
6174       error (1, 0,
6175 	     gettext ("invalid encoding"));
6176     }
6177 
6178   return readp;
6179 }
6180 
6181 
6182 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)6183 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6184 		   Dwarf_Word vma_base, unsigned int code_align,
6185 		   int data_align,
6186 		   unsigned int version, unsigned int ptr_size,
6187 		   unsigned int encoding,
6188 		   Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
6189 {
6190   char regnamebuf[REGNAMESZ];
6191   const char *regname (unsigned int regno)
6192   {
6193     register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6194     return regnamebuf;
6195   }
6196 
6197   puts ("\n   Program:");
6198   Dwarf_Word pc = vma_base;
6199   while (readp < endp)
6200     {
6201       unsigned int opcode = *readp++;
6202 
6203       if (opcode < DW_CFA_advance_loc)
6204 	/* Extended opcode.  */
6205 	switch (opcode)
6206 	  {
6207 	    uint64_t op1;
6208 	    int64_t sop1;
6209 	    uint64_t op2;
6210 	    int64_t sop2;
6211 
6212 	  case DW_CFA_nop:
6213 	    puts ("     nop");
6214 	    break;
6215 	  case DW_CFA_set_loc:
6216 	    if ((uint64_t) (endp - readp) < 1)
6217 	      goto invalid;
6218 	    readp = read_encoded (encoding, readp, endp, &op1, dbg);
6219 	    printf ("     set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6220 		    op1, pc = vma_base + op1);
6221 	    break;
6222 	  case DW_CFA_advance_loc1:
6223 	    if ((uint64_t) (endp - readp) < 1)
6224 	      goto invalid;
6225 	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
6226 		    *readp, pc += *readp * code_align);
6227 	    ++readp;
6228 	    break;
6229 	  case DW_CFA_advance_loc2:
6230 	    if ((uint64_t) (endp - readp) < 2)
6231 	      goto invalid;
6232 	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
6233 	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6234 		    op1, pc += op1 * code_align);
6235 	    break;
6236 	  case DW_CFA_advance_loc4:
6237 	    if ((uint64_t) (endp - readp) < 4)
6238 	      goto invalid;
6239 	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
6240 	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6241 		    op1, pc += op1 * code_align);
6242 	    break;
6243 	  case DW_CFA_offset_extended:
6244 	    if ((uint64_t) (endp - readp) < 1)
6245 	      goto invalid;
6246 	    get_uleb128 (op1, readp, endp);
6247 	    if ((uint64_t) (endp - readp) < 1)
6248 	      goto invalid;
6249 	    get_uleb128 (op2, readp, endp);
6250 	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6251 		    "\n",
6252 		    op1, regname (op1), op2 * data_align);
6253 	    break;
6254 	  case DW_CFA_restore_extended:
6255 	    if ((uint64_t) (endp - readp) < 1)
6256 	      goto invalid;
6257 	    get_uleb128 (op1, readp, endp);
6258 	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
6259 		    op1, regname (op1));
6260 	    break;
6261 	  case DW_CFA_undefined:
6262 	    if ((uint64_t) (endp - readp) < 1)
6263 	      goto invalid;
6264 	    get_uleb128 (op1, readp, endp);
6265 	    printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
6266 	    break;
6267 	  case DW_CFA_same_value:
6268 	    if ((uint64_t) (endp - readp) < 1)
6269 	      goto invalid;
6270 	    get_uleb128 (op1, readp, endp);
6271 	    printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
6272 	    break;
6273 	  case DW_CFA_register:
6274 	    if ((uint64_t) (endp - readp) < 1)
6275 	      goto invalid;
6276 	    get_uleb128 (op1, readp, endp);
6277 	    if ((uint64_t) (endp - readp) < 1)
6278 	      goto invalid;
6279 	    get_uleb128 (op2, readp, endp);
6280 	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6281 		    op1, regname (op1), op2, regname (op2));
6282 	    break;
6283 	  case DW_CFA_remember_state:
6284 	    puts ("     remember_state");
6285 	    break;
6286 	  case DW_CFA_restore_state:
6287 	    puts ("     restore_state");
6288 	    break;
6289 	  case DW_CFA_def_cfa:
6290 	    if ((uint64_t) (endp - readp) < 1)
6291 	      goto invalid;
6292 	    get_uleb128 (op1, readp, endp);
6293 	    if ((uint64_t) (endp - readp) < 1)
6294 	      goto invalid;
6295 	    get_uleb128 (op2, readp, endp);
6296 	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6297 		    op1, regname (op1), op2);
6298 	    break;
6299 	  case DW_CFA_def_cfa_register:
6300 	    if ((uint64_t) (endp - readp) < 1)
6301 	      goto invalid;
6302 	    get_uleb128 (op1, readp, endp);
6303 	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
6304 		    op1, regname (op1));
6305 	    break;
6306 	  case DW_CFA_def_cfa_offset:
6307 	    if ((uint64_t) (endp - readp) < 1)
6308 	      goto invalid;
6309 	    get_uleb128 (op1, readp, endp);
6310 	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
6311 	    break;
6312 	  case DW_CFA_def_cfa_expression:
6313 	    if ((uint64_t) (endp - readp) < 1)
6314 	      goto invalid;
6315 	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
6316 	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
6317 	    if ((uint64_t) (endp - readp) < op1)
6318 	      {
6319 	    invalid:
6320 	        fputs (gettext ("         <INVALID DATA>\n"), stdout);
6321 		return;
6322 	      }
6323 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6324 		       op1, readp);
6325 	    readp += op1;
6326 	    break;
6327 	  case DW_CFA_expression:
6328 	    if ((uint64_t) (endp - readp) < 1)
6329 	      goto invalid;
6330 	    get_uleb128 (op1, readp, endp);
6331 	    if ((uint64_t) (endp - readp) < 1)
6332 	      goto invalid;
6333 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6334 	    printf ("     expression r%" PRIu64 " (%s) \n",
6335 		    op1, regname (op1));
6336 	    if ((uint64_t) (endp - readp) < op2)
6337 	      goto invalid;
6338 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6339 		       op2, readp);
6340 	    readp += op2;
6341 	    break;
6342 	  case DW_CFA_offset_extended_sf:
6343 	    if ((uint64_t) (endp - readp) < 1)
6344 	      goto invalid;
6345 	    get_uleb128 (op1, readp, endp);
6346 	    if ((uint64_t) (endp - readp) < 1)
6347 	      goto invalid;
6348 	    get_sleb128 (sop2, readp, endp);
6349 	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6350 		    PRId64 "\n",
6351 		    op1, regname (op1), sop2 * data_align);
6352 	    break;
6353 	  case DW_CFA_def_cfa_sf:
6354 	    if ((uint64_t) (endp - readp) < 1)
6355 	      goto invalid;
6356 	    get_uleb128 (op1, readp, endp);
6357 	    if ((uint64_t) (endp - readp) < 1)
6358 	      goto invalid;
6359 	    get_sleb128 (sop2, readp, endp);
6360 	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6361 		    op1, regname (op1), sop2 * data_align);
6362 	    break;
6363 	  case DW_CFA_def_cfa_offset_sf:
6364 	    if ((uint64_t) (endp - readp) < 1)
6365 	      goto invalid;
6366 	    get_sleb128 (sop1, readp, endp);
6367 	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6368 	    break;
6369 	  case DW_CFA_val_offset:
6370 	    if ((uint64_t) (endp - readp) < 1)
6371 	      goto invalid;
6372 	    get_uleb128 (op1, readp, endp);
6373 	    if ((uint64_t) (endp - readp) < 1)
6374 	      goto invalid;
6375 	    get_uleb128 (op2, readp, endp);
6376 	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6377 		    op1, op2 * data_align);
6378 	    break;
6379 	  case DW_CFA_val_offset_sf:
6380 	    if ((uint64_t) (endp - readp) < 1)
6381 	      goto invalid;
6382 	    get_uleb128 (op1, readp, endp);
6383 	    if ((uint64_t) (endp - readp) < 1)
6384 	      goto invalid;
6385 	    get_sleb128 (sop2, readp, endp);
6386 	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6387 		    op1, sop2 * data_align);
6388 	    break;
6389 	  case DW_CFA_val_expression:
6390 	    if ((uint64_t) (endp - readp) < 1)
6391 	      goto invalid;
6392 	    get_uleb128 (op1, readp, endp);
6393 	    if ((uint64_t) (endp - readp) < 1)
6394 	      goto invalid;
6395 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6396 	    printf ("     val_expression r%" PRIu64 " (%s)\n",
6397 		    op1, regname (op1));
6398 	    if ((uint64_t) (endp - readp) < op2)
6399 	      goto invalid;
6400 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6401 		       NULL, op2, readp);
6402 	    readp += op2;
6403 	    break;
6404 	  case DW_CFA_MIPS_advance_loc8:
6405 	    if ((uint64_t) (endp - readp) < 8)
6406 	      goto invalid;
6407 	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
6408 	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6409 		    op1, pc += op1 * code_align);
6410 	    break;
6411 	  case DW_CFA_GNU_window_save:
6412 	    puts ("     GNU_window_save");
6413 	    break;
6414 	  case DW_CFA_GNU_args_size:
6415 	    if ((uint64_t) (endp - readp) < 1)
6416 	      goto invalid;
6417 	    get_uleb128 (op1, readp, endp);
6418 	    printf ("     args_size %" PRIu64 "\n", op1);
6419 	    break;
6420 	  default:
6421 	    printf ("     ??? (%u)\n", opcode);
6422 	    break;
6423 	  }
6424       else if (opcode < DW_CFA_offset)
6425 	printf ("     advance_loc %u to %#" PRIx64 "\n",
6426 		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6427       else if (opcode < DW_CFA_restore)
6428 	{
6429 	  uint64_t offset;
6430 	  if ((uint64_t) (endp - readp) < 1)
6431 	    goto invalid;
6432 	  get_uleb128 (offset, readp, endp);
6433 	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
6434 		  opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
6435 	}
6436       else
6437 	printf ("     restore r%u (%s)\n",
6438 		opcode & 0x3f, regname (opcode & 0x3f));
6439     }
6440 }
6441 
6442 
6443 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6444 encoded_ptr_size (int encoding, unsigned int ptr_size)
6445 {
6446   switch (encoding & 7)
6447     {
6448     case DW_EH_PE_udata4:
6449       return 4;
6450     case DW_EH_PE_udata8:
6451       return 8;
6452     case 0:
6453       return ptr_size;
6454     }
6455 
6456   fprintf (stderr, "Unsupported pointer encoding: %#x, "
6457 	   "assuming pointer size of %d.\n", encoding, ptr_size);
6458   return ptr_size;
6459 }
6460 
6461 
6462 static unsigned int
print_encoding(unsigned int val)6463 print_encoding (unsigned int val)
6464 {
6465   switch (val & 0xf)
6466     {
6467     case DW_EH_PE_absptr:
6468       fputs ("absptr", stdout);
6469       break;
6470     case DW_EH_PE_uleb128:
6471       fputs ("uleb128", stdout);
6472       break;
6473     case DW_EH_PE_udata2:
6474       fputs ("udata2", stdout);
6475       break;
6476     case DW_EH_PE_udata4:
6477       fputs ("udata4", stdout);
6478       break;
6479     case DW_EH_PE_udata8:
6480       fputs ("udata8", stdout);
6481       break;
6482     case DW_EH_PE_sleb128:
6483       fputs ("sleb128", stdout);
6484       break;
6485     case DW_EH_PE_sdata2:
6486       fputs ("sdata2", stdout);
6487       break;
6488     case DW_EH_PE_sdata4:
6489       fputs ("sdata4", stdout);
6490       break;
6491     case DW_EH_PE_sdata8:
6492       fputs ("sdata8", stdout);
6493       break;
6494     default:
6495       /* We did not use any of the bits after all.  */
6496       return val;
6497     }
6498 
6499   return val & ~0xf;
6500 }
6501 
6502 
6503 static unsigned int
print_relinfo(unsigned int val)6504 print_relinfo (unsigned int val)
6505 {
6506   switch (val & 0x70)
6507     {
6508     case DW_EH_PE_pcrel:
6509       fputs ("pcrel", stdout);
6510       break;
6511     case DW_EH_PE_textrel:
6512       fputs ("textrel", stdout);
6513       break;
6514     case DW_EH_PE_datarel:
6515       fputs ("datarel", stdout);
6516       break;
6517     case DW_EH_PE_funcrel:
6518       fputs ("funcrel", stdout);
6519       break;
6520     case DW_EH_PE_aligned:
6521       fputs ("aligned", stdout);
6522       break;
6523     default:
6524       return val;
6525     }
6526 
6527   return val & ~0x70;
6528 }
6529 
6530 
6531 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6532 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6533 {
6534   printf ("(%s", pfx);
6535 
6536   if (fde_encoding == DW_EH_PE_omit)
6537     puts ("omit)");
6538   else
6539     {
6540       unsigned int w = fde_encoding;
6541 
6542       w = print_encoding (w);
6543 
6544       if (w & 0x70)
6545 	{
6546 	  if (w != fde_encoding)
6547 	    fputc_unlocked (' ', stdout);
6548 
6549 	  w = print_relinfo (w);
6550 	}
6551 
6552       if (w != 0)
6553 	printf ("%s%x", w != fde_encoding ? " " : "", w);
6554 
6555       puts (")");
6556     }
6557 }
6558 
6559 
6560 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6561 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6562 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6563 {
6564   size_t shstrndx;
6565   /* We know this call will succeed since it did in the caller.  */
6566   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6567   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6568 
6569   /* Needed if we find PC-relative addresses.  */
6570   GElf_Addr bias;
6571   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6572     {
6573       error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
6574       return;
6575     }
6576 
6577   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6578   Elf_Data *data = (is_eh_frame
6579 		    ? elf_rawdata (scn, NULL)
6580 		    : (dbg->sectiondata[IDX_debug_frame]
6581 		       ?: elf_rawdata (scn, NULL)));
6582 
6583   if (unlikely (data == NULL))
6584     {
6585       error (0, 0, gettext ("cannot get %s content: %s"),
6586 	     scnname, elf_errmsg (-1));
6587       return;
6588     }
6589 
6590   if (is_eh_frame)
6591     printf (gettext ("\
6592 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6593 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6594   else
6595     printf (gettext ("\
6596 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6597 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6598 
6599   struct cieinfo
6600   {
6601     ptrdiff_t cie_offset;
6602     const char *augmentation;
6603     unsigned int code_alignment_factor;
6604     unsigned int data_alignment_factor;
6605     uint8_t address_size;
6606     uint8_t fde_encoding;
6607     uint8_t lsda_encoding;
6608     struct cieinfo *next;
6609   } *cies = NULL;
6610 
6611   const unsigned char *readp = data->d_buf;
6612   const unsigned char *const dataend = ((unsigned char *) data->d_buf
6613 					+ data->d_size);
6614   while (readp < dataend)
6615     {
6616       if (unlikely (readp + 4 > dataend))
6617 	{
6618 	invalid_data:
6619 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6620 		     elf_ndxscn (scn), scnname);
6621 	      return;
6622 	}
6623 
6624       /* At the beginning there must be a CIE.  There can be multiple,
6625 	 hence we test tis in a loop.  */
6626       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6627 
6628       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6629       unsigned int length = 4;
6630       if (unlikely (unit_length == 0xffffffff))
6631 	{
6632 	  if (unlikely (readp + 8 > dataend))
6633 	    goto invalid_data;
6634 
6635 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6636 	  length = 8;
6637 	}
6638 
6639       if (unlikely (unit_length == 0))
6640 	{
6641 	  printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
6642 	  continue;
6643 	}
6644 
6645       Dwarf_Word maxsize = dataend - readp;
6646       if (unlikely (unit_length > maxsize))
6647 	goto invalid_data;
6648 
6649       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6650 
6651       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6652       const unsigned char *const cieend = readp + unit_length;
6653       if (unlikely (cieend > dataend))
6654 	goto invalid_data;
6655 
6656       Dwarf_Off cie_id;
6657       if (length == 4)
6658 	{
6659 	  if (unlikely (cieend - readp < 4))
6660 	    goto invalid_data;
6661 	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6662 	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6663 	    cie_id = DW_CIE_ID_64;
6664 	}
6665       else
6666 	{
6667 	  if (unlikely (cieend - readp < 8))
6668 	    goto invalid_data;
6669 	  cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6670 	}
6671 
6672       uint_fast8_t version = 2;
6673       unsigned int code_alignment_factor;
6674       int data_alignment_factor;
6675       unsigned int fde_encoding = 0;
6676       unsigned int lsda_encoding = 0;
6677       Dwarf_Word initial_location = 0;
6678       Dwarf_Word vma_base = 0;
6679 
6680       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6681 	{
6682 	  if (unlikely (cieend - readp < 2))
6683 	    goto invalid_data;
6684 	  version = *readp++;
6685 	  const char *const augmentation = (const char *) readp;
6686 	  readp = memchr (readp, '\0', cieend - readp);
6687 	  if (unlikely (readp == NULL))
6688 	    goto invalid_data;
6689 	  ++readp;
6690 
6691 	  uint_fast8_t segment_size = 0;
6692 	  if (version >= 4)
6693 	    {
6694 	      if (cieend - readp < 5)
6695 		goto invalid_data;
6696 	      ptr_size = *readp++;
6697 	      segment_size = *readp++;
6698 	    }
6699 
6700 	  if (cieend - readp < 1)
6701 	    goto invalid_data;
6702 	  get_uleb128 (code_alignment_factor, readp, cieend);
6703 	  if (cieend - readp < 1)
6704 	    goto invalid_data;
6705 	  get_sleb128 (data_alignment_factor, readp, cieend);
6706 
6707 	  /* In some variant for unwind data there is another field.  */
6708 	  if (strcmp (augmentation, "eh") == 0)
6709 	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6710 
6711 	  unsigned int return_address_register;
6712 	  if (cieend - readp < 1)
6713 	    goto invalid_data;
6714 	  if (unlikely (version == 1))
6715 	    return_address_register = *readp++;
6716 	  else
6717 	    get_uleb128 (return_address_register, readp, cieend);
6718 
6719 	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6720 		  "   CIE_id:                   %" PRIu64 "\n"
6721 		  "   version:                  %u\n"
6722 		  "   augmentation:             \"%s\"\n",
6723 		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
6724 		  version, augmentation);
6725 	  if (version >= 4)
6726 	    printf ("   address_size:             %u\n"
6727 		    "   segment_size:             %u\n",
6728 		    ptr_size, segment_size);
6729 	  printf ("   code_alignment_factor:    %u\n"
6730 		  "   data_alignment_factor:    %d\n"
6731 		  "   return_address_register:  %u\n",
6732 		  code_alignment_factor,
6733 		  data_alignment_factor, return_address_register);
6734 
6735 	  if (augmentation[0] == 'z')
6736 	    {
6737 	      unsigned int augmentationlen;
6738 	      get_uleb128 (augmentationlen, readp, cieend);
6739 
6740 	      if (augmentationlen > (size_t) (cieend - readp))
6741 		{
6742 		  error (0, 0, gettext ("invalid augmentation length"));
6743 		  readp = cieend;
6744 		  continue;
6745 		}
6746 
6747 	      const char *hdr = "Augmentation data:";
6748 	      const char *cp = augmentation + 1;
6749 	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6750 		{
6751 		  printf ("   %-26s%#x ", hdr, *readp);
6752 		  hdr = "";
6753 
6754 		  if (*cp == 'R')
6755 		    {
6756 		      fde_encoding = *readp++;
6757 		      print_encoding_base (gettext ("FDE address encoding: "),
6758 					   fde_encoding);
6759 		    }
6760 		  else if (*cp == 'L')
6761 		    {
6762 		      lsda_encoding = *readp++;
6763 		      print_encoding_base (gettext ("LSDA pointer encoding: "),
6764 					   lsda_encoding);
6765 		    }
6766 		  else if (*cp == 'P')
6767 		    {
6768 		      /* Personality.  This field usually has a relocation
6769 			 attached pointing to __gcc_personality_v0.  */
6770 		      const unsigned char *startp = readp;
6771 		      unsigned int encoding = *readp++;
6772 		      uint64_t val = 0;
6773 		      readp = read_encoded (encoding, readp,
6774 					    readp - 1 + augmentationlen,
6775 					    &val, dbg);
6776 
6777 		      while (++startp < readp)
6778 			printf ("%#x ", *startp);
6779 
6780 		      putchar ('(');
6781 		      print_encoding (encoding);
6782 		      putchar (' ');
6783 		      switch (encoding & 0xf)
6784 			{
6785 			case DW_EH_PE_sleb128:
6786 			case DW_EH_PE_sdata2:
6787 			case DW_EH_PE_sdata4:
6788 			  printf ("%" PRId64 ")\n", val);
6789 			  break;
6790 			default:
6791 			  printf ("%#" PRIx64 ")\n", val);
6792 			  break;
6793 			}
6794 		    }
6795 		  else
6796 		    printf ("(%x)\n", *readp++);
6797 
6798 		  ++cp;
6799 		}
6800 	    }
6801 
6802 	  if (likely (ptr_size == 4 || ptr_size == 8))
6803 	    {
6804 	      struct cieinfo *newp = alloca (sizeof (*newp));
6805 	      newp->cie_offset = offset;
6806 	      newp->augmentation = augmentation;
6807 	      newp->fde_encoding = fde_encoding;
6808 	      newp->lsda_encoding = lsda_encoding;
6809 	      newp->address_size = ptr_size;
6810 	      newp->code_alignment_factor = code_alignment_factor;
6811 	      newp->data_alignment_factor = data_alignment_factor;
6812 	      newp->next = cies;
6813 	      cies = newp;
6814 	    }
6815 	}
6816       else
6817 	{
6818 	  struct cieinfo *cie = cies;
6819 	  while (cie != NULL)
6820 	    if (is_eh_frame
6821 		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6822 		: cie_id == (Dwarf_Off) cie->cie_offset)
6823 	      break;
6824 	    else
6825 	      cie = cie->next;
6826 	  if (unlikely (cie == NULL))
6827 	    {
6828 	      puts ("invalid CIE reference in FDE");
6829 	      return;
6830 	    }
6831 
6832 	  /* Initialize from CIE data.  */
6833 	  fde_encoding = cie->fde_encoding;
6834 	  lsda_encoding = cie->lsda_encoding;
6835 	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6836 	  code_alignment_factor = cie->code_alignment_factor;
6837 	  data_alignment_factor = cie->data_alignment_factor;
6838 
6839 	  const unsigned char *base = readp;
6840 	  // XXX There are sometimes relocations for this value
6841 	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6842 	  Dwarf_Word address_range
6843 	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
6844 
6845 	  /* pcrel for an FDE address is relative to the runtime
6846 	     address of the start_address field itself.  Sign extend
6847 	     if necessary to make sure the calculation is done on the
6848 	     full 64 bit address even when initial_location only holds
6849 	     the lower 32 bits.  */
6850 	  Dwarf_Addr pc_start = initial_location;
6851 	  if (ptr_size == 4)
6852 	    pc_start = (uint64_t) (int32_t) pc_start;
6853 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6854 	    pc_start += ((uint64_t) shdr->sh_addr
6855 			 + (base - (const unsigned char *) data->d_buf)
6856 			 - bias);
6857 
6858 	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6859 		  "   CIE_pointer:              %" PRIu64 "\n"
6860 		  "   initial_location:         ",
6861 		  offset, (uint64_t) unit_length,
6862 		  cie->cie_offset, (uint64_t) cie_id);
6863 	  print_dwarf_addr (dwflmod, cie->address_size,
6864 			    pc_start, initial_location);
6865 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6866 	    {
6867 	      vma_base = (((uint64_t) shdr->sh_offset
6868 			   + (base - (const unsigned char *) data->d_buf)
6869 			   + (uint64_t) initial_location)
6870 			  & (ptr_size == 4
6871 			     ? UINT64_C (0xffffffff)
6872 			     : UINT64_C (0xffffffffffffffff)));
6873 	      printf (gettext (" (offset: %#" PRIx64 ")"),
6874 		      (uint64_t) vma_base);
6875 	    }
6876 
6877 	  printf ("\n   address_range:            %#" PRIx64,
6878 		  (uint64_t) address_range);
6879 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6880 	    printf (gettext (" (end offset: %#" PRIx64 ")"),
6881 		    ((uint64_t) vma_base + (uint64_t) address_range)
6882 		    & (ptr_size == 4
6883 		       ? UINT64_C (0xffffffff)
6884 		       : UINT64_C (0xffffffffffffffff)));
6885 	  putchar ('\n');
6886 
6887 	  if (cie->augmentation[0] == 'z')
6888 	    {
6889 	      unsigned int augmentationlen;
6890 	      if (cieend - readp < 1)
6891 		goto invalid_data;
6892 	      get_uleb128 (augmentationlen, readp, cieend);
6893 
6894 	      if (augmentationlen > (size_t) (cieend - readp))
6895 		{
6896 		  error (0, 0, gettext ("invalid augmentation length"));
6897 		  readp = cieend;
6898 		  continue;
6899 		}
6900 
6901 	      if (augmentationlen > 0)
6902 		{
6903 		  const char *hdr = "Augmentation data:";
6904 		  const char *cp = cie->augmentation + 1;
6905 		  unsigned int u = 0;
6906 		  while (*cp != '\0'
6907 			 && cp < cie->augmentation + augmentationlen + 1)
6908 		    {
6909 		      if (*cp == 'L')
6910 			{
6911 			  uint64_t lsda_pointer;
6912 			  const unsigned char *p
6913 			    = read_encoded (lsda_encoding, &readp[u],
6914 					    &readp[augmentationlen],
6915 					    &lsda_pointer, dbg);
6916 			  u = p - readp;
6917 			  printf (gettext ("\
6918    %-26sLSDA pointer: %#" PRIx64 "\n"),
6919 				  hdr, lsda_pointer);
6920 			  hdr = "";
6921 			}
6922 		      ++cp;
6923 		    }
6924 
6925 		  while (u < augmentationlen)
6926 		    {
6927 		      printf ("   %-26s%#x\n", hdr, readp[u++]);
6928 		      hdr = "";
6929 		    }
6930 		}
6931 
6932 	      readp += augmentationlen;
6933 	    }
6934 	}
6935 
6936       /* Handle the initialization instructions.  */
6937       if (ptr_size != 4 && ptr_size !=8)
6938 	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6939       else
6940 	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6941 			   data_alignment_factor, version, ptr_size,
6942 			   fde_encoding, dwflmod, ebl, dbg);
6943       readp = cieend;
6944     }
6945 }
6946 
6947 
6948 /* Returns the signedness (or false if it cannot be determined) and
6949    the byte size (or zero if it cannot be gotten) of the given DIE
6950    DW_AT_type attribute.  Uses dwarf_peel_type and dwarf_aggregate_size.  */
6951 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)6952 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
6953 {
6954   Dwarf_Attribute attr;
6955   Dwarf_Die type;
6956 
6957   *bytes = 0;
6958   *is_signed = false;
6959 
6960   if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
6961 								DW_AT_type,
6962 								&attr), &type),
6963 		       &type) == 0)
6964     {
6965       Dwarf_Word val;
6966       *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
6967 						 &attr), &val) == 0
6968 		    && (val == DW_ATE_signed || val == DW_ATE_signed_char));
6969 
6970       if (dwarf_aggregate_size (&type, &val) == 0)
6971 	*bytes = val;
6972     }
6973 }
6974 
6975 struct attrcb_args
6976 {
6977   Dwfl_Module *dwflmod;
6978   Dwarf *dbg;
6979   Dwarf_Die *dies;
6980   int level;
6981   bool silent;
6982   bool is_split;
6983   unsigned int version;
6984   unsigned int addrsize;
6985   unsigned int offset_size;
6986   struct Dwarf_CU *cu;
6987 };
6988 
6989 
6990 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)6991 attr_callback (Dwarf_Attribute *attrp, void *arg)
6992 {
6993   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
6994   const int level = cbargs->level;
6995   Dwarf_Die *die = &cbargs->dies[level];
6996   bool is_split = cbargs->is_split;
6997 
6998   unsigned int attr = dwarf_whatattr (attrp);
6999   if (unlikely (attr == 0))
7000     {
7001       if (!cbargs->silent)
7002 	error (0, 0, gettext ("DIE [%" PRIx64 "] "
7003 			      "cannot get attribute code: %s"),
7004 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7005       return DWARF_CB_ABORT;
7006     }
7007 
7008   unsigned int form = dwarf_whatform (attrp);
7009   if (unlikely (form == 0))
7010     {
7011       if (!cbargs->silent)
7012 	error (0, 0, gettext ("DIE [%" PRIx64 "] "
7013 			      "cannot get attribute form: %s"),
7014 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7015       return DWARF_CB_ABORT;
7016     }
7017 
7018   switch (form)
7019     {
7020     case DW_FORM_addr:
7021     case DW_FORM_addrx:
7022     case DW_FORM_addrx1:
7023     case DW_FORM_addrx2:
7024     case DW_FORM_addrx3:
7025     case DW_FORM_addrx4:
7026     case DW_FORM_GNU_addr_index:
7027       if (!cbargs->silent)
7028 	{
7029 	  Dwarf_Addr addr;
7030 	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7031 	    {
7032 	    attrval_out:
7033 	      if (!cbargs->silent)
7034 		error (0, 0, gettext ("DIE [%" PRIx64 "] "
7035 				      "cannot get attribute '%s' (%s) value: "
7036 				      "%s"),
7037 		       dwarf_dieoffset (die),
7038 		       dwarf_attr_name (attr),
7039 		       dwarf_form_name (form),
7040 		       dwarf_errmsg (-1));
7041 	      /* Don't ABORT, it might be other attributes can be resolved.  */
7042 	      return DWARF_CB_OK;
7043 	    }
7044 	  if (form != DW_FORM_addr )
7045 	    {
7046 	      Dwarf_Word word;
7047 	      if (dwarf_formudata (attrp, &word) != 0)
7048 		goto attrval_out;
7049 	      printf ("           %*s%-20s (%s) [%" PRIx64 "] ",
7050 		      (int) (level * 2), "", dwarf_attr_name (attr),
7051 		      dwarf_form_name (form), word);
7052 	    }
7053 	  else
7054 	    printf ("           %*s%-20s (%s) ",
7055 		    (int) (level * 2), "", dwarf_attr_name (attr),
7056 		    dwarf_form_name (form));
7057 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7058 	  printf ("\n");
7059 	}
7060       break;
7061 
7062     case DW_FORM_indirect:
7063     case DW_FORM_strp:
7064     case DW_FORM_line_strp:
7065     case DW_FORM_strx:
7066     case DW_FORM_strx1:
7067     case DW_FORM_strx2:
7068     case DW_FORM_strx3:
7069     case DW_FORM_strx4:
7070     case DW_FORM_string:
7071     case DW_FORM_GNU_strp_alt:
7072     case DW_FORM_GNU_str_index:
7073       if (cbargs->silent)
7074 	break;
7075       const char *str = dwarf_formstring (attrp);
7076       if (unlikely (str == NULL))
7077 	goto attrval_out;
7078       printf ("           %*s%-20s (%s) \"%s\"\n",
7079 	      (int) (level * 2), "", dwarf_attr_name (attr),
7080 	      dwarf_form_name (form), str);
7081       break;
7082 
7083     case DW_FORM_ref_addr:
7084     case DW_FORM_ref_udata:
7085     case DW_FORM_ref8:
7086     case DW_FORM_ref4:
7087     case DW_FORM_ref2:
7088     case DW_FORM_ref1:
7089     case DW_FORM_GNU_ref_alt:
7090     case DW_FORM_ref_sup4:
7091     case DW_FORM_ref_sup8:
7092       if (cbargs->silent)
7093 	break;
7094       Dwarf_Die ref;
7095       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7096 	goto attrval_out;
7097 
7098       printf ("           %*s%-20s (%s) ",
7099 	      (int) (level * 2), "", dwarf_attr_name (attr),
7100 	      dwarf_form_name (form));
7101       if (is_split)
7102 	printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7103       else
7104 	printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7105       break;
7106 
7107     case DW_FORM_ref_sig8:
7108       if (cbargs->silent)
7109 	break;
7110       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
7111 	      (int) (level * 2), "", dwarf_attr_name (attr),
7112 	      dwarf_form_name (form),
7113 	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7114       break;
7115 
7116     case DW_FORM_sec_offset:
7117     case DW_FORM_rnglistx:
7118     case DW_FORM_loclistx:
7119     case DW_FORM_implicit_const:
7120     case DW_FORM_udata:
7121     case DW_FORM_sdata:
7122     case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7123     case DW_FORM_data4:
7124     case DW_FORM_data2:
7125     case DW_FORM_data1:;
7126       Dwarf_Word num;
7127       if (unlikely (dwarf_formudata (attrp, &num) != 0))
7128 	goto attrval_out;
7129 
7130       const char *valuestr = NULL;
7131       bool as_hex_id = false;
7132       switch (attr)
7133 	{
7134 	  /* This case can take either a constant or a loclistptr.  */
7135 	case DW_AT_data_member_location:
7136 	  if (form != DW_FORM_sec_offset
7137 	      && (cbargs->version >= 4
7138 		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7139 	    {
7140 	      if (!cbargs->silent)
7141 		printf ("           %*s%-20s (%s) %" PRIuMAX "\n",
7142 			(int) (level * 2), "", dwarf_attr_name (attr),
7143 			dwarf_form_name (form), (uintmax_t) num);
7144 	      return DWARF_CB_OK;
7145 	    }
7146 	  FALLTHROUGH;
7147 
7148 	/* These cases always take a loclist[ptr] and no constant. */
7149 	case DW_AT_location:
7150 	case DW_AT_data_location:
7151 	case DW_AT_vtable_elem_location:
7152 	case DW_AT_string_length:
7153 	case DW_AT_use_location:
7154 	case DW_AT_frame_base:
7155 	case DW_AT_return_addr:
7156 	case DW_AT_static_link:
7157 	case DW_AT_segment:
7158 	case DW_AT_GNU_call_site_value:
7159 	case DW_AT_GNU_call_site_data_value:
7160 	case DW_AT_GNU_call_site_target:
7161 	case DW_AT_GNU_call_site_target_clobbered:
7162 	case DW_AT_GNU_locviews:
7163 	  {
7164 	    bool nlpt;
7165 	    if (cbargs->cu->version < 5)
7166 	      {
7167 		if (! cbargs->is_split)
7168 		  {
7169 		    nlpt = notice_listptr (section_loc, &known_locsptr,
7170 					   cbargs->addrsize,
7171 					   cbargs->offset_size,
7172 					   cbargs->cu, num, attr);
7173 		  }
7174 		else
7175 		  nlpt = true;
7176 	      }
7177 	    else
7178 	      {
7179 		/* Only register for a real section offset.  Otherwise
7180 		   it is a DW_FORM_loclistx which is just an index
7181 		   number and we should already have registered the
7182 		   section offset for the index when we saw the
7183 		   DW_AT_loclists_base CU attribute.  */
7184 		if (form == DW_FORM_sec_offset)
7185 		  nlpt = notice_listptr (section_loc, &known_loclistsptr,
7186 					 cbargs->addrsize, cbargs->offset_size,
7187 					 cbargs->cu, num, attr);
7188 		else
7189 		  nlpt = true;
7190 
7191 	      }
7192 
7193 	    if (!cbargs->silent)
7194 	      {
7195 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7196 		  printf ("           %*s%-20s (%s) location list [%6"
7197 			  PRIxMAX "]%s\n",
7198 			  (int) (level * 2), "", dwarf_attr_name (attr),
7199 			  dwarf_form_name (form), (uintmax_t) num,
7200 			  nlpt ? "" : " <WARNING offset too big>");
7201 		else
7202 		  printf ("           %*s%-20s (%s) location index [%6"
7203 			  PRIxMAX "]\n",
7204 			  (int) (level * 2), "", dwarf_attr_name (attr),
7205 			  dwarf_form_name (form), (uintmax_t) num);
7206 	      }
7207 	  }
7208 	  return DWARF_CB_OK;
7209 
7210 	case DW_AT_loclists_base:
7211 	  {
7212 	    bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7213                                         cbargs->addrsize, cbargs->offset_size,
7214                                         cbargs->cu, num, attr);
7215 
7216 	    if (!cbargs->silent)
7217 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7218 		      (int) (level * 2), "", dwarf_attr_name (attr),
7219 		      dwarf_form_name (form), (uintmax_t) num,
7220 		      nlpt ? "" : " <WARNING offset too big>");
7221 	  }
7222 	  return DWARF_CB_OK;
7223 
7224 	case DW_AT_ranges:
7225 	case DW_AT_start_scope:
7226 	  {
7227 	    bool nlpt;
7228 	    if (cbargs->cu->version < 5)
7229 	      nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7230 				     cbargs->addrsize, cbargs->offset_size,
7231 				     cbargs->cu, num, attr);
7232 	    else
7233 	      {
7234 		/* Only register for a real section offset.  Otherwise
7235 		   it is a DW_FORM_rangelistx which is just an index
7236 		   number and we should already have registered the
7237 		   section offset for the index when we saw the
7238 		   DW_AT_rnglists_base CU attribute.  */
7239 		if (form == DW_FORM_sec_offset)
7240 		  nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7241 					 cbargs->addrsize, cbargs->offset_size,
7242 					 cbargs->cu, num, attr);
7243 		else
7244 		  nlpt = true;
7245 	      }
7246 
7247 	    if (!cbargs->silent)
7248 	      {
7249 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7250 		  printf ("           %*s%-20s (%s) range list [%6"
7251 			  PRIxMAX "]%s\n",
7252 			  (int) (level * 2), "", dwarf_attr_name (attr),
7253 			  dwarf_form_name (form), (uintmax_t) num,
7254 			  nlpt ? "" : " <WARNING offset too big>");
7255 		else
7256 		  printf ("           %*s%-20s (%s) range index [%6"
7257 			  PRIxMAX "]\n",
7258 			  (int) (level * 2), "", dwarf_attr_name (attr),
7259 			  dwarf_form_name (form), (uintmax_t) num);
7260 	      }
7261 	  }
7262 	  return DWARF_CB_OK;
7263 
7264 	case DW_AT_rnglists_base:
7265 	  {
7266 	    bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7267 					cbargs->addrsize, cbargs->offset_size,
7268 					cbargs->cu, num, attr);
7269 	    if (!cbargs->silent)
7270 	      printf ("           %*s%-20s (%s) range list [%6"
7271 		      PRIxMAX "]%s\n",
7272 		      (int) (level * 2), "", dwarf_attr_name (attr),
7273 		      dwarf_form_name (form), (uintmax_t) num,
7274 		      nlpt ? "" : " <WARNING offset too big>");
7275 	  }
7276 	  return DWARF_CB_OK;
7277 
7278 	case DW_AT_addr_base:
7279 	case DW_AT_GNU_addr_base:
7280 	  {
7281 	    bool addrbase = notice_listptr (section_addr, &known_addrbases,
7282 					    cbargs->addrsize,
7283 					    cbargs->offset_size,
7284 					    cbargs->cu, num, attr);
7285 	    if (!cbargs->silent)
7286 	      printf ("           %*s%-20s (%s) address base [%6"
7287 		      PRIxMAX "]%s\n",
7288 		      (int) (level * 2), "", dwarf_attr_name (attr),
7289 		      dwarf_form_name (form), (uintmax_t) num,
7290 		      addrbase ? "" : " <WARNING offset too big>");
7291 	  }
7292 	  return DWARF_CB_OK;
7293 
7294 	case DW_AT_str_offsets_base:
7295 	  {
7296 	    bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7297 					      cbargs->addrsize,
7298 					      cbargs->offset_size,
7299 					      cbargs->cu, num, attr);
7300 	    if (!cbargs->silent)
7301 	      printf ("           %*s%-20s (%s) str offsets base [%6"
7302 		      PRIxMAX "]%s\n",
7303 		      (int) (level * 2), "", dwarf_attr_name (attr),
7304 		      dwarf_form_name (form), (uintmax_t) num,
7305 		      stroffbase ? "" : " <WARNING offset too big>");
7306 	  }
7307 	  return DWARF_CB_OK;
7308 
7309 	case DW_AT_language:
7310 	  valuestr = dwarf_lang_name (num);
7311 	  break;
7312 	case DW_AT_encoding:
7313 	  valuestr = dwarf_encoding_name (num);
7314 	  break;
7315 	case DW_AT_accessibility:
7316 	  valuestr = dwarf_access_name (num);
7317 	  break;
7318 	case DW_AT_defaulted:
7319 	  valuestr = dwarf_defaulted_name (num);
7320 	  break;
7321 	case DW_AT_visibility:
7322 	  valuestr = dwarf_visibility_name (num);
7323 	  break;
7324 	case DW_AT_virtuality:
7325 	  valuestr = dwarf_virtuality_name (num);
7326 	  break;
7327 	case DW_AT_identifier_case:
7328 	  valuestr = dwarf_identifier_case_name (num);
7329 	  break;
7330 	case DW_AT_calling_convention:
7331 	  valuestr = dwarf_calling_convention_name (num);
7332 	  break;
7333 	case DW_AT_inline:
7334 	  valuestr = dwarf_inline_name (num);
7335 	  break;
7336 	case DW_AT_ordering:
7337 	  valuestr = dwarf_ordering_name (num);
7338 	  break;
7339 	case DW_AT_decl_file:
7340 	case DW_AT_call_file:
7341 	  {
7342 	    if (cbargs->silent)
7343 	      break;
7344 
7345 	    /* Try to get the actual file, the current interface only
7346 	       gives us full paths, but we only want to show the file
7347 	       name for now.  */
7348 	    Dwarf_Die cudie;
7349 	    if (dwarf_cu_die (cbargs->cu, &cudie,
7350 			      NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7351 	      {
7352 		Dwarf_Files *files;
7353 		size_t nfiles;
7354 		if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7355 		  {
7356 		    valuestr = dwarf_filesrc (files, num, NULL, NULL);
7357 		    if (valuestr != NULL)
7358 		      {
7359 			char *filename = strrchr (valuestr, '/');
7360 			if (filename != NULL)
7361 			  valuestr = filename + 1;
7362 		      }
7363 		    else
7364 		      error (0, 0, gettext ("invalid file (%" PRId64 "): %s"),
7365 			     num, dwarf_errmsg (-1));
7366 		  }
7367 		else
7368 		  error (0, 0, gettext ("no srcfiles for CU [%" PRIx64 "]"),
7369 			 dwarf_dieoffset (&cudie));
7370 	      }
7371 	    else
7372 	     error (0, 0, gettext ("couldn't get DWARF CU: %s"),
7373 		    dwarf_errmsg (-1));
7374 	    if (valuestr == NULL)
7375 	      valuestr = "???";
7376 	  }
7377 	  break;
7378 	case DW_AT_GNU_dwo_id:
7379 	  as_hex_id = true;
7380 	  break;
7381 
7382 	default:
7383 	  /* Nothing.  */
7384 	  break;
7385 	}
7386 
7387       if (cbargs->silent)
7388 	break;
7389 
7390       /* When highpc is in constant form it is relative to lowpc.
7391 	 In that case also show the address.  */
7392       Dwarf_Addr highpc;
7393       if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7394 	{
7395 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (",
7396 		  (int) (level * 2), "", dwarf_attr_name (attr),
7397 		  dwarf_form_name (form), (uintmax_t) num);
7398 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7399 	  printf (")\n");
7400 	}
7401       else
7402 	{
7403 	  if (as_hex_id)
7404 	    {
7405 	      printf ("           %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7406 		      (int) (level * 2), "", dwarf_attr_name (attr),
7407 		      dwarf_form_name (form), num);
7408 	    }
7409 	  else
7410 	    {
7411 	      Dwarf_Sword snum = 0;
7412 	      bool is_signed;
7413 	      int bytes = 0;
7414 	      if (attr == DW_AT_const_value)
7415 		die_type_sign_bytes (die, &is_signed, &bytes);
7416 	      else
7417 		is_signed = (form == DW_FORM_sdata
7418 			     || form == DW_FORM_implicit_const);
7419 
7420 	      if (is_signed)
7421 		if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7422 		  goto attrval_out;
7423 
7424 	      if (valuestr == NULL)
7425 		{
7426 		  printf ("           %*s%-20s (%s) ",
7427 			  (int) (level * 2), "", dwarf_attr_name (attr),
7428 			  dwarf_form_name (form));
7429 		}
7430 	      else
7431 		{
7432 		  printf ("           %*s%-20s (%s) %s (",
7433 			  (int) (level * 2), "", dwarf_attr_name (attr),
7434 			  dwarf_form_name (form), valuestr);
7435 		}
7436 
7437 	      switch (bytes)
7438 		{
7439 		case 1:
7440 		  if (is_signed)
7441 		    printf ("%" PRId8, (int8_t) snum);
7442 		  else
7443 		    printf ("%" PRIu8, (uint8_t) num);
7444 		  break;
7445 
7446 		case 2:
7447 		  if (is_signed)
7448 		    printf ("%" PRId16, (int16_t) snum);
7449 		  else
7450 		    printf ("%" PRIu16, (uint16_t) num);
7451 		  break;
7452 
7453 		case 4:
7454 		  if (is_signed)
7455 		    printf ("%" PRId32, (int32_t) snum);
7456 		  else
7457 		    printf ("%" PRIu32, (uint32_t) num);
7458 		  break;
7459 
7460 		case 8:
7461 		  if (is_signed)
7462 		    printf ("%" PRId64, (int64_t) snum);
7463 		  else
7464 		    printf ("%" PRIu64, (uint64_t) num);
7465 		  break;
7466 
7467 		default:
7468 		  if (is_signed)
7469 		    printf ("%" PRIdMAX, (intmax_t) snum);
7470 		  else
7471 		    printf ("%" PRIuMAX, (uintmax_t) num);
7472 		  break;
7473 		}
7474 
7475 	      /* Make clear if we switched from a signed encoding to
7476 		 an unsigned value.  */
7477 	      if (attr == DW_AT_const_value
7478 		  && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7479 		  && !is_signed)
7480 		printf (" (%" PRIdMAX ")", (intmax_t) num);
7481 
7482 	      if (valuestr == NULL)
7483 		printf ("\n");
7484 	      else
7485 		printf (")\n");
7486 	    }
7487 	}
7488       break;
7489 
7490     case DW_FORM_flag:
7491       if (cbargs->silent)
7492 	break;
7493       bool flag;
7494       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7495 	goto attrval_out;
7496 
7497       printf ("           %*s%-20s (%s) %s\n",
7498 	      (int) (level * 2), "", dwarf_attr_name (attr),
7499 	      dwarf_form_name (form), flag ? yes_str : no_str);
7500       break;
7501 
7502     case DW_FORM_flag_present:
7503       if (cbargs->silent)
7504 	break;
7505       printf ("           %*s%-20s (%s) %s\n",
7506 	      (int) (level * 2), "", dwarf_attr_name (attr),
7507 	      dwarf_form_name (form), yes_str);
7508       break;
7509 
7510     case DW_FORM_exprloc:
7511     case DW_FORM_block4:
7512     case DW_FORM_block2:
7513     case DW_FORM_block1:
7514     case DW_FORM_block:
7515     case DW_FORM_data16: /* DWARF5 calls this a constant class.  */
7516       if (cbargs->silent)
7517 	break;
7518       Dwarf_Block block;
7519       if (unlikely (dwarf_formblock (attrp, &block) != 0))
7520 	goto attrval_out;
7521 
7522       printf ("           %*s%-20s (%s) ",
7523 	      (int) (level * 2), "", dwarf_attr_name (attr),
7524 	      dwarf_form_name (form));
7525 
7526       switch (attr)
7527 	{
7528 	default:
7529 	  if (form != DW_FORM_exprloc)
7530 	    {
7531 	      print_block (block.length, block.data);
7532 	      break;
7533 	    }
7534 	  FALLTHROUGH;
7535 
7536 	case DW_AT_location:
7537 	case DW_AT_data_location:
7538 	case DW_AT_data_member_location:
7539 	case DW_AT_vtable_elem_location:
7540 	case DW_AT_string_length:
7541 	case DW_AT_use_location:
7542 	case DW_AT_frame_base:
7543 	case DW_AT_return_addr:
7544 	case DW_AT_static_link:
7545 	case DW_AT_allocated:
7546 	case DW_AT_associated:
7547 	case DW_AT_bit_size:
7548 	case DW_AT_bit_offset:
7549 	case DW_AT_bit_stride:
7550 	case DW_AT_byte_size:
7551 	case DW_AT_byte_stride:
7552 	case DW_AT_count:
7553 	case DW_AT_lower_bound:
7554 	case DW_AT_upper_bound:
7555 	case DW_AT_GNU_call_site_value:
7556 	case DW_AT_GNU_call_site_data_value:
7557 	case DW_AT_GNU_call_site_target:
7558 	case DW_AT_GNU_call_site_target_clobbered:
7559 	  if (form != DW_FORM_data16)
7560 	    {
7561 	      putchar ('\n');
7562 	      print_ops (cbargs->dwflmod, cbargs->dbg,
7563 			 12 + level * 2, 12 + level * 2,
7564 			 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7565 			 attrp->cu, block.length, block.data);
7566 	    }
7567 	  else
7568 	    print_block (block.length, block.data);
7569 	  break;
7570 
7571 	case DW_AT_discr_list:
7572 	  if (block.length == 0)
7573 	    puts ("<default>");
7574 	  else if (form != DW_FORM_data16)
7575 	    {
7576 	      const unsigned char *readp = block.data;
7577 	      const unsigned char *readendp = readp + block.length;
7578 
7579 	      /* See if we are dealing with a signed or unsigned
7580 		 values.  If the parent of this variant DIE is a
7581 		 variant_part then it will either have a discriminant
7582 		 which points to the member which type is the
7583 		 discriminant type.  Or the variant_part itself has a
7584 		 type representing the discriminant.  */
7585 	      bool is_signed = false;
7586 	      if (level > 0)
7587 		{
7588 		  Dwarf_Die *parent = &cbargs->dies[level - 1];
7589 		  if (dwarf_tag (die) == DW_TAG_variant
7590 		      && dwarf_tag (parent) == DW_TAG_variant_part)
7591 		    {
7592 		      Dwarf_Die member;
7593 		      Dwarf_Attribute discr_attr;
7594 		      int bytes;
7595 		      if (dwarf_formref_die (dwarf_attr (parent,
7596 							 DW_AT_discr,
7597 							 &discr_attr),
7598 					     &member) != NULL)
7599 			die_type_sign_bytes (&member, &is_signed, &bytes);
7600 		      else
7601 			die_type_sign_bytes (parent, &is_signed, &bytes);
7602 		    }
7603 		}
7604 	      while (readp < readendp)
7605 		{
7606 		  int d = (int) *readp++;
7607 		  printf ("%s ", dwarf_discr_list_name (d));
7608 		  if (readp >= readendp)
7609 		    goto attrval_out;
7610 
7611 		  Dwarf_Word val;
7612 		  Dwarf_Sword sval;
7613 		  if (d == DW_DSC_label)
7614 		    {
7615 		      if (is_signed)
7616 			{
7617 			  get_sleb128 (sval, readp, readendp);
7618 			  printf ("%" PRId64 "", sval);
7619 			}
7620 		      else
7621 			{
7622 			  get_uleb128 (val, readp, readendp);
7623 			  printf ("%" PRIu64 "", val);
7624 			}
7625 		    }
7626 		  else if (d == DW_DSC_range)
7627 		    {
7628 		      if (is_signed)
7629 			{
7630 			  get_sleb128 (sval, readp, readendp);
7631 			  printf ("%" PRId64 "..", sval);
7632 			  if (readp >= readendp)
7633 			    goto attrval_out;
7634 			  get_sleb128 (sval, readp, readendp);
7635 			  printf ("%" PRId64 "", sval);
7636 			}
7637 		      else
7638 			{
7639 			  get_uleb128 (val, readp, readendp);
7640 			  printf ("%" PRIu64 "..", val);
7641 			  if (readp >= readendp)
7642 			    goto attrval_out;
7643 			  get_uleb128 (val, readp, readendp);
7644 			  printf ("%" PRIu64 "", val);
7645 			}
7646 		    }
7647 		  else
7648 		    {
7649 		      print_block (readendp - readp, readp);
7650 		      break;
7651 		    }
7652 		  if (readp < readendp)
7653 		    printf (", ");
7654 		}
7655 	      putchar ('\n');
7656 	    }
7657 	  else
7658 	    print_block (block.length, block.data);
7659 	  break;
7660 	}
7661       break;
7662 
7663     default:
7664       if (cbargs->silent)
7665 	break;
7666       printf ("           %*s%-20s (%s) ???\n",
7667 	      (int) (level * 2), "", dwarf_attr_name (attr),
7668 	      dwarf_form_name (form));
7669       break;
7670     }
7671 
7672   return DWARF_CB_OK;
7673 }
7674 
7675 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7676 print_debug_units (Dwfl_Module *dwflmod,
7677 		   Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7678 		   Elf_Scn *scn, GElf_Shdr *shdr,
7679 		   Dwarf *dbg, bool debug_types)
7680 {
7681   const bool silent = !(print_debug_sections & section_info) && !debug_types;
7682   const char *secname = section_name (ebl, shdr);
7683 
7684   if (!silent)
7685     printf (gettext ("\
7686 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7687 	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7688 
7689   /* If the section is empty we don't have to do anything.  */
7690   if (!silent && shdr->sh_size == 0)
7691     return;
7692 
7693   int maxdies = 20;
7694   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
7695 
7696   /* New compilation unit.  */
7697   Dwarf_Half version;
7698 
7699   Dwarf_Die result;
7700   Dwarf_Off abbroffset;
7701   uint8_t addrsize;
7702   uint8_t offsize;
7703   uint64_t unit_id;
7704   Dwarf_Off subdie_off;
7705 
7706   int unit_res;
7707   Dwarf_CU *cu;
7708   Dwarf_CU cu_mem;
7709   uint8_t unit_type;
7710   Dwarf_Die cudie;
7711 
7712   /* We cheat a little because we want to see only the CUs from .debug_info
7713      or .debug_types.  We know the Dwarf_CU struct layout.  Set it up at
7714      the end of .debug_info if we want .debug_types only.  Check the returned
7715      Dwarf_CU is still in the expected section.  */
7716   if (debug_types)
7717     {
7718       cu_mem.dbg = dbg;
7719       cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7720       cu_mem.sec_idx = IDX_debug_info;
7721       cu = &cu_mem;
7722     }
7723   else
7724     cu = NULL;
7725 
7726  next_cu:
7727   unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7728 			      &cudie, NULL);
7729   if (unit_res == 1)
7730     goto do_return;
7731 
7732   if (unit_res == -1)
7733     {
7734       if (!silent)
7735 	error (0, 0, gettext ("cannot get next unit: %s"), dwarf_errmsg (-1));
7736       goto do_return;
7737     }
7738 
7739   if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7740     goto do_return;
7741 
7742   dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7743 		&unit_id, &subdie_off);
7744 
7745   if (!silent)
7746     {
7747       Dwarf_Off offset = cu->start;
7748       if (debug_types && version < 5)
7749 	{
7750 	  Dwarf_Die typedie;
7751 	  Dwarf_Off dieoffset;
7752 	  dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
7753 							   &typedie));
7754 	  printf (gettext (" Type unit at offset %" PRIu64 ":\n"
7755 			   " Version: %" PRIu16
7756 			   ", Abbreviation section offset: %" PRIu64
7757 			   ", Address size: %" PRIu8
7758 			   ", Offset size: %" PRIu8
7759 			   "\n Type signature: %#" PRIx64
7760 			   ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7761 		  (uint64_t) offset, version, abbroffset, addrsize, offsize,
7762 		  unit_id, (uint64_t) subdie_off, dieoffset);
7763 	}
7764       else
7765 	{
7766 	  printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
7767 			   " Version: %" PRIu16
7768 			   ", Abbreviation section offset: %" PRIu64
7769 			   ", Address size: %" PRIu8
7770 			   ", Offset size: %" PRIu8 "\n"),
7771 		  (uint64_t) offset, version, abbroffset, addrsize, offsize);
7772 
7773 	  if (version >= 5 || (unit_type != DW_UT_compile
7774 			       && unit_type != DW_UT_partial))
7775 	    {
7776 	      printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7777 			       dwarf_unit_name (unit_type), unit_type);
7778 	      if (unit_type == DW_UT_type
7779 		  || unit_type == DW_UT_skeleton
7780 		  || unit_type == DW_UT_split_compile
7781 		  || unit_type == DW_UT_split_type)
7782 		printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7783 	      if (unit_type == DW_UT_type
7784 		  || unit_type == DW_UT_split_type)
7785 		{
7786 		  Dwarf_Die typedie;
7787 		  Dwarf_Off dieoffset;
7788 		  dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7789 				 NULL, NULL, NULL);
7790 		  dieoffset = dwarf_dieoffset (&typedie);
7791 		  printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7792 			  subdie_off, dieoffset);
7793 		}
7794 	      printf ("\n");
7795 	    }
7796 	}
7797     }
7798 
7799   if (version < 2 || version > 5
7800       || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7801     {
7802       if (!silent)
7803 	error (0, 0, gettext ("unknown version (%d) or unit type (%d)"),
7804 	       version, unit_type);
7805       goto next_cu;
7806     }
7807 
7808   struct attrcb_args args =
7809     {
7810       .dwflmod = dwflmod,
7811       .silent = silent,
7812       .version = version,
7813       .addrsize = addrsize,
7814       .offset_size = offsize
7815     };
7816 
7817   bool is_split = false;
7818   int level = 0;
7819   dies[0] = cudie;
7820   args.cu = dies[0].cu;
7821   args.dbg = dbg;
7822   args.is_split = is_split;
7823 
7824   /* We might return here again for the split CU subdie.  */
7825   do_cu:
7826   do
7827     {
7828       Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7829       if (unlikely (offset == (Dwarf_Off) -1))
7830 	{
7831 	  if (!silent)
7832 	    error (0, 0, gettext ("cannot get DIE offset: %s"),
7833 		   dwarf_errmsg (-1));
7834 	  goto do_return;
7835 	}
7836 
7837       int tag = dwarf_tag (&dies[level]);
7838       if (unlikely (tag == DW_TAG_invalid))
7839 	{
7840 	  if (!silent)
7841 	    error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
7842 				  "] in section '%s': %s"),
7843 		   (uint64_t) offset, secname, dwarf_errmsg (-1));
7844 	  goto do_return;
7845 	}
7846 
7847       if (!silent)
7848 	{
7849 	  unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7850 	  if (is_split)
7851 	    printf (" {%6" PRIx64 "}  ", (uint64_t) offset);
7852 	  else
7853 	    printf (" [%6" PRIx64 "]  ", (uint64_t) offset);
7854 	  printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7855 		  dwarf_tag_name (tag), code);
7856 	}
7857 
7858       /* Print the attribute values.  */
7859       args.level = level;
7860       args.dies = dies;
7861       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7862 
7863       /* Make room for the next level's DIE.  */
7864       if (level + 1 == maxdies)
7865 	dies = (Dwarf_Die *) xrealloc (dies,
7866 				       (maxdies += 10)
7867 				       * sizeof (Dwarf_Die));
7868 
7869       int res = dwarf_child (&dies[level], &dies[level + 1]);
7870       if (res > 0)
7871 	{
7872 	  while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7873 	    if (level-- == 0)
7874 	      break;
7875 
7876 	  if (unlikely (res == -1))
7877 	    {
7878 	      if (!silent)
7879 		error (0, 0, gettext ("cannot get next DIE: %s\n"),
7880 		       dwarf_errmsg (-1));
7881 	      goto do_return;
7882 	    }
7883 	}
7884       else if (unlikely (res < 0))
7885 	{
7886 	  if (!silent)
7887 	    error (0, 0, gettext ("cannot get next DIE: %s"),
7888 		   dwarf_errmsg (-1));
7889 	  goto do_return;
7890 	}
7891       else
7892 	++level;
7893     }
7894   while (level >= 0);
7895 
7896   /* We might want to show the split compile unit if this was a skeleton.
7897      We need to scan it if we are requesting printing .debug_ranges for
7898      DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7899      section.  */
7900   if (unit_type == DW_UT_skeleton
7901       && ((!silent && show_split_units)
7902 	  || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7903     {
7904       Dwarf_Die subdie;
7905       if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7906 	  || dwarf_tag (&subdie) == DW_TAG_invalid)
7907 	{
7908 	  if (!silent)
7909 	    {
7910 	      Dwarf_Attribute dwo_at;
7911 	      const char *dwo_name =
7912 		(dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7913 					       &dwo_at))
7914 		 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7915 						   &dwo_at))
7916 		     ?: "<unknown>"));
7917 	      fprintf (stderr,
7918 		       "Could not find split unit '%s', id: %" PRIx64 "\n",
7919 		       dwo_name, unit_id);
7920 	    }
7921 	}
7922       else
7923 	{
7924 	  Dwarf_CU *split_cu = subdie.cu;
7925 	  dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7926 			&addrsize, &offsize, &unit_id, &subdie_off);
7927 	  Dwarf_Off offset = cu->start;
7928 
7929 	  if (!silent)
7930 	    {
7931 	      printf (gettext (" Split compilation unit at offset %"
7932 			       PRIu64 ":\n"
7933 			       " Version: %" PRIu16
7934 			       ", Abbreviation section offset: %" PRIu64
7935 			       ", Address size: %" PRIu8
7936 			       ", Offset size: %" PRIu8 "\n"),
7937 		      (uint64_t) offset, version, abbroffset,
7938 		      addrsize, offsize);
7939 	      printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7940 		      dwarf_unit_name (unit_type), unit_type);
7941 	      printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7942 	      printf ("\n");
7943 	    }
7944 
7945 	  unit_type = DW_UT_split_compile;
7946 	  is_split = true;
7947 	  level = 0;
7948 	  dies[0] = subdie;
7949 	  args.cu = dies[0].cu;
7950 	  args.dbg = split_cu->dbg;
7951 	  args.is_split = is_split;
7952 	  goto do_cu;
7953 	}
7954     }
7955 
7956   /* And again... */
7957   goto next_cu;
7958 
7959  do_return:
7960   free (dies);
7961 }
7962 
7963 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7964 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7965 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7966 {
7967   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
7968 }
7969 
7970 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7971 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7972 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7973 {
7974   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
7975 }
7976 
7977 
7978 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7979 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
7980 			    GElf_Ehdr *ehdr __attribute__ ((unused)),
7981 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7982 {
7983   printf (gettext ("\
7984 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
7985 	  elf_ndxscn (scn), section_name (ebl, shdr),
7986 	  (uint64_t) shdr->sh_offset);
7987 
7988   size_t address_size
7989     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7990 
7991   Dwarf_Lines *lines;
7992   size_t nlines;
7993   Dwarf_Off off, next_off = 0;
7994   Dwarf_CU *cu = NULL;
7995   while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
7996 			   &lines, &nlines) == 0)
7997     {
7998       Dwarf_Die cudie;
7999       if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8000 				       NULL, NULL, NULL, NULL) == 0)
8001 	printf (" CU [%" PRIx64 "] %s\n",
8002 		dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8003       else
8004 	{
8005 	  /* DWARF5 lines can be independent of any CU, but they probably
8006 	     are used by some CU.  Determine the CU this block is for.  */
8007 	  Dwarf_Off cuoffset;
8008 	  Dwarf_Off ncuoffset = 0;
8009 	  size_t hsize;
8010 	  while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8011 			       NULL, NULL, NULL) == 0)
8012 	    {
8013 	      if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8014 		continue;
8015 	      Dwarf_Attribute stmt_list;
8016 	      if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8017 		continue;
8018 	      Dwarf_Word lineoff;
8019 	      if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8020 		continue;
8021 	      if (lineoff == off)
8022 		{
8023 		  /* Found the CU.  */
8024 		  cu = cudie.cu;
8025 		  break;
8026 		}
8027 	    }
8028 
8029 	  if (cu != NULL)
8030 	    printf (" CU [%" PRIx64 "] %s\n",
8031 		    dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8032 	  else
8033 	    printf (" No CU\n");
8034 	}
8035 
8036       printf ("  line:col SBPE* disc isa op address"
8037 	      " (Statement Block Prologue Epilogue *End)\n");
8038       const char *last_file = "";
8039       for (size_t n = 0; n < nlines; n++)
8040 	{
8041 	  Dwarf_Line *line = dwarf_onesrcline (lines, n);
8042 	  if (line == NULL)
8043 	    {
8044 	      printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8045 	      continue;
8046 	    }
8047 	  Dwarf_Word mtime, length;
8048 	  const char *file = dwarf_linesrc (line, &mtime, &length);
8049 	  if (file == NULL)
8050 	    {
8051 	      printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8052 	      last_file = "";
8053 	    }
8054 	  else if (strcmp (last_file, file) != 0)
8055 	    {
8056 	      printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8057 		      file, mtime, length);
8058 	      last_file = file;
8059 	    }
8060 
8061 	  int lineno, colno;
8062 	  bool statement, endseq, block, prologue_end, epilogue_begin;
8063 	  unsigned int lineop, isa, disc;
8064 	  Dwarf_Addr address;
8065 	  dwarf_lineaddr (line, &address);
8066 	  dwarf_lineno (line, &lineno);
8067 	  dwarf_linecol (line, &colno);
8068 	  dwarf_lineop_index (line, &lineop);
8069 	  dwarf_linebeginstatement (line, &statement);
8070 	  dwarf_lineendsequence (line, &endseq);
8071 	  dwarf_lineblock (line, &block);
8072 	  dwarf_lineprologueend (line, &prologue_end);
8073 	  dwarf_lineepiloguebegin (line, &epilogue_begin);
8074 	  dwarf_lineisa (line, &isa);
8075 	  dwarf_linediscriminator (line, &disc);
8076 
8077 	  /* End sequence is special, it is one byte past.  */
8078 	  printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8079 		  lineno, colno,
8080 		  (statement ? 'S' : ' '),
8081 		  (block ? 'B' : ' '),
8082 		  (prologue_end ? 'P' : ' '),
8083 		  (epilogue_begin ? 'E' : ' '),
8084 		  (endseq ? '*' : ' '),
8085 		  disc, isa, lineop);
8086 	  print_dwarf_addr (dwflmod, address_size,
8087 			    address - (endseq ? 1 : 0), address);
8088 	  printf ("\n");
8089 
8090 	  if (endseq)
8091 	    printf("\n");
8092 	}
8093     }
8094 }
8095 
8096 
8097 /* Print the value of a form.
8098    Returns new value of readp, or readendp on failure.  */
8099 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)8100 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8101 		 const unsigned char *readendp, unsigned int offset_len,
8102 		 Dwarf_Off str_offsets_base)
8103 {
8104   Dwarf_Word val;
8105   unsigned char *endp;
8106   Elf_Data *data;
8107   char *str;
8108   switch (form)
8109     {
8110     case DW_FORM_data1:
8111       if (readendp - readp < 1)
8112 	{
8113 	invalid_data:
8114 	  error (0, 0, "invalid data");
8115 	  return readendp;
8116 	}
8117       val = *readp++;
8118       printf (" %" PRIx8, (unsigned int) val);
8119       break;
8120 
8121     case DW_FORM_data2:
8122       if (readendp - readp < 2)
8123 	goto invalid_data;
8124       val = read_2ubyte_unaligned_inc (dbg, readp);
8125       printf(" %" PRIx16, (unsigned int) val);
8126       break;
8127 
8128     case DW_FORM_data4:
8129       if (readendp - readp < 4)
8130 	goto invalid_data;
8131       val = read_4ubyte_unaligned_inc (dbg, readp);
8132       printf (" %" PRIx32, (unsigned int) val);
8133       break;
8134 
8135     case DW_FORM_data8:
8136       if (readendp - readp < 8)
8137 	goto invalid_data;
8138       val = read_8ubyte_unaligned_inc (dbg, readp);
8139       printf (" %" PRIx64, val);
8140       break;
8141 
8142     case DW_FORM_sdata:
8143       if (readendp - readp < 1)
8144 	goto invalid_data;
8145       get_sleb128 (val, readp, readendp);
8146       printf (" %" PRIx64, val);
8147       break;
8148 
8149     case DW_FORM_udata:
8150       if (readendp - readp < 1)
8151 	goto invalid_data;
8152       get_uleb128 (val, readp, readendp);
8153       printf (" %" PRIx64, val);
8154       break;
8155 
8156     case DW_FORM_block:
8157       if (readendp - readp < 1)
8158 	goto invalid_data;
8159       get_uleb128 (val, readp, readendp);
8160       if ((size_t) (readendp - readp) < val)
8161 	goto invalid_data;
8162       print_bytes (val, readp);
8163       readp += val;
8164       break;
8165 
8166     case DW_FORM_block1:
8167       if (readendp - readp < 1)
8168 	goto invalid_data;
8169       val = *readp++;
8170       if ((size_t) (readendp - readp) < val)
8171 	goto invalid_data;
8172       print_bytes (val, readp);
8173       readp += val;
8174       break;
8175 
8176     case DW_FORM_block2:
8177       if (readendp - readp < 2)
8178 	goto invalid_data;
8179       val = read_2ubyte_unaligned_inc (dbg, readp);
8180       if ((size_t) (readendp - readp) < val)
8181 	goto invalid_data;
8182       print_bytes (val, readp);
8183       readp += val;
8184       break;
8185 
8186     case DW_FORM_block4:
8187       if (readendp - readp < 4)
8188 	goto invalid_data;
8189       val = read_4ubyte_unaligned_inc (dbg, readp);
8190       if ((size_t) (readendp - readp) < val)
8191 	goto invalid_data;
8192       print_bytes (val, readp);
8193       readp += val;
8194       break;
8195 
8196     case DW_FORM_data16:
8197       if (readendp - readp < 16)
8198 	goto invalid_data;
8199       print_bytes (16, readp);
8200       readp += 16;
8201       break;
8202 
8203     case DW_FORM_flag:
8204       if (readendp - readp < 1)
8205 	goto invalid_data;
8206       val = *readp++;
8207       printf ("%s", val != 0 ? yes_str : no_str);
8208       break;
8209 
8210     case DW_FORM_string:
8211       endp = memchr (readp, '\0', readendp - readp);
8212       if (endp == NULL)
8213 	goto invalid_data;
8214       printf ("%s", readp);
8215       readp = endp + 1;
8216       break;
8217 
8218     case DW_FORM_strp:
8219     case DW_FORM_line_strp:
8220     case DW_FORM_strp_sup:
8221       if ((size_t) (readendp - readp) < offset_len)
8222 	goto invalid_data;
8223       if (offset_len == 8)
8224 	val = read_8ubyte_unaligned_inc (dbg, readp);
8225       else
8226 	val = read_4ubyte_unaligned_inc (dbg, readp);
8227       if (form == DW_FORM_strp)
8228 	data = dbg->sectiondata[IDX_debug_str];
8229       else if (form == DW_FORM_line_strp)
8230 	data = dbg->sectiondata[IDX_debug_line_str];
8231       else /* form == DW_FORM_strp_sup */
8232 	{
8233 	  Dwarf *alt = dwarf_getalt (dbg);
8234 	  data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8235 	}
8236       if (data == NULL || val >= data->d_size
8237 	  || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8238 	str = "???";
8239       else
8240 	str = (char *) data->d_buf + val;
8241       printf ("%s (%" PRIu64 ")", str, val);
8242       break;
8243 
8244     case DW_FORM_sec_offset:
8245       if ((size_t) (readendp - readp) < offset_len)
8246 	goto invalid_data;
8247       if (offset_len == 8)
8248 	val = read_8ubyte_unaligned_inc (dbg, readp);
8249       else
8250 	val = read_4ubyte_unaligned_inc (dbg, readp);
8251       printf ("[%" PRIx64 "]", val);
8252       break;
8253 
8254     case DW_FORM_strx:
8255     case DW_FORM_GNU_str_index:
8256       if (readendp - readp < 1)
8257 	goto invalid_data;
8258       get_uleb128 (val, readp, readendp);
8259     strx_val:
8260       data = dbg->sectiondata[IDX_debug_str_offsets];
8261       if (data == NULL
8262 	  || data->d_size - str_offsets_base < val)
8263 	str = "???";
8264       else
8265 	{
8266 	  const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8267 	  const unsigned char *strreadendp = data->d_buf + data->d_size;
8268 	  if ((size_t) (strreadendp - strreadp) < offset_len)
8269 	    str = "???";
8270 	  else
8271 	    {
8272 	      Dwarf_Off idx;
8273 	      if (offset_len == 8)
8274 		idx = read_8ubyte_unaligned (dbg, strreadp);
8275 	      else
8276 		idx = read_4ubyte_unaligned (dbg, strreadp);
8277 
8278 	      data = dbg->sectiondata[IDX_debug_str];
8279 	      if (data == NULL || idx >= data->d_size
8280 		  || memchr (data->d_buf + idx, '\0',
8281 			     data->d_size - idx) == NULL)
8282 		str = "???";
8283 	      else
8284 		str = (char *) data->d_buf + idx;
8285 	    }
8286 	}
8287       printf ("%s (%" PRIu64 ")", str, val);
8288       break;
8289 
8290     case DW_FORM_strx1:
8291       if (readendp - readp < 1)
8292 	goto invalid_data;
8293       val = *readp++;
8294       goto strx_val;
8295 
8296     case DW_FORM_strx2:
8297       if (readendp - readp < 2)
8298 	goto invalid_data;
8299       val = read_2ubyte_unaligned_inc (dbg, readp);
8300       goto strx_val;
8301 
8302     case DW_FORM_strx3:
8303       if (readendp - readp < 3)
8304 	goto invalid_data;
8305       val = read_3ubyte_unaligned_inc (dbg, readp);
8306       goto strx_val;
8307 
8308     case DW_FORM_strx4:
8309       if (readendp - readp < 4)
8310 	goto invalid_data;
8311       val = read_4ubyte_unaligned_inc (dbg, readp);
8312       goto strx_val;
8313 
8314     default:
8315       error (0, 0, gettext ("unknown form: %s"), dwarf_form_name (form));
8316       return readendp;
8317     }
8318 
8319   return readp;
8320 }
8321 
8322 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8323 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8324 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8325 {
8326   if (decodedline)
8327     {
8328       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8329       return;
8330     }
8331 
8332   printf (gettext ("\
8333 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8334 	  elf_ndxscn (scn), section_name (ebl, shdr),
8335 	  (uint64_t) shdr->sh_offset);
8336 
8337   if (shdr->sh_size == 0)
8338     return;
8339 
8340   /* There is no functionality in libdw to read the information in the
8341      way it is represented here.  Hardcode the decoder.  */
8342   Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8343 		    ?: elf_rawdata (scn, NULL));
8344   if (unlikely (data == NULL))
8345     {
8346       error (0, 0, gettext ("cannot get line data section data: %s"),
8347 	     elf_errmsg (-1));
8348       return;
8349     }
8350 
8351   const unsigned char *linep = (const unsigned char *) data->d_buf;
8352   const unsigned char *lineendp;
8353 
8354   while (linep
8355 	 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8356     {
8357       size_t start_offset = linep - (const unsigned char *) data->d_buf;
8358 
8359       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
8360 
8361       if (unlikely (linep + 4 > lineendp))
8362 	goto invalid_data;
8363       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8364       unsigned int length = 4;
8365       if (unlikely (unit_length == 0xffffffff))
8366 	{
8367 	  if (unlikely (linep + 8 > lineendp))
8368 	    {
8369 	    invalid_data:
8370 	      error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8371 		     elf_ndxscn (scn), section_name (ebl, shdr));
8372 	      return;
8373 	    }
8374 	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8375 	  length = 8;
8376 	}
8377 
8378       /* Check whether we have enough room in the section.  */
8379       if (unlikely (unit_length > (size_t) (lineendp - linep)))
8380 	goto invalid_data;
8381       lineendp = linep + unit_length;
8382 
8383       /* The next element of the header is the version identifier.  */
8384       if ((size_t) (lineendp - linep) < 2)
8385 	goto invalid_data;
8386       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8387 
8388       size_t address_size
8389 	= elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8390       unsigned char segment_selector_size = 0;
8391       if (version > 4)
8392 	{
8393 	  if ((size_t) (lineendp - linep) < 2)
8394 	    goto invalid_data;
8395 	  address_size = *linep++;
8396 	  segment_selector_size = *linep++;
8397 	}
8398 
8399       /* Next comes the header length.  */
8400       Dwarf_Word header_length;
8401       if (length == 4)
8402 	{
8403 	  if ((size_t) (lineendp - linep) < 4)
8404 	    goto invalid_data;
8405 	  header_length = read_4ubyte_unaligned_inc (dbg, linep);
8406 	}
8407       else
8408 	{
8409 	  if ((size_t) (lineendp - linep) < 8)
8410 	    goto invalid_data;
8411 	  header_length = read_8ubyte_unaligned_inc (dbg, linep);
8412 	}
8413 
8414       /* Next the minimum instruction length.  */
8415       if ((size_t) (lineendp - linep) < 1)
8416 	goto invalid_data;
8417       uint_fast8_t minimum_instr_len = *linep++;
8418 
8419       /* Next the maximum operations per instruction, in version 4 format.  */
8420       uint_fast8_t max_ops_per_instr;
8421       if (version < 4)
8422 	max_ops_per_instr = 1;
8423       else
8424 	{
8425 	  if ((size_t) (lineendp - linep) < 1)
8426 	    goto invalid_data;
8427 	  max_ops_per_instr = *linep++;
8428 	}
8429 
8430       /* We need at least 4 more bytes.  */
8431       if ((size_t) (lineendp - linep) < 4)
8432 	goto invalid_data;
8433 
8434       /* Then the flag determining the default value of the is_stmt
8435 	 register.  */
8436       uint_fast8_t default_is_stmt = *linep++;
8437 
8438       /* Now the line base.  */
8439       int_fast8_t line_base = (const char)*linep++;
8440 
8441       /* And the line range.  */
8442       uint_fast8_t line_range = *linep++;
8443 
8444       /* The opcode base.  */
8445       uint_fast8_t opcode_base = *linep++;
8446 
8447       /* Print what we got so far.  */
8448       printf (gettext ("\n"
8449 		       " Length:                         %" PRIu64 "\n"
8450 		       " DWARF version:                  %" PRIuFAST16 "\n"
8451 		       " Prologue length:                %" PRIu64 "\n"
8452 		       " Address size:                   %zd\n"
8453 		       " Segment selector size:          %zd\n"
8454 		       " Min instruction length:         %" PRIuFAST8 "\n"
8455 		       " Max operations per instruction: %" PRIuFAST8 "\n"
8456 		       " Initial value if 'is_stmt':     %" PRIuFAST8 "\n"
8457 		       " Line base:                      %" PRIdFAST8 "\n"
8458 		       " Line range:                     %" PRIuFAST8 "\n"
8459 		       " Opcode base:                    %" PRIuFAST8 "\n"
8460 		       "\n"
8461 		       "Opcodes:\n"),
8462 	      (uint64_t) unit_length, version, (uint64_t) header_length,
8463 	      address_size, (size_t) segment_selector_size,
8464 	      minimum_instr_len, max_ops_per_instr,
8465 	      default_is_stmt, line_base,
8466 	      line_range, opcode_base);
8467 
8468       if (version < 2 || version > 5)
8469 	{
8470 	  error (0, 0, gettext ("cannot handle .debug_line version: %u\n"),
8471 		 (unsigned int) version);
8472 	  linep = lineendp;
8473 	  continue;
8474 	}
8475 
8476       if (address_size != 4 && address_size != 8)
8477 	{
8478 	  error (0, 0, gettext ("cannot handle address size: %u\n"),
8479 		 (unsigned int) address_size);
8480 	  linep = lineendp;
8481 	  continue;
8482 	}
8483 
8484       if (segment_selector_size != 0)
8485 	{
8486 	  error (0, 0, gettext ("cannot handle segment selector size: %u\n"),
8487 		 (unsigned int) segment_selector_size);
8488 	  linep = lineendp;
8489 	  continue;
8490 	}
8491 
8492       if (unlikely (linep + opcode_base - 1 >= lineendp))
8493 	{
8494 	invalid_unit:
8495 	  error (0, 0,
8496 		 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
8497 		 linep - (const unsigned char *) data->d_buf,
8498 		 elf_ndxscn (scn), section_name (ebl, shdr));
8499 	  linep = lineendp;
8500 	  continue;
8501 	}
8502       int opcode_base_l10 = 1;
8503       unsigned int tmp = opcode_base;
8504       while (tmp > 10)
8505 	{
8506 	  tmp /= 10;
8507 	  ++opcode_base_l10;
8508 	}
8509       const uint8_t *standard_opcode_lengths = linep - 1;
8510       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8511 	printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
8512 			  "  [%*" PRIuFAST8 "]  %hhu arguments\n",
8513 			  (int) linep[cnt - 1]),
8514 		opcode_base_l10, cnt, linep[cnt - 1]);
8515       linep += opcode_base - 1;
8516 
8517       if (unlikely (linep >= lineendp))
8518 	goto invalid_unit;
8519 
8520       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8521 
8522       puts (gettext ("\nDirectory table:"));
8523       if (version > 4)
8524 	{
8525 	  struct encpair { uint16_t desc; uint16_t form; };
8526 	  struct encpair enc[256];
8527 
8528 	  printf (gettext ("      ["));
8529 	  if ((size_t) (lineendp - linep) < 1)
8530 	    goto invalid_data;
8531 	  unsigned char directory_entry_format_count = *linep++;
8532 	  for (int i = 0; i < directory_entry_format_count; i++)
8533 	    {
8534 	      uint16_t desc, form;
8535 	      if ((size_t) (lineendp - linep) < 1)
8536 		goto invalid_data;
8537 	      get_uleb128 (desc, linep, lineendp);
8538 	      if ((size_t) (lineendp - linep) < 1)
8539 		goto invalid_data;
8540 	      get_uleb128 (form, linep, lineendp);
8541 
8542 	      enc[i].desc = desc;
8543 	      enc[i].form = form;
8544 
8545 	      printf ("%s(%s)",
8546 		      dwarf_line_content_description_name (desc),
8547 		      dwarf_form_name (form));
8548 	      if (i + 1 < directory_entry_format_count)
8549 		printf (", ");
8550 	    }
8551 	  printf ("]\n");
8552 
8553 	  uint64_t directories_count;
8554 	  if ((size_t) (lineendp - linep) < 1)
8555             goto invalid_data;
8556 	  get_uleb128 (directories_count, linep, lineendp);
8557 
8558 	  if (directory_entry_format_count == 0
8559 	      && directories_count != 0)
8560 	    goto invalid_data;
8561 
8562 	  for (uint64_t i = 0; i < directories_count; i++)
8563 	    {
8564 	      printf (" %-5" PRIu64 " ", i);
8565 	      for (int j = 0; j < directory_entry_format_count; j++)
8566 		{
8567 		  linep = print_form_data (dbg, enc[j].form,
8568 					   linep, lineendp, length,
8569 					   str_offsets_base);
8570 		  if (j + 1 < directory_entry_format_count)
8571 		    printf (", ");
8572 		}
8573 	      printf ("\n");
8574 	      if (linep >= lineendp)
8575 		goto invalid_unit;
8576 	    }
8577 	}
8578       else
8579 	{
8580 	  while (linep < lineendp && *linep != 0)
8581 	    {
8582 	      unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8583 	      if (unlikely (endp == NULL))
8584 		goto invalid_unit;
8585 
8586 	      printf (" %s\n", (char *) linep);
8587 
8588 	      linep = endp + 1;
8589 	    }
8590 	  if (linep >= lineendp || *linep != 0)
8591 	    goto invalid_unit;
8592 	  /* Skip the final NUL byte.  */
8593 	  ++linep;
8594 	}
8595 
8596       if (unlikely (linep >= lineendp))
8597 	goto invalid_unit;
8598 
8599       puts (gettext ("\nFile name table:"));
8600       if (version > 4)
8601 	{
8602 	  struct encpair { uint16_t desc; uint16_t form; };
8603 	  struct encpair enc[256];
8604 
8605 	  printf (gettext ("      ["));
8606 	  if ((size_t) (lineendp - linep) < 1)
8607 	    goto invalid_data;
8608 	  unsigned char file_name_format_count = *linep++;
8609 	  for (int i = 0; i < file_name_format_count; i++)
8610 	    {
8611 	      uint64_t desc, form;
8612 	      if ((size_t) (lineendp - linep) < 1)
8613 		goto invalid_data;
8614 	      get_uleb128 (desc, linep, lineendp);
8615 	      if ((size_t) (lineendp - linep) < 1)
8616 		goto invalid_data;
8617 	      get_uleb128 (form, linep, lineendp);
8618 
8619 	      if (! libdw_valid_user_form (form))
8620 		goto invalid_data;
8621 
8622 	      enc[i].desc = desc;
8623 	      enc[i].form = form;
8624 
8625 	      printf ("%s(%s)",
8626 		      dwarf_line_content_description_name (desc),
8627 		      dwarf_form_name (form));
8628 	      if (i + 1 < file_name_format_count)
8629 		printf (", ");
8630 	    }
8631 	  printf ("]\n");
8632 
8633 	  uint64_t file_name_count;
8634 	  if ((size_t) (lineendp - linep) < 1)
8635             goto invalid_data;
8636 	  get_uleb128 (file_name_count, linep, lineendp);
8637 
8638 	  if (file_name_format_count == 0
8639 	      && file_name_count != 0)
8640 	    goto invalid_data;
8641 
8642 	  for (uint64_t i = 0; i < file_name_count; i++)
8643 	    {
8644 	      printf (" %-5" PRIu64 " ", i);
8645 	      for (int j = 0; j < file_name_format_count; j++)
8646 		{
8647 		  linep = print_form_data (dbg, enc[j].form,
8648 					   linep, lineendp, length,
8649 					   str_offsets_base);
8650 		  if (j + 1 < file_name_format_count)
8651 		    printf (", ");
8652 		}
8653 	      printf ("\n");
8654 	      if (linep >= lineendp)
8655 		goto invalid_unit;
8656 	    }
8657 	}
8658       else
8659 	{
8660 	  puts (gettext (" Entry Dir   Time      Size      Name"));
8661 	  for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8662 	    {
8663 	      /* First comes the file name.  */
8664 	      char *fname = (char *) linep;
8665 	      unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8666 	      if (unlikely (endp == NULL))
8667 		goto invalid_unit;
8668 	      linep = endp + 1;
8669 
8670 	      /* Then the index.  */
8671 	      unsigned int diridx;
8672 	      if (lineendp - linep < 1)
8673 		goto invalid_unit;
8674 	      get_uleb128 (diridx, linep, lineendp);
8675 
8676 	      /* Next comes the modification time.  */
8677 	      unsigned int mtime;
8678 	      if (lineendp - linep < 1)
8679 		goto invalid_unit;
8680 	      get_uleb128 (mtime, linep, lineendp);
8681 
8682 	      /* Finally the length of the file.  */
8683 	      unsigned int fsize;
8684 	      if (lineendp - linep < 1)
8685 		goto invalid_unit;
8686 	      get_uleb128 (fsize, linep, lineendp);
8687 
8688 	      printf (" %-5u %-5u %-9u %-9u %s\n",
8689 		      cnt, diridx, mtime, fsize, fname);
8690 	    }
8691 	  if (linep >= lineendp || *linep != '\0')
8692 	    goto invalid_unit;
8693 	  /* Skip the final NUL byte.  */
8694 	  ++linep;
8695 	}
8696 
8697       puts (gettext ("\nLine number statements:"));
8698       Dwarf_Word address = 0;
8699       unsigned int op_index = 0;
8700       size_t line = 1;
8701       uint_fast8_t is_stmt = default_is_stmt;
8702 
8703       /* Apply the "operation advance" from a special opcode
8704 	 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
8705       unsigned int op_addr_advance;
8706       bool show_op_index;
8707       inline void advance_pc (unsigned int op_advance)
8708       {
8709 	op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8710 					       / max_ops_per_instr);
8711 	address += op_addr_advance;
8712 	show_op_index = (op_index > 0 ||
8713 			 (op_index + op_advance) % max_ops_per_instr > 0);
8714 	op_index = (op_index + op_advance) % max_ops_per_instr;
8715       }
8716 
8717       if (max_ops_per_instr == 0)
8718 	{
8719 	  error (0, 0,
8720 		 gettext ("invalid maximum operations per instruction is zero"));
8721 	  linep = lineendp;
8722 	  continue;
8723 	}
8724 
8725       while (linep < lineendp)
8726 	{
8727 	  size_t offset = linep - (const unsigned char *) data->d_buf;
8728 	  unsigned int u128;
8729 	  int s128;
8730 
8731 	  /* Read the opcode.  */
8732 	  unsigned int opcode = *linep++;
8733 
8734 	  printf (" [%6" PRIx64 "]", (uint64_t)offset);
8735 	  /* Is this a special opcode?  */
8736 	  if (likely (opcode >= opcode_base))
8737 	    {
8738 	      if (unlikely (line_range == 0))
8739 		goto invalid_unit;
8740 
8741 	      /* Yes.  Handling this is quite easy since the opcode value
8742 		 is computed with
8743 
8744 		 opcode = (desired line increment - line_base)
8745 			   + (line_range * address advance) + opcode_base
8746 	      */
8747 	      int line_increment = (line_base
8748 				    + (opcode - opcode_base) % line_range);
8749 
8750 	      /* Perform the increments.  */
8751 	      line += line_increment;
8752 	      advance_pc ((opcode - opcode_base) / line_range);
8753 
8754 	      printf (gettext (" special opcode %u: address+%u = "),
8755 		      opcode, op_addr_advance);
8756 	      print_dwarf_addr (dwflmod, 0, address, address);
8757 	      if (show_op_index)
8758 		printf (gettext (", op_index = %u, line%+d = %zu\n"),
8759 			op_index, line_increment, line);
8760 	      else
8761 		printf (gettext (", line%+d = %zu\n"),
8762 			line_increment, line);
8763 	    }
8764 	  else if (opcode == 0)
8765 	    {
8766 	      /* This an extended opcode.  */
8767 	      if (unlikely (linep + 2 > lineendp))
8768 		goto invalid_unit;
8769 
8770 	      /* The length.  */
8771 	      unsigned int len = *linep++;
8772 
8773 	      if (unlikely (linep + len > lineendp))
8774 		goto invalid_unit;
8775 
8776 	      /* The sub-opcode.  */
8777 	      opcode = *linep++;
8778 
8779 	      printf (gettext (" extended opcode %u: "), opcode);
8780 
8781 	      switch (opcode)
8782 		{
8783 		case DW_LNE_end_sequence:
8784 		  puts (gettext (" end of sequence"));
8785 
8786 		  /* Reset the registers we care about.  */
8787 		  address = 0;
8788 		  op_index = 0;
8789 		  line = 1;
8790 		  is_stmt = default_is_stmt;
8791 		  break;
8792 
8793 		case DW_LNE_set_address:
8794 		  op_index = 0;
8795 		  if (unlikely ((size_t) (lineendp - linep) < address_size))
8796 		    goto invalid_unit;
8797 		  if (address_size == 4)
8798 		    address = read_4ubyte_unaligned_inc (dbg, linep);
8799 		  else
8800 		    address = read_8ubyte_unaligned_inc (dbg, linep);
8801 		  {
8802 		    printf (gettext (" set address to "));
8803 		    print_dwarf_addr (dwflmod, 0, address, address);
8804 		    printf ("\n");
8805 		  }
8806 		  break;
8807 
8808 		case DW_LNE_define_file:
8809 		  {
8810 		    char *fname = (char *) linep;
8811 		    unsigned char *endp = memchr (linep, '\0',
8812 						  lineendp - linep);
8813 		    if (unlikely (endp == NULL))
8814 		      goto invalid_unit;
8815 		    linep = endp + 1;
8816 
8817 		    unsigned int diridx;
8818 		    if (lineendp - linep < 1)
8819 		      goto invalid_unit;
8820 		    get_uleb128 (diridx, linep, lineendp);
8821 		    Dwarf_Word mtime;
8822 		    if (lineendp - linep < 1)
8823 		      goto invalid_unit;
8824 		    get_uleb128 (mtime, linep, lineendp);
8825 		    Dwarf_Word filelength;
8826 		    if (lineendp - linep < 1)
8827 		      goto invalid_unit;
8828 		    get_uleb128 (filelength, linep, lineendp);
8829 
8830 		    printf (gettext ("\
8831  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8832 			    diridx, (uint64_t) mtime, (uint64_t) filelength,
8833 			    fname);
8834 		  }
8835 		  break;
8836 
8837 		case DW_LNE_set_discriminator:
8838 		  /* Takes one ULEB128 parameter, the discriminator.  */
8839 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8840 				|| lineendp - linep < 1))
8841 		    goto invalid_unit;
8842 
8843 		  get_uleb128 (u128, linep, lineendp);
8844 		  printf (gettext (" set discriminator to %u\n"), u128);
8845 		  break;
8846 
8847 		default:
8848 		  /* Unknown, ignore it.  */
8849 		  puts (gettext (" unknown opcode"));
8850 		  linep += len - 1;
8851 		  break;
8852 		}
8853 	    }
8854 	  else if (opcode <= DW_LNS_set_isa)
8855 	    {
8856 	      /* This is a known standard opcode.  */
8857 	      switch (opcode)
8858 		{
8859 		case DW_LNS_copy:
8860 		  /* Takes no argument.  */
8861 		  puts (gettext (" copy"));
8862 		  break;
8863 
8864 		case DW_LNS_advance_pc:
8865 		  /* Takes one uleb128 parameter which is added to the
8866 		     address.  */
8867 		  if (lineendp - linep < 1)
8868 		    goto invalid_unit;
8869 		  get_uleb128 (u128, linep, lineendp);
8870 		  advance_pc (u128);
8871 		  {
8872 		    printf (gettext (" advance address by %u to "),
8873 			    op_addr_advance);
8874 		    print_dwarf_addr (dwflmod, 0, address, address);
8875 		    if (show_op_index)
8876 		      printf (gettext (", op_index to %u"), op_index);
8877 		    printf ("\n");
8878 		  }
8879 		  break;
8880 
8881 		case DW_LNS_advance_line:
8882 		  /* Takes one sleb128 parameter which is added to the
8883 		     line.  */
8884 		  if (lineendp - linep < 1)
8885 		    goto invalid_unit;
8886 		  get_sleb128 (s128, linep, lineendp);
8887 		  line += s128;
8888 		  printf (gettext ("\
8889  advance line by constant %d to %" PRId64 "\n"),
8890 			  s128, (int64_t) line);
8891 		  break;
8892 
8893 		case DW_LNS_set_file:
8894 		  /* Takes one uleb128 parameter which is stored in file.  */
8895 		  if (lineendp - linep < 1)
8896 		    goto invalid_unit;
8897 		  get_uleb128 (u128, linep, lineendp);
8898 		  printf (gettext (" set file to %" PRIu64 "\n"),
8899 			  (uint64_t) u128);
8900 		  break;
8901 
8902 		case DW_LNS_set_column:
8903 		  /* Takes one uleb128 parameter which is stored in column.  */
8904 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8905 				|| lineendp - linep < 1))
8906 		    goto invalid_unit;
8907 
8908 		  get_uleb128 (u128, linep, lineendp);
8909 		  printf (gettext (" set column to %" PRIu64 "\n"),
8910 			  (uint64_t) u128);
8911 		  break;
8912 
8913 		case DW_LNS_negate_stmt:
8914 		  /* Takes no argument.  */
8915 		  is_stmt = 1 - is_stmt;
8916 		  printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8917 			  "is_stmt", is_stmt);
8918 		  break;
8919 
8920 		case DW_LNS_set_basic_block:
8921 		  /* Takes no argument.  */
8922 		  puts (gettext (" set basic block flag"));
8923 		  break;
8924 
8925 		case DW_LNS_const_add_pc:
8926 		  /* Takes no argument.  */
8927 
8928 		  if (unlikely (line_range == 0))
8929 		    goto invalid_unit;
8930 
8931 		  advance_pc ((255 - opcode_base) / line_range);
8932 		  {
8933 		    printf (gettext (" advance address by constant %u to "),
8934 			    op_addr_advance);
8935 		    print_dwarf_addr (dwflmod, 0, address, address);
8936 		    if (show_op_index)
8937 		      printf (gettext (", op_index to %u"), op_index);
8938 		    printf ("\n");
8939 		  }
8940 		  break;
8941 
8942 		case DW_LNS_fixed_advance_pc:
8943 		  /* Takes one 16 bit parameter which is added to the
8944 		     address.  */
8945 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8946 				|| lineendp - linep < 2))
8947 		    goto invalid_unit;
8948 
8949 		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
8950 		  address += u128;
8951 		  op_index = 0;
8952 		  {
8953 		    printf (gettext ("\
8954  advance address by fixed value %u to \n"),
8955 			    u128);
8956 		    print_dwarf_addr (dwflmod, 0, address, address);
8957 		    printf ("\n");
8958 		  }
8959 		  break;
8960 
8961 		case DW_LNS_set_prologue_end:
8962 		  /* Takes no argument.  */
8963 		  puts (gettext (" set prologue end flag"));
8964 		  break;
8965 
8966 		case DW_LNS_set_epilogue_begin:
8967 		  /* Takes no argument.  */
8968 		  puts (gettext (" set epilogue begin flag"));
8969 		  break;
8970 
8971 		case DW_LNS_set_isa:
8972 		  /* Takes one uleb128 parameter which is stored in isa.  */
8973 		  if (unlikely (standard_opcode_lengths[opcode] != 1
8974 				|| lineendp - linep < 1))
8975 		    goto invalid_unit;
8976 
8977 		  get_uleb128 (u128, linep, lineendp);
8978 		  printf (gettext (" set isa to %u\n"), u128);
8979 		  break;
8980 		}
8981 	    }
8982 	  else
8983 	    {
8984 	      /* This is a new opcode the generator but not we know about.
8985 		 Read the parameters associated with it but then discard
8986 		 everything.  Read all the parameters for this opcode.  */
8987 	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8988 				" unknown opcode with %" PRIu8 " parameters:",
8989 				standard_opcode_lengths[opcode]),
8990 		      standard_opcode_lengths[opcode]);
8991 	      for (int n = standard_opcode_lengths[opcode];
8992 		   n > 0 && linep < lineendp; --n)
8993 		{
8994 		  get_uleb128 (u128, linep, lineendp);
8995 		  if (n != standard_opcode_lengths[opcode])
8996 		    putc_unlocked (',', stdout);
8997 		  printf (" %u", u128);
8998 		}
8999 
9000 	      /* Next round, ignore this opcode.  */
9001 	      continue;
9002 	    }
9003 	}
9004     }
9005 
9006   /* There must only be one data block.  */
9007   assert (elf_getdata (scn, data) == NULL);
9008 }
9009 
9010 
9011 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9012 print_debug_loclists_section (Dwfl_Module *dwflmod,
9013 			      Ebl *ebl,
9014 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
9015 			      Elf_Scn *scn, GElf_Shdr *shdr,
9016 			      Dwarf *dbg)
9017 {
9018   printf (gettext ("\
9019 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9020 	  elf_ndxscn (scn), section_name (ebl, shdr),
9021 	  (uint64_t) shdr->sh_offset);
9022 
9023   Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9024 		    ?: elf_rawdata (scn, NULL));
9025   if (unlikely (data == NULL))
9026     {
9027       error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
9028 	     elf_errmsg (-1));
9029       return;
9030     }
9031 
9032   /* For the listptr to get the base address/CU.  */
9033   sort_listptr (&known_loclistsptr, "loclistsptr");
9034   size_t listptr_idx = 0;
9035 
9036   const unsigned char *readp = data->d_buf;
9037   const unsigned char *const dataend = ((unsigned char *) data->d_buf
9038 					+ data->d_size);
9039   while (readp < dataend)
9040     {
9041       if (unlikely (readp > dataend - 4))
9042 	{
9043 	invalid_data:
9044 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
9045 		 elf_ndxscn (scn), section_name (ebl, shdr));
9046 	  return;
9047 	}
9048 
9049       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9050       printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
9051 	      (uint64_t) offset);
9052 
9053       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9054       unsigned int offset_size = 4;
9055       if (unlikely (unit_length == 0xffffffff))
9056 	{
9057 	  if (unlikely (readp > dataend - 8))
9058 	    goto invalid_data;
9059 
9060 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9061 	  offset_size = 8;
9062 	}
9063       printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
9064 
9065       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9066 	 bytes to complete the header.  And this unit cannot go beyond
9067 	 the section data.  */
9068       if (readp > dataend - 8
9069 	  || unit_length < 8
9070 	  || unit_length > (uint64_t) (dataend - readp))
9071 	goto invalid_data;
9072 
9073       const unsigned char *nexthdr = readp + unit_length;
9074 
9075       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9076       printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
9077 
9078       if (version != 5)
9079 	{
9080 	  error (0, 0, gettext ("Unknown version"));
9081 	  goto next_table;
9082 	}
9083 
9084       uint8_t address_size = *readp++;
9085       printf (gettext (" Address size:   %8" PRIu64 "\n"),
9086 	      (uint64_t) address_size);
9087 
9088       if (address_size != 4 && address_size != 8)
9089 	{
9090 	  error (0, 0, gettext ("unsupported address size"));
9091 	  goto next_table;
9092 	}
9093 
9094       uint8_t segment_size = *readp++;
9095       printf (gettext (" Segment size:   %8" PRIu64 "\n"),
9096 	      (uint64_t) segment_size);
9097 
9098       if (segment_size != 0)
9099         {
9100           error (0, 0, gettext ("unsupported segment size"));
9101           goto next_table;
9102         }
9103 
9104       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9105       printf (gettext (" Offset entries: %8" PRIu64 "\n"),
9106 	      (uint64_t) offset_entry_count);
9107 
9108       /* We need the CU that uses this unit to get the initial base address. */
9109       Dwarf_Addr cu_base = 0;
9110       struct Dwarf_CU *cu = NULL;
9111       if (listptr_cu (&known_loclistsptr, &listptr_idx,
9112 		      (Dwarf_Off) offset,
9113 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9114 		      &cu_base, &cu)
9115 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
9116 	{
9117 	  Dwarf_Die cudie;
9118 	  if (dwarf_cu_die (cu, &cudie,
9119 			    NULL, NULL, NULL, NULL,
9120 			    NULL, NULL) == NULL)
9121 	    printf (gettext (" Unknown CU base: "));
9122 	  else
9123 	    printf (gettext (" CU [%6" PRIx64 "] base: "),
9124 		    dwarf_dieoffset (&cudie));
9125 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9126 	  printf ("\n");
9127 	}
9128       else
9129 	printf (gettext (" Not associated with a CU.\n"));
9130 
9131       printf ("\n");
9132 
9133       const unsigned char *offset_array_start = readp;
9134       if (offset_entry_count > 0)
9135 	{
9136 	  uint64_t max_entries = (unit_length - 8) / offset_size;
9137 	  if (offset_entry_count > max_entries)
9138 	    {
9139 	      error (0, 0,
9140 		     gettext ("too many offset entries for unit length"));
9141 	      offset_entry_count = max_entries;
9142 	    }
9143 
9144 	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
9145 		  (uint64_t) (offset_array_start
9146 			      - (unsigned char *) data->d_buf));
9147 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9148 	    {
9149 	      printf ("   [%6" PRIu32 "] ", idx);
9150 	      if (offset_size == 4)
9151 		{
9152 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9153 		  printf ("0x%" PRIx32 "\n", off);
9154 		}
9155 	      else
9156 		{
9157 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9158 		  printf ("0x%" PRIx64 "\n", off);
9159 		}
9160 	    }
9161 	  printf ("\n");
9162 	}
9163 
9164       Dwarf_Addr base = cu_base;
9165       bool start_of_list = true;
9166       while (readp < nexthdr)
9167 	{
9168 	  uint8_t kind = *readp++;
9169 	  uint64_t op1, op2, len;
9170 
9171 	  /* Skip padding.  */
9172 	  if (start_of_list && kind == DW_LLE_end_of_list)
9173 	    continue;
9174 
9175 	  if (start_of_list)
9176 	    {
9177 	      base = cu_base;
9178 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9179 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9180 		      (uint64_t) (readp - offset_array_start - 1));
9181 	      start_of_list = false;
9182 	    }
9183 
9184 	  printf ("    %s", dwarf_loc_list_encoding_name (kind));
9185 	  switch (kind)
9186 	    {
9187 	    case DW_LLE_end_of_list:
9188 	      start_of_list = true;
9189 	      printf ("\n\n");
9190 	      break;
9191 
9192 	    case DW_LLE_base_addressx:
9193 	      if ((uint64_t) (nexthdr - readp) < 1)
9194 		{
9195 		invalid_entry:
9196 		  error (0, 0, gettext ("invalid loclists data"));
9197 		  goto next_table;
9198 		}
9199 	      get_uleb128 (op1, readp, nexthdr);
9200 	      printf (" %" PRIx64 "\n", op1);
9201 	      if (! print_unresolved_addresses)
9202 		{
9203 		  Dwarf_Addr addr;
9204 		  if (get_indexed_addr (cu, op1, &addr) != 0)
9205 		    printf ("      ???\n");
9206 		  else
9207 		    {
9208 		      printf ("      ");
9209 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
9210 		      printf ("\n");
9211 		    }
9212 		}
9213 	      break;
9214 
9215 	    case DW_LLE_startx_endx:
9216 	      if ((uint64_t) (nexthdr - readp) < 1)
9217 		goto invalid_entry;
9218 	      get_uleb128 (op1, readp, nexthdr);
9219 	      if ((uint64_t) (nexthdr - readp) < 1)
9220 		goto invalid_entry;
9221 	      get_uleb128 (op2, readp, nexthdr);
9222 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9223 	      if (! print_unresolved_addresses)
9224 		{
9225 		  Dwarf_Addr addr1;
9226 		  Dwarf_Addr addr2;
9227 		  if (get_indexed_addr (cu, op1, &addr1) != 0
9228 		      || get_indexed_addr (cu, op2, &addr2) != 0)
9229 		    {
9230 		      printf ("      ???..\n");
9231 		      printf ("      ???\n");
9232 		    }
9233 		  else
9234 		    {
9235 		      printf ("      ");
9236 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9237 		      printf ("..\n      ");
9238 		      print_dwarf_addr (dwflmod, address_size,
9239 					addr2 - 1, addr2);
9240 		      printf ("\n");
9241 		    }
9242 		}
9243 	      if ((uint64_t) (nexthdr - readp) < 1)
9244 		goto invalid_entry;
9245 	      get_uleb128 (len, readp, nexthdr);
9246 	      if ((uint64_t) (nexthdr - readp) < len)
9247 		goto invalid_entry;
9248 	      print_ops (dwflmod, dbg, 8, 8, version,
9249 			 address_size, offset_size, cu, len, readp);
9250 	      readp += len;
9251 	      break;
9252 
9253 	    case DW_LLE_startx_length:
9254 	      if ((uint64_t) (nexthdr - readp) < 1)
9255 		goto invalid_entry;
9256 	      get_uleb128 (op1, readp, nexthdr);
9257 	      if ((uint64_t) (nexthdr - readp) < 1)
9258 		goto invalid_entry;
9259 	      get_uleb128 (op2, readp, nexthdr);
9260 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9261 	      if (! print_unresolved_addresses)
9262 		{
9263 		  Dwarf_Addr addr1;
9264 		  Dwarf_Addr addr2;
9265 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
9266 		    {
9267 		      printf ("      ???..\n");
9268 		      printf ("      ???\n");
9269 		    }
9270 		  else
9271 		    {
9272 		      addr2 = addr1 + op2;
9273 		      printf ("      ");
9274 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9275 		      printf ("..\n      ");
9276 		      print_dwarf_addr (dwflmod, address_size,
9277 					addr2 - 1, addr2);
9278 		      printf ("\n");
9279 		    }
9280 		}
9281 	      if ((uint64_t) (nexthdr - readp) < 1)
9282 		goto invalid_entry;
9283 	      get_uleb128 (len, readp, nexthdr);
9284 	      if ((uint64_t) (nexthdr - readp) < len)
9285 		goto invalid_entry;
9286 	      print_ops (dwflmod, dbg, 8, 8, version,
9287 			 address_size, offset_size, cu, len, readp);
9288 	      readp += len;
9289 	      break;
9290 
9291 	    case DW_LLE_offset_pair:
9292 	      if ((uint64_t) (nexthdr - readp) < 1)
9293 		goto invalid_entry;
9294 	      get_uleb128 (op1, readp, nexthdr);
9295 	      if ((uint64_t) (nexthdr - readp) < 1)
9296 		goto invalid_entry;
9297 	      get_uleb128 (op2, readp, nexthdr);
9298 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9299 	      if (! print_unresolved_addresses)
9300 		{
9301 		  op1 += base;
9302 		  op2 += base;
9303 		  printf ("      ");
9304 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9305 		  printf ("..\n      ");
9306 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9307 		  printf ("\n");
9308 		}
9309 	      if ((uint64_t) (nexthdr - readp) < 1)
9310 		goto invalid_entry;
9311 	      get_uleb128 (len, readp, nexthdr);
9312 	      if ((uint64_t) (nexthdr - readp) < len)
9313 		goto invalid_entry;
9314 	      print_ops (dwflmod, dbg, 8, 8, version,
9315 			 address_size, offset_size, cu, len, readp);
9316 	      readp += len;
9317 	      break;
9318 
9319 	    case DW_LLE_default_location:
9320 	      if ((uint64_t) (nexthdr - readp) < 1)
9321 		goto invalid_entry;
9322 	      get_uleb128 (len, readp, nexthdr);
9323 	      if ((uint64_t) (nexthdr - readp) < len)
9324 		goto invalid_entry;
9325 	      print_ops (dwflmod, dbg, 8, 8, version,
9326 			 address_size, offset_size, cu, len, readp);
9327 	      readp += len;
9328 	      break;
9329 
9330 	    case DW_LLE_base_address:
9331 	      if (address_size == 4)
9332 		{
9333 		  if ((uint64_t) (nexthdr - readp) < 4)
9334 		    goto invalid_entry;
9335 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9336 		}
9337 	      else
9338 		{
9339 		  if ((uint64_t) (nexthdr - readp) < 8)
9340 		    goto invalid_entry;
9341 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9342 		}
9343 	      base = op1;
9344 	      printf (" 0x%" PRIx64 "\n", base);
9345 	      if (! print_unresolved_addresses)
9346 		{
9347 		  printf ("      ");
9348 		  print_dwarf_addr (dwflmod, address_size, base, base);
9349 		  printf ("\n");
9350 		}
9351 	      break;
9352 
9353 	    case DW_LLE_start_end:
9354 	      if (address_size == 4)
9355 		{
9356 		  if ((uint64_t) (nexthdr - readp) < 8)
9357 		    goto invalid_entry;
9358 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9359 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
9360 		}
9361 	      else
9362 		{
9363 		  if ((uint64_t) (nexthdr - readp) < 16)
9364 		    goto invalid_entry;
9365 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9366 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
9367 		}
9368 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9369 	      if (! print_unresolved_addresses)
9370 		{
9371 		  printf ("      ");
9372 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9373 		  printf ("..\n      ");
9374 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9375 		  printf ("\n");
9376 		}
9377 	      if ((uint64_t) (nexthdr - readp) < 1)
9378 		goto invalid_entry;
9379 	      get_uleb128 (len, readp, nexthdr);
9380 	      if ((uint64_t) (nexthdr - readp) < len)
9381 		goto invalid_entry;
9382 	      print_ops (dwflmod, dbg, 8, 8, version,
9383 			 address_size, offset_size, cu, len, readp);
9384 	      readp += len;
9385 	      break;
9386 
9387 	    case DW_LLE_start_length:
9388 	      if (address_size == 4)
9389 		{
9390 		  if ((uint64_t) (nexthdr - readp) < 4)
9391 		    goto invalid_entry;
9392 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
9393 		}
9394 	      else
9395 		{
9396 		  if ((uint64_t) (nexthdr - readp) < 8)
9397 		    goto invalid_entry;
9398 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
9399 		}
9400 	      if ((uint64_t) (nexthdr - readp) < 1)
9401 		goto invalid_entry;
9402 	      get_uleb128 (op2, readp, nexthdr);
9403 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9404 	      if (! print_unresolved_addresses)
9405 		{
9406 		  op2 = op1 + op2;
9407 		  printf ("      ");
9408 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
9409 		  printf ("..\n      ");
9410 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9411 		  printf ("\n");
9412 		}
9413 	      if ((uint64_t) (nexthdr - readp) < 1)
9414 		goto invalid_entry;
9415 	      get_uleb128 (len, readp, nexthdr);
9416 	      if ((uint64_t) (nexthdr - readp) < len)
9417 		goto invalid_entry;
9418 	      print_ops (dwflmod, dbg, 8, 8, version,
9419 			 address_size, offset_size, cu, len, readp);
9420 	      readp += len;
9421 	      break;
9422 
9423 	    default:
9424 	      goto invalid_entry;
9425 	    }
9426 	}
9427 
9428     next_table:
9429       if (readp != nexthdr)
9430 	{
9431           size_t padding = nexthdr - readp;
9432           printf (gettext ("   %zu padding bytes\n\n"), padding);
9433 	  readp = nexthdr;
9434 	}
9435     }
9436 }
9437 
9438 
9439 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9440 print_debug_loc_section (Dwfl_Module *dwflmod,
9441 			 Ebl *ebl, GElf_Ehdr *ehdr,
9442 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9443 {
9444   Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9445 		    ?: elf_rawdata (scn, NULL));
9446 
9447   if (unlikely (data == NULL))
9448     {
9449       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9450 	     elf_errmsg (-1));
9451       return;
9452     }
9453 
9454   printf (gettext ("\
9455 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9456 	  elf_ndxscn (scn), section_name (ebl, shdr),
9457 	  (uint64_t) shdr->sh_offset);
9458 
9459   sort_listptr (&known_locsptr, "loclistptr");
9460   size_t listptr_idx = 0;
9461 
9462   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9463   uint_fast8_t offset_size = 4;
9464 
9465   bool first = true;
9466   Dwarf_Addr base = 0;
9467   unsigned char *readp = data->d_buf;
9468   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9469   Dwarf_CU *last_cu = NULL;
9470   while (readp < endp)
9471     {
9472       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9473       Dwarf_CU *cu = last_cu;
9474       unsigned int attr = 0;
9475 
9476       if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9477 				      &address_size, &offset_size, &base,
9478 				      &cu, offset, &readp, endp, &attr))
9479 	continue;
9480 
9481       if (last_cu != cu)
9482        {
9483 	Dwarf_Die cudie;
9484 	if (dwarf_cu_die (cu, &cudie,
9485 			  NULL, NULL, NULL, NULL,
9486 			  NULL, NULL) == NULL)
9487 	  printf (gettext ("\n Unknown CU base: "));
9488 	else
9489 	  printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9490 		  dwarf_dieoffset (&cudie));
9491 	print_dwarf_addr (dwflmod, address_size, base, base);
9492 	printf ("\n");
9493        }
9494       last_cu = cu;
9495 
9496       if (attr == DW_AT_GNU_locviews)
9497 	{
9498 	  Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9499 						    listptr_idx);
9500 	  const unsigned char *locp = readp;
9501 	  const unsigned char *locendp;
9502 	  if (next_off == 0
9503 	      || next_off > (size_t) (endp
9504 				      - (const unsigned char *) data->d_buf))
9505 	    locendp = endp;
9506 	  else
9507 	    locendp = (const unsigned char *) data->d_buf + next_off;
9508 
9509 	  while (locp < locendp)
9510 	    {
9511 	      uint64_t v1, v2;
9512 	      get_uleb128 (v1, locp, locendp);
9513 	      if (locp >= locendp)
9514 		{
9515 		  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9516 		  break;
9517 		}
9518 	      get_uleb128 (v2, locp, locendp);
9519 	      if (first)		/* First view pair in a list.  */
9520 		printf (" [%6tx] ", offset);
9521 	      else
9522 		printf ("          ");
9523 	      printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9524 	      first = false;
9525 	    }
9526 
9527 	  first = true;
9528 	  readp = (unsigned char *) locendp;
9529 	  continue;
9530 	}
9531 
9532       /* GNU DebugFission encoded addresses as addrx.  */
9533       bool is_debugfission = ((cu != NULL
9534 			       || split_dwarf_cu_base (dbg, &cu, &base))
9535 			      && (cu->version < 5
9536 				  && cu->unit_type == DW_UT_split_compile));
9537       if (!is_debugfission
9538 	  && unlikely (data->d_size - offset < (size_t) address_size * 2))
9539         {
9540 	invalid_data:
9541 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
9542 	  break;
9543 	}
9544 
9545       Dwarf_Addr begin;
9546       Dwarf_Addr end;
9547       bool use_base = true;
9548       if (is_debugfission)
9549 	{
9550 	  const unsigned char *locp = readp;
9551 	  const unsigned char *locendp = readp + data->d_size;
9552 	  if (locp >= locendp)
9553 	    goto invalid_data;
9554 
9555 	  Dwarf_Word idx;
9556 	  unsigned char code = *locp++;
9557 	  switch (code)
9558 	    {
9559 	    case DW_LLE_GNU_end_of_list_entry:
9560 	      begin = 0;
9561 	      end = 0;
9562 	      break;
9563 
9564 	    case DW_LLE_GNU_base_address_selection_entry:
9565 	      if (locp >= locendp)
9566 		goto invalid_data;
9567 	      begin = (Dwarf_Addr) -1;
9568 	      get_uleb128 (idx, locp, locendp);
9569 	      if (get_indexed_addr (cu, idx, &end) != 0)
9570 		end = idx; /* ... */
9571 	      break;
9572 
9573 	    case DW_LLE_GNU_start_end_entry:
9574 	      if (locp >= locendp)
9575 		goto invalid_data;
9576 	      get_uleb128 (idx, locp, locendp);
9577 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9578 		begin = idx; /* ... */
9579 	      if (locp >= locendp)
9580 		goto invalid_data;
9581 	      get_uleb128 (idx, locp, locendp);
9582 	      if (get_indexed_addr (cu, idx, &end) != 0)
9583 		end = idx; /* ... */
9584 	      use_base = false;
9585 	      break;
9586 
9587 	    case DW_LLE_GNU_start_length_entry:
9588 	      if (locp >= locendp)
9589 		goto invalid_data;
9590 	      get_uleb128 (idx, locp, locendp);
9591 	      if (get_indexed_addr (cu, idx, &begin) != 0)
9592 		begin = idx; /* ... */
9593 	      if (locendp - locp < 4)
9594 		goto invalid_data;
9595 	      end = read_4ubyte_unaligned_inc (dbg, locp);
9596 	      end += begin;
9597 	      use_base = false;
9598 	      break;
9599 
9600 	    default:
9601 		goto invalid_data;
9602 	    }
9603 
9604 	  readp = (unsigned char *) locp;
9605 	}
9606       else if (address_size == 8)
9607 	{
9608 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
9609 	  end = read_8ubyte_unaligned_inc (dbg, readp);
9610 	}
9611       else
9612 	{
9613 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
9614 	  end = read_4ubyte_unaligned_inc (dbg, readp);
9615 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
9616 	    begin = (Dwarf_Addr) -1l;
9617 	}
9618 
9619       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
9620 	{
9621 	  printf (gettext (" [%6tx] base address\n          "), offset);
9622 	  print_dwarf_addr (dwflmod, address_size, end, end);
9623 	  printf ("\n");
9624 	  base = end;
9625 	}
9626       else if (begin == 0 && end == 0) /* End of list entry.  */
9627 	{
9628 	  if (first)
9629 	    printf (gettext (" [%6tx] empty list\n"), offset);
9630 	  first = true;
9631 	}
9632       else
9633 	{
9634 	  /* We have a location expression entry.  */
9635 	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9636 
9637 	  if (first)		/* First entry in a list.  */
9638 	    printf (" [%6tx] ", offset);
9639 	  else
9640 	    printf ("          ");
9641 
9642 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9643 	  if (! print_unresolved_addresses)
9644 	    {
9645 	      Dwarf_Addr dab = use_base ? base + begin : begin;
9646 	      Dwarf_Addr dae = use_base ? base + end : end;
9647 	      printf ("          ");
9648 	      print_dwarf_addr (dwflmod, address_size, dab, dab);
9649 	      printf ("..\n          ");
9650 	      print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9651 	      printf ("\n");
9652 	    }
9653 
9654 	  if (endp - readp <= (ptrdiff_t) len)
9655 	    {
9656 	      fputs (gettext ("   <INVALID DATA>\n"), stdout);
9657 	      break;
9658 	    }
9659 
9660 	  print_ops (dwflmod, dbg, 11, 11,
9661 		     cu != NULL ? cu->version : 3,
9662 		     address_size, offset_size, cu, len, readp);
9663 
9664 	  first = false;
9665 	  readp += len;
9666 	}
9667     }
9668 }
9669 
9670 struct mac_culist
9671 {
9672   Dwarf_Die die;
9673   Dwarf_Off offset;
9674   Dwarf_Files *files;
9675   struct mac_culist *next;
9676 };
9677 
9678 
9679 static int
mac_compare(const void * p1,const void * p2)9680 mac_compare (const void *p1, const void *p2)
9681 {
9682   struct mac_culist *m1 = (struct mac_culist *) p1;
9683   struct mac_culist *m2 = (struct mac_culist *) p2;
9684 
9685   if (m1->offset < m2->offset)
9686     return -1;
9687   if (m1->offset > m2->offset)
9688     return 1;
9689   return 0;
9690 }
9691 
9692 
9693 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9694 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9695 			     Ebl *ebl,
9696 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
9697 			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9698 {
9699   printf (gettext ("\
9700 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9701 	  elf_ndxscn (scn), section_name (ebl, shdr),
9702 	  (uint64_t) shdr->sh_offset);
9703   putc_unlocked ('\n', stdout);
9704 
9705   /* There is no function in libdw to iterate over the raw content of
9706      the section but it is easy enough to do.  */
9707   Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9708 		    ?: elf_rawdata (scn, NULL));
9709   if (unlikely (data == NULL))
9710     {
9711       error (0, 0, gettext ("cannot get macro information section data: %s"),
9712 	     elf_errmsg (-1));
9713       return;
9714     }
9715 
9716   /* Get the source file information for all CUs.  */
9717   Dwarf_Off offset;
9718   Dwarf_Off ncu = 0;
9719   size_t hsize;
9720   struct mac_culist *culist = NULL;
9721   size_t nculist = 0;
9722   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9723     {
9724       Dwarf_Die cudie;
9725       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9726 	continue;
9727 
9728       Dwarf_Attribute attr;
9729       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9730 	continue;
9731 
9732       Dwarf_Word macoff;
9733       if (dwarf_formudata (&attr, &macoff) != 0)
9734 	continue;
9735 
9736       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9737       newp->die = cudie;
9738       newp->offset = macoff;
9739       newp->files = NULL;
9740       newp->next = culist;
9741       culist = newp;
9742       ++nculist;
9743     }
9744 
9745   /* Convert the list into an array for easier consumption.  */
9746   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9747 							 * sizeof (*cus));
9748   /* Add sentinel.  */
9749   cus[nculist].offset = data->d_size;
9750   cus[nculist].files = (Dwarf_Files *) -1l;
9751   if (nculist > 0)
9752     {
9753       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9754 	{
9755 	  assert (cnt < nculist);
9756 	  cus[cnt] = *culist;
9757 	  culist = culist->next;
9758 	}
9759 
9760       /* Sort the array according to the offset in the .debug_macinfo
9761 	 section.  Note we keep the sentinel at the end.  */
9762       qsort (cus, nculist, sizeof (*cus), mac_compare);
9763     }
9764 
9765   const unsigned char *readp = (const unsigned char *) data->d_buf;
9766   const unsigned char *readendp = readp + data->d_size;
9767   int level = 1;
9768 
9769   while (readp < readendp)
9770     {
9771       unsigned int opcode = *readp++;
9772       unsigned int u128;
9773       unsigned int u128_2;
9774       const unsigned char *endp;
9775 
9776       switch (opcode)
9777 	{
9778 	case DW_MACINFO_define:
9779 	case DW_MACINFO_undef:
9780 	case DW_MACINFO_vendor_ext:
9781 	  /*  For the first two opcodes the parameters are
9782 		line, string
9783 	      For the latter
9784 		number, string.
9785 	      We can treat these cases together.  */
9786 	  get_uleb128 (u128, readp, readendp);
9787 
9788 	  endp = memchr (readp, '\0', readendp - readp);
9789 	  if (unlikely (endp == NULL))
9790 	    {
9791 	      printf (gettext ("\
9792 %*s*** non-terminated string at end of section"),
9793 		      level, "");
9794 	      return;
9795 	    }
9796 
9797 	  if (opcode == DW_MACINFO_define)
9798 	    printf ("%*s#define %s, line %u\n",
9799 		    level, "", (char *) readp, u128);
9800 	  else if (opcode == DW_MACINFO_undef)
9801 	    printf ("%*s#undef %s, line %u\n",
9802 		    level, "", (char *) readp, u128);
9803 	  else
9804 	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9805 
9806 	  readp = endp + 1;
9807 	  break;
9808 
9809 	case DW_MACINFO_start_file:
9810 	  /* The two parameters are line and file index, in this order.  */
9811 	  get_uleb128 (u128, readp, readendp);
9812 	  if (readendp - readp < 1)
9813 	    {
9814 	      printf (gettext ("\
9815 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9816 		      level, "");
9817 	      return;
9818 	    }
9819 	  get_uleb128 (u128_2, readp, readendp);
9820 
9821 	  /* Find the CU DIE for this file.  */
9822 	  size_t macoff = readp - (const unsigned char *) data->d_buf;
9823 	  const char *fname = "???";
9824 	  if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
9825 	    {
9826 	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9827 		++cus;
9828 
9829 	      if (cus[0].files == NULL
9830 		  && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9831 		cus[0].files = (Dwarf_Files *) -1l;
9832 
9833 	      if (cus[0].files != (Dwarf_Files *) -1l)
9834 		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9835 			 ?: "???");
9836 	    }
9837 
9838 	  printf ("%*sstart_file %u, [%u] %s\n",
9839 		  level, "", u128, u128_2, fname);
9840 	  ++level;
9841 	  break;
9842 
9843 	case DW_MACINFO_end_file:
9844 	  --level;
9845 	  printf ("%*send_file\n", level, "");
9846 	  /* Nothing more to do.  */
9847 	  break;
9848 
9849 	default:
9850 	  // XXX gcc seems to generate files with a trailing zero.
9851 	  if (unlikely (opcode != 0 || readp != readendp))
9852 	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9853 	  break;
9854 	}
9855     }
9856 }
9857 
9858 
9859 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9860 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9861 			   Ebl *ebl,
9862 			   GElf_Ehdr *ehdr __attribute__ ((unused)),
9863 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9864 {
9865   printf (gettext ("\
9866 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9867 	  elf_ndxscn (scn), section_name (ebl, shdr),
9868 	  (uint64_t) shdr->sh_offset);
9869   putc_unlocked ('\n', stdout);
9870 
9871   Elf_Data *data =  elf_getdata (scn, NULL);
9872   if (unlikely (data == NULL))
9873     {
9874       error (0, 0, gettext ("cannot get macro information section data: %s"),
9875 	     elf_errmsg (-1));
9876       return;
9877     }
9878 
9879   /* Get the source file information for all CUs.  Uses same
9880      datastructure as macinfo.  But uses offset field to directly
9881      match .debug_line offset.  And just stored in a list.  */
9882   Dwarf_Off offset;
9883   Dwarf_Off ncu = 0;
9884   size_t hsize;
9885   struct mac_culist *culist = NULL;
9886   size_t nculist = 0;
9887   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9888     {
9889       Dwarf_Die cudie;
9890       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9891 	continue;
9892 
9893       Dwarf_Attribute attr;
9894       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9895 	continue;
9896 
9897       Dwarf_Word lineoff;
9898       if (dwarf_formudata (&attr, &lineoff) != 0)
9899 	continue;
9900 
9901       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9902       newp->die = cudie;
9903       newp->offset = lineoff;
9904       newp->files = NULL;
9905       newp->next = culist;
9906       culist = newp;
9907       ++nculist;
9908     }
9909 
9910   const unsigned char *readp = (const unsigned char *) data->d_buf;
9911   const unsigned char *readendp = readp + data->d_size;
9912 
9913   while (readp < readendp)
9914     {
9915       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
9916 	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
9917 
9918       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9919       // optional vendor extension macro entry table.
9920       if (readp + 2 > readendp)
9921 	{
9922 	invalid_data:
9923 	  error (0, 0, gettext ("invalid data"));
9924 	  return;
9925 	}
9926       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9927       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
9928 
9929       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
9930       // 5 when it gets standardized.
9931       if (vers != 4 && vers != 5)
9932 	{
9933 	  printf (gettext ("  unknown version, cannot parse section\n"));
9934 	  return;
9935 	}
9936 
9937       if (readp + 1 > readendp)
9938 	goto invalid_data;
9939       const unsigned char flag = *readp++;
9940       printf (gettext (" Flag:               0x%" PRIx8), flag);
9941       if (flag != 0)
9942 	{
9943 	  printf (" (");
9944 	  if ((flag & 0x01) != 0)
9945 	    {
9946 	      printf ("offset_size");
9947 	      if ((flag & 0xFE) !=  0)
9948 		printf (", ");
9949 	    }
9950 	  if ((flag & 0x02) != 0)
9951 	    {
9952 	      printf ("debug_line_offset");
9953 	      if ((flag & 0xFC) !=  0)
9954 		printf (", ");
9955 	    }
9956 	  if ((flag & 0x04) != 0)
9957 	    {
9958 	      printf ("operands_table");
9959 	      if ((flag & 0xF8) !=  0)
9960 		printf (", ");
9961 	    }
9962 	  if ((flag & 0xF8) != 0)
9963 	    printf ("unknown");
9964 	  printf (")");
9965 	}
9966       printf ("\n");
9967 
9968       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9969       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
9970       Dwarf_Off line_offset = -1;
9971       if (flag & 0x02)
9972 	{
9973 	  if (offset_len == 8)
9974 	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9975 	  else
9976 	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9977 	  printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9978 		  line_offset);
9979 	}
9980 
9981       struct mac_culist *cu = NULL;
9982       if (line_offset != (Dwarf_Off) -1)
9983 	{
9984 	  cu = culist;
9985 	  while (cu != NULL && line_offset != cu->offset)
9986 	    cu = cu->next;
9987 	}
9988 
9989       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9990 							       ? cu->die.cu
9991 							       : NULL));
9992 
9993       const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9994       memset (vendor, 0, sizeof vendor);
9995       if (flag & 0x04)
9996 	{
9997 	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
9998 	  // of arguments, for each argument 1 byte form code.
9999 	  if (readp + 1 > readendp)
10000 	    goto invalid_data;
10001 	  unsigned int tlen = *readp++;
10002 	  printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
10003 		  tlen);
10004 	  for (unsigned int i = 0; i < tlen; i++)
10005 	    {
10006 	      if (readp + 1 > readendp)
10007 		goto invalid_data;
10008 	      unsigned int opcode = *readp++;
10009 	      printf (gettext ("    [%" PRIx8 "]"), opcode);
10010 	      if (opcode < DW_MACRO_lo_user
10011 		  || opcode > DW_MACRO_hi_user)
10012 		goto invalid_data;
10013 	      // Record the start of description for this vendor opcode.
10014 	      // uleb128 nr args, 1 byte per arg form.
10015 	      vendor[opcode - DW_MACRO_lo_user] = readp;
10016 	      if (readp + 1 > readendp)
10017 		goto invalid_data;
10018 	      unsigned int args = *readp++;
10019 	      if (args > 0)
10020 		{
10021 		  printf (gettext (" %" PRIu8 " arguments:"), args);
10022 		  while (args > 0)
10023 		    {
10024 		      if (readp + 1 > readendp)
10025 			goto invalid_data;
10026 		      unsigned int form = *readp++;
10027 		      printf (" %s", dwarf_form_name (form));
10028 		      if (! libdw_valid_user_form (form))
10029 			goto invalid_data;
10030 		      args--;
10031 		      if (args > 0)
10032 			putchar_unlocked (',');
10033 		    }
10034 		}
10035 	      else
10036 		printf (gettext (" no arguments."));
10037 	      putchar_unlocked ('\n');
10038 	    }
10039 	}
10040       putchar_unlocked ('\n');
10041 
10042       int level = 1;
10043       if (readp + 1 > readendp)
10044 	goto invalid_data;
10045       unsigned int opcode = *readp++;
10046       while (opcode != 0)
10047 	{
10048 	  unsigned int u128;
10049 	  unsigned int u128_2;
10050 	  const unsigned char *endp;
10051 	  uint64_t off;
10052 
10053           switch (opcode)
10054             {
10055             case DW_MACRO_start_file:
10056 	      get_uleb128 (u128, readp, readendp);
10057 	      if (readp >= readendp)
10058 		goto invalid_data;
10059 	      get_uleb128 (u128_2, readp, readendp);
10060 
10061 	      /* Find the CU DIE that matches this line offset.  */
10062 	      const char *fname = "???";
10063 	      if (cu != NULL)
10064 		{
10065 		  if (cu->files == NULL
10066 		      && dwarf_getsrcfiles (&cu->die, &cu->files,
10067 					    NULL) != 0)
10068 		    cu->files = (Dwarf_Files *) -1l;
10069 
10070 		  if (cu->files != (Dwarf_Files *) -1l)
10071 		    fname = (dwarf_filesrc (cu->files, u128_2,
10072 					    NULL, NULL) ?: "???");
10073 		}
10074 	      printf ("%*sstart_file %u, [%u] %s\n",
10075 		      level, "", u128, u128_2, fname);
10076 	      ++level;
10077 	      break;
10078 
10079 	    case DW_MACRO_end_file:
10080 	      --level;
10081 	      printf ("%*send_file\n", level, "");
10082 	      break;
10083 
10084 	    case DW_MACRO_define:
10085 	      get_uleb128 (u128, readp, readendp);
10086 	      endp = memchr (readp, '\0', readendp - readp);
10087 	      if (endp == NULL)
10088 		goto invalid_data;
10089 	      printf ("%*s#define %s, line %u\n",
10090 		      level, "", readp, u128);
10091 	      readp = endp + 1;
10092 	      break;
10093 
10094 	    case DW_MACRO_undef:
10095 	      get_uleb128 (u128, readp, readendp);
10096 	      endp = memchr (readp, '\0', readendp - readp);
10097 	      if (endp == NULL)
10098 		goto invalid_data;
10099 	      printf ("%*s#undef %s, line %u\n",
10100 		      level, "", readp, u128);
10101 	      readp = endp + 1;
10102 	      break;
10103 
10104 	    case DW_MACRO_define_strp:
10105 	      get_uleb128 (u128, readp, readendp);
10106 	      if (readp + offset_len > readendp)
10107 		goto invalid_data;
10108 	      if (offset_len == 8)
10109 		off = read_8ubyte_unaligned_inc (dbg, readp);
10110 	      else
10111 		off = read_4ubyte_unaligned_inc (dbg, readp);
10112 	      printf ("%*s#define %s, line %u (indirect)\n",
10113 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10114 	      break;
10115 
10116 	    case DW_MACRO_undef_strp:
10117 	      get_uleb128 (u128, readp, readendp);
10118 	      if (readp + offset_len > readendp)
10119 		goto invalid_data;
10120 	      if (offset_len == 8)
10121 		off = read_8ubyte_unaligned_inc (dbg, readp);
10122 	      else
10123 		off = read_4ubyte_unaligned_inc (dbg, readp);
10124 	      printf ("%*s#undef %s, line %u (indirect)\n",
10125 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10126 	      break;
10127 
10128 	    case DW_MACRO_import:
10129 	      if (readp + offset_len > readendp)
10130 		goto invalid_data;
10131 	      if (offset_len == 8)
10132 		off = read_8ubyte_unaligned_inc (dbg, readp);
10133 	      else
10134 		off = read_4ubyte_unaligned_inc (dbg, readp);
10135 	      printf ("%*s#include offset 0x%" PRIx64 "\n",
10136 		      level, "", off);
10137 	      break;
10138 
10139 	    case DW_MACRO_define_sup:
10140 	      get_uleb128 (u128, readp, readendp);
10141 	      if (readp + offset_len > readendp)
10142 		goto invalid_data;
10143 	      printf ("%*s#define ", level, "");
10144 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10145 					readp, readendp, offset_len,
10146 					str_offsets_base);
10147 	      printf (", line %u (sup)\n", u128);
10148 	      break;
10149 
10150 	    case DW_MACRO_undef_sup:
10151 	      get_uleb128 (u128, readp, readendp);
10152 	      if (readp + offset_len > readendp)
10153 		goto invalid_data;
10154 	      printf ("%*s#undef ", level, "");
10155 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10156 					readp, readendp, offset_len,
10157 					str_offsets_base);
10158 	      printf (", line %u (sup)\n", u128);
10159 	      break;
10160 
10161 	    case DW_MACRO_import_sup:
10162 	      if (readp + offset_len > readendp)
10163 		goto invalid_data;
10164 	      if (offset_len == 8)
10165 		off = read_8ubyte_unaligned_inc (dbg, readp);
10166 	      else
10167 		off = read_4ubyte_unaligned_inc (dbg, readp);
10168 	      // XXX Needs support for reading from supplementary object file.
10169 	      printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10170 		      level, "", off);
10171 	      break;
10172 
10173 	    case DW_MACRO_define_strx:
10174 	      get_uleb128 (u128, readp, readendp);
10175 	      if (readp + offset_len > readendp)
10176 		goto invalid_data;
10177 	      printf ("%*s#define ", level, "");
10178 	      readp =  print_form_data (dbg, DW_FORM_strx,
10179 					readp, readendp, offset_len,
10180 					str_offsets_base);
10181 	      printf (", line %u (strx)\n", u128);
10182 	      break;
10183 
10184 	    case DW_MACRO_undef_strx:
10185 	      get_uleb128 (u128, readp, readendp);
10186 	      if (readp + offset_len > readendp)
10187 		goto invalid_data;
10188 	      printf ("%*s#undef ", level, "");
10189 	      readp =  print_form_data (dbg, DW_FORM_strx,
10190 					readp, readendp, offset_len,
10191 					str_offsets_base);
10192 	      printf (", line %u (strx)\n", u128);
10193 	      break;
10194 
10195 	    default:
10196 	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10197 	      if (opcode < DW_MACRO_lo_user
10198 		  || opcode > DW_MACRO_lo_user
10199 		  || vendor[opcode - DW_MACRO_lo_user] == NULL)
10200 		goto invalid_data;
10201 
10202 	      const unsigned char *op_desc;
10203 	      op_desc = vendor[opcode - DW_MACRO_lo_user];
10204 
10205 	      // Just skip the arguments, we cannot really interpret them,
10206 	      // but print as much as we can.
10207 	      unsigned int args = *op_desc++;
10208 	      while (args > 0 && readp < readendp)
10209 		{
10210 		  unsigned int form = *op_desc++;
10211 		  readp = print_form_data (dbg, form, readp, readendp,
10212 					   offset_len, str_offsets_base);
10213 		  args--;
10214 		  if (args > 0)
10215 		    printf (", ");
10216 		}
10217 	      putchar_unlocked ('\n');
10218 	    }
10219 
10220 	  if (readp + 1 > readendp)
10221 	    goto invalid_data;
10222 	  opcode = *readp++;
10223 	  if (opcode == 0)
10224 	    putchar_unlocked ('\n');
10225 	}
10226     }
10227 }
10228 
10229 
10230 /* Callback for printing global names.  */
10231 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10232 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10233 		void *arg)
10234 {
10235   int *np = (int *) arg;
10236 
10237   printf (gettext (" [%5d] DIE offset: %6" PRId64
10238 		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10239 	  (*np)++, global->die_offset, global->cu_offset, global->name);
10240 
10241   return 0;
10242 }
10243 
10244 
10245 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
10246 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10247 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10248 			      Ebl *ebl,
10249 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
10250 			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10251 {
10252   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10253 	  elf_ndxscn (scn), section_name (ebl, shdr),
10254 	  (uint64_t) shdr->sh_offset);
10255 
10256   int n = 0;
10257   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10258 }
10259 
10260 /* Print the content of the DWARF string section '.debug_str'.  */
10261 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10262 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10263 			 Ebl *ebl,
10264 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10265 			 Elf_Scn *scn, GElf_Shdr *shdr,
10266 			 Dwarf *dbg __attribute__ ((unused)))
10267 {
10268   Elf_Data *data = elf_rawdata (scn, NULL);
10269   const size_t sh_size = data ? data->d_size : 0;
10270 
10271   /* Compute floor(log16(shdr->sh_size)).  */
10272   GElf_Addr tmp = sh_size;
10273   int digits = 1;
10274   while (tmp >= 16)
10275     {
10276       ++digits;
10277       tmp >>= 4;
10278     }
10279   digits = MAX (4, digits);
10280 
10281   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10282 		   " %*s  String\n"),
10283 	  elf_ndxscn (scn),
10284 	  section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10285 	  /* TRANS: the debugstr| prefix makes the string unique.  */
10286 	  digits + 2, sgettext ("debugstr|Offset"));
10287 
10288   Dwarf_Off offset = 0;
10289   while (offset < sh_size)
10290     {
10291       size_t len;
10292       const char *str = (const char *) data->d_buf + offset;
10293       const char *endp = memchr (str, '\0', sh_size - offset);
10294       if (unlikely (endp == NULL))
10295 	{
10296 	  printf (gettext (" *** error, missing string terminator\n"));
10297 	  break;
10298 	}
10299 
10300       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
10301       len = endp - str;
10302       offset += len + 1;
10303     }
10304 }
10305 
10306 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10307 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10308 				 Ebl *ebl,
10309 				 GElf_Ehdr *ehdr __attribute__ ((unused)),
10310 				 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10311 {
10312   printf (gettext ("\
10313 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10314 	  elf_ndxscn (scn), section_name (ebl, shdr),
10315 	  (uint64_t) shdr->sh_offset);
10316 
10317   if (shdr->sh_size == 0)
10318     return;
10319 
10320   /* We like to get the section from libdw to make sure they are relocated.  */
10321   Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10322 		    ?: elf_rawdata (scn, NULL));
10323   if (unlikely (data == NULL))
10324     {
10325       error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10326 	     elf_errmsg (-1));
10327       return;
10328     }
10329 
10330   size_t idx = 0;
10331   sort_listptr (&known_stroffbases, "str_offsets");
10332 
10333   const unsigned char *start = (const unsigned char *) data->d_buf;
10334   const unsigned char *readp = start;
10335   const unsigned char *readendp = ((const unsigned char *) data->d_buf
10336 				   + data->d_size);
10337 
10338   while (readp < readendp)
10339     {
10340       /* Most string offset tables will have a header.  For split
10341 	 dwarf unit GNU DebugFission didn't add one.  But they were
10342 	 also only defined for split units (main or skeleton units
10343 	 didn't have indirect strings).  So if we don't have a
10344 	 DW_AT_str_offsets_base at all and this is offset zero, then
10345 	 just start printing offsets immediately, if this is a .dwo
10346 	 section.  */
10347       Dwarf_Off off = (Dwarf_Off) (readp
10348 				   - (const unsigned char *) data->d_buf);
10349 
10350       printf ("Table at offset %" PRIx64 " ", off);
10351 
10352       struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10353       const unsigned char *next_unitp = readendp;
10354       uint8_t offset_size;
10355       bool has_header;
10356       if (listptr == NULL)
10357 	{
10358 	  /* This can happen for .dwo files.  There is only an header
10359 	     in the case this is a version 5 split DWARF file.  */
10360 	  Dwarf_CU *cu;
10361 	  uint8_t unit_type;
10362 	  if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10363 			       NULL, NULL) != 0)
10364 	    {
10365 	      error (0, 0, "Warning: Cannot find any DWARF unit.");
10366 	      /* Just guess some values.  */
10367 	      has_header = false;
10368 	      offset_size = 4;
10369 	    }
10370 	  else if (off == 0
10371 		   && (unit_type == DW_UT_split_type
10372 		       || unit_type == DW_UT_split_compile))
10373 	    {
10374 	      has_header = cu->version > 4;
10375 	      offset_size = cu->offset_size;
10376 	    }
10377 	  else
10378 	    {
10379 	      error (0, 0,
10380 		     "Warning: No CU references .debug_str_offsets after %"
10381 		     PRIx64, off);
10382 	      has_header = cu->version > 4;
10383 	      offset_size = cu->offset_size;
10384 	    }
10385 	  printf ("\n");
10386 	}
10387       else
10388 	{
10389 	  /* This must be DWARF5, since GNU DebugFission didn't define
10390 	     DW_AT_str_offsets_base.  */
10391 	  has_header = true;
10392 
10393 	  Dwarf_Die cudie;
10394 	  if (dwarf_cu_die (listptr->cu, &cudie,
10395 			    NULL, NULL, NULL, NULL,
10396 			    NULL, NULL) == NULL)
10397 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10398 	  else
10399 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10400 	}
10401 
10402       if (has_header)
10403 	{
10404 	  uint64_t unit_length;
10405 	  uint16_t version;
10406 	  uint16_t padding;
10407 
10408 	  unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10409 	  if (unlikely (unit_length == 0xffffffff))
10410 	    {
10411 	      if (unlikely (readp > readendp - 8))
10412 		{
10413 		invalid_data:
10414 		  error (0, 0, "Invalid data");
10415 		  return;
10416 		}
10417 	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10418 	      offset_size = 8;
10419 	    }
10420 	  else
10421 	    offset_size = 4;
10422 
10423 	  printf ("\n");
10424 	  printf (gettext (" Length:        %8" PRIu64 "\n"),
10425 		  unit_length);
10426 	  printf (gettext (" Offset size:   %8" PRIu8 "\n"),
10427 		  offset_size);
10428 
10429 	  /* We need at least 2-bytes (version) + 2-bytes (padding) =
10430 	     4 bytes to complete the header.  And this unit cannot go
10431 	     beyond the section data.  */
10432 	  if (readp > readendp - 4
10433 	      || unit_length < 4
10434 	      || unit_length > (uint64_t) (readendp - readp))
10435 	    goto invalid_data;
10436 
10437 	  next_unitp = readp + unit_length;
10438 
10439 	  version = read_2ubyte_unaligned_inc (dbg, readp);
10440 	  printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10441 
10442 	  if (version != 5)
10443 	    {
10444 	      error (0, 0, gettext ("Unknown version"));
10445 	      goto next_unit;
10446 	    }
10447 
10448 	  padding = read_2ubyte_unaligned_inc (dbg, readp);
10449 	  printf (gettext (" Padding:       %8" PRIx16 "\n"), padding);
10450 
10451 	  if (listptr != NULL
10452 	      && listptr->offset != (Dwarf_Off) (readp - start))
10453 	    {
10454 	      error (0, 0, "String offsets index doesn't start after header");
10455 	      goto next_unit;
10456 	    }
10457 
10458 	  printf ("\n");
10459 	}
10460 
10461       int digits = 1;
10462       size_t offsets = (next_unitp - readp) / offset_size;
10463       while (offsets >= 10)
10464 	{
10465 	  ++digits;
10466 	  offsets /= 10;
10467 	}
10468 
10469       unsigned int uidx = 0;
10470       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
10471       printf (" Offsets start at 0x%zx:\n", index_offset);
10472       while (readp <= next_unitp - offset_size)
10473 	{
10474 	  Dwarf_Word offset;
10475 	  if (offset_size == 4)
10476 	    offset = read_4ubyte_unaligned_inc (dbg, readp);
10477 	  else
10478 	    offset = read_8ubyte_unaligned_inc (dbg, readp);
10479 	  const char *str = dwarf_getstring (dbg, offset, NULL);
10480 	  printf (" [%*u] [%*" PRIx64 "]  \"%s\"\n",
10481 		  digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10482 	}
10483       printf ("\n");
10484 
10485       if (readp != next_unitp)
10486 	error (0, 0, "extra %zd bytes at end of unit",
10487 	       (size_t) (next_unitp - readp));
10488 
10489     next_unit:
10490       readp = next_unitp;
10491     }
10492 }
10493 
10494 
10495 /* Print the content of the call frame search table section
10496    '.eh_frame_hdr'.  */
10497 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10498 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10499 			       Ebl *ebl __attribute__ ((unused)),
10500 			       GElf_Ehdr *ehdr __attribute__ ((unused)),
10501 			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10502 {
10503   printf (gettext ("\
10504 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10505 	  elf_ndxscn (scn));
10506 
10507   Elf_Data *data = elf_rawdata (scn, NULL);
10508 
10509   if (unlikely (data == NULL))
10510     {
10511       error (0, 0, gettext ("cannot get %s content: %s"),
10512 	     ".eh_frame_hdr", elf_errmsg (-1));
10513       return;
10514     }
10515 
10516   const unsigned char *readp = data->d_buf;
10517   const unsigned char *const dataend = ((unsigned char *) data->d_buf
10518 					+ data->d_size);
10519 
10520   if (unlikely (readp + 4 > dataend))
10521     {
10522     invalid_data:
10523       error (0, 0, gettext ("invalid data"));
10524       return;
10525     }
10526 
10527   unsigned int version = *readp++;
10528   unsigned int eh_frame_ptr_enc = *readp++;
10529   unsigned int fde_count_enc = *readp++;
10530   unsigned int table_enc = *readp++;
10531 
10532   printf (" version:          %u\n"
10533 	  " eh_frame_ptr_enc: %#x ",
10534 	  version, eh_frame_ptr_enc);
10535   print_encoding_base ("", eh_frame_ptr_enc);
10536   printf (" fde_count_enc:    %#x ", fde_count_enc);
10537   print_encoding_base ("", fde_count_enc);
10538   printf (" table_enc:        %#x ", table_enc);
10539   print_encoding_base ("", table_enc);
10540 
10541   uint64_t eh_frame_ptr = 0;
10542   if (eh_frame_ptr_enc != DW_EH_PE_omit)
10543     {
10544       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10545 			    dbg);
10546       if (unlikely (readp == NULL))
10547 	goto invalid_data;
10548 
10549       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
10550       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10551 	printf (" (offset: %#" PRIx64 ")",
10552 		/* +4 because of the 4 byte header of the section.  */
10553 		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10554 
10555       putchar_unlocked ('\n');
10556     }
10557 
10558   uint64_t fde_count = 0;
10559   if (fde_count_enc != DW_EH_PE_omit)
10560     {
10561       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10562       if (unlikely (readp == NULL))
10563 	goto invalid_data;
10564 
10565       printf (" fde_count:        %" PRIu64 "\n", fde_count);
10566     }
10567 
10568   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10569     return;
10570 
10571   puts (" Table:");
10572 
10573   /* Optimize for the most common case.  */
10574   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10575     while (fde_count > 0 && readp + 8 <= dataend)
10576       {
10577 	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10578 	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10579 				   + (int64_t) initial_location);
10580 	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10581 	// XXX Possibly print symbol name or section offset for initial_offset
10582 	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10583 		" fde=[%6" PRIx64 "]\n",
10584 		initial_location, initial_offset,
10585 		address, address - (eh_frame_ptr + 4));
10586       }
10587   else
10588     while (0 && readp < dataend)
10589       {
10590 
10591       }
10592 }
10593 
10594 
10595 /* Print the content of the exception handling table section
10596    '.eh_frame_hdr'.  */
10597 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10598 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10599 			     Ebl *ebl __attribute__ ((unused)),
10600 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
10601 			     Elf_Scn *scn,
10602 			     GElf_Shdr *shdr __attribute__ ((unused)),
10603 			     Dwarf *dbg __attribute__ ((unused)))
10604 {
10605   printf (gettext ("\
10606 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10607 	  elf_ndxscn (scn));
10608 
10609   Elf_Data *data = elf_rawdata (scn, NULL);
10610 
10611   if (unlikely (data == NULL))
10612     {
10613       error (0, 0, gettext ("cannot get %s content: %s"),
10614 	     ".gcc_except_table", elf_errmsg (-1));
10615       return;
10616     }
10617 
10618   const unsigned char *readp = data->d_buf;
10619   const unsigned char *const dataend = readp + data->d_size;
10620 
10621   if (unlikely (readp + 1 > dataend))
10622     {
10623     invalid_data:
10624       error (0, 0, gettext ("invalid data"));
10625       return;
10626     }
10627   unsigned int lpstart_encoding = *readp++;
10628   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
10629   print_encoding_base ("", lpstart_encoding);
10630   if (lpstart_encoding != DW_EH_PE_omit)
10631     {
10632       uint64_t lpstart;
10633       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10634       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
10635     }
10636 
10637   if (unlikely (readp + 1 > dataend))
10638     goto invalid_data;
10639   unsigned int ttype_encoding = *readp++;
10640   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
10641   print_encoding_base ("", ttype_encoding);
10642   const unsigned char *ttype_base = NULL;
10643   if (ttype_encoding != DW_EH_PE_omit)
10644     {
10645       unsigned int ttype_base_offset;
10646       get_uleb128 (ttype_base_offset, readp, dataend);
10647       printf (" TType base offset:   %#x\n", ttype_base_offset);
10648       if ((size_t) (dataend - readp) > ttype_base_offset)
10649         ttype_base = readp + ttype_base_offset;
10650     }
10651 
10652   if (unlikely (readp + 1 > dataend))
10653     goto invalid_data;
10654   unsigned int call_site_encoding = *readp++;
10655   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
10656   print_encoding_base ("", call_site_encoding);
10657   unsigned int call_site_table_len;
10658   get_uleb128 (call_site_table_len, readp, dataend);
10659 
10660   const unsigned char *const action_table = readp + call_site_table_len;
10661   if (unlikely (action_table > dataend))
10662     goto invalid_data;
10663   unsigned int u = 0;
10664   unsigned int max_action = 0;
10665   while (readp < action_table)
10666     {
10667       if (u == 0)
10668 	puts (gettext ("\n Call site table:"));
10669 
10670       uint64_t call_site_start;
10671       readp = read_encoded (call_site_encoding, readp, dataend,
10672 			    &call_site_start, dbg);
10673       uint64_t call_site_length;
10674       readp = read_encoded (call_site_encoding, readp, dataend,
10675 			    &call_site_length, dbg);
10676       uint64_t landing_pad;
10677       readp = read_encoded (call_site_encoding, readp, dataend,
10678 			    &landing_pad, dbg);
10679       unsigned int action;
10680       get_uleb128 (action, readp, dataend);
10681       max_action = MAX (action, max_action);
10682       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
10683 		       "        Call site length:  %" PRIu64 "\n"
10684 		       "        Landing pad:       %#" PRIx64 "\n"
10685 		       "        Action:            %u\n"),
10686 	      u++, call_site_start, call_site_length, landing_pad, action);
10687     }
10688   if (readp != action_table)
10689     goto invalid_data;
10690 
10691   unsigned int max_ar_filter = 0;
10692   if (max_action > 0)
10693     {
10694       puts ("\n Action table:");
10695 
10696       size_t maxdata = (size_t) (dataend - action_table);
10697       if (max_action > maxdata || maxdata - max_action < 1)
10698 	{
10699 	invalid_action_table:
10700 	  fputs (gettext ("   <INVALID DATA>\n"), stdout);
10701 	  return;
10702 	}
10703 
10704       const unsigned char *const action_table_end
10705 	= action_table + max_action + 1;
10706 
10707       u = 0;
10708       do
10709 	{
10710 	  int ar_filter;
10711 	  get_sleb128 (ar_filter, readp, action_table_end);
10712 	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10713 	    max_ar_filter = ar_filter;
10714 	  int ar_disp;
10715 	  if (readp >= action_table_end)
10716 	    goto invalid_action_table;
10717 	  get_sleb128 (ar_disp, readp, action_table_end);
10718 
10719 	  printf (" [%4u] ar_filter:  % d\n"
10720 		  "        ar_disp:    % -5d",
10721 		  u, ar_filter, ar_disp);
10722 	  if (abs (ar_disp) & 1)
10723 	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10724 	  else if (ar_disp != 0)
10725 	    puts (" -> ???");
10726 	  else
10727 	    putchar_unlocked ('\n');
10728 	  ++u;
10729 	}
10730       while (readp < action_table_end);
10731     }
10732 
10733   if (max_ar_filter > 0 && ttype_base != NULL)
10734     {
10735       unsigned char dsize;
10736       puts ("\n TType table:");
10737 
10738       // XXX Not *4, size of encoding;
10739       switch (ttype_encoding & 7)
10740 	{
10741 	case DW_EH_PE_udata2:
10742 	case DW_EH_PE_sdata2:
10743 	  dsize = 2;
10744 	  break;
10745 	case DW_EH_PE_udata4:
10746 	case DW_EH_PE_sdata4:
10747 	  dsize = 4;
10748 	  break;
10749 	case DW_EH_PE_udata8:
10750 	case DW_EH_PE_sdata8:
10751 	  dsize = 8;
10752 	  break;
10753 	default:
10754 	  dsize = 0;
10755 	  error (1, 0, gettext ("invalid TType encoding"));
10756 	  abort();
10757 	}
10758 
10759       if (max_ar_filter
10760 	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10761 	goto invalid_data;
10762 
10763       readp = ttype_base - max_ar_filter * dsize;
10764       do
10765 	{
10766 	  uint64_t ttype;
10767 	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10768 				dbg);
10769 	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10770 	}
10771       while (readp < ttype_base);
10772     }
10773 }
10774 
10775 /* Print the content of the '.gdb_index' section.
10776    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10777 */
10778 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10779 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10780 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10781 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10782 {
10783   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10784 		   " contains %" PRId64 " bytes :\n"),
10785 	  elf_ndxscn (scn), section_name (ebl, shdr),
10786 	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10787 
10788   Elf_Data *data = elf_rawdata (scn, NULL);
10789 
10790   if (unlikely (data == NULL))
10791     {
10792       error (0, 0, gettext ("cannot get %s content: %s"),
10793 	     ".gdb_index", elf_errmsg (-1));
10794       return;
10795     }
10796 
10797   // .gdb_index is always in little endian.
10798   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10799   dbg = &dummy_dbg;
10800 
10801   const unsigned char *readp = data->d_buf;
10802   const unsigned char *const dataend = readp + data->d_size;
10803 
10804   if (unlikely (readp + 4 > dataend))
10805     {
10806     invalid_data:
10807       error (0, 0, gettext ("invalid data"));
10808       return;
10809     }
10810 
10811   int32_t vers = read_4ubyte_unaligned (dbg, readp);
10812   printf (gettext (" Version:         %" PRId32 "\n"), vers);
10813 
10814   // The only difference between version 4 and version 5 is the
10815   // hash used for generating the table.  Version 6 contains symbols
10816   // for inlined functions, older versions didn't.  Version 7 adds
10817   // symbol kinds.  Version 8 just indicates that it correctly includes
10818   // TUs for symbols.
10819   if (vers < 4 || vers > 8)
10820     {
10821       printf (gettext ("  unknown version, cannot parse section\n"));
10822       return;
10823     }
10824 
10825   readp += 4;
10826   if (unlikely (readp + 4 > dataend))
10827     goto invalid_data;
10828 
10829   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10830   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
10831 
10832   readp += 4;
10833   if (unlikely (readp + 4 > dataend))
10834     goto invalid_data;
10835 
10836   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10837   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
10838 
10839   readp += 4;
10840   if (unlikely (readp + 4 > dataend))
10841     goto invalid_data;
10842 
10843   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10844   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
10845 
10846   readp += 4;
10847   if (unlikely (readp + 4 > dataend))
10848     goto invalid_data;
10849 
10850   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10851   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
10852 
10853   readp += 4;
10854   if (unlikely (readp + 4 > dataend))
10855     goto invalid_data;
10856 
10857   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10858   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10859 
10860   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10861 		< const_off))
10862     goto invalid_data;
10863 
10864   readp = data->d_buf + cu_off;
10865 
10866   const unsigned char *nextp = data->d_buf + tu_off;
10867   if (tu_off >= data->d_size)
10868     goto invalid_data;
10869 
10870   size_t cu_nr = (nextp - readp) / 16;
10871 
10872   printf (gettext ("\n CU list at offset %#" PRIx32
10873 		   " contains %zu entries:\n"),
10874 	  cu_off, cu_nr);
10875 
10876   size_t n = 0;
10877   while (dataend - readp >= 16 && n < cu_nr)
10878     {
10879       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10880       readp += 8;
10881 
10882       uint64_t len = read_8ubyte_unaligned (dbg, readp);
10883       readp += 8;
10884 
10885       printf (" [%4zu] start: %0#8" PRIx64
10886 	      ", length: %5" PRIu64 "\n", n, off, len);
10887       n++;
10888     }
10889 
10890   readp = data->d_buf + tu_off;
10891   nextp = data->d_buf + addr_off;
10892   if (addr_off >= data->d_size)
10893     goto invalid_data;
10894 
10895   size_t tu_nr = (nextp - readp) / 24;
10896 
10897   printf (gettext ("\n TU list at offset %#" PRIx32
10898 		   " contains %zu entries:\n"),
10899 	  tu_off, tu_nr);
10900 
10901   n = 0;
10902   while (dataend - readp >= 24 && n < tu_nr)
10903     {
10904       uint64_t off = read_8ubyte_unaligned (dbg, readp);
10905       readp += 8;
10906 
10907       uint64_t type = read_8ubyte_unaligned (dbg, readp);
10908       readp += 8;
10909 
10910       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10911       readp += 8;
10912 
10913       printf (" [%4zu] CU offset: %5" PRId64
10914 	      ", type offset: %5" PRId64
10915 	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10916       n++;
10917     }
10918 
10919   readp = data->d_buf + addr_off;
10920   nextp = data->d_buf + sym_off;
10921   if (sym_off >= data->d_size)
10922     goto invalid_data;
10923 
10924   size_t addr_nr = (nextp - readp) / 20;
10925 
10926   printf (gettext ("\n Address list at offset %#" PRIx32
10927 		   " contains %zu entries:\n"),
10928 	  addr_off, addr_nr);
10929 
10930   n = 0;
10931   while (dataend - readp >= 20 && n < addr_nr)
10932     {
10933       uint64_t low = read_8ubyte_unaligned (dbg, readp);
10934       readp += 8;
10935 
10936       uint64_t high = read_8ubyte_unaligned (dbg, readp);
10937       readp += 8;
10938 
10939       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10940       readp += 4;
10941 
10942       printf (" [%4zu] ", n);
10943       print_dwarf_addr (dwflmod, 8, low, low);
10944       printf ("..");
10945       print_dwarf_addr (dwflmod, 8, high - 1, high);
10946       printf (", CU index: %5" PRId32 "\n", idx);
10947       n++;
10948     }
10949 
10950   const unsigned char *const_start = data->d_buf + const_off;
10951   if (const_off >= data->d_size)
10952     goto invalid_data;
10953 
10954   readp = data->d_buf + sym_off;
10955   nextp = const_start;
10956   size_t sym_nr = (nextp - readp) / 8;
10957 
10958   printf (gettext ("\n Symbol table at offset %#" PRIx32
10959 		   " contains %zu slots:\n"),
10960 	  addr_off, sym_nr);
10961 
10962   n = 0;
10963   while (dataend - readp >= 8 && n < sym_nr)
10964     {
10965       uint32_t name = read_4ubyte_unaligned (dbg, readp);
10966       readp += 4;
10967 
10968       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10969       readp += 4;
10970 
10971       if (name != 0 || vector != 0)
10972 	{
10973 	  const unsigned char *sym = const_start + name;
10974 	  if (unlikely ((size_t) (dataend - const_start) < name
10975 			|| memchr (sym, '\0', dataend - sym) == NULL))
10976 	    goto invalid_data;
10977 
10978 	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10979 
10980 	  const unsigned char *readcus = const_start + vector;
10981 	  if (unlikely ((size_t) (dataend - const_start) < vector))
10982 	    goto invalid_data;
10983 	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10984 	  while (cus--)
10985 	    {
10986 	      uint32_t cu_kind, cu, kind;
10987 	      bool is_static;
10988 	      readcus += 4;
10989 	      if (unlikely (readcus + 4 > dataend))
10990 		goto invalid_data;
10991 	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
10992 	      cu = cu_kind & ((1 << 24) - 1);
10993 	      kind = (cu_kind >> 28) & 7;
10994 	      is_static = cu_kind & (1U << 31);
10995 	      if (cu > cu_nr - 1)
10996 		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10997 	      else
10998 		printf ("%" PRId32, cu);
10999 	      if (kind != 0)
11000 		{
11001 		  printf (" (");
11002 		  switch (kind)
11003 		    {
11004 		    case 1:
11005 		      printf ("type");
11006 		      break;
11007 		    case 2:
11008 		      printf ("var");
11009 		      break;
11010 		    case 3:
11011 		      printf ("func");
11012 		      break;
11013 		    case 4:
11014 		      printf ("other");
11015 		      break;
11016 		    default:
11017 		      printf ("unknown-0x%" PRIx32, kind);
11018 		      break;
11019 		    }
11020 		  printf (":%c)", (is_static ? 'S' : 'G'));
11021 		}
11022 	      if (cus > 0)
11023 		printf (", ");
11024 	    }
11025 	  printf ("\n");
11026 	}
11027       n++;
11028     }
11029 }
11030 
11031 /* Returns true and sets split DWARF CU id if there is a split compile
11032    unit in the given Dwarf, and no non-split units are found (before it).  */
11033 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11034 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11035 {
11036   Dwarf_CU *cu = NULL;
11037   while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11038     {
11039       uint8_t unit_type;
11040       if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11041 			 id, NULL, NULL) != 0)
11042 	return false;
11043 
11044       if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11045 	return false;
11046 
11047       /* We really only care about the split compile unit, the types
11048 	 should be fine and self sufficient.  Also they don't have an
11049 	 id that we can match with a skeleton unit.  */
11050       if (unit_type == DW_UT_split_compile)
11051 	{
11052 	  *split_cu = cu;
11053 	  return true;
11054 	}
11055     }
11056 
11057   return false;
11058 }
11059 
11060 /* Check that there is one and only one Dwfl_Module, return in arg.  */
11061 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11062 getone_dwflmod (Dwfl_Module *dwflmod,
11063 	       void **userdata __attribute__ ((unused)),
11064 	       const char *name __attribute__ ((unused)),
11065 	       Dwarf_Addr base __attribute__ ((unused)),
11066 	       void *arg)
11067 {
11068   Dwfl_Module **m = (Dwfl_Module **) arg;
11069   if (*m != NULL)
11070     return DWARF_CB_ABORT;
11071   *m = dwflmod;
11072   return DWARF_CB_OK;
11073 }
11074 
11075 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11076 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11077 {
11078   /* Used for skeleton file, if necessary for split DWARF.  */
11079   Dwfl *skel_dwfl = NULL;
11080   Dwfl_Module *skel_mod = NULL;
11081   char *skel_name = NULL;
11082   Dwarf *split_dbg = NULL;
11083   Dwarf_CU *split_cu = NULL;
11084 
11085   /* Before we start the real work get a debug context descriptor.  */
11086   Dwarf_Addr dwbias;
11087   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11088   Dwarf dummy_dbg =
11089     {
11090       .elf = ebl->elf,
11091       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11092     };
11093   if (dbg == NULL)
11094     {
11095       if ((print_debug_sections & ~section_exception) != 0)
11096 	error (0, 0, gettext ("cannot get debug context descriptor: %s"),
11097 	       dwfl_errmsg (-1));
11098       dbg = &dummy_dbg;
11099     }
11100   else
11101     {
11102       /* If we are asked about a split dwarf (.dwo) file, use the user
11103 	 provided, or find the corresponding skeleton file. If we got
11104 	 a skeleton file, replace the given dwflmod and dbg, with one
11105 	 derived from the skeleton file to provide enough context.  */
11106       uint64_t split_id;
11107       if (is_split_dwarf (dbg, &split_id, &split_cu))
11108 	{
11109 	  if (dwarf_skeleton != NULL)
11110 	    skel_name = strdup (dwarf_skeleton);
11111 	  else
11112 	    {
11113 	      /* Replace file.dwo with file.o and see if that matches. */
11114 	      const char *fname;
11115 	      dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11116 				&fname, NULL);
11117 	      if (fname != NULL)
11118 		{
11119 		  size_t flen = strlen (fname);
11120 		  if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11121 		    {
11122 		      skel_name = strdup (fname);
11123 		      if (skel_name != NULL)
11124 			{
11125 			  skel_name[flen - 3] = 'o';
11126 			  skel_name[flen - 2] = '\0';
11127 			}
11128 		    }
11129 		}
11130 	    }
11131 
11132 	  if (skel_name != NULL)
11133 	    {
11134 	      int skel_fd = open (skel_name, O_RDONLY);
11135 	      if (skel_fd == -1)
11136 		fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11137 			 " '%s'\n", skel_name);
11138 	      else
11139 		skel_dwfl = create_dwfl (skel_fd, skel_name);
11140 
11141 	      if (skel_dwfl != NULL)
11142 		{
11143 		  if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11144 				       &skel_mod, 0) != 0)
11145 		    {
11146 		      fprintf (stderr, "Warning: Bad DWARF skeleton,"
11147 			       " multiple modules '%s'\n", skel_name);
11148 		      dwfl_end (skel_dwfl);
11149 		      skel_mod = NULL;
11150 		    }
11151 		}
11152 	      else if (skel_fd != -1)
11153 		fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11154 			 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11155 
11156 	      if (skel_mod != NULL)
11157 		{
11158 		  Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11159 		  if (skel_dbg != NULL)
11160 		    {
11161 		      /* First check the skeleton CU DIE, only fetch
11162 			 the split DIE if we know the id matches to
11163 			 not unnecessary search for any split DIEs we
11164 			 don't need. */
11165 		      Dwarf_CU *cu = NULL;
11166 		      while (dwarf_get_units (skel_dbg, cu, &cu,
11167 					      NULL, NULL, NULL, NULL) == 0)
11168 			{
11169 			  uint8_t unit_type;
11170 			  uint64_t skel_id;
11171 			  if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11172 					     &skel_id, NULL, NULL) == 0
11173 			      && unit_type == DW_UT_skeleton
11174 			      && split_id == skel_id)
11175 			    {
11176 			      Dwarf_Die subdie;
11177 			      if (dwarf_cu_info (cu, NULL, NULL, NULL,
11178 						 &subdie,
11179 						 NULL, NULL, NULL) == 0
11180 				  && dwarf_tag (&subdie) != DW_TAG_invalid)
11181 				{
11182 				  split_dbg = dwarf_cu_getdwarf (subdie.cu);
11183 				  if (split_dbg == NULL)
11184 				    fprintf (stderr,
11185 					     "Warning: Couldn't get split_dbg:"
11186 					     " %s\n", dwarf_errmsg (-1));
11187 				  break;
11188 				}
11189 			      else
11190 				{
11191 				  /* Everything matches up, but not
11192 				     according to libdw. Which means
11193 				     the user knew better.  So...
11194 				     Terrible hack... We can never
11195 				     destroy the underlying dwfl
11196 				     because it would free the wrong
11197 				     Dwarfs... So we leak memory...*/
11198 				  if (cu->split == NULL
11199 				      && dwarf_skeleton != NULL)
11200 				    {
11201 				      do_not_close_dwfl = true;
11202 				      __libdw_link_skel_split (cu, split_cu);
11203 				      split_dbg = dwarf_cu_getdwarf (split_cu);
11204 				      break;
11205 				    }
11206 				  else
11207 				    fprintf (stderr, "Warning: Couldn't get"
11208 					     " skeleton subdie: %s\n",
11209 					     dwarf_errmsg (-1));
11210 				}
11211 			    }
11212 			}
11213 		      if (split_dbg == NULL)
11214 			fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11215 		    }
11216 		  else
11217 		    fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11218 			     " %s\n", dwfl_errmsg (-1));
11219 		}
11220 	    }
11221 
11222 	  if (split_dbg != NULL)
11223 	    {
11224 	      dbg = split_dbg;
11225 	      dwflmod = skel_mod;
11226 	    }
11227 	  else if (skel_name == NULL)
11228 	    fprintf (stderr,
11229 		     "Warning: split DWARF file, but no skeleton found.\n");
11230 	}
11231       else if (dwarf_skeleton != NULL)
11232 	fprintf (stderr, "Warning: DWARF skeleton given,"
11233 		 " but not a split DWARF file\n");
11234     }
11235 
11236   /* Get the section header string table index.  */
11237   size_t shstrndx;
11238   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11239     error (EXIT_FAILURE, 0,
11240 	   gettext ("cannot get section header string table index"));
11241 
11242   /* If the .debug_info section is listed as implicitly required then
11243      we must make sure to handle it before handling any other debug
11244      section.  Various other sections depend on the CU DIEs being
11245      scanned (silently) first.  */
11246   bool implicit_info = (implicit_debug_sections & section_info) != 0;
11247   bool explicit_info = (print_debug_sections & section_info) != 0;
11248   if (implicit_info)
11249     {
11250       Elf_Scn *scn = NULL;
11251       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11252 	{
11253 	  GElf_Shdr shdr_mem;
11254 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11255 
11256 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11257 	    {
11258 	      const char *name = elf_strptr (ebl->elf, shstrndx,
11259 					     shdr->sh_name);
11260 	      if (name == NULL)
11261 		continue;
11262 
11263 	      if (strcmp (name, ".debug_info") == 0
11264 		  || strcmp (name, ".debug_info.dwo") == 0
11265 		  || strcmp (name, ".zdebug_info") == 0
11266 		  || strcmp (name, ".zdebug_info.dwo") == 0)
11267 		{
11268 		  print_debug_info_section (dwflmod, ebl, ehdr,
11269 					    scn, shdr, dbg);
11270 		  break;
11271 		}
11272 	    }
11273 	}
11274       print_debug_sections &= ~section_info;
11275       implicit_debug_sections &= ~section_info;
11276     }
11277 
11278   /* Look through all the sections for the debugging sections to print.  */
11279   Elf_Scn *scn = NULL;
11280   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11281     {
11282       GElf_Shdr shdr_mem;
11283       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11284 
11285       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11286 	{
11287 	  static const struct
11288 	  {
11289 	    const char *name;
11290 	    enum section_e bitmask;
11291 	    void (*fp) (Dwfl_Module *, Ebl *,
11292 			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11293 	  } debug_sections[] =
11294 	    {
11295 #define NEW_SECTION(name) \
11296 	      { ".debug_" #name, section_##name, print_debug_##name##_section }
11297 	      NEW_SECTION (abbrev),
11298 	      NEW_SECTION (addr),
11299 	      NEW_SECTION (aranges),
11300 	      NEW_SECTION (frame),
11301 	      NEW_SECTION (info),
11302 	      NEW_SECTION (types),
11303 	      NEW_SECTION (line),
11304 	      NEW_SECTION (loc),
11305 	      /* loclists is loc for DWARF5.  */
11306 	      { ".debug_loclists", section_loc,
11307 		print_debug_loclists_section },
11308 	      NEW_SECTION (pubnames),
11309 	      NEW_SECTION (str),
11310 	      /* A DWARF5 specialised debug string section.  */
11311 	      { ".debug_line_str", section_str,
11312 		print_debug_str_section },
11313 	      /* DWARF5 string offsets table.  */
11314 	      { ".debug_str_offsets", section_str,
11315 		print_debug_str_offsets_section },
11316 	      NEW_SECTION (macinfo),
11317 	      NEW_SECTION (macro),
11318 	      NEW_SECTION (ranges),
11319 	      /* rnglists is ranges for DWARF5.  */
11320 	      { ".debug_rnglists", section_ranges,
11321 		print_debug_rnglists_section },
11322 	      { ".eh_frame", section_frame | section_exception,
11323 		print_debug_frame_section },
11324 	      { ".eh_frame_hdr", section_frame | section_exception,
11325 		print_debug_frame_hdr_section },
11326 	      { ".gcc_except_table", section_frame | section_exception,
11327 		print_debug_exception_table },
11328 	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
11329 	    };
11330 	  const int ndebug_sections = (sizeof (debug_sections)
11331 				       / sizeof (debug_sections[0]));
11332 	  const char *name = elf_strptr (ebl->elf, shstrndx,
11333 					 shdr->sh_name);
11334 	  if (name == NULL)
11335 	    continue;
11336 
11337 	  int n;
11338 	  for (n = 0; n < ndebug_sections; ++n)
11339 	    {
11340 	      size_t dbglen = strlen (debug_sections[n].name);
11341 	      size_t scnlen = strlen (name);
11342 	      if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11343 		   && (dbglen == scnlen
11344 		       || (scnlen == dbglen + 4
11345 			   && strstr (name, ".dwo") == name + dbglen)))
11346 		  || (name[0] == '.' && name[1] == 'z'
11347 		      && debug_sections[n].name[1] == 'd'
11348 		      && strncmp (&name[2], &debug_sections[n].name[1],
11349 				  dbglen - 1) == 0
11350 		      && (scnlen == dbglen + 1
11351 			  || (scnlen == dbglen + 5
11352 			      && strstr (name, ".dwo") == name + dbglen + 1))))
11353 		{
11354 		  if ((print_debug_sections | implicit_debug_sections)
11355 		      & debug_sections[n].bitmask)
11356 		    debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11357 		  break;
11358 		}
11359 	    }
11360 	}
11361     }
11362 
11363   dwfl_end (skel_dwfl);
11364   free (skel_name);
11365 
11366   /* Turn implicit and/or explicit back on in case we go over another file.  */
11367   if (implicit_info)
11368     implicit_debug_sections |= section_info;
11369   if (explicit_info)
11370     print_debug_sections |= section_info;
11371 
11372   reset_listptr (&known_locsptr);
11373   reset_listptr (&known_loclistsptr);
11374   reset_listptr (&known_rangelistptr);
11375   reset_listptr (&known_rnglistptr);
11376   reset_listptr (&known_addrbases);
11377   reset_listptr (&known_stroffbases);
11378 }
11379 
11380 
11381 #define ITEM_INDENT		4
11382 #define WRAP_COLUMN		75
11383 
11384 /* Print "NAME: FORMAT", wrapping when output text would make the line
11385    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
11386    but this function is also used for registers which should be printed
11387    aligned.  Fortunately registers output uses fixed fields width (such
11388    as %11d) for the alignment.
11389 
11390    Line breaks should not depend on the particular values although that
11391    may happen in some cases of the core items.  */
11392 
11393 static unsigned int
11394 __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,...)11395 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11396 		 size_t name_width, const char *name, const char *format, ...)
11397 {
11398   size_t len = strlen (name);
11399   if (name_width < len)
11400     name_width = len;
11401 
11402   char *out;
11403   va_list ap;
11404   va_start (ap, format);
11405   int out_len = vasprintf (&out, format, ap);
11406   va_end (ap);
11407   if (out_len == -1)
11408     error (EXIT_FAILURE, 0, _("memory exhausted"));
11409 
11410   size_t n = name_width + sizeof ": " - 1 + out_len;
11411 
11412   if (colno == 0)
11413     {
11414       printf ("%*s", ITEM_INDENT, "");
11415       colno = ITEM_INDENT + n;
11416     }
11417   else if (colno + 2 + n < wrap)
11418     {
11419       printf ("%c ", sep);
11420       colno += 2 + n;
11421     }
11422   else
11423     {
11424       printf ("\n%*s", ITEM_INDENT, "");
11425       colno = ITEM_INDENT + n;
11426     }
11427 
11428   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11429 
11430   free (out);
11431 
11432   return colno;
11433 }
11434 
11435 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11436 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11437 	 void *value, const void *data, size_t size)
11438 {
11439   Elf_Data valuedata =
11440     {
11441       .d_type = type,
11442       .d_buf = value,
11443       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11444       .d_version = EV_CURRENT,
11445     };
11446   Elf_Data indata =
11447     {
11448       .d_type = type,
11449       .d_buf = (void *) data,
11450       .d_size = valuedata.d_size,
11451       .d_version = EV_CURRENT,
11452     };
11453 
11454   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11455 		 ? elf32_xlatetom : elf64_xlatetom)
11456     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11457   if (d == NULL)
11458     error (EXIT_FAILURE, 0,
11459 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11460 
11461   return data + indata.d_size;
11462 }
11463 
11464 typedef uint8_t GElf_Byte;
11465 
11466 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11467 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11468 		  unsigned int colno, size_t *repeated_size)
11469 {
11470   uint_fast16_t count = item->count ?: 1;
11471   /* Ebl_Core_Item count is always a small number.
11472      Make sure the backend didn't put in some large bogus value.  */
11473   assert (count < 128);
11474 
11475 #define TYPES								      \
11476   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
11477   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
11478   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
11479   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
11480   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
11481   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11482 
11483 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11484   typedef union { TYPES; } value_t;
11485   void *data = alloca (count * sizeof (value_t));
11486 #undef DO_TYPE
11487 
11488 #define DO_TYPE(NAME, Name, hex, dec) \
11489     GElf_##Name *value_##Name __attribute__((unused)) = data
11490   TYPES;
11491 #undef DO_TYPE
11492 
11493   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11494   size_t convsize = size;
11495   if (repeated_size != NULL)
11496     {
11497       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11498 	{
11499 	  data = alloca (*repeated_size);
11500 	  count *= *repeated_size / size;
11501 	  convsize = count * size;
11502 	  *repeated_size -= convsize;
11503 	}
11504       else if (item->count != 0 || item->format != '\n')
11505 	*repeated_size -= size;
11506     }
11507 
11508   convert (core, item->type, count, data, desc + item->offset, convsize);
11509 
11510   Elf_Type type = item->type;
11511   if (type == ELF_T_ADDR)
11512     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11513 
11514   switch (item->format)
11515     {
11516     case 'd':
11517       assert (count == 1);
11518       switch (type)
11519 	{
11520 #define DO_TYPE(NAME, Name, hex, dec)					      \
11521 	  case ELF_T_##NAME:						      \
11522 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11523 				     0, item->name, dec, value_##Name[0]); \
11524 	    break
11525 	  TYPES;
11526 #undef DO_TYPE
11527 	default:
11528 	  abort ();
11529 	}
11530       break;
11531 
11532     case 'x':
11533       assert (count == 1);
11534       switch (type)
11535 	{
11536 #define DO_TYPE(NAME, Name, hex, dec)					      \
11537 	  case ELF_T_##NAME:						      \
11538 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
11539 				     0, item->name, hex, value_##Name[0]);      \
11540 	    break
11541 	  TYPES;
11542 #undef DO_TYPE
11543 	default:
11544 	  abort ();
11545 	}
11546       break;
11547 
11548     case 'b':
11549     case 'B':
11550       assert (size % sizeof (unsigned int) == 0);
11551       unsigned int nbits = count * size * 8;
11552       unsigned int pop = 0;
11553       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11554 	pop += __builtin_popcount (*i);
11555       bool negate = pop > nbits / 2;
11556       const unsigned int bias = item->format == 'b';
11557 
11558       {
11559 	char printed[(negate ? nbits - pop : pop) * 16 + 1];
11560 	char *p = printed;
11561 	*p = '\0';
11562 
11563 	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11564 	  {
11565 	    assert (size == sizeof (unsigned int) * 2);
11566 	    for (unsigned int *i = data;
11567 		 (void *) i < data + count * size; i += 2)
11568 	      {
11569 		unsigned int w = i[1];
11570 		i[1] = i[0];
11571 		i[0] = w;
11572 	      }
11573 	  }
11574 
11575 	unsigned int lastbit = 0;
11576 	unsigned int run = 0;
11577 	for (const unsigned int *i = data;
11578 	     (void *) i < data + count * size; ++i)
11579 	  {
11580 	    unsigned int bit = ((void *) i - data) * 8;
11581 	    unsigned int w = negate ? ~*i : *i;
11582 	    while (w != 0)
11583 	      {
11584 		/* Note that a right shift equal to (or greater than)
11585 		   the number of bits of w is undefined behaviour.  In
11586 		   particular when the least significant bit is bit 32
11587 		   (w = 0x8000000) then w >>= n is undefined.  So
11588 		   explicitly handle that case separately.  */
11589 		unsigned int n = ffs (w);
11590 		if (n < sizeof (w) * 8)
11591 		  w >>= n;
11592 		else
11593 		  w = 0;
11594 		bit += n;
11595 
11596 		if (lastbit != 0 && lastbit + 1 == bit)
11597 		  ++run;
11598 		else
11599 		  {
11600 		    if (lastbit == 0)
11601 		      p += sprintf (p, "%u", bit - bias);
11602 		    else if (run == 0)
11603 		      p += sprintf (p, ",%u", bit - bias);
11604 		    else
11605 		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11606 		    run = 0;
11607 		  }
11608 
11609 		lastbit = bit;
11610 	      }
11611 	  }
11612 	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11613 	  p += sprintf (p, "-%u", lastbit - bias);
11614 
11615 	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11616 				 negate ? "~<%s>" : "<%s>", printed);
11617       }
11618       break;
11619 
11620     case 'T':
11621     case (char) ('T'|0x80):
11622       assert (count == 2);
11623       Dwarf_Word sec;
11624       Dwarf_Word usec;
11625       switch (type)
11626 	{
11627 #define DO_TYPE(NAME, Name, hex, dec)					      \
11628 	  case ELF_T_##NAME:						      \
11629 	    sec = value_##Name[0];					      \
11630 	    usec = value_##Name[1];					      \
11631 	    break
11632 	  TYPES;
11633 #undef DO_TYPE
11634 	default:
11635 	  abort ();
11636 	}
11637       if (unlikely (item->format == (char) ('T'|0x80)))
11638 	{
11639 	  /* This is a hack for an ill-considered 64-bit ABI where
11640 	     tv_usec is actually a 32-bit field with 32 bits of padding
11641 	     rounding out struct timeval.  We've already converted it as
11642 	     a 64-bit field.  For little-endian, this just means the
11643 	     high half is the padding; it's presumably zero, but should
11644 	     be ignored anyway.  For big-endian, it means the 32-bit
11645 	     field went into the high half of USEC.  */
11646 	  GElf_Ehdr ehdr_mem;
11647 	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11648 	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11649 	    usec >>= 32;
11650 	  else
11651 	    usec &= UINT32_MAX;
11652 	}
11653       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11654 			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
11655       break;
11656 
11657     case 'c':
11658       assert (count == 1);
11659       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11660 			       "%c", value_Byte[0]);
11661       break;
11662 
11663     case 's':
11664       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11665 			       "%.*s", (int) count, value_Byte);
11666       break;
11667 
11668     case '\n':
11669       /* This is a list of strings separated by '\n'.  */
11670       assert (item->count == 0);
11671       assert (repeated_size != NULL);
11672       assert (item->name == NULL);
11673       if (unlikely (item->offset >= *repeated_size))
11674 	break;
11675 
11676       const char *s = desc + item->offset;
11677       size = *repeated_size - item->offset;
11678       *repeated_size = 0;
11679       while (size > 0)
11680 	{
11681 	  const char *eol = memchr (s, '\n', size);
11682 	  int len = size;
11683 	  if (eol != NULL)
11684 	    len = eol - s;
11685 	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11686 	  if (eol == NULL)
11687 	    break;
11688 	  size -= eol + 1 - s;
11689 	  s = eol + 1;
11690 	}
11691 
11692       colno = WRAP_COLUMN;
11693       break;
11694 
11695     case 'h':
11696       break;
11697 
11698     default:
11699       error (0, 0, "XXX not handling format '%c' for %s",
11700 	     item->format, item->name);
11701       break;
11702     }
11703 
11704 #undef TYPES
11705 
11706   return colno;
11707 }
11708 
11709 
11710 /* Sort items by group, and by layout offset within each group.  */
11711 static int
compare_core_items(const void * a,const void * b)11712 compare_core_items (const void *a, const void *b)
11713 {
11714   const Ebl_Core_Item *const *p1 = a;
11715   const Ebl_Core_Item *const *p2 = b;
11716   const Ebl_Core_Item *item1 = *p1;
11717   const Ebl_Core_Item *item2 = *p2;
11718 
11719   return ((item1->group == item2->group ? 0
11720 	   : strcmp (item1->group, item2->group))
11721 	  ?: (int) item1->offset - (int) item2->offset);
11722 }
11723 
11724 /* Sort item groups by layout offset of the first item in the group.  */
11725 static int
compare_core_item_groups(const void * a,const void * b)11726 compare_core_item_groups (const void *a, const void *b)
11727 {
11728   const Ebl_Core_Item *const *const *p1 = a;
11729   const Ebl_Core_Item *const *const *p2 = b;
11730   const Ebl_Core_Item *const *group1 = *p1;
11731   const Ebl_Core_Item *const *group2 = *p2;
11732   const Ebl_Core_Item *item1 = *group1;
11733   const Ebl_Core_Item *item2 = *group2;
11734 
11735   return (int) item1->offset - (int) item2->offset;
11736 }
11737 
11738 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11739 handle_core_items (Elf *core, const void *desc, size_t descsz,
11740 		   const Ebl_Core_Item *items, size_t nitems)
11741 {
11742   if (nitems == 0)
11743     return 0;
11744   unsigned int colno = 0;
11745 
11746   /* FORMAT '\n' makes sense to be present only as a single item as it
11747      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
11748      if present as a single item but they can be also processed with other
11749      items below.  */
11750   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11751 		      || items[0].format == 'B'))
11752     {
11753       assert (items[0].offset == 0);
11754       size_t size = descsz;
11755       colno = handle_core_item (core, items, desc, colno, &size);
11756       /* If SIZE is not zero here there is some remaining data.  But we do not
11757 	 know how to process it anyway.  */
11758       return colno;
11759     }
11760   for (size_t i = 0; i < nitems; ++i)
11761     assert (items[i].format != '\n');
11762 
11763   /* Sort to collect the groups together.  */
11764   const Ebl_Core_Item *sorted_items[nitems];
11765   for (size_t i = 0; i < nitems; ++i)
11766     sorted_items[i] = &items[i];
11767   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11768 
11769   /* Collect the unique groups and sort them.  */
11770   const Ebl_Core_Item **groups[nitems];
11771   groups[0] = &sorted_items[0];
11772   size_t ngroups = 1;
11773   for (size_t i = 1; i < nitems; ++i)
11774     if (sorted_items[i]->group != sorted_items[i - 1]->group
11775 	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11776       groups[ngroups++] = &sorted_items[i];
11777   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11778 
11779   /* Write out all the groups.  */
11780   const void *last = desc;
11781   do
11782     {
11783       for (size_t i = 0; i < ngroups; ++i)
11784 	{
11785 	  for (const Ebl_Core_Item **item = groups[i];
11786 	       (item < &sorted_items[nitems]
11787 		&& ((*item)->group == groups[i][0]->group
11788 		    || !strcmp ((*item)->group, groups[i][0]->group)));
11789 	       ++item)
11790 	    colno = handle_core_item (core, *item, desc, colno, NULL);
11791 
11792 	  /* Force a line break at the end of the group.  */
11793 	  colno = WRAP_COLUMN;
11794 	}
11795 
11796       if (descsz == 0)
11797 	break;
11798 
11799       /* This set of items consumed a certain amount of the note's data.
11800 	 If there is more data there, we have another unit of the same size.
11801 	 Loop to print that out too.  */
11802       const Ebl_Core_Item *item = &items[nitems - 1];
11803       size_t eltsz = item->offset + gelf_fsize (core, item->type,
11804 						item->count ?: 1, EV_CURRENT);
11805 
11806       int reps = -1;
11807       do
11808 	{
11809 	  ++reps;
11810 	  desc += eltsz;
11811 	  descsz -= eltsz;
11812 	}
11813       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11814 
11815       if (reps == 1)
11816 	{
11817 	  /* For just one repeat, print it unabridged twice.  */
11818 	  desc -= eltsz;
11819 	  descsz += eltsz;
11820 	}
11821       else if (reps > 1)
11822 	printf (gettext ("\n%*s... <repeats %u more times> ..."),
11823 		ITEM_INDENT, "", reps);
11824 
11825       last = desc;
11826     }
11827   while (descsz > 0);
11828 
11829   return colno;
11830 }
11831 
11832 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11833 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11834 		      unsigned int colno)
11835 {
11836   desc += regloc->offset;
11837 
11838   abort ();			/* XXX */
11839   return colno;
11840 }
11841 
11842 
11843 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11844 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11845 		      const Ebl_Register_Location *regloc, const void *desc,
11846 		      unsigned int colno)
11847 {
11848   if (regloc->bits % 8 != 0)
11849     return handle_bit_registers (regloc, desc, colno);
11850 
11851   desc += regloc->offset;
11852 
11853   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11854     {
11855       char name[REGNAMESZ];
11856       int bits;
11857       int type;
11858       register_info (ebl, reg, regloc, name, &bits, &type);
11859 
11860 #define TYPES								      \
11861       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
11862       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
11863       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
11864       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
11865 
11866 #define BITS(bits, xtype, sfmt, ufmt)				\
11867       uint##bits##_t b##bits; int##bits##_t b##bits##s
11868       union { TYPES; uint64_t b128[2]; } value;
11869 #undef	BITS
11870 
11871       switch (type)
11872 	{
11873 	case DW_ATE_unsigned:
11874 	case DW_ATE_signed:
11875 	case DW_ATE_address:
11876 	  switch (bits)
11877 	    {
11878 #define BITS(bits, xtype, sfmt, ufmt)					      \
11879 	    case bits:							      \
11880 	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
11881 	      if (type == DW_ATE_signed)				      \
11882 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11883 					 maxregname, name,		      \
11884 					 sfmt, value.b##bits##s);	      \
11885 	      else							      \
11886 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
11887 					 maxregname, name,		      \
11888 					 ufmt, value.b##bits);		      \
11889 	      break
11890 
11891 	    TYPES;
11892 
11893 	    case 128:
11894 	      assert (type == DW_ATE_unsigned);
11895 	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11896 	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11897 	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
11898 				       maxregname, name,
11899 				       "0x%.16" PRIx64 "%.16" PRIx64,
11900 				       value.b128[!be], value.b128[be]);
11901 	      break;
11902 
11903 	    default:
11904 	      abort ();
11905 #undef	BITS
11906 	    }
11907 	  break;
11908 
11909 	default:
11910 	  /* Print each byte in hex, the whole thing in native byte order.  */
11911 	  assert (bits % 8 == 0);
11912 	  const uint8_t *bytes = desc;
11913 	  desc += bits / 8;
11914 	  char hex[bits / 4 + 1];
11915 	  hex[bits / 4] = '\0';
11916 	  int incr = 1;
11917 	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11918 	    {
11919 	      bytes += bits / 8 - 1;
11920 	      incr = -1;
11921 	    }
11922 	  size_t idx = 0;
11923 	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11924 	    {
11925 	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11926 	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11927 	    }
11928 	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
11929 				   maxregname, name, "0x%s", hex);
11930 	  break;
11931 	}
11932       desc += regloc->pad;
11933 
11934 #undef TYPES
11935     }
11936 
11937   return colno;
11938 }
11939 
11940 
11941 struct register_info
11942 {
11943   const Ebl_Register_Location *regloc;
11944   const char *set;
11945   char name[REGNAMESZ];
11946   int regno;
11947   int bits;
11948   int type;
11949 };
11950 
11951 static int
register_bitpos(const struct register_info * r)11952 register_bitpos (const struct register_info *r)
11953 {
11954   return (r->regloc->offset * 8
11955 	  + ((r->regno - r->regloc->regno)
11956 	     * (r->regloc->bits + r->regloc->pad * 8)));
11957 }
11958 
11959 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)11960 compare_sets_by_info (const struct register_info *r1,
11961 		      const struct register_info *r2)
11962 {
11963   return ((int) r2->bits - (int) r1->bits
11964 	  ?: register_bitpos (r1) - register_bitpos (r2));
11965 }
11966 
11967 /* Sort registers by set, and by size and layout offset within each set.  */
11968 static int
compare_registers(const void * a,const void * b)11969 compare_registers (const void *a, const void *b)
11970 {
11971   const struct register_info *r1 = a;
11972   const struct register_info *r2 = b;
11973 
11974   /* Unused elements sort last.  */
11975   if (r1->regloc == NULL)
11976     return r2->regloc == NULL ? 0 : 1;
11977   if (r2->regloc == NULL)
11978     return -1;
11979 
11980   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11981 	  ?: compare_sets_by_info (r1, r2));
11982 }
11983 
11984 /* Sort register sets by layout offset of the first register in the set.  */
11985 static int
compare_register_sets(const void * a,const void * b)11986 compare_register_sets (const void *a, const void *b)
11987 {
11988   const struct register_info *const *p1 = a;
11989   const struct register_info *const *p2 = b;
11990   return compare_sets_by_info (*p1, *p2);
11991 }
11992 
11993 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)11994 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11995 		       const Ebl_Register_Location *reglocs, size_t nregloc)
11996 {
11997   if (nregloc == 0)
11998     return 0;
11999 
12000   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12001   if (maxnreg <= 0)
12002     {
12003       for (size_t i = 0; i < nregloc; ++i)
12004 	if (maxnreg < reglocs[i].regno + reglocs[i].count)
12005 	  maxnreg = reglocs[i].regno + reglocs[i].count;
12006       assert (maxnreg > 0);
12007     }
12008 
12009   struct register_info regs[maxnreg];
12010   memset (regs, 0, sizeof regs);
12011 
12012   /* Sort to collect the sets together.  */
12013   int maxreg = 0;
12014   for (size_t i = 0; i < nregloc; ++i)
12015     for (int reg = reglocs[i].regno;
12016 	 reg < reglocs[i].regno + reglocs[i].count;
12017 	 ++reg)
12018       {
12019 	assert (reg < maxnreg);
12020 	if (reg > maxreg)
12021 	  maxreg = reg;
12022 	struct register_info *info = &regs[reg];
12023 	info->regloc = &reglocs[i];
12024 	info->regno = reg;
12025 	info->set = register_info (ebl, reg, &reglocs[i],
12026 				   info->name, &info->bits, &info->type);
12027       }
12028   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12029 
12030   /* Collect the unique sets and sort them.  */
12031   inline bool same_set (const struct register_info *a,
12032 			const struct register_info *b)
12033   {
12034     return (a < &regs[maxnreg] && a->regloc != NULL
12035 	    && b < &regs[maxnreg] && b->regloc != NULL
12036 	    && a->bits == b->bits
12037 	    && (a->set == b->set || !strcmp (a->set, b->set)));
12038   }
12039   struct register_info *sets[maxreg + 1];
12040   sets[0] = &regs[0];
12041   size_t nsets = 1;
12042   for (int i = 1; i <= maxreg; ++i)
12043     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
12044       sets[nsets++] = &regs[i];
12045   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12046 
12047   /* Write out all the sets.  */
12048   unsigned int colno = 0;
12049   for (size_t i = 0; i < nsets; ++i)
12050     {
12051       /* Find the longest name of a register in this set.  */
12052       size_t maxname = 0;
12053       const struct register_info *end;
12054       for (end = sets[i]; same_set (sets[i], end); ++end)
12055 	{
12056 	  size_t len = strlen (end->name);
12057 	  if (len > maxname)
12058 	    maxname = len;
12059 	}
12060 
12061       for (const struct register_info *reg = sets[i];
12062 	   reg < end;
12063 	   reg += reg->regloc->count ?: 1)
12064 	colno = handle_core_register (ebl, core, maxname,
12065 				      reg->regloc, desc, colno);
12066 
12067       /* Force a line break at the end of the group.  */
12068       colno = WRAP_COLUMN;
12069     }
12070 
12071   return colno;
12072 }
12073 
12074 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12075 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12076 {
12077   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12078   if (data == NULL)
12079   elf_error:
12080     error (EXIT_FAILURE, 0,
12081 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12082 
12083   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12084   for (size_t i = 0; i < nauxv; ++i)
12085     {
12086       GElf_auxv_t av_mem;
12087       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12088       if (av == NULL)
12089 	goto elf_error;
12090 
12091       const char *name;
12092       const char *fmt;
12093       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12094 	{
12095 	  /* Unknown type.  */
12096 	  if (av->a_un.a_val == 0)
12097 	    printf ("    %" PRIu64 "\n", av->a_type);
12098 	  else
12099 	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
12100 		    av->a_type, av->a_un.a_val);
12101 	}
12102       else
12103 	switch (fmt[0])
12104 	  {
12105 	  case '\0':		/* Normally zero.  */
12106 	    if (av->a_un.a_val == 0)
12107 	      {
12108 		printf ("    %s\n", name);
12109 		break;
12110 	      }
12111 	    FALLTHROUGH;
12112 	  case 'x':		/* hex */
12113 	  case 'p':		/* address */
12114 	  case 's':		/* address of string */
12115 	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12116 	    break;
12117 	  case 'u':
12118 	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
12119 	    break;
12120 	  case 'd':
12121 	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
12122 	    break;
12123 
12124 	  case 'b':
12125 	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
12126 	    GElf_Xword bit = 1;
12127 	    const char *pfx = "<";
12128 	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12129 	      {
12130 		if (av->a_un.a_val & bit)
12131 		  {
12132 		    printf ("%s%s", pfx, p);
12133 		    pfx = " ";
12134 		  }
12135 		bit <<= 1;
12136 	      }
12137 	    printf (">\n");
12138 	    break;
12139 
12140 	  default:
12141 	    abort ();
12142 	  }
12143     }
12144 }
12145 
12146 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12147 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12148 {
12149   return ptr < end && (size_t) (end - ptr) >= sz;
12150 }
12151 
12152 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12153 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12154 	      int *retp)
12155 {
12156   if (! buf_has_data (*ptrp, end, 4))
12157     return false;
12158 
12159   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12160   return true;
12161 }
12162 
12163 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12164 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12165 		uint64_t *retp)
12166 {
12167   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12168   if (! buf_has_data (*ptrp, end, sz))
12169     return false;
12170 
12171   union
12172   {
12173     uint64_t u64;
12174     uint32_t u32;
12175   } u;
12176 
12177   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12178 
12179   if (sz == 4)
12180     *retp = u.u32;
12181   else
12182     *retp = u.u64;
12183   return true;
12184 }
12185 
12186 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12187 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12188 {
12189   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12190   if (data == NULL)
12191     error (EXIT_FAILURE, 0,
12192 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12193 
12194   unsigned char const *ptr = data->d_buf;
12195   unsigned char const *const end = data->d_buf + data->d_size;
12196 
12197   /* Siginfo head is three ints: signal number, error number, origin
12198      code.  */
12199   int si_signo, si_errno, si_code;
12200   if (! buf_read_int (core, &ptr, end, &si_signo)
12201       || ! buf_read_int (core, &ptr, end, &si_errno)
12202       || ! buf_read_int (core, &ptr, end, &si_code))
12203     {
12204     fail:
12205       printf ("    Not enough data in NT_SIGINFO note.\n");
12206       return;
12207     }
12208 
12209   /* Next is a pointer-aligned union of structures.  On 64-bit
12210      machines, that implies a word of padding.  */
12211   if (gelf_getclass (core) == ELFCLASS64)
12212     ptr += 4;
12213 
12214   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
12215 	  si_signo, si_errno, si_code);
12216 
12217   if (si_code > 0)
12218     switch (si_signo)
12219       {
12220       case CORE_SIGILL:
12221       case CORE_SIGFPE:
12222       case CORE_SIGSEGV:
12223       case CORE_SIGBUS:
12224 	{
12225 	  uint64_t addr;
12226 	  if (! buf_read_ulong (core, &ptr, end, &addr))
12227 	    goto fail;
12228 	  printf ("    fault address: %#" PRIx64 "\n", addr);
12229 	  break;
12230 	}
12231       default:
12232 	;
12233       }
12234   else if (si_code == CORE_SI_USER)
12235     {
12236       int pid, uid;
12237       if (! buf_read_int (core, &ptr, end, &pid)
12238 	  || ! buf_read_int (core, &ptr, end, &uid))
12239 	goto fail;
12240       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
12241     }
12242 }
12243 
12244 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12245 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12246 {
12247   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12248   if (data == NULL)
12249     error (EXIT_FAILURE, 0,
12250 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12251 
12252   unsigned char const *ptr = data->d_buf;
12253   unsigned char const *const end = data->d_buf + data->d_size;
12254 
12255   uint64_t count, page_size;
12256   if (! buf_read_ulong (core, &ptr, end, &count)
12257       || ! buf_read_ulong (core, &ptr, end, &page_size))
12258     {
12259     fail:
12260       printf ("    Not enough data in NT_FILE note.\n");
12261       return;
12262     }
12263 
12264   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12265   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12266   if (count > maxcount)
12267     goto fail;
12268 
12269   /* Where file names are stored.  */
12270   unsigned char const *const fstart = ptr + 3 * count * addrsize;
12271   char const *fptr = (char *) fstart;
12272 
12273   printf ("    %" PRId64 " files:\n", count);
12274   for (uint64_t i = 0; i < count; ++i)
12275     {
12276       uint64_t mstart, mend, moffset;
12277       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12278 	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
12279 	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12280 	goto fail;
12281 
12282       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12283       if (fnext == NULL)
12284 	goto fail;
12285 
12286       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
12287 		       " %08" PRIx64 " %" PRId64,
12288 		       mstart, mend, moffset * page_size, mend - mstart);
12289       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12290 
12291       fptr = fnext + 1;
12292     }
12293 }
12294 
12295 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12296 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12297 		  const char *name, const void *desc)
12298 {
12299   GElf_Word regs_offset;
12300   size_t nregloc;
12301   const Ebl_Register_Location *reglocs;
12302   size_t nitems;
12303   const Ebl_Core_Item *items;
12304 
12305   if (! ebl_core_note (ebl, nhdr, name, desc,
12306 		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
12307     return;
12308 
12309   /* Pass 0 for DESCSZ when there are registers in the note,
12310      so that the ITEMS array does not describe the whole thing.
12311      For non-register notes, the actual descsz might be a multiple
12312      of the unit size, not just exactly the unit size.  */
12313   unsigned int colno = handle_core_items (ebl->elf, desc,
12314 					  nregloc == 0 ? nhdr->n_descsz : 0,
12315 					  items, nitems);
12316   if (colno != 0)
12317     putchar_unlocked ('\n');
12318 
12319   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12320 				 reglocs, nregloc);
12321   if (colno != 0)
12322     putchar_unlocked ('\n');
12323 }
12324 
12325 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12326 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12327 		   GElf_Off start, Elf_Data *data)
12328 {
12329   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
12330 
12331   if (data == NULL)
12332     goto bad_note;
12333 
12334   size_t offset = 0;
12335   GElf_Nhdr nhdr;
12336   size_t name_offset;
12337   size_t desc_offset;
12338   while (offset < data->d_size
12339 	 && (offset = gelf_getnote (data, offset,
12340 				    &nhdr, &name_offset, &desc_offset)) > 0)
12341     {
12342       const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12343       const char *desc = data->d_buf + desc_offset;
12344 
12345       /* GNU Build Attributes are weird, they store most of their data
12346 	 into the owner name field.  Extract just the owner name
12347 	 prefix here, then use the rest later as data.  */
12348       bool is_gnu_build_attr
12349 	= strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12350 		   strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12351       const char *print_name = (is_gnu_build_attr
12352 				? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12353       size_t print_namesz = (is_gnu_build_attr
12354 			     ? strlen (print_name) : nhdr.n_namesz);
12355 
12356       char buf[100];
12357       char buf2[100];
12358       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
12359 	      (int) print_namesz, print_name, nhdr.n_descsz,
12360 	      ehdr->e_type == ET_CORE
12361 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
12362 					 buf, sizeof (buf))
12363 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12364 					   nhdr.n_descsz,
12365 					   buf2, sizeof (buf2)));
12366 
12367       /* Filter out invalid entries.  */
12368       if (memchr (name, '\0', nhdr.n_namesz) != NULL
12369 	  /* XXX For now help broken Linux kernels.  */
12370 	  || 1)
12371 	{
12372 	  if (ehdr->e_type == ET_CORE)
12373 	    {
12374 	      if (nhdr.n_type == NT_AUXV
12375 		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
12376 		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
12377 		  && !memcmp (name, "CORE", 4))
12378 		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12379 				  start + desc_offset);
12380 	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12381 		switch (nhdr.n_type)
12382 		  {
12383 		  case NT_SIGINFO:
12384 		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12385 					 start + desc_offset);
12386 		    break;
12387 
12388 		  case NT_FILE:
12389 		    handle_file_note (ebl->elf, nhdr.n_descsz,
12390 				      start + desc_offset);
12391 		    break;
12392 
12393 		  default:
12394 		    handle_core_note (ebl, &nhdr, name, desc);
12395 		  }
12396 	      else
12397 		handle_core_note (ebl, &nhdr, name, desc);
12398 	    }
12399 	  else
12400 	    ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12401 			     nhdr.n_descsz, desc);
12402 	}
12403     }
12404 
12405   if (offset == data->d_size)
12406     return;
12407 
12408  bad_note:
12409   error (0, 0,
12410 	 gettext ("cannot get content of note: %s"),
12411 	 data != NULL ? "garbage data" : elf_errmsg (-1));
12412 }
12413 
12414 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12415 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12416 {
12417   /* If we have section headers, just look for SHT_NOTE sections.
12418      In a debuginfo file, the program headers are not reliable.  */
12419   if (shnum != 0)
12420     {
12421       /* Get the section header string table index.  */
12422       size_t shstrndx;
12423       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12424 	error (EXIT_FAILURE, 0,
12425 	       gettext ("cannot get section header string table index"));
12426 
12427       Elf_Scn *scn = NULL;
12428       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12429 	{
12430 	  GElf_Shdr shdr_mem;
12431 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12432 
12433 	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12434 	    /* Not what we are looking for.  */
12435 	    continue;
12436 
12437 	  if (notes_section != NULL)
12438 	    {
12439 	      char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12440 	      if (sname == NULL || strcmp (sname, notes_section) != 0)
12441 		continue;
12442 	    }
12443 
12444 	  printf (gettext ("\
12445 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12446 		  elf_ndxscn (scn),
12447 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12448 		  shdr->sh_size, shdr->sh_offset);
12449 
12450 	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
12451 			     elf_getdata (scn, NULL));
12452 	}
12453       return;
12454     }
12455 
12456   /* We have to look through the program header to find the note
12457      sections.  There can be more than one.  */
12458   for (size_t cnt = 0; cnt < phnum; ++cnt)
12459     {
12460       GElf_Phdr mem;
12461       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12462 
12463       if (phdr == NULL || phdr->p_type != PT_NOTE)
12464 	/* Not what we are looking for.  */
12465 	continue;
12466 
12467       printf (gettext ("\
12468 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12469 	      phdr->p_filesz, phdr->p_offset);
12470 
12471       handle_notes_data (ebl, ehdr, phdr->p_offset,
12472 			 elf_getdata_rawchunk (ebl->elf,
12473 					       phdr->p_offset, phdr->p_filesz,
12474 					       (phdr->p_align == 8
12475 						? ELF_T_NHDR8 : ELF_T_NHDR)));
12476     }
12477 }
12478 
12479 
12480 static void
hex_dump(const uint8_t * data,size_t len)12481 hex_dump (const uint8_t *data, size_t len)
12482 {
12483   size_t pos = 0;
12484   while (pos < len)
12485     {
12486       printf ("  0x%08zx ", pos);
12487 
12488       const size_t chunk = MIN (len - pos, 16);
12489 
12490       for (size_t i = 0; i < chunk; ++i)
12491 	if (i % 4 == 3)
12492 	  printf ("%02x ", data[pos + i]);
12493 	else
12494 	  printf ("%02x", data[pos + i]);
12495 
12496       if (chunk < 16)
12497 	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12498 
12499       for (size_t i = 0; i < chunk; ++i)
12500 	{
12501 	  unsigned char b = data[pos + i];
12502 	  printf ("%c", isprint (b) ? b : '.');
12503 	}
12504 
12505       putchar ('\n');
12506       pos += chunk;
12507     }
12508 }
12509 
12510 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12511 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12512 {
12513   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12514     printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12515 	    elf_ndxscn (scn), name);
12516   else
12517     {
12518       if (print_decompress)
12519 	{
12520 	  /* We try to decompress the section, but keep the old shdr around
12521 	     so we can show both the original shdr size and the uncompressed
12522 	     data size.   */
12523 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12524 	    {
12525 	      if (elf_compress (scn, 0, 0) < 0)
12526 		printf ("WARNING: %s [%zd]\n",
12527 			gettext ("Couldn't uncompress section"),
12528 			elf_ndxscn (scn));
12529 	    }
12530 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12531 	    {
12532 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12533 		printf ("WARNING: %s [%zd]\n",
12534 			gettext ("Couldn't uncompress section"),
12535 			elf_ndxscn (scn));
12536 	    }
12537 	}
12538 
12539       Elf_Data *data = elf_rawdata (scn, NULL);
12540       if (data == NULL)
12541 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12542 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12543       else
12544 	{
12545 	  if (data->d_size == shdr->sh_size)
12546 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12547 			     " bytes at offset %#0" PRIx64 ":\n"),
12548 		    elf_ndxscn (scn), name,
12549 		    shdr->sh_size, shdr->sh_offset);
12550 	  else
12551 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12552 			     " bytes (%zd uncompressed) at offset %#0"
12553 			     PRIx64 ":\n"),
12554 		    elf_ndxscn (scn), name,
12555 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12556 	  hex_dump (data->d_buf, data->d_size);
12557 	}
12558     }
12559 }
12560 
12561 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12562 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12563 {
12564   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12565     printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12566 	    elf_ndxscn (scn), name);
12567   else
12568     {
12569       if (print_decompress)
12570 	{
12571 	  /* We try to decompress the section, but keep the old shdr around
12572 	     so we can show both the original shdr size and the uncompressed
12573 	     data size.  */
12574 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12575 	    {
12576 	      if (elf_compress (scn, 0, 0) < 0)
12577 		printf ("WARNING: %s [%zd]\n",
12578 			gettext ("Couldn't uncompress section"),
12579 			elf_ndxscn (scn));
12580 	    }
12581 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12582 	    {
12583 	      if (elf_compress_gnu (scn, 0, 0) < 0)
12584 		printf ("WARNING: %s [%zd]\n",
12585 			gettext ("Couldn't uncompress section"),
12586 			elf_ndxscn (scn));
12587 	    }
12588 	}
12589 
12590       Elf_Data *data = elf_rawdata (scn, NULL);
12591       if (data == NULL)
12592 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12593 	       elf_ndxscn (scn), name, elf_errmsg (-1));
12594       else
12595 	{
12596 	  if (data->d_size == shdr->sh_size)
12597 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12598 			     " bytes at offset %#0" PRIx64 ":\n"),
12599 		    elf_ndxscn (scn), name,
12600 		    shdr->sh_size, shdr->sh_offset);
12601 	  else
12602 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12603 			     " bytes (%zd uncompressed) at offset %#0"
12604 			     PRIx64 ":\n"),
12605 		    elf_ndxscn (scn), name,
12606 		    shdr->sh_size, data->d_size, shdr->sh_offset);
12607 
12608 	  const char *start = data->d_buf;
12609 	  const char *const limit = start + data->d_size;
12610 	  do
12611 	    {
12612 	      const char *end = memchr (start, '\0', limit - start);
12613 	      const size_t pos = start - (const char *) data->d_buf;
12614 	      if (unlikely (end == NULL))
12615 		{
12616 		  printf ("  [%6zx]- %.*s\n",
12617 			  pos, (int) (limit - start), start);
12618 		  break;
12619 		}
12620 	      printf ("  [%6zx]  %s\n", pos, start);
12621 	      start = end + 1;
12622 	    } while (start < limit);
12623 	}
12624     }
12625 }
12626 
12627 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))12628 for_each_section_argument (Elf *elf, const struct section_argument *list,
12629 			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12630 					 const char *name))
12631 {
12632   /* Get the section header string table index.  */
12633   size_t shstrndx;
12634   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12635     error (EXIT_FAILURE, 0,
12636 	   gettext ("cannot get section header string table index"));
12637 
12638   for (const struct section_argument *a = list; a != NULL; a = a->next)
12639     {
12640       Elf_Scn *scn;
12641       GElf_Shdr shdr_mem;
12642       const char *name = NULL;
12643 
12644       char *endp = NULL;
12645       unsigned long int shndx = strtoul (a->arg, &endp, 0);
12646       if (endp != a->arg && *endp == '\0')
12647 	{
12648 	  scn = elf_getscn (elf, shndx);
12649 	  if (scn == NULL)
12650 	    {
12651 	      error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12652 	      continue;
12653 	    }
12654 
12655 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
12656 	    error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12657 		   elf_errmsg (-1));
12658 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12659 	  (*dump) (scn, &shdr_mem, name);
12660 	}
12661       else
12662 	{
12663 	  /* Need to look up the section by name.  */
12664 	  scn = NULL;
12665 	  bool found = false;
12666 	  while ((scn = elf_nextscn (elf, scn)) != NULL)
12667 	    {
12668 	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
12669 		continue;
12670 	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12671 	      if (name == NULL)
12672 		continue;
12673 	      if (!strcmp (name, a->arg))
12674 		{
12675 		  found = true;
12676 		  (*dump) (scn, &shdr_mem, name);
12677 		}
12678 	    }
12679 
12680 	  if (unlikely (!found) && !a->implicit)
12681 	    error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12682 	}
12683     }
12684 }
12685 
12686 static void
dump_data(Ebl * ebl)12687 dump_data (Ebl *ebl)
12688 {
12689   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12690 }
12691 
12692 static void
dump_strings(Ebl * ebl)12693 dump_strings (Ebl *ebl)
12694 {
12695   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12696 }
12697 
12698 static void
print_strings(Ebl * ebl)12699 print_strings (Ebl *ebl)
12700 {
12701   /* Get the section header string table index.  */
12702   size_t shstrndx;
12703   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12704     error (EXIT_FAILURE, 0,
12705 	   gettext ("cannot get section header string table index"));
12706 
12707   Elf_Scn *scn;
12708   GElf_Shdr shdr_mem;
12709   const char *name;
12710   scn = NULL;
12711   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12712     {
12713       if (gelf_getshdr (scn, &shdr_mem) == NULL)
12714 	continue;
12715 
12716       if (shdr_mem.sh_type != SHT_PROGBITS
12717 	  || !(shdr_mem.sh_flags & SHF_STRINGS))
12718 	continue;
12719 
12720       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12721       if (name == NULL)
12722 	continue;
12723 
12724       print_string_section (scn, &shdr_mem, name);
12725     }
12726 }
12727 
12728 static void
dump_archive_index(Elf * elf,const char * fname)12729 dump_archive_index (Elf *elf, const char *fname)
12730 {
12731   size_t narsym;
12732   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12733   if (arsym == NULL)
12734     {
12735       int result = elf_errno ();
12736       if (unlikely (result != ELF_E_NO_INDEX))
12737 	error (EXIT_FAILURE, 0,
12738 	       gettext ("cannot get symbol index of archive '%s': %s"),
12739 	       fname, elf_errmsg (result));
12740       else
12741 	printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12742       return;
12743     }
12744 
12745   printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12746 	  fname, narsym);
12747 
12748   size_t as_off = 0;
12749   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12750     {
12751       if (s->as_off != as_off)
12752 	{
12753 	  as_off = s->as_off;
12754 
12755 	  Elf *subelf = NULL;
12756 	  if (unlikely (elf_rand (elf, as_off) == 0)
12757 	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12758 			   == NULL))
12759 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12760 	    while (1)
12761 #endif
12762 	      error (EXIT_FAILURE, 0,
12763 		     gettext ("cannot extract member at offset %zu in '%s': %s"),
12764 		     as_off, fname, elf_errmsg (-1));
12765 
12766 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
12767 
12768 	  printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12769 
12770 	  elf_end (subelf);
12771 	}
12772 
12773       printf ("\t%s\n", s->as_name);
12774     }
12775 }
12776 
12777 #include "debugpred.h"
12778