• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Print information from ELF file in human-readable form.
2    Copyright (C) 1999-2018 Red Hat, Inc.
3    Copyright (C) 2023 Mark J. Wielaard <mark@klomp.org>
4    This file is part of elfutils.
5 
6    This file is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    elfutils is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 
23 #include <argp.h>
24 #include <assert.h>
25 #include <ctype.h>
26 #include <dwarf.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <gelf.h>
30 #include <inttypes.h>
31 #include <langinfo.h>
32 #include <libdw.h>
33 #include <libdwfl.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   { "syms", 's', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
120   { "dyn-syms", PRINT_DYNSYM_TABLE, NULL, 0,
121     N_("Display (only) the dynamic symbol table"), 0 },
122   { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
123   { "notes", 'n', "SECTION", OPTION_ARG_OPTIONAL, N_("Display the ELF notes"), 0 },
124   { "arch-specific", 'A', NULL, 0,
125     N_("Display architecture specific information, if any"), 0 },
126   { "exception", 'e', NULL, 0,
127     N_("Display sections for exception handling"), 0 },
128 
129   { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
130   { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
131     N_("Display DWARF section content.  SECTION can be one of abbrev, addr, "
132        "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
133        "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
134   { "hex-dump", 'x', "SECTION", 0,
135     N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
136   { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
137     N_("Print string contents of sections"), 0 },
138   { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
139   { "archive-index", 'c', NULL, 0,
140     N_("Display the symbol index of an archive"), 0 },
141   { "use-dynamic", 'D', NULL, 0,
142     N_("Use the dynamic segment when possible for displaying info"), 0 },
143 
144   { NULL, 0, NULL, 0, N_("Output control:"), 0 },
145   { "numeric-addresses", 'N', NULL, 0,
146     N_("Do not find symbol names for addresses in DWARF data"), 0 },
147   { "unresolved-address-offsets", 'U', NULL, 0,
148     N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
149   { "wide", 'W', NULL, 0,
150     N_("Ignored for compatibility (lines always wide)"), 0 },
151   { "decompress", 'z', NULL, 0,
152     N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
153   { NULL, 0, NULL, 0, NULL, 0 }
154 };
155 
156 /* Short description of program.  */
157 static const char doc[] = N_("\
158 Print information from ELF file in human-readable form.");
159 
160 /* Strings for arguments in help texts.  */
161 static const char args_doc[] = N_("FILE...");
162 
163 /* Prototype for option handler.  */
164 static error_t parse_opt (int key, char *arg, struct argp_state *state);
165 
166 /* Data structure to communicate with argp functions.  */
167 static struct argp argp =
168 {
169   options, parse_opt, args_doc, doc, NULL, NULL, NULL
170 };
171 
172 /* If non-null, the section from which we should read to (compressed) ELF.  */
173 static const char *elf_input_section = NULL;
174 
175 /* If non-null, the file that contains the skeleton CUs.  */
176 static const char *dwarf_skeleton = NULL;
177 
178 /* Flags set by the option controlling the output.  */
179 
180 /* True if dynamic segment should be printed.  */
181 static bool print_dynamic_table;
182 
183 /* True if the file header should be printed.  */
184 static bool print_file_header;
185 
186 /* True if the program headers should be printed.  */
187 static bool print_program_header;
188 
189 /* True if relocations should be printed.  */
190 static bool print_relocations;
191 
192 /* True if the section headers should be printed.  */
193 static bool print_section_header;
194 
195 /* True if the symbol table should be printed.  */
196 static bool print_symbol_table;
197 
198 /* True if (only) the dynsym table should be printed.  */
199 static bool print_dynsym_table;
200 
201 /* True if reconstruct dynamic symbol table from the PT_DYNAMIC segment.  */
202 static bool use_dynamic_segment;
203 
204 /* A specific section name, or NULL to print all symbol tables.  */
205 static char *symbol_table_section;
206 
207 /* A specific section name, or NULL to print all ELF notes.  */
208 static char *notes_section;
209 
210 /* True if the version information should be printed.  */
211 static bool print_version_info;
212 
213 /* True if section groups should be printed.  */
214 static bool print_section_groups;
215 
216 /* True if bucket list length histogram should be printed.  */
217 static bool print_histogram;
218 
219 /* True if the architecture specific data should be printed.  */
220 static bool print_arch;
221 
222 /* True if note section content should be printed.  */
223 static bool print_notes;
224 
225 /* True if SHF_STRINGS section content should be printed.  */
226 static bool print_string_sections;
227 
228 /* True if archive index should be printed.  */
229 static bool print_archive_index;
230 
231 /* True if any of the control options except print_archive_index is set.  */
232 static bool any_control_option;
233 
234 /* True if we should print addresses from DWARF in symbolic form.  */
235 static bool print_address_names = true;
236 
237 /* True if we should print raw values instead of relativized addresses.  */
238 static bool print_unresolved_addresses = false;
239 
240 /* True if we should print the .debug_aranges section using libdw.  */
241 static bool decodedaranges = false;
242 
243 /* True if we should print the .debug_aranges section using libdw.  */
244 static bool decodedline = false;
245 
246 /* True if we want to show more information about compressed sections.  */
247 static bool print_decompress = false;
248 
249 /* True if we want to show split compile units for debug_info skeletons.  */
250 static bool show_split_units = false;
251 
252 /* Select printing of debugging sections.  */
253 static enum section_e
254 {
255   section_abbrev = 1,		/* .debug_abbrev  */
256   section_aranges = 2,		/* .debug_aranges  */
257   section_frame = 4,		/* .debug_frame or .eh_frame & al.  */
258   section_info = 8,		/* .debug_info, (implies .debug_types)  */
259   section_line = 16,		/* .debug_line  */
260   section_loc = 32,		/* .debug_loc  */
261   section_pubnames = 64,	/* .debug_pubnames  */
262   section_str = 128,		/* .debug_str  */
263   section_macinfo = 256,	/* .debug_macinfo  */
264   section_ranges = 512, 	/* .debug_ranges  */
265   section_exception = 1024,	/* .eh_frame & al.  */
266   section_gdb_index = 2048,	/* .gdb_index  */
267   section_macro = 4096,		/* .debug_macro  */
268   section_addr = 8192,		/* .debug_addr  */
269   section_types = 16384,	/* .debug_types (implied by .debug_info)  */
270   section_all = (section_abbrev | section_aranges | section_frame
271 		 | section_info | section_line | section_loc
272 		 | section_pubnames | section_str | section_macinfo
273 		 | section_ranges | section_exception | section_gdb_index
274 		 | section_macro | section_addr | section_types)
275 } print_debug_sections, implicit_debug_sections;
276 
277 /* Select hex dumping of sections.  */
278 static struct section_argument *dump_data_sections;
279 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
280 
281 /* Select string dumping of sections.  */
282 static struct section_argument *string_sections;
283 static struct section_argument **string_sections_tail = &string_sections;
284 
285 struct section_argument
286 {
287   struct section_argument *next;
288   const char *arg;
289   bool implicit;
290 };
291 
292 /* Numbers of sections and program headers in the file.  */
293 static size_t shnum;
294 static size_t phnum;
295 
296 
297 /* Declarations of local functions.  */
298 static void process_file (int fd, const char *fname, bool only_one);
299 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
300 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
301 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
302 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
303 static void print_scngrp (Ebl *ebl);
304 static void print_dynamic (Ebl *ebl);
305 static void print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr);
306 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
307 			       GElf_Shdr *shdr);
308 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
309 				GElf_Shdr *shdr);
310 static void handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn,
311 				GElf_Shdr *shdr);
312 static bool print_symtab (Ebl *ebl, int type);
313 static bool handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
314 static bool handle_dynamic_symtab (Ebl *ebl);
315 static void
316 process_symtab(
317 	Ebl * ebl,
318 	unsigned int nsyms,
319 	Elf64_Word idx,
320 	Elf32_Word verneed_stridx,
321 	Elf32_Word verdef_stridx,
322 	Elf_Data * symdata,
323 	Elf_Data * versym_data,
324 	Elf_Data * symstr_data,
325 	Elf_Data * verneed_data,
326 	Elf_Data * verdef_data,
327 	Elf_Data * xndx_data);
328 static void print_verinfo (Ebl *ebl);
329 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
330 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
331 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
332 			   GElf_Shdr *shdr);
333 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
334 static void handle_hash (Ebl *ebl);
335 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
336 static void print_liblist (Ebl *ebl);
337 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
338 static void dump_data (Ebl *ebl);
339 static void dump_strings (Ebl *ebl);
340 static void print_strings (Ebl *ebl);
341 static void dump_archive_index (Elf *, const char *);
342 static void print_dwarf_addr (Dwfl_Module *dwflmod, int address_size,
343 			      Dwarf_Addr address, Dwarf_Addr raw);
344 
345 enum dyn_idx
346 {
347   i_symtab_shndx,
348   i_strsz,
349   i_verneed,
350   i_verneednum,
351   i_verdef,
352   i_verdefnum,
353   i_versym,
354   i_symtab,
355   i_strtab,
356   i_hash,
357   i_gnu_hash,
358   i_max
359 };
360 
361 /* Declarations of local functions for use-dynamic.  */
362 static Elf_Data *get_dynscn_strtab (Elf *elf, GElf_Phdr *phdr);
363 static void get_dynscn_addrs (Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max]);
364 static void find_offsets (Elf *elf, GElf_Addr main_bias, size_t n,
365 			  GElf_Addr addrs[n], GElf_Off offs[n]);
366 
367 /* Looked up once with gettext in main.  */
368 static char *yes_str;
369 static char *no_str;
370 
371 static void
cleanup_list(struct section_argument * list)372 cleanup_list (struct section_argument *list)
373 {
374   while (list != NULL)
375     {
376       struct section_argument *a = list;
377       list = a->next;
378       free (a);
379     }
380 }
381 
382 int
main(int argc,char * argv[])383 main (int argc, char *argv[])
384 {
385   /* We use no threads here which can interfere with handling a stream.  */
386   (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
387 
388   /* Set locale.  */
389   setlocale (LC_ALL, "");
390 
391   /* Initialize the message catalog.  */
392   textdomain (PACKAGE_TARNAME);
393 
394   /* Look up once.  */
395   yes_str = _("yes");
396   no_str = _("no");
397 
398   /* Parse and process arguments.  */
399   int remaining;
400   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
401 
402   /* Before we start tell the ELF library which version we are using.  */
403   elf_version (EV_CURRENT);
404 
405   /* Now process all the files given at the command line.  */
406   bool only_one = remaining + 1 == argc;
407   do
408     {
409       /* Open the file.  */
410       int fd = open (argv[remaining], O_RDONLY);
411       if (fd == -1)
412 	{
413 	  error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
414 	  continue;
415 	}
416 
417       process_file (fd, argv[remaining], only_one);
418 
419       close (fd);
420     }
421   while (++remaining < argc);
422 
423   cleanup_list (dump_data_sections);
424   cleanup_list (string_sections);
425 
426   return error_message_count != 0;
427 }
428 
429 static void
add_dump_section(const char * name,int key,bool implicit)430 add_dump_section (const char *name,
431 		  int key,
432 		  bool implicit)
433 {
434   struct section_argument *a = xmalloc (sizeof *a);
435   a->arg = name;
436   a->next = NULL;
437   a->implicit = implicit;
438   struct section_argument ***tailp
439     = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
440   **tailp = a;
441   *tailp = &a->next;
442 }
443 
444 /* Handle program arguments.  */
445 static error_t
parse_opt(int key,char * arg,struct argp_state * state)446 parse_opt (int key, char *arg,
447 	   struct argp_state *state __attribute__ ((unused)))
448 {
449   switch (key)
450     {
451     case 'a':
452       print_file_header = true;
453       print_program_header = true;
454       print_relocations = true;
455       print_section_header = true;
456       print_symbol_table = true;
457       print_version_info = true;
458       print_dynamic_table = true;
459       print_section_groups = true;
460       print_histogram = true;
461       print_arch = true;
462       print_notes = true;
463       implicit_debug_sections |= section_exception;
464       add_dump_section (".strtab", key, true);
465       add_dump_section (".dynstr", key, true);
466       add_dump_section (".comment", key, true);
467       any_control_option = true;
468       break;
469     case 'A':
470       print_arch = true;
471       any_control_option = true;
472       break;
473     case 'd':
474       print_dynamic_table = true;
475       any_control_option = true;
476       break;
477     case 'D':
478       use_dynamic_segment = true;
479       break;
480     case 'e':
481       print_debug_sections |= section_exception;
482       any_control_option = true;
483       break;
484     case 'g':
485       print_section_groups = true;
486       any_control_option = true;
487       break;
488     case 'h':
489       print_file_header = true;
490       any_control_option = true;
491       break;
492     case 'I':
493       print_histogram = true;
494       any_control_option = true;
495       break;
496     case 'l':
497       print_program_header = true;
498       any_control_option = true;
499       break;
500     case 'n':
501       print_notes = true;
502       any_control_option = true;
503       notes_section = arg;
504       break;
505     case 'r':
506       print_relocations = true;
507       any_control_option = true;
508      break;
509     case 'S':
510       print_section_header = true;
511       any_control_option = true;
512       break;
513     case 's':
514       print_symbol_table = true;
515       any_control_option = true;
516       symbol_table_section = arg;
517       break;
518     case PRINT_DYNSYM_TABLE:
519       print_dynsym_table = true;
520       any_control_option = true;
521       break;
522     case 'V':
523       print_version_info = true;
524       any_control_option = true;
525       break;
526     case 'c':
527       print_archive_index = true;
528       break;
529     case 'w':
530       if (arg == NULL)
531 	{
532 	  print_debug_sections = section_all;
533 	  implicit_debug_sections = section_info;
534 	  show_split_units = true;
535 	}
536       else if (strcmp (arg, "abbrev") == 0)
537 	print_debug_sections |= section_abbrev;
538       else if (strcmp (arg, "addr") == 0)
539 	{
540 	  print_debug_sections |= section_addr;
541 	  implicit_debug_sections |= section_info;
542 	}
543       else if (strcmp (arg, "aranges") == 0)
544 	print_debug_sections |= section_aranges;
545       else if (strcmp (arg, "decodedaranges") == 0)
546 	{
547 	  print_debug_sections |= section_aranges;
548 	  decodedaranges = true;
549 	}
550       else if (strcmp (arg, "ranges") == 0)
551 	{
552 	  print_debug_sections |= section_ranges;
553 	  implicit_debug_sections |= section_info;
554 	}
555       else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
556 	print_debug_sections |= section_frame;
557       else if (strcmp (arg, "info") == 0)
558 	{
559 	  print_debug_sections |= section_info;
560 	  print_debug_sections |= section_types;
561 	}
562       else if (strcmp (arg, "info+") == 0)
563 	{
564 	  print_debug_sections |= section_info;
565 	  print_debug_sections |= section_types;
566 	  show_split_units = true;
567 	}
568       else if (strcmp (arg, "loc") == 0)
569 	{
570 	  print_debug_sections |= section_loc;
571 	  implicit_debug_sections |= section_info;
572 	}
573       else if (strcmp (arg, "line") == 0)
574 	print_debug_sections |= section_line;
575       else if (strcmp (arg, "decodedline") == 0)
576 	{
577 	  print_debug_sections |= section_line;
578 	  decodedline = true;
579 	}
580       else if (strcmp (arg, "pubnames") == 0)
581 	print_debug_sections |= section_pubnames;
582       else if (strcmp (arg, "str") == 0)
583 	{
584 	  print_debug_sections |= section_str;
585 	  /* For mapping string offset tables to CUs.  */
586 	  implicit_debug_sections |= section_info;
587 	}
588       else if (strcmp (arg, "macinfo") == 0)
589 	print_debug_sections |= section_macinfo;
590       else if (strcmp (arg, "macro") == 0)
591 	print_debug_sections |= section_macro;
592       else if (strcmp (arg, "exception") == 0)
593 	print_debug_sections |= section_exception;
594       else if (strcmp (arg, "gdb_index") == 0)
595 	print_debug_sections |= section_gdb_index;
596       else
597 	{
598 	  fprintf (stderr, _("Unknown DWARF debug section `%s'.\n"),
599 		   arg);
600 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
601 		     program_invocation_short_name);
602 	  exit (1);
603 	}
604       any_control_option = true;
605       break;
606     case 'p':
607       any_control_option = true;
608       if (arg == NULL)
609 	{
610 	  print_string_sections = true;
611 	  break;
612 	}
613       FALLTHROUGH;
614     case 'x':
615       add_dump_section (arg, key, false);
616       any_control_option = true;
617       break;
618     case 'N':
619       print_address_names = false;
620       break;
621     case 'U':
622       print_unresolved_addresses = true;
623       break;
624     case ARGP_KEY_NO_ARGS:
625       fputs (_("Missing file name.\n"), stderr);
626       goto do_argp_help;
627     case ARGP_KEY_FINI:
628       if (! any_control_option && ! print_archive_index)
629 	{
630 	  fputs (_("No operation specified.\n"), stderr);
631 	do_argp_help:
632 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
633 		     program_invocation_short_name);
634 	  exit (EXIT_FAILURE);
635 	}
636       break;
637     case 'W':			/* Ignored.  */
638       break;
639     case 'z':
640       print_decompress = true;
641       break;
642     case ELF_INPUT_SECTION:
643       if (arg == NULL)
644 	elf_input_section = ".gnu_debugdata";
645       else
646 	elf_input_section = arg;
647       break;
648     case DWARF_SKELETON:
649       dwarf_skeleton = arg;
650       break;
651     default:
652       return ARGP_ERR_UNKNOWN;
653     }
654   return 0;
655 }
656 
657 
658 /* Create a file descriptor to read the data from the
659    elf_input_section given a file descriptor to an ELF file.  */
660 static int
open_input_section(int fd)661 open_input_section (int fd)
662 {
663   size_t shnums;
664   size_t cnt;
665   size_t shstrndx;
666   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
667   if (elf == NULL)
668     {
669       error (0, 0, _("cannot generate Elf descriptor: %s"),
670 	     elf_errmsg (-1));
671       return -1;
672     }
673 
674   if (elf_getshdrnum (elf, &shnums) < 0)
675     {
676       error (0, 0, _("cannot determine number of sections: %s"),
677 	     elf_errmsg (-1));
678     open_error:
679       elf_end (elf);
680       return -1;
681     }
682 
683   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
684     {
685       error (0, 0, _("cannot get section header string table index"));
686       goto open_error;
687     }
688 
689   for (cnt = 0; cnt < shnums; ++cnt)
690     {
691       Elf_Scn *scn = elf_getscn (elf, cnt);
692       if (scn == NULL)
693 	{
694 	  error (0, 0, _("cannot get section: %s"),
695 		 elf_errmsg (-1));
696 	  goto open_error;
697 	}
698 
699       GElf_Shdr shdr_mem;
700       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
701       if (unlikely (shdr == NULL))
702 	{
703 	  error (0, 0, _("cannot get section header: %s"),
704 		 elf_errmsg (-1));
705 	  goto open_error;
706 	}
707 
708       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
709       if (sname == NULL)
710 	{
711 	  error (0, 0, _("cannot get section name"));
712 	  goto open_error;
713 	}
714 
715       if (strcmp (sname, elf_input_section) == 0)
716 	{
717 	  Elf_Data *data = elf_rawdata (scn, NULL);
718 	  if (data == NULL)
719 	    {
720 	      error (0, 0, _("cannot get %s content: %s"),
721 		     sname, elf_errmsg (-1));
722 	      goto open_error;
723 	    }
724 
725 	  /* Create (and immediately unlink) a temporary file to store
726 	     section data in to create a file descriptor for it.  */
727 	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
728 	  static const char suffix[] = "/readelfXXXXXX";
729 	  int tmplen = strlen (tmpdir) + sizeof (suffix);
730 	  char *tempname = alloca (tmplen);
731 	  sprintf (tempname, "%s%s", tmpdir, suffix);
732 
733 	  int sfd = mkstemp (tempname);
734 	  if (sfd == -1)
735 	    {
736 	      error (0, 0, _("cannot create temp file '%s'"),
737 		     tempname);
738 	      goto open_error;
739 	    }
740 	  unlink (tempname);
741 
742 	  ssize_t size = data->d_size;
743 	  if (write_retry (sfd, data->d_buf, size) != size)
744 	    {
745 	      error (0, 0, _("cannot write section data"));
746 	      goto open_error;
747 	    }
748 
749 	  if (elf_end (elf) != 0)
750 	    {
751 	      error (0, 0, _("error while closing Elf descriptor: %s"),
752 		     elf_errmsg (-1));
753 	      return -1;
754 	    }
755 
756 	  if (lseek (sfd, 0, SEEK_SET) == -1)
757 	    {
758 	      error (0, 0, _("error while rewinding file descriptor"));
759 	      return -1;
760 	    }
761 
762 	  return sfd;
763 	}
764     }
765 
766   /* Named section not found.  */
767   if (elf_end (elf) != 0)
768     error (0, 0, _("error while closing Elf descriptor: %s"),
769 	   elf_errmsg (-1));
770   return -1;
771 }
772 
773 /* Check if the file is an archive, and if so dump its index.  */
774 static void
check_archive_index(int fd,const char * fname,bool only_one)775 check_archive_index (int fd, const char *fname, bool only_one)
776 {
777   /* Create an `Elf' descriptor.  */
778   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
779   if (elf == NULL)
780     error (0, 0, _("cannot generate Elf descriptor: %s"),
781 	   elf_errmsg (-1));
782   else
783     {
784       if (elf_kind (elf) == ELF_K_AR)
785 	{
786 	  if (!only_one)
787 	    printf ("\n%s:\n\n", fname);
788 	  dump_archive_index (elf, fname);
789 	}
790       else
791 	error (0, 0,
792 	       _("'%s' is not an archive, cannot print archive index"),
793 	       fname);
794 
795       /* Now we can close the descriptor.  */
796       if (elf_end (elf) != 0)
797 	error (0, 0, _("error while closing Elf descriptor: %s"),
798 	       elf_errmsg (-1));
799     }
800 }
801 
802 /* Trivial callback used for checking if we opened an archive.  */
803 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)804 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
805 	       void **userdata __attribute__ ((unused)),
806 	       const char *name __attribute__ ((unused)),
807 	       Dwarf_Addr base __attribute__ ((unused)),
808 	       void *arg)
809 {
810   if (*(bool *) arg)
811     return DWARF_CB_ABORT;
812   *(bool *) arg = true;
813   return DWARF_CB_OK;
814 }
815 
816 struct process_dwflmod_args
817 {
818   int fd;
819   bool only_one;
820 };
821 
822 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)823 process_dwflmod (Dwfl_Module *dwflmod,
824 		 void **userdata __attribute__ ((unused)),
825 		 const char *name __attribute__ ((unused)),
826 		 Dwarf_Addr base __attribute__ ((unused)),
827 		 void *arg)
828 {
829   const struct process_dwflmod_args *a = arg;
830 
831   /* Print the file name.  */
832   if (!a->only_one)
833     {
834       const char *fname;
835       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
836 
837       printf ("\n%s:\n\n", fname);
838     }
839 
840   process_elf_file (dwflmod, a->fd);
841 
842   return DWARF_CB_OK;
843 }
844 
845 /* Stub libdwfl callback, only the ELF handle already open is ever used.
846    Only used for finding the alternate debug file if the Dwarf comes from
847    the main file.  We are not interested in separate debuginfo.  */
848 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)849 find_no_debuginfo (Dwfl_Module *mod,
850 		   void **userdata,
851 		   const char *modname,
852 		   Dwarf_Addr base,
853 		   const char *file_name,
854 		   const char *debuglink_file,
855 		   GElf_Word debuglink_crc,
856 		   char **debuginfo_file_name)
857 {
858   Dwarf_Addr dwbias;
859   dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
860 
861   /* We are only interested if the Dwarf has been setup on the main
862      elf file but is only missing the alternate debug link.  If dwbias
863      hasn't even been setup, this is searching for separate debuginfo
864      for the main elf.  We don't care in that case.  */
865   if (dwbias == (Dwarf_Addr) -1)
866     return -1;
867 
868   return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
869 				       file_name, debuglink_file,
870 				       debuglink_crc, debuginfo_file_name);
871 }
872 
873 static Dwfl *
create_dwfl(int fd,const char * fname)874 create_dwfl (int fd, const char *fname)
875 {
876   /* Duplicate an fd for dwfl_report_offline to swallow.  */
877   int dwfl_fd = dup (fd);
878   if (unlikely (dwfl_fd < 0))
879     error_exit (errno, "dup");
880 
881   /* Use libdwfl in a trivial way to open the libdw handle for us.
882      This takes care of applying relocations to DWARF data in ET_REL files.  */
883   static const Dwfl_Callbacks callbacks =
884     {
885       .section_address = dwfl_offline_section_address,
886       .find_debuginfo = find_no_debuginfo
887     };
888   Dwfl *dwfl = dwfl_begin (&callbacks);
889   if (likely (dwfl != NULL))
890     /* Let 0 be the logical address of the file (or first in archive).  */
891     dwfl->offline_next_address = 0;
892   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
893     {
894       struct stat st;
895       if (fstat (dwfl_fd, &st) != 0)
896 	error (0, errno, _("cannot stat input file"));
897       else if (unlikely (st.st_size == 0))
898 	error (0, 0, _("input file is empty"));
899       else
900 	error (0, 0, _("failed reading '%s': %s"),
901 	       fname, dwfl_errmsg (-1));
902       close (dwfl_fd);		/* Consumed on success, not on failure.  */
903       dwfl = NULL;
904     }
905   else
906     dwfl_report_end (dwfl, NULL, NULL);
907 
908   return dwfl;
909 }
910 
911 /* Process one input file.  */
912 static void
process_file(int fd,const char * fname,bool only_one)913 process_file (int fd, const char *fname, bool only_one)
914 {
915   if (print_archive_index)
916     check_archive_index (fd, fname, only_one);
917 
918   if (!any_control_option)
919     return;
920 
921   if (elf_input_section != NULL)
922     {
923       /* Replace fname and fd with section content. */
924       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
925       sprintf (fnname, "%s:%s", fname, elf_input_section);
926       fd = open_input_section (fd);
927       if (fd == -1)
928         {
929           error (0, 0, _("No such section '%s' in '%s'"),
930 		 elf_input_section, fname);
931           return;
932         }
933       fname = fnname;
934     }
935 
936   Dwfl *dwfl = create_dwfl (fd, fname);
937   if (dwfl != NULL)
938     {
939       if (only_one)
940 	{
941 	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
942 	  bool seen = false;
943 	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
944 	}
945 
946       /* Process the one or more modules gleaned from this file.  */
947       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
948       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
949     }
950   /* Terrible hack for hooking unrelated skeleton/split compile units,
951      see __libdw_link_skel_split in print_debug.  */
952   if (! do_not_close_dwfl)
953     dwfl_end (dwfl);
954 
955   /* Need to close the replaced fd if we created it.  Caller takes
956      care of original.  */
957   if (elf_input_section != NULL)
958     close (fd);
959 }
960 
961 /* Check whether there are any compressed sections in the ELF file.  */
962 static bool
elf_contains_chdrs(Elf * elf)963 elf_contains_chdrs (Elf *elf)
964 {
965   Elf_Scn *scn = NULL;
966   while ((scn = elf_nextscn (elf, scn)) != NULL)
967     {
968       GElf_Shdr shdr_mem;
969       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
970       if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
971 	return true;
972     }
973   return false;
974 }
975 
976 /* Process one ELF file.  */
977 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)978 process_elf_file (Dwfl_Module *dwflmod, int fd)
979 {
980   GElf_Addr dwflbias;
981   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
982 
983   GElf_Ehdr ehdr_mem;
984   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
985 
986   if (ehdr == NULL)
987     {
988       error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1));
989       return;
990     }
991 
992   Ebl *ebl = ebl_openbackend (elf);
993   if (unlikely (ebl == NULL))
994     {
995     ebl_error:
996       error (0, errno, _("cannot create EBL handle"));
997       return;
998     }
999 
1000   /* Determine the number of sections.  */
1001   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
1002     error_exit (0, _("cannot determine number of sections: %s"),
1003 		elf_errmsg (-1));
1004 
1005   /* Determine the number of phdrs.  */
1006   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
1007     error_exit (0, _("cannot determine number of program headers: %s"),
1008 		elf_errmsg (-1));
1009 
1010   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
1011      may have applied relocation to some sections.  If there are any
1012      compressed sections, any pass (or libdw/libdwfl) might have
1013      uncompressed them.  So we need to get a fresh Elf handle on the
1014      file to display those.  */
1015   bool print_unchanged = ((print_section_header
1016 			   || print_relocations
1017 			   || dump_data_sections != NULL
1018 			   || print_notes)
1019 			  && (ehdr->e_type == ET_REL
1020 			      || elf_contains_chdrs (ebl->elf)));
1021 
1022   Elf *pure_elf = NULL;
1023   Ebl *pure_ebl = ebl;
1024   if (print_unchanged)
1025     {
1026       /* Read the file afresh.  */
1027       off_t aroff = elf_getaroff (elf);
1028       pure_elf = dwelf_elf_begin (fd);
1029       if (aroff > 0)
1030 	{
1031 	  /* Archive member.  */
1032 	  (void) elf_rand (pure_elf, aroff);
1033 	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
1034 	  elf_end (pure_elf);
1035 	  pure_elf = armem;
1036 	}
1037       if (pure_elf == NULL)
1038 	{
1039 	  error (0, 0, _("cannot read ELF: %s"), elf_errmsg (-1));
1040 	  return;
1041 	}
1042       pure_ebl = ebl_openbackend (pure_elf);
1043       if (pure_ebl == NULL)
1044 	goto ebl_error;
1045     }
1046 
1047   bool symtab_printed = false;
1048 
1049   if (print_file_header)
1050     print_ehdr (ebl, ehdr);
1051   if (print_section_header)
1052     print_shdr (pure_ebl, ehdr);
1053   if (print_program_header)
1054     print_phdr (ebl, ehdr);
1055   if (print_section_groups)
1056     print_scngrp (ebl);
1057   if (print_dynamic_table)
1058     print_dynamic (ebl);
1059   if (print_relocations)
1060     print_relocs (pure_ebl, dwflmod, ehdr);
1061   if (print_histogram)
1062     handle_hash (ebl);
1063   if (print_symbol_table || print_dynsym_table)
1064     symtab_printed |= print_symtab (ebl, SHT_DYNSYM);
1065   if (print_version_info)
1066     print_verinfo (ebl);
1067   if (print_symbol_table && !use_dynamic_segment)
1068     symtab_printed |= print_symtab (ebl, SHT_SYMTAB);
1069 
1070   if ((print_symbol_table || print_dynsym_table)
1071       && !symtab_printed && symbol_table_section != NULL)
1072     printf ("WARNING: %s: '%s'\n", _("cannot find section"),
1073         symbol_table_section);
1074 
1075   if (print_arch)
1076     print_liblist (ebl);
1077   if (print_arch)
1078     print_attributes (ebl, ehdr);
1079   if (dump_data_sections != NULL)
1080     dump_data (pure_ebl);
1081   if (string_sections != NULL)
1082     dump_strings (ebl);
1083   if ((print_debug_sections | implicit_debug_sections) != 0)
1084     print_debug (dwflmod, ebl, ehdr);
1085   if (print_notes)
1086     handle_notes (pure_ebl, ehdr);
1087   if (print_string_sections)
1088     print_strings (ebl);
1089 
1090   if (pure_ebl != ebl)
1091     {
1092       ebl_closebackend (ebl);
1093       ebl_closebackend (pure_ebl);
1094       elf_end (pure_elf);
1095     }
1096   else
1097     ebl_closebackend (ebl);
1098 }
1099 
1100 
1101 /* Print file type.  */
1102 static void
print_file_type(unsigned short int e_type)1103 print_file_type (unsigned short int e_type)
1104 {
1105   if (likely (e_type <= ET_CORE))
1106     {
1107       static const char *const knowntypes[] =
1108       {
1109 	N_("NONE (None)"),
1110 	N_("REL (Relocatable file)"),
1111 	N_("EXEC (Executable file)"),
1112 	N_("DYN (Shared object file)"),
1113 	N_("CORE (Core file)")
1114       };
1115       puts (_(knowntypes[e_type]));
1116     }
1117   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1118     printf (_("OS Specific: (%x)\n"),  e_type);
1119   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1120     printf (_("Processor Specific: (%x)\n"),  e_type);
1121   else
1122     puts ("???");
1123 }
1124 
1125 
1126 /* Print ELF header.  */
1127 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1128 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1129 {
1130   fputs_unlocked (_("ELF Header:\n  Magic:  "), stdout);
1131   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1132     printf (" %02hhx", ehdr->e_ident[cnt]);
1133 
1134   printf (_("\n  Class:                             %s\n"),
1135 	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1136 	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1137 	  : "\?\?\?");
1138 
1139   printf (_("  Data:                              %s\n"),
1140 	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1141 	  ? "2's complement, little endian"
1142 	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1143 	  ? "2's complement, big endian" : "\?\?\?");
1144 
1145   printf (_("  Ident Version:                     %hhd %s\n"),
1146 	  ehdr->e_ident[EI_VERSION],
1147 	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)")
1148 	  : "(\?\?\?)");
1149 
1150   char buf[512];
1151   printf (_("  OS/ABI:                            %s\n"),
1152 	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1153 
1154   printf (_("  ABI Version:                       %hhd\n"),
1155 	  ehdr->e_ident[EI_ABIVERSION]);
1156 
1157   fputs_unlocked (_("  Type:                              "), stdout);
1158   print_file_type (ehdr->e_type);
1159 
1160   const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1161   if (machine != NULL)
1162     printf (_("  Machine:                           %s\n"), machine);
1163   else
1164     printf (_("  Machine:                           <unknown>: 0x%x\n"),
1165 	    ehdr->e_machine);
1166 
1167   printf (_("  Version:                           %d %s\n"),
1168 	  ehdr->e_version,
1169 	  ehdr->e_version  == EV_CURRENT ? _("(current)") : "(\?\?\?)");
1170 
1171   printf (_("  Entry point address:               %#" PRIx64 "\n"),
1172 	  ehdr->e_entry);
1173 
1174   printf (_("  Start of program headers:          %" PRId64 " %s\n"),
1175 	  ehdr->e_phoff, _("(bytes into file)"));
1176 
1177   printf (_("  Start of section headers:          %" PRId64 " %s\n"),
1178 	  ehdr->e_shoff, _("(bytes into file)"));
1179 
1180   printf (_("  Flags:                             %s\n"),
1181 	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1182 
1183   printf (_("  Size of this header:               %" PRId16 " %s\n"),
1184 	  ehdr->e_ehsize, _("(bytes)"));
1185 
1186   printf (_("  Size of program header entries:    %" PRId16 " %s\n"),
1187 	  ehdr->e_phentsize, _("(bytes)"));
1188 
1189   printf (_("  Number of program headers entries: %" PRId16),
1190 	  ehdr->e_phnum);
1191   if (ehdr->e_phnum == PN_XNUM)
1192     {
1193       GElf_Shdr shdr_mem;
1194       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1195       if (shdr != NULL)
1196 	printf (_(" (%" PRIu32 " in [0].sh_info)"),
1197 		(uint32_t) shdr->sh_info);
1198       else
1199 	fputs_unlocked (_(" ([0] not available)"), stdout);
1200     }
1201   fputc_unlocked ('\n', stdout);
1202 
1203   printf (_("  Size of section header entries:    %" PRId16 " %s\n"),
1204 	  ehdr->e_shentsize, _("(bytes)"));
1205 
1206   printf (_("  Number of section headers entries: %" PRId16),
1207 	  ehdr->e_shnum);
1208   if (ehdr->e_shnum == 0)
1209     {
1210       GElf_Shdr shdr_mem;
1211       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1212       if (shdr != NULL)
1213 	printf (_(" (%" PRIu32 " in [0].sh_size)"),
1214 		(uint32_t) shdr->sh_size);
1215       else
1216 	fputs_unlocked (_(" ([0] not available)"), stdout);
1217     }
1218   fputc_unlocked ('\n', stdout);
1219 
1220   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1221     {
1222       GElf_Shdr shdr_mem;
1223       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1224       if (shdr != NULL)
1225 	/* We managed to get the zeroth section.  */
1226 	snprintf (buf, sizeof (buf), _(" (%" PRIu32 " in [0].sh_link)"),
1227 		  (uint32_t) shdr->sh_link);
1228       else
1229 	{
1230 	  strncpy (buf, _(" ([0] not available)"), sizeof (buf) - 1);
1231 	  buf[sizeof (buf) - 1] = '\0';
1232 	}
1233 
1234       printf (_("  Section header string table index: XINDEX%s\n\n"),
1235 	      buf);
1236     }
1237   else
1238     printf (_("  Section header string table index: %" PRId16 "\n\n"),
1239 	    ehdr->e_shstrndx);
1240 }
1241 
1242 
1243 static const char *
get_visibility_type(int value)1244 get_visibility_type (int value)
1245 {
1246   switch (value)
1247     {
1248     case STV_DEFAULT:
1249       return "DEFAULT";
1250     case STV_INTERNAL:
1251       return "INTERNAL";
1252     case STV_HIDDEN:
1253       return "HIDDEN";
1254     case STV_PROTECTED:
1255       return "PROTECTED";
1256     default:
1257       return "???";
1258     }
1259 }
1260 
1261 static const char *
elf_ch_type_name(unsigned int code)1262 elf_ch_type_name (unsigned int code)
1263 {
1264   switch (code)
1265     {
1266     case 0:
1267       return "NONE";
1268     case ELFCOMPRESS_ZLIB:
1269       return "ZLIB";
1270     case ELFCOMPRESS_ZSTD:
1271       return "ZSTD";
1272     default:
1273       return "UNKNOWN";
1274     }
1275 }
1276 
1277 /* Print the section headers.  */
1278 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1279 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1280 {
1281   size_t cnt;
1282   size_t shstrndx;
1283 
1284   if (! print_file_header)
1285     {
1286       size_t sections;
1287       if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
1288 	error_exit (0, _("cannot get number of sections: %s"),
1289 		    elf_errmsg (-1));
1290 
1291       printf (_("\
1292 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1293 \n"),
1294 	      sections, ehdr->e_shoff);
1295     }
1296 
1297   /* Get the section header string table index.  */
1298   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1299     error_exit (0, _("cannot get section header string table index: %s"),
1300 		elf_errmsg (-1));
1301 
1302   puts (_("Section Headers:"));
1303 
1304   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1305     puts (_("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
1306   else
1307     puts (_("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
1308 
1309   if (print_decompress)
1310     {
1311       if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1312 	puts (_("     [Compression  Size   Al]"));
1313       else
1314 	puts (_("     [Compression  Size     Al]"));
1315     }
1316 
1317   for (cnt = 0; cnt < shnum; ++cnt)
1318     {
1319       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1320 
1321       if (unlikely (scn == NULL))
1322 	error_exit (0, _("cannot get section: %s"),
1323 		    elf_errmsg (-1));
1324 
1325       /* Get the section header.  */
1326       GElf_Shdr shdr_mem;
1327       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1328       if (unlikely (shdr == NULL))
1329 	error_exit (0, _("cannot get section header: %s"),
1330 		    elf_errmsg (-1));
1331 
1332       char flagbuf[20];
1333       char *cp = flagbuf;
1334       if (shdr->sh_flags & SHF_WRITE)
1335 	*cp++ = 'W';
1336       if (shdr->sh_flags & SHF_ALLOC)
1337 	*cp++ = 'A';
1338       if (shdr->sh_flags & SHF_EXECINSTR)
1339 	*cp++ = 'X';
1340       if (shdr->sh_flags & SHF_MERGE)
1341 	*cp++ = 'M';
1342       if (shdr->sh_flags & SHF_STRINGS)
1343 	*cp++ = 'S';
1344       if (shdr->sh_flags & SHF_INFO_LINK)
1345 	*cp++ = 'I';
1346       if (shdr->sh_flags & SHF_LINK_ORDER)
1347 	*cp++ = 'L';
1348       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1349 	*cp++ = 'N';
1350       if (shdr->sh_flags & SHF_GROUP)
1351 	*cp++ = 'G';
1352       if (shdr->sh_flags & SHF_TLS)
1353 	*cp++ = 'T';
1354       if (shdr->sh_flags & SHF_COMPRESSED)
1355 	*cp++ = 'C';
1356       if (shdr->sh_flags & SHF_ORDERED)
1357 	*cp++ = 'O';
1358       if (shdr->sh_flags & SHF_EXCLUDE)
1359 	*cp++ = 'E';
1360       if (shdr->sh_flags & SHF_GNU_RETAIN)
1361 	*cp++ = 'R';
1362       *cp = '\0';
1363 
1364       const char *sname;
1365       char buf[128];
1366       sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1367       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1368 	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1369 	      " %2" PRId64 "\n",
1370 	      cnt, sname,
1371 	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1372 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1373 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1374 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1375 	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1376 	      shdr->sh_addralign);
1377 
1378       if (print_decompress)
1379 	{
1380 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1381 	    {
1382 	      GElf_Chdr chdr;
1383 	      if (gelf_getchdr (scn, &chdr) != NULL)
1384 		printf ("     [ELF %s (%" PRId32 ") %0*" PRIx64
1385 			" %2" PRId64 "]\n",
1386 			elf_ch_type_name (chdr.ch_type),
1387 			chdr.ch_type,
1388 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1389 			chdr.ch_size, chdr.ch_addralign);
1390 	      else
1391 		error (0, 0,
1392 		       _("bad compression header for section %zd: %s"),
1393 		       elf_ndxscn (scn), elf_errmsg (-1));
1394 	    }
1395 	  else if (startswith (sname, ".zdebug"))
1396 	    {
1397 	      ssize_t size;
1398 	      if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1399 		printf ("     [GNU ZLIB     %0*zx   ]\n",
1400 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1401 	      else
1402 		error (0, 0,
1403 		       _("bad gnu compressed size for section %zd: %s"),
1404 		       elf_ndxscn (scn), elf_errmsg (-1));
1405 	    }
1406 	}
1407     }
1408 
1409   fputc_unlocked ('\n', stdout);
1410 }
1411 
1412 
1413 /* Print the program header.  */
1414 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1415 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1416 {
1417   if (phnum == 0)
1418     /* No program header, this is OK in relocatable objects.  */
1419     return;
1420 
1421   puts (_("Program Headers:"));
1422   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1423     puts (_("\
1424   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
1425   else
1426     puts (_("\
1427   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
1428 
1429   /* Process all program headers.  */
1430   bool has_relro = false;
1431   GElf_Addr relro_from = 0;
1432   GElf_Addr relro_to = 0;
1433   for (size_t cnt = 0; cnt < phnum; ++cnt)
1434     {
1435       char buf[128];
1436       GElf_Phdr mem;
1437       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1438 
1439       /* If for some reason the header cannot be returned show this.  */
1440       if (unlikely (phdr == NULL))
1441 	{
1442 	  puts ("  ???");
1443 	  continue;
1444 	}
1445 
1446       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1447 	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1448 	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1449 	      phdr->p_offset,
1450 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1451 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1452 	      phdr->p_filesz,
1453 	      phdr->p_memsz,
1454 	      phdr->p_flags & PF_R ? 'R' : ' ',
1455 	      phdr->p_flags & PF_W ? 'W' : ' ',
1456 	      phdr->p_flags & PF_X ? 'E' : ' ',
1457 	      phdr->p_align);
1458 
1459       if (phdr->p_type == PT_INTERP)
1460 	{
1461 	  /* If we are sure the file offset is valid then we can show
1462 	     the user the name of the interpreter.  We check whether
1463 	     there is a section at the file offset.  Normally there
1464 	     would be a section called ".interp".  But in separate
1465 	     .debug files it is a NOBITS section (and so doesn't match
1466 	     with gelf_offscn).  Which probably means the offset is
1467 	     not valid another reason could be because the ELF file
1468 	     just doesn't contain any section headers, in that case
1469 	     just play it safe and don't display anything.  */
1470 
1471 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1472 	  GElf_Shdr shdr_mem;
1473 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1474 
1475 	  size_t maxsize;
1476 	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
1477 
1478 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1479 	      && filedata != NULL && phdr->p_offset < maxsize
1480 	      && phdr->p_filesz <= maxsize - phdr->p_offset
1481 	      && memchr (filedata + phdr->p_offset, '\0',
1482 			 phdr->p_filesz) != NULL)
1483 	    printf (_("\t[Requesting program interpreter: %s]\n"),
1484 		    filedata + phdr->p_offset);
1485 	}
1486       else if (phdr->p_type == PT_GNU_RELRO)
1487 	{
1488 	  has_relro = true;
1489 	  relro_from = phdr->p_vaddr;
1490 	  relro_to = relro_from + phdr->p_memsz;
1491 	}
1492     }
1493 
1494   size_t sections;
1495   if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
1496     error_exit (0, _("cannot get number of sections: %s"),
1497 		elf_errmsg (-1));
1498 
1499   if (sections == 0)
1500     /* No sections in the file.  Punt.  */
1501     return;
1502 
1503   /* Get the section header string table index.  */
1504   size_t shstrndx;
1505   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1506     error_exit (0, _("cannot get section header string table index"));
1507 
1508   puts (_("\n Section to Segment mapping:\n  Segment Sections..."));
1509 
1510   for (size_t cnt = 0; cnt < phnum; ++cnt)
1511     {
1512       /* Print the segment number.  */
1513       printf ("   %2.2zu     ", cnt);
1514 
1515       GElf_Phdr phdr_mem;
1516       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1517       /* This must not happen.  */
1518       if (unlikely (phdr == NULL))
1519 	error_exit (0, _("cannot get program header: %s"),
1520 		    elf_errmsg (-1));
1521 
1522       /* Iterate over the sections.  */
1523       bool in_relro = false;
1524       bool in_ro = false;
1525       for (size_t inner = 1; inner < shnum; ++inner)
1526 	{
1527 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1528 	  /* This should not happen.  */
1529 	  if (unlikely (scn == NULL))
1530 	    error_exit (0, _("cannot get section: %s"),
1531 			elf_errmsg (-1));
1532 
1533 	  /* Get the section header.  */
1534 	  GElf_Shdr shdr_mem;
1535 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1536 	  if (unlikely (shdr == NULL))
1537 	    error_exit (0, _("cannot get section header: %s"),
1538 			elf_errmsg (-1));
1539 
1540 	  if (shdr->sh_size > 0
1541 	      /* Compare allocated sections by VMA, unallocated
1542 		 sections by file offset.  */
1543 	      && (shdr->sh_flags & SHF_ALLOC
1544 		  ? (shdr->sh_addr >= phdr->p_vaddr
1545 		     && (shdr->sh_addr + shdr->sh_size
1546 			 <= phdr->p_vaddr + phdr->p_memsz))
1547 		  : (shdr->sh_offset >= phdr->p_offset
1548 		     && (shdr->sh_offset + shdr->sh_size
1549 			 <= phdr->p_offset + phdr->p_filesz))))
1550 	    {
1551 	      if (has_relro && !in_relro
1552 		  && shdr->sh_addr >= relro_from
1553 		  && shdr->sh_addr + shdr->sh_size <= relro_to)
1554 		{
1555 		  fputs_unlocked (" [RELRO:", stdout);
1556 		  in_relro = true;
1557 		}
1558 	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1559 		{
1560 		  fputs_unlocked ("]", stdout);
1561 		  in_relro =  false;
1562 		}
1563 	      else if (has_relro && in_relro
1564 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1565 		fputs_unlocked ("] <RELRO:", stdout);
1566 	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1567 		{
1568 		  if (!in_ro)
1569 		    {
1570 		      fputs_unlocked (" [RO:", stdout);
1571 		      in_ro = true;
1572 		    }
1573 		}
1574 	      else
1575 		{
1576 		  /* Determine the segment this section is part of.  */
1577 		  size_t cnt2;
1578 		  GElf_Phdr phdr2_mem;
1579 		  GElf_Phdr *phdr2 = NULL;
1580 		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1581 		    {
1582 		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1583 
1584 		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1585 			  && shdr->sh_addr >= phdr2->p_vaddr
1586 			  && (shdr->sh_addr + shdr->sh_size
1587 			      <= phdr2->p_vaddr + phdr2->p_memsz))
1588 			break;
1589 		    }
1590 
1591 		  if (cnt2 < phnum)
1592 		    {
1593 		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1594 			{
1595 			  fputs_unlocked (" [RO:", stdout);
1596 			  in_ro = true;
1597 			}
1598 		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1599 			{
1600 			  fputs_unlocked ("]", stdout);
1601 			  in_ro = false;
1602 			}
1603 		    }
1604 		}
1605 
1606 	      printf (" %s",
1607 		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1608 
1609 	      /* Signal that this section is only partially covered.  */
1610 	      if (has_relro && in_relro
1611 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1612 		{
1613 		  fputs_unlocked (">", stdout);
1614 		  in_relro =  false;
1615 		}
1616 	    }
1617 	}
1618       if (in_relro || in_ro)
1619 	fputs_unlocked ("]", stdout);
1620 
1621       /* Finish the line.  */
1622       fputc_unlocked ('\n', stdout);
1623     }
1624 }
1625 
1626 
1627 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1628 section_name (Ebl *ebl, GElf_Shdr *shdr)
1629 {
1630   size_t shstrndx;
1631   if (shdr == NULL || elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1632     return "???";
1633   return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1634 }
1635 
1636 
1637 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1638 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1639 {
1640   /* Get the data of the section.  */
1641   Elf_Data *data = elf_getdata (scn, NULL);
1642 
1643   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1644   GElf_Shdr symshdr_mem;
1645   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1646   Elf_Data *symdata = elf_getdata (symscn, NULL);
1647 
1648   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1649       || symdata == NULL)
1650     return;
1651 
1652   /* Get the section header string table index.  */
1653   size_t shstrndx;
1654   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1655     error_exit (0, _("cannot get section header string table index"));
1656 
1657   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1658 
1659   GElf_Sym sym_mem;
1660   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1661 
1662   printf ((grpref[0] & GRP_COMDAT)
1663 	  ? ngettext ("\
1664 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1665 		      "\
1666 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1667 		      data->d_size / sizeof (Elf32_Word) - 1)
1668 	  : ngettext ("\
1669 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1670 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1671 		      data->d_size / sizeof (Elf32_Word) - 1),
1672 	  elf_ndxscn (scn),
1673 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1674 	  (sym == NULL ? NULL
1675 	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1676 	  ?: _("<INVALID SYMBOL>"),
1677 	  data->d_size / sizeof (Elf32_Word) - 1);
1678 
1679   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1680     {
1681       GElf_Shdr grpshdr_mem;
1682       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1683 					 &grpshdr_mem);
1684 
1685       const char *str;
1686       printf ("  [%2u] %s\n",
1687 	      grpref[cnt],
1688 	      grpshdr != NULL
1689 	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1690 	      ? str : _("<INVALID SECTION>"));
1691     }
1692 }
1693 
1694 
1695 static void
print_scngrp(Ebl * ebl)1696 print_scngrp (Ebl *ebl)
1697 {
1698   /* Find all relocation sections and handle them.  */
1699   Elf_Scn *scn = NULL;
1700 
1701   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1702     {
1703        /* Handle the section if it is a symbol table.  */
1704       GElf_Shdr shdr_mem;
1705       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1706 
1707       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1708 	{
1709 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1710 	    {
1711 	      if (elf_compress (scn, 0, 0) < 0)
1712 		printf ("WARNING: %s [%zd]\n",
1713 			_("Couldn't uncompress section"),
1714 			elf_ndxscn (scn));
1715 	      shdr = gelf_getshdr (scn, &shdr_mem);
1716 	      if (unlikely (shdr == NULL))
1717 		error_exit (0, _("cannot get section [%zd] header: %s"),
1718 			    elf_ndxscn (scn),
1719 			    elf_errmsg (-1));
1720 	    }
1721 	  handle_scngrp (ebl, scn, shdr);
1722 	}
1723     }
1724 }
1725 
1726 
1727 static const struct flags
1728 {
1729   int mask;
1730   const char *str;
1731 } dt_flags[] =
1732   {
1733     { DF_ORIGIN, "ORIGIN" },
1734     { DF_SYMBOLIC, "SYMBOLIC" },
1735     { DF_TEXTREL, "TEXTREL" },
1736     { DF_BIND_NOW, "BIND_NOW" },
1737     { DF_STATIC_TLS, "STATIC_TLS" }
1738   };
1739 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1740 
1741 static const struct flags dt_flags_1[] =
1742   {
1743     { DF_1_NOW, "NOW" },
1744     { DF_1_GLOBAL, "GLOBAL" },
1745     { DF_1_GROUP, "GROUP" },
1746     { DF_1_NODELETE, "NODELETE" },
1747     { DF_1_LOADFLTR, "LOADFLTR" },
1748     { DF_1_INITFIRST, "INITFIRST" },
1749     { DF_1_NOOPEN, "NOOPEN" },
1750     { DF_1_ORIGIN, "ORIGIN" },
1751     { DF_1_DIRECT, "DIRECT" },
1752     { DF_1_TRANS, "TRANS" },
1753     { DF_1_INTERPOSE, "INTERPOSE" },
1754     { DF_1_NODEFLIB, "NODEFLIB" },
1755     { DF_1_NODUMP, "NODUMP" },
1756     { DF_1_CONFALT, "CONFALT" },
1757     { DF_1_ENDFILTEE, "ENDFILTEE" },
1758     { DF_1_DISPRELDNE, "DISPRELDNE" },
1759     { DF_1_DISPRELPND, "DISPRELPND" },
1760   };
1761 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1762 
1763 static const struct flags dt_feature_1[] =
1764   {
1765     { DTF_1_PARINIT, "PARINIT" },
1766     { DTF_1_CONFEXP, "CONFEXP" }
1767   };
1768 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1769 				  / sizeof (dt_feature_1[0]));
1770 
1771 static const struct flags dt_posflag_1[] =
1772   {
1773     { DF_P1_LAZYLOAD, "LAZYLOAD" },
1774     { DF_P1_GROUPPERM, "GROUPPERM" }
1775   };
1776 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1777 				  / sizeof (dt_posflag_1[0]));
1778 
1779 
1780 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1781 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1782 		int nflags)
1783 {
1784   bool first = true;
1785   int cnt;
1786 
1787   for (cnt = 0; cnt < nflags; ++cnt)
1788     if (d_val & flags[cnt].mask)
1789       {
1790 	if (!first)
1791 	  putchar_unlocked (' ');
1792 	fputs_unlocked (flags[cnt].str, stdout);
1793 	d_val &= ~flags[cnt].mask;
1794 	first = false;
1795       }
1796 
1797   if (d_val != 0)
1798     {
1799       if (!first)
1800 	putchar_unlocked (' ');
1801       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1802     }
1803 
1804   putchar_unlocked ('\n');
1805 }
1806 
1807 
1808 static void
print_dt_flags(int class,GElf_Xword d_val)1809 print_dt_flags (int class, GElf_Xword d_val)
1810 {
1811   print_flags (class, d_val, dt_flags, ndt_flags);
1812 }
1813 
1814 
1815 static void
print_dt_flags_1(int class,GElf_Xword d_val)1816 print_dt_flags_1 (int class, GElf_Xword d_val)
1817 {
1818   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1819 }
1820 
1821 
1822 static void
print_dt_feature_1(int class,GElf_Xword d_val)1823 print_dt_feature_1 (int class, GElf_Xword d_val)
1824 {
1825   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1826 }
1827 
1828 
1829 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1830 print_dt_posflag_1 (int class, GElf_Xword d_val)
1831 {
1832   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1833 }
1834 
1835 
1836 static size_t
get_dyn_ents(Elf_Data * dyn_data)1837 get_dyn_ents (Elf_Data * dyn_data)
1838 {
1839   GElf_Dyn *dyn;
1840   GElf_Dyn dyn_mem;
1841   size_t dyn_idx = 0;
1842   do
1843     {
1844       dyn = gelf_getdyn(dyn_data, dyn_idx, &dyn_mem);
1845       if (dyn != NULL)
1846 	++dyn_idx;
1847     }
1848   while (dyn != NULL && dyn->d_tag != DT_NULL);
1849 
1850   return dyn_idx;
1851 }
1852 
1853 
1854 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,GElf_Phdr * phdr)1855 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
1856 {
1857   int class = gelf_getclass (ebl->elf);
1858   GElf_Shdr glink_mem;
1859   GElf_Shdr *glink;
1860   Elf_Data *data;
1861   size_t cnt;
1862   size_t shstrndx;
1863   size_t dyn_ents;
1864 
1865   /* Get the data of the section.  */
1866   if (use_dynamic_segment && phdr != NULL)
1867     data = elf_getdata_rawchunk(ebl->elf, phdr->p_offset,
1868 				phdr->p_filesz, ELF_T_DYN);
1869   else
1870     data = elf_getdata (scn, NULL);
1871 
1872   if (data == NULL)
1873     return;
1874 
1875   /* Get the dynamic section entry number */
1876   dyn_ents = get_dyn_ents (data);
1877 
1878   if (!use_dynamic_segment && shdr != NULL)
1879     {
1880       /* Get the section header string table index.  */
1881       if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1882 	error_exit (0, _("cannot get section header string table index"));
1883 
1884       glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1885       if (glink == NULL)
1886 	error_exit (0, _("invalid sh_link value in section %zu"),
1887 		    elf_ndxscn (scn));
1888 
1889       printf (ngettext ("\
1890 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1891 		    "\
1892 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1893 			dyn_ents),
1894 	      (unsigned long int) dyn_ents,
1895 	      class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1896 	      shdr->sh_offset,
1897 	      (int) shdr->sh_link,
1898 	      elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1899     }
1900   else if (phdr != NULL)
1901     {
1902       printf (ngettext ("\
1903 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "\n",
1904 		    "\
1905 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "\n",
1906 			dyn_ents),
1907 	      (unsigned long int) dyn_ents,
1908 	      class == ELFCLASS32 ? 10 : 18, phdr->p_paddr,
1909 	      phdr->p_offset);
1910     }
1911 
1912   fputs_unlocked (_("  Type              Value\n"), stdout);
1913 
1914   /* if --use-dynamic option is enabled,
1915      use the string table to get the related library info.  */
1916   Elf_Data *strtab_data = NULL;
1917   if (use_dynamic_segment && phdr != NULL)
1918     {
1919       strtab_data = get_dynscn_strtab(ebl->elf, phdr);
1920       if (strtab_data == NULL)
1921 	error_exit (0, _("cannot get string table by using dynamic segment"));
1922     }
1923 
1924   for (cnt = 0; cnt < dyn_ents; ++cnt)
1925     {
1926       GElf_Dyn dynmem;
1927       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1928       if (dyn == NULL)
1929 	break;
1930 
1931       char buf[64];
1932       printf ("  %-17s ",
1933 	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1934 
1935       char *name = NULL;
1936       if (dyn->d_tag == DT_NEEDED
1937 	  || dyn->d_tag == DT_SONAME
1938 	  || dyn->d_tag == DT_RPATH
1939 	  || dyn->d_tag == DT_RUNPATH)
1940 	{
1941 	  if (! use_dynamic_segment && shdr != NULL)
1942 	    name = elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val);
1943 	  else if (dyn->d_un.d_val < strtab_data->d_size
1944 		   && memrchr (strtab_data->d_buf + dyn->d_un.d_val, '\0',
1945 			       strtab_data->d_size - 1 - dyn->d_un.d_val) != NULL)
1946 	    name = ((char *) strtab_data->d_buf) + dyn->d_un.d_val;
1947 	}
1948 
1949       switch (dyn->d_tag)
1950 	{
1951 	case DT_NULL:
1952 	case DT_DEBUG:
1953 	case DT_BIND_NOW:
1954 	case DT_TEXTREL:
1955 	  /* No further output.  */
1956 	  fputc_unlocked ('\n', stdout);
1957 	  break;
1958 
1959 	case DT_NEEDED:
1960 	  printf (_("Shared library: [%s]\n"), name);
1961 	  break;
1962 
1963 	case DT_SONAME:
1964 	  printf (_("Library soname: [%s]\n"), name);
1965 	  break;
1966 
1967 	case DT_RPATH:
1968 	  printf (_("Library rpath: [%s]\n"), name);
1969 	  break;
1970 
1971 	case DT_RUNPATH:
1972 	  printf (_("Library runpath: [%s]\n"), name);
1973 	  break;
1974 
1975 	case DT_PLTRELSZ:
1976 	case DT_RELASZ:
1977 	case DT_STRSZ:
1978 	case DT_RELSZ:
1979 	case DT_RELRSZ:
1980 	case DT_RELAENT:
1981 	case DT_SYMENT:
1982 	case DT_RELENT:
1983 	case DT_RELRENT:
1984 	case DT_PLTPADSZ:
1985 	case DT_MOVEENT:
1986 	case DT_MOVESZ:
1987 	case DT_INIT_ARRAYSZ:
1988 	case DT_FINI_ARRAYSZ:
1989 	case DT_SYMINSZ:
1990 	case DT_SYMINENT:
1991 	case DT_GNU_CONFLICTSZ:
1992 	case DT_GNU_LIBLISTSZ:
1993 	  printf (_("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1994 	  break;
1995 
1996 	case DT_VERDEFNUM:
1997 	case DT_VERNEEDNUM:
1998 	case DT_RELACOUNT:
1999 	case DT_RELCOUNT:
2000 	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
2001 	  break;
2002 
2003 	case DT_PLTREL:;
2004 	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
2005 						      NULL, 0);
2006 	  puts (tagname ?: "???");
2007 	  break;
2008 
2009 	case DT_FLAGS:
2010 	  print_dt_flags (class, dyn->d_un.d_val);
2011 	  break;
2012 
2013 	case DT_FLAGS_1:
2014 	  print_dt_flags_1 (class, dyn->d_un.d_val);
2015 	  break;
2016 
2017 	case DT_FEATURE_1:
2018 	  print_dt_feature_1 (class, dyn->d_un.d_val);
2019 	  break;
2020 
2021 	case DT_POSFLAG_1:
2022 	  print_dt_posflag_1 (class, dyn->d_un.d_val);
2023 	  break;
2024 
2025 	default:
2026 	  printf ("%#0*" PRIx64 "\n",
2027 		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
2028 	  break;
2029 	}
2030     }
2031 }
2032 
2033 
2034 /* Print the dynamic segment.  */
2035 static void
print_dynamic(Ebl * ebl)2036 print_dynamic (Ebl *ebl)
2037 {
2038   for (size_t i = 0; i < phnum; ++i)
2039     {
2040       GElf_Phdr phdr_mem;
2041       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
2042 
2043       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
2044 	{
2045 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
2046 	  GElf_Shdr shdr_mem;
2047 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2048 	  if ((use_dynamic_segment && phdr != NULL)
2049 	      || (shdr != NULL && shdr->sh_type == SHT_DYNAMIC))
2050 	    handle_dynamic (ebl, scn, shdr, phdr);
2051 	  break;
2052 	}
2053     }
2054 }
2055 
2056 
2057 /* Print relocations.  */
2058 static void
print_relocs(Ebl * ebl,Dwfl_Module * mod,GElf_Ehdr * ehdr)2059 print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr)
2060 {
2061   /* Find all relocation sections and handle them.  */
2062   Elf_Scn *scn = NULL;
2063 
2064   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2065     {
2066        /* Handle the section if it is a symbol table.  */
2067       GElf_Shdr shdr_mem;
2068       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2069 
2070       if (likely (shdr != NULL))
2071 	{
2072 	  if (shdr->sh_type == SHT_REL)
2073 	    handle_relocs_rel (ebl, ehdr, scn, shdr);
2074 	  else if (shdr->sh_type == SHT_RELA)
2075 	    handle_relocs_rela (ebl, ehdr, scn, shdr);
2076 	  else if (shdr->sh_type == SHT_RELR)
2077 	    handle_relocs_relr (ebl, mod, scn, shdr);
2078 	}
2079     }
2080 }
2081 
2082 
2083 /* Handle a relocation section.  */
2084 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2085 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2086 {
2087   int class = gelf_getclass (ebl->elf);
2088   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
2089   int nentries = shdr->sh_size / sh_entsize;
2090 
2091   /* Get the data of the section.  */
2092   Elf_Data *data = elf_getdata (scn, NULL);
2093   if (data == NULL)
2094     return;
2095 
2096   /* Get the symbol table information.  */
2097   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2098   GElf_Shdr symshdr_mem;
2099   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2100   Elf_Data *symdata = elf_getdata (symscn, NULL);
2101 
2102   /* Get the section header of the section the relocations are for.  */
2103   GElf_Shdr destshdr_mem;
2104   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2105 				      &destshdr_mem);
2106 
2107   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2108     {
2109       printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2110 	      shdr->sh_offset);
2111       return;
2112     }
2113 
2114   /* Search for the optional extended section index table.  */
2115   Elf_Data *xndxdata = NULL;
2116   int xndxscnidx = elf_scnshndx (scn);
2117   if (unlikely (xndxscnidx > 0))
2118     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2119 
2120   /* Get the section header string table index.  */
2121   size_t shstrndx;
2122   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2123     error_exit (0, _("cannot get section header string table index"));
2124 
2125   if (shdr->sh_info != 0)
2126     printf (ngettext ("\
2127 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2128 		    "\
2129 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2130 		      nentries),
2131 	    elf_ndxscn (scn),
2132 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2133 	    (unsigned int) shdr->sh_info,
2134 	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2135 	    shdr->sh_offset,
2136 	    nentries);
2137   else
2138     /* The .rel.dyn section does not refer to a specific section but
2139        instead of section index zero.  Do not try to print a section
2140        name.  */
2141     printf (ngettext ("\
2142 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2143 		    "\
2144 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2145 		      nentries),
2146 	    (unsigned int) elf_ndxscn (scn),
2147 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2148 	    shdr->sh_offset,
2149 	    nentries);
2150   fputs_unlocked (class == ELFCLASS32
2151 		  ? _("\
2152   Offset      Type                 Value       Name\n")
2153 		  : _("\
2154   Offset              Type                 Value               Name\n"),
2155 	 stdout);
2156 
2157   int is_statically_linked = 0;
2158   for (int cnt = 0; cnt < nentries; ++cnt)
2159     {
2160       GElf_Rel relmem;
2161       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2162       if (likely (rel != NULL))
2163 	{
2164 	  char buf[128];
2165 	  GElf_Sym symmem;
2166 	  Elf32_Word xndx;
2167 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2168 					    GELF_R_SYM (rel->r_info),
2169 					    &symmem, &xndx);
2170 	  if (unlikely (sym == NULL))
2171 	    {
2172 	      /* As a special case we have to handle relocations in static
2173 		 executables.  This only happens for IRELATIVE relocations
2174 		 (so far).  There is no symbol table.  */
2175 	      if (is_statically_linked == 0)
2176 		{
2177 		  /* Find the program header and look for a PT_INTERP entry. */
2178 		  is_statically_linked = -1;
2179 		  if (ehdr->e_type == ET_EXEC)
2180 		    {
2181 		      is_statically_linked = 1;
2182 
2183 		      for (size_t inner = 0; inner < phnum; ++inner)
2184 			{
2185 			  GElf_Phdr phdr_mem;
2186 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2187 							  &phdr_mem);
2188 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2189 			    {
2190 			      is_statically_linked = -1;
2191 			      break;
2192 			    }
2193 			}
2194 		    }
2195 		}
2196 
2197 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2198 		printf ("\
2199   %#0*" PRIx64 "  %-20s %*s  %s\n",
2200 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2201 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2202 			/* Avoid the leading R_ which isn't carrying any
2203 			   information.  */
2204 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2205 					       buf, sizeof (buf)) + 2
2206 			: _("<INVALID RELOC>"),
2207 			class == ELFCLASS32 ? 10 : 18, "",
2208 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2209 	      else
2210 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
2211 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2212 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2213 			/* Avoid the leading R_ which isn't carrying any
2214 			   information.  */
2215 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2216 					       buf, sizeof (buf)) + 2
2217 			: _("<INVALID RELOC>"),
2218 			_("INVALID SYMBOL"),
2219 			(long int) GELF_R_SYM (rel->r_info));
2220 	    }
2221 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2222 	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2223 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2224 		    likely (ebl_reloc_type_check (ebl,
2225 						  GELF_R_TYPE (rel->r_info)))
2226 		    /* Avoid the leading R_ which isn't carrying any
2227 		       information.  */
2228 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2229 					   buf, sizeof (buf)) + 2
2230 		    : _("<INVALID RELOC>"),
2231 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2232 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2233 	  else
2234 	    {
2235 	      /* This is a relocation against a STT_SECTION symbol.  */
2236 	      GElf_Shdr secshdr_mem;
2237 	      GElf_Shdr *secshdr;
2238 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2239 						  sym->st_shndx == SHN_XINDEX
2240 						  ? xndx : sym->st_shndx),
2241 				      &secshdr_mem);
2242 
2243 	      if (unlikely (secshdr == NULL))
2244 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
2245 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2246 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2247 			/* Avoid the leading R_ which isn't carrying any
2248 			   information.  */
2249 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2250 					       buf, sizeof (buf)) + 2
2251 			: _("<INVALID RELOC>"),
2252 			_("INVALID SECTION"),
2253 			(long int) (sym->st_shndx == SHN_XINDEX
2254 				    ? xndx : sym->st_shndx));
2255 	      else
2256 		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2257 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2258 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2259 			/* Avoid the leading R_ which isn't carrying any
2260 			   information.  */
2261 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2262 					       buf, sizeof (buf)) + 2
2263 			: _("<INVALID RELOC>"),
2264 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2265 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2266 	    }
2267 	}
2268     }
2269 }
2270 
2271 
2272 /* Handle a relocation section.  */
2273 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2274 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2275 {
2276   int class = gelf_getclass (ebl->elf);
2277   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2278   int nentries = shdr->sh_size / sh_entsize;
2279 
2280   /* Get the data of the section.  */
2281   Elf_Data *data = elf_getdata (scn, NULL);
2282   if (data == NULL)
2283     return;
2284 
2285   /* Get the symbol table information.  */
2286   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2287   GElf_Shdr symshdr_mem;
2288   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2289   Elf_Data *symdata = elf_getdata (symscn, NULL);
2290 
2291   /* Get the section header of the section the relocations are for.  */
2292   GElf_Shdr destshdr_mem;
2293   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2294 				      &destshdr_mem);
2295 
2296   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2297     {
2298       printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2299 	      shdr->sh_offset);
2300       return;
2301     }
2302 
2303   /* Search for the optional extended section index table.  */
2304   Elf_Data *xndxdata = NULL;
2305   int xndxscnidx = elf_scnshndx (scn);
2306   if (unlikely (xndxscnidx > 0))
2307     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2308 
2309   /* Get the section header string table index.  */
2310   size_t shstrndx;
2311   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2312     error_exit (0, _("cannot get section header string table index"));
2313 
2314   if (shdr->sh_info != 0)
2315     printf (ngettext ("\
2316 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2317 		    "\
2318 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2319 		    nentries),
2320 	  elf_ndxscn (scn),
2321 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2322 	  (unsigned int) shdr->sh_info,
2323 	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2324 	  shdr->sh_offset,
2325 	  nentries);
2326   else
2327     /* The .rela.dyn section does not refer to a specific section but
2328        instead of section index zero.  Do not try to print a section
2329        name.  */
2330     printf (ngettext ("\
2331 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2332 		    "\
2333 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2334 		      nentries),
2335 	    (unsigned int) elf_ndxscn (scn),
2336 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2337 	    shdr->sh_offset,
2338 	    nentries);
2339   fputs_unlocked (class == ELFCLASS32
2340 		  ? _("\
2341   Offset      Type            Value       Addend Name\n")
2342 		  : _("\
2343   Offset              Type            Value               Addend Name\n"),
2344 		  stdout);
2345 
2346   int is_statically_linked = 0;
2347   for (int cnt = 0; cnt < nentries; ++cnt)
2348     {
2349       GElf_Rela relmem;
2350       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2351       if (likely (rel != NULL))
2352 	{
2353 	  char buf[64];
2354 	  GElf_Sym symmem;
2355 	  Elf32_Word xndx;
2356 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2357 					    GELF_R_SYM (rel->r_info),
2358 					    &symmem, &xndx);
2359 
2360 	  if (unlikely (sym == NULL))
2361 	    {
2362 	      /* As a special case we have to handle relocations in static
2363 		 executables.  This only happens for IRELATIVE relocations
2364 		 (so far).  There is no symbol table.  */
2365 	      if (is_statically_linked == 0)
2366 		{
2367 		  /* Find the program header and look for a PT_INTERP entry. */
2368 		  is_statically_linked = -1;
2369 		  if (ehdr->e_type == ET_EXEC)
2370 		    {
2371 		      is_statically_linked = 1;
2372 
2373 		      for (size_t inner = 0; inner < phnum; ++inner)
2374 			{
2375 			  GElf_Phdr phdr_mem;
2376 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2377 							  &phdr_mem);
2378 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2379 			    {
2380 			      is_statically_linked = -1;
2381 			      break;
2382 			    }
2383 			}
2384 		    }
2385 		}
2386 
2387 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2388 		printf ("\
2389   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
2390 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2391 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2392 			/* Avoid the leading R_ which isn't carrying any
2393 			   information.  */
2394 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2395 					       buf, sizeof (buf)) + 2
2396 			: _("<INVALID RELOC>"),
2397 			class == ELFCLASS32 ? 10 : 18, "",
2398 			rel->r_addend,
2399 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2400 	      else
2401 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2402 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2403 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2404 			/* Avoid the leading R_ which isn't carrying any
2405 			   information.  */
2406 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2407 					       buf, sizeof (buf)) + 2
2408 			: _("<INVALID RELOC>"),
2409 			_("INVALID SYMBOL"),
2410 			(long int) GELF_R_SYM (rel->r_info));
2411 	    }
2412 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2413 	    printf ("\
2414   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2415 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2416 		    likely (ebl_reloc_type_check (ebl,
2417 						  GELF_R_TYPE (rel->r_info)))
2418 		    /* Avoid the leading R_ which isn't carrying any
2419 		       information.  */
2420 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2421 					   buf, sizeof (buf)) + 2
2422 		    : _("<INVALID RELOC>"),
2423 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2424 		    rel->r_addend,
2425 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2426 	  else
2427 	    {
2428 	      /* This is a relocation against a STT_SECTION symbol.  */
2429 	      GElf_Shdr secshdr_mem;
2430 	      GElf_Shdr *secshdr;
2431 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2432 						  sym->st_shndx == SHN_XINDEX
2433 						  ? xndx : sym->st_shndx),
2434 				      &secshdr_mem);
2435 
2436 	      if (unlikely (secshdr == NULL))
2437 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2438 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2439 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2440 			/* Avoid the leading R_ which isn't carrying any
2441 			   information.  */
2442 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2443 					       buf, sizeof (buf)) + 2
2444 			: _("<INVALID RELOC>"),
2445 			_("INVALID SECTION"),
2446 			(long int) (sym->st_shndx == SHN_XINDEX
2447 				    ? xndx : sym->st_shndx));
2448 	      else
2449 		printf ("\
2450   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2451 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2452 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2453 			/* Avoid the leading R_ which isn't carrying any
2454 			   information.  */
2455 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2456 					       buf, sizeof (buf)) + 2
2457 			: _("<INVALID RELOC>"),
2458 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2459 			rel->r_addend,
2460 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2461 	    }
2462 	}
2463     }
2464 }
2465 
2466 /* Handle a relocation section.  */
2467 static void
handle_relocs_relr(Ebl * ebl,Dwfl_Module * mod,Elf_Scn * scn,GElf_Shdr * shdr)2468 handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, GElf_Shdr *shdr)
2469 {
2470   int class = gelf_getclass (ebl->elf);
2471   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELR, 1, EV_CURRENT);
2472   int nentries = shdr->sh_size / sh_entsize;
2473 
2474   /* Get the data of the section.  */
2475   Elf_Data *data = elf_getdata (scn, NULL);
2476   if (data == NULL)
2477     return;
2478 
2479   /* Get the section header string table index.  */
2480   size_t shstrndx;
2481   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2482     error_exit (0, _("cannot get section header string table index"));
2483 
2484   /* A .relr.dyn section does not refer to a specific section.  */
2485   printf (ngettext ("\
2486 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2487 		    "\
2488 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2489 		    nentries),
2490 	  (unsigned int) elf_ndxscn (scn),
2491 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2492 	  shdr->sh_offset,
2493 	  nentries);
2494 
2495   if (class == ELFCLASS32)
2496     {
2497       uint32_t base = 0;
2498       for (int cnt = 0; cnt < nentries; ++cnt)
2499 	{
2500 	  Elf32_Word *words = data->d_buf;
2501 	  Elf32_Word entry = words[cnt];
2502 
2503 	  /* Just the raw entries?  */
2504 	  if (print_unresolved_addresses)
2505             printf ("  %#010" PRIx32 "%s\n", entry,
2506                     (entry & 1) == 0 ? " *" : "");
2507 	  else
2508 	    {
2509 	      /* A real address, also sets base.  */
2510 	      if ((entry & 1) == 0)
2511 		{
2512 		  printf ("  ");
2513 		  print_dwarf_addr (mod, 4, entry, entry);
2514 		  printf (" *\n");
2515 
2516 		  base = entry + 4;
2517 		}
2518 	      else
2519 		{
2520 		  /* Untangle address from base and bits.  */
2521 		  uint32_t addr;
2522 		  for (addr = base; (entry >>= 1) != 0; addr += 4)
2523 		    if ((entry & 1) != 0)
2524 		      {
2525 			printf ("  ");
2526 			print_dwarf_addr (mod, 4, addr, addr);
2527 			printf ("\n");
2528 		      }
2529 		  base += 4 * (4 * 8 - 1);
2530 		}
2531 	    }
2532 	}
2533     }
2534   else
2535     {
2536       uint64_t base = 0;
2537       for (int cnt = 0; cnt < nentries; ++cnt)
2538 	{
2539 	  Elf64_Xword *xwords = data->d_buf;
2540 	  Elf64_Xword entry = xwords[cnt];
2541 
2542 	  /* Just the raw entries?  */
2543 	  if (print_unresolved_addresses)
2544 	    printf ("  %#018" PRIx64 "%s\n", entry,
2545 		    (entry & 1) == 0 ? " *" : "");
2546 	  else
2547 	    {
2548 	      /* A real address, also sets base.  */
2549 	      if ((entry & 1) == 0)
2550 		{
2551 		  printf ("  ");
2552 		  print_dwarf_addr (mod, 8, entry, entry);
2553 		  printf (" *\n");
2554 
2555 		  base = entry + 8;
2556 		}
2557 	      else
2558 		{
2559 		  /* Untangle address from base and bits.  */
2560 		  uint64_t addr;
2561 		  for (addr = base; (entry >>= 1) != 0; addr += 8)
2562 		    if ((entry & 1) != 0)
2563 		      {
2564 			printf ("  ");
2565 			print_dwarf_addr (mod, 8, addr, addr);
2566 			printf ("\n");
2567 		      }
2568 		  base += 8 * (8 * 8 - 1);
2569 		}
2570 	    }
2571 	}
2572     }
2573 }
2574 
2575 /* Print the program header.  Return true if a symtab is printed,
2576    false otherwise.  */
2577 static bool
print_symtab(Ebl * ebl,int type)2578 print_symtab (Ebl *ebl, int type)
2579 {
2580   /* Use the dynamic section info to display symbol tables.  */
2581   if (use_dynamic_segment && type == SHT_DYNSYM)
2582     return handle_dynamic_symtab(ebl);
2583 
2584   /* Find the symbol table(s).  For this we have to search through the
2585      section table.  */
2586   Elf_Scn *scn = NULL;
2587   bool symtab_printed = false;
2588 
2589   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2590     {
2591       /* Handle the section if it is a symbol table.  */
2592       GElf_Shdr shdr_mem;
2593       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2594 
2595       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2596 	{
2597 	  if (symbol_table_section != NULL)
2598 	    {
2599 	      /* Get the section header string table index.  */
2600 	      size_t shstrndx;
2601 	      const char *sname;
2602 	      if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2603 		error_exit (0,
2604 			    _("cannot get section header string table index"));
2605 	      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2606 	      if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2607 		continue;
2608 	    }
2609 
2610 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2611 	    {
2612 	      if (elf_compress (scn, 0, 0) < 0)
2613 		printf ("WARNING: %s [%zd]\n",
2614 			_("Couldn't uncompress section"),
2615 			elf_ndxscn (scn));
2616 	      shdr = gelf_getshdr (scn, &shdr_mem);
2617 	      if (unlikely (shdr == NULL))
2618 		error_exit (0,
2619 			    _("cannot get section [%zd] header: %s"),
2620 			    elf_ndxscn (scn), elf_errmsg (-1));
2621 	    }
2622 	  symtab_printed = handle_symtab (ebl, scn, shdr);
2623 	}
2624     }
2625 
2626   return symtab_printed;
2627 }
2628 
2629 
2630 static void
process_symtab(Ebl * ebl,unsigned int nsyms,Elf64_Word idx,Elf32_Word verneed_stridx,Elf32_Word verdef_stridx,Elf_Data * symdata,Elf_Data * versym_data,Elf_Data * symstr_data,Elf_Data * verneed_data,Elf_Data * verdef_data,Elf_Data * xndx_data)2631 process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx,
2632                 Elf32_Word verneed_stridx, Elf32_Word verdef_stridx,
2633                 Elf_Data *symdata, Elf_Data *versym_data,
2634                 Elf_Data *symstr_data, Elf_Data *verneed_data,
2635                 Elf_Data *verdef_data, Elf_Data *xndx_data)
2636 {
2637   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2638     {
2639       char typebuf[64];
2640       char bindbuf[64];
2641       char scnbuf[64];
2642       Elf32_Word xndx;
2643       GElf_Sym sym_mem;
2644       GElf_Sym *sym
2645           = gelf_getsymshndx (symdata, xndx_data, cnt, &sym_mem, &xndx);
2646 
2647       if (unlikely (sym == NULL))
2648         continue;
2649 
2650       /* Determine the real section index.  */
2651       if (likely (sym->st_shndx != SHN_XINDEX))
2652         xndx = sym->st_shndx;
2653 
2654       printf (_ ("\
2655 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2656               cnt, gelf_getclass (ebl->elf) == ELFCLASS32 ? 8 : 16,
2657               sym->st_value, sym->st_size,
2658               ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), typebuf,
2659                                     sizeof (typebuf)),
2660               ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2661                                        bindbuf, sizeof (bindbuf)),
2662               get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2663               ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2664                                 sizeof (scnbuf), NULL, shnum),
2665               use_dynamic_segment == true
2666                   ? (char *)symstr_data->d_buf + sym->st_name
2667                   : elf_strptr (ebl->elf, idx, sym->st_name));
2668 
2669       if (versym_data != NULL)
2670         {
2671           /* Get the version information.  */
2672           GElf_Versym versym_mem;
2673           GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2674 
2675           if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2676             {
2677               bool is_nobits = false;
2678               bool check_def = xndx != SHN_UNDEF;
2679 
2680               if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2681                 {
2682                   GElf_Shdr symshdr_mem;
2683                   GElf_Shdr *symshdr = gelf_getshdr (
2684                       elf_getscn (ebl->elf, xndx), &symshdr_mem);
2685 
2686                   is_nobits
2687                       = (symshdr != NULL && symshdr->sh_type == SHT_NOBITS);
2688                 }
2689 
2690               if (is_nobits || !check_def)
2691                 {
2692                   /* We must test both.  */
2693                   GElf_Vernaux vernaux_mem;
2694                   GElf_Vernaux *vernaux = NULL;
2695                   size_t vn_offset = 0;
2696 
2697                   GElf_Verneed verneed_mem;
2698                   GElf_Verneed *verneed
2699                       = gelf_getverneed (verneed_data, 0, &verneed_mem);
2700                   while (verneed != NULL)
2701                     {
2702                       size_t vna_offset = vn_offset;
2703 
2704                       vernaux = gelf_getvernaux (verneed_data,
2705                                                  vna_offset += verneed->vn_aux,
2706                                                  &vernaux_mem);
2707                       while (vernaux != NULL && vernaux->vna_other != *versym
2708                              && vernaux->vna_next != 0
2709                              && (verneed_data->d_size - vna_offset
2710                                  >= vernaux->vna_next))
2711                         {
2712                           /* Update the offset.  */
2713                           vna_offset += vernaux->vna_next;
2714 
2715                           vernaux = (vernaux->vna_next == 0
2716                                          ? NULL
2717                                          : gelf_getvernaux (verneed_data,
2718                                                             vna_offset,
2719                                                             &vernaux_mem));
2720                         }
2721 
2722                       /* Check whether we found the version.  */
2723                       if (vernaux != NULL && vernaux->vna_other == *versym)
2724                         /* Found it.  */
2725                         break;
2726 
2727                       if (verneed_data->d_size - vn_offset < verneed->vn_next)
2728                         break;
2729 
2730                       vn_offset += verneed->vn_next;
2731                       verneed
2732                           = (verneed->vn_next == 0
2733                                  ? NULL
2734                                  : gelf_getverneed (verneed_data, vn_offset,
2735                                                     &verneed_mem));
2736                     }
2737 
2738                   if (vernaux != NULL && vernaux->vna_other == *versym)
2739                     {
2740                       printf ("@%s (%u)",
2741                               use_dynamic_segment == true
2742                                   ? (char *)symstr_data->d_buf
2743                                         + vernaux->vna_name
2744                                   : elf_strptr (ebl->elf, verneed_stridx,
2745                                                 vernaux->vna_name),
2746                               (unsigned int)vernaux->vna_other);
2747                       check_def = 0;
2748                     }
2749                   else if (unlikely (!is_nobits))
2750                     error (0, 0, _ ("bad dynamic symbol"));
2751                   else
2752                     check_def = 1;
2753                 }
2754 
2755               if (check_def && *versym != 0x8001)
2756                 {
2757                   /* We must test both.  */
2758                   size_t vd_offset = 0;
2759 
2760                   GElf_Verdef verdef_mem;
2761                   GElf_Verdef *verdef
2762                       = gelf_getverdef (verdef_data, 0, &verdef_mem);
2763                   while (verdef != NULL)
2764                     {
2765                       if (verdef->vd_ndx == (*versym & 0x7fff))
2766                         /* Found the definition.  */
2767                         break;
2768 
2769                       if (verdef_data->d_size - vd_offset < verdef->vd_next)
2770                         break;
2771 
2772                       vd_offset += verdef->vd_next;
2773                       verdef = (verdef->vd_next == 0
2774                                     ? NULL
2775                                     : gelf_getverdef (verdef_data, vd_offset,
2776                                                       &verdef_mem));
2777                     }
2778 
2779                   if (verdef != NULL)
2780                     {
2781                       GElf_Verdaux verdaux_mem;
2782                       GElf_Verdaux *verdaux = gelf_getverdaux (
2783                           verdef_data, vd_offset + verdef->vd_aux,
2784                           &verdaux_mem);
2785 
2786                       if (verdaux != NULL)
2787                         printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2788                                 use_dynamic_segment == true
2789                                     ? (char *)symstr_data->d_buf
2790                                           + verdaux->vda_name
2791                                     : elf_strptr (ebl->elf, verdef_stridx,
2792                                                   verdaux->vda_name));
2793                     }
2794                 }
2795             }
2796         }
2797 
2798       putchar_unlocked ('\n');
2799     }
2800 }
2801 
2802 
2803 static bool
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2804 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2805 {
2806   Elf_Data *versym_data = NULL;
2807   Elf_Data *verneed_data = NULL;
2808   Elf_Data *verdef_data = NULL;
2809   Elf_Data *xndx_data = NULL;
2810   int class = gelf_getclass (ebl->elf);
2811   Elf32_Word verneed_stridx = 0;
2812   Elf32_Word verdef_stridx = 0;
2813 
2814   /* Get the data of the section.  */
2815   Elf_Data *data = elf_getdata (scn, NULL);
2816   if (data == NULL)
2817     return false;
2818 
2819   /* Find out whether we have other sections we might need.  */
2820   Elf_Scn *runscn = NULL;
2821   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2822     {
2823       GElf_Shdr runshdr_mem;
2824       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2825 
2826       if (likely (runshdr != NULL))
2827 	{
2828 	  if (runshdr->sh_type == SHT_GNU_versym
2829 	      && runshdr->sh_link == elf_ndxscn (scn))
2830 	    /* Bingo, found the version information.  Now get the data.  */
2831 	    versym_data = elf_getdata (runscn, NULL);
2832 	  else if (runshdr->sh_type == SHT_GNU_verneed)
2833 	    {
2834 	      /* This is the information about the needed versions.  */
2835 	      verneed_data = elf_getdata (runscn, NULL);
2836 	      verneed_stridx = runshdr->sh_link;
2837 	    }
2838 	  else if (runshdr->sh_type == SHT_GNU_verdef)
2839 	    {
2840 	      /* This is the information about the defined versions.  */
2841 	      verdef_data = elf_getdata (runscn, NULL);
2842 	      verdef_stridx = runshdr->sh_link;
2843 	    }
2844 	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2845 	      && runshdr->sh_link == elf_ndxscn (scn))
2846 	    /* Extended section index.  */
2847 	    xndx_data = elf_getdata (runscn, NULL);
2848 	}
2849     }
2850 
2851   /* Get the section header string table index.  */
2852   size_t shstrndx;
2853   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2854     error_exit (0, _("cannot get section header string table index"));
2855 
2856   GElf_Shdr glink_mem;
2857   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2858 				   &glink_mem);
2859   if (glink == NULL)
2860     error_exit (0, _("invalid sh_link value in section %zu"),
2861 		elf_ndxscn (scn));
2862 
2863   /* Now we can compute the number of entries in the section.  */
2864   unsigned int nsyms = data->d_size / (class == ELFCLASS32
2865 				       ? sizeof (Elf32_Sym)
2866 				       : sizeof (Elf64_Sym));
2867 
2868   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2869 		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
2870 		    nsyms),
2871 	  (unsigned int) elf_ndxscn (scn),
2872 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2873   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
2874 		    " %lu local symbols  String table: [%2u] '%s'\n",
2875 		    shdr->sh_info),
2876 	  (unsigned long int) shdr->sh_info,
2877 	  (unsigned int) shdr->sh_link,
2878 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2879 
2880   fputs_unlocked (class == ELFCLASS32
2881 		  ? _("\
2882   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
2883 		  : _("\
2884   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
2885 		  stdout);
2886 
2887 	process_symtab(ebl, nsyms, shdr->sh_link, verneed_stridx, verdef_stridx,
2888 	data, versym_data, NULL, verneed_data, verdef_data, xndx_data);
2889     return true;
2890 }
2891 
2892 
2893 static bool
handle_dynamic_symtab(Ebl * ebl)2894 handle_dynamic_symtab (Ebl *ebl)
2895 {
2896   GElf_Phdr phdr_mem;
2897   GElf_Phdr *phdr = NULL;
2898   /* phnum is a static variable which was already fetched in function
2899      process_elf_file.  */
2900   for (size_t i = 0; i < phnum; ++i)
2901     {
2902       phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
2903       if (phdr->p_type == PT_DYNAMIC)
2904 	break;
2905     }
2906   if (phdr == NULL)
2907     return false;
2908 
2909   GElf_Addr addrs[i_max] = {
2910     0,
2911   };
2912   GElf_Off offs[i_max] = {
2913     0,
2914   };
2915   get_dynscn_addrs (ebl->elf, phdr, addrs);
2916   find_offsets (ebl->elf, 0, i_max, addrs, offs);
2917 
2918   size_t syments = 0;
2919 
2920   GElf_Ehdr ehdr_mem;
2921   GElf_Ehdr *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem);
2922 
2923   if (offs[i_hash] != 0)
2924     {
2925       /* In the original format, .hash says the size of .dynsym.  */
2926 
2927       size_t entsz = SH_ENTSIZE_HASH (ehdr);
2928       Elf_Data *data
2929           = elf_getdata_rawchunk (ebl->elf, offs[i_hash] + entsz, entsz,
2930                                   (entsz == 4 ? ELF_T_WORD : ELF_T_XWORD));
2931       if (data != NULL)
2932         syments = (entsz == 4 ? *(const GElf_Word *)data->d_buf
2933                               : *(const GElf_Xword *)data->d_buf);
2934     }
2935   if (offs[i_gnu_hash] != 0 && syments == 0)
2936     {
2937       /* In the new format, we can derive it with some work.  */
2938 
2939       const struct
2940       {
2941         Elf32_Word nbuckets;
2942         Elf32_Word symndx;
2943         Elf32_Word maskwords;
2944         Elf32_Word shift2;
2945       } * header;
2946 
2947       Elf_Data *data = elf_getdata_rawchunk (ebl->elf, offs[i_gnu_hash],
2948                                              sizeof *header, ELF_T_WORD);
2949       if (data != NULL)
2950         {
2951           header = data->d_buf;
2952           Elf32_Word nbuckets = header->nbuckets;
2953           Elf32_Word symndx = header->symndx;
2954           GElf_Off buckets_at
2955               = (offs[i_gnu_hash] + sizeof *header
2956                  + (gelf_getclass (ebl->elf) * sizeof (Elf32_Word)
2957                     * header->maskwords));
2958 
2959           // elf_getdata_rawchunk takes a size_t, make sure it
2960           // doesn't overflow.
2961 #if SIZE_MAX <= UINT32_MAX
2962           if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
2963             data = NULL;
2964           else
2965 #endif
2966             data = elf_getdata_rawchunk (ebl->elf, buckets_at,
2967                                          nbuckets * sizeof (Elf32_Word),
2968                                          ELF_T_WORD);
2969           if (data != NULL && symndx < nbuckets)
2970             {
2971               const Elf32_Word *const buckets = data->d_buf;
2972               Elf32_Word maxndx = symndx;
2973               for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
2974                 if (buckets[bucket] > maxndx)
2975                   maxndx = buckets[bucket];
2976 
2977               GElf_Off hasharr_at
2978                   = (buckets_at + nbuckets * sizeof (Elf32_Word));
2979               hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
2980               do
2981                 {
2982                   data = elf_getdata_rawchunk (
2983                       ebl->elf, hasharr_at, sizeof (Elf32_Word), ELF_T_WORD);
2984                   if (data != NULL && (*(const Elf32_Word *)data->d_buf & 1u))
2985                     {
2986                       syments = maxndx + 1;
2987                       break;
2988                     }
2989                   ++maxndx;
2990                   hasharr_at += sizeof (Elf32_Word);
2991                 }
2992               while (data != NULL);
2993             }
2994         }
2995     }
2996   if (offs[i_strtab] > offs[i_symtab] && syments == 0)
2997     syments = ((offs[i_strtab] - offs[i_symtab])
2998                / gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT));
2999 
3000   if (syments <= 0 || offs[i_strtab] == 0 || offs[i_symtab] == 0)
3001     {
3002       error_exit (0, _ ("Dynamic symbol information is not available for "
3003                         "displaying symbols."));
3004     }
3005 
3006   /* All the data chunk initializaion.  */
3007   Elf_Data *symdata = NULL;
3008   Elf_Data *symstrdata = NULL;
3009   Elf_Data *versym_data = NULL;
3010   Elf_Data *verdef_data = NULL;
3011   Elf_Data *verneed_data = NULL;
3012 
3013   symdata = elf_getdata_rawchunk (
3014       ebl->elf, offs[i_symtab],
3015       gelf_fsize (ebl->elf, ELF_T_SYM, syments, EV_CURRENT), ELF_T_SYM);
3016   symstrdata = elf_getdata_rawchunk (ebl->elf, offs[i_strtab], addrs[i_strsz],
3017                                      ELF_T_BYTE);
3018   versym_data = elf_getdata_rawchunk (
3019       ebl->elf, offs[i_versym], syments * sizeof (Elf64_Half), ELF_T_HALF);
3020 
3021   /* Get the verneed_data without vernaux.  */
3022   verneed_data = elf_getdata_rawchunk (
3023       ebl->elf, offs[i_verneed], addrs[i_verneednum] * sizeof (Elf64_Verneed),
3024       ELF_T_VNEED);
3025   size_t vernauxnum = 0;
3026   size_t vn_next_offset = 0;
3027 
3028   for (size_t i = 0; i < addrs[i_verneednum]; i++)
3029     {
3030       GElf_Verneed *verneed
3031           = (GElf_Verneed *)(verneed_data->d_buf + vn_next_offset);
3032       vernauxnum += verneed->vn_cnt;
3033       vn_next_offset += verneed->vn_next;
3034     }
3035 
3036   /* Update the verneed_data to include the vernaux.  */
3037   verneed_data = elf_getdata_rawchunk (
3038       ebl->elf, offs[i_verneed],
3039       (addrs[i_verneednum] + vernauxnum) * sizeof (GElf_Verneed), ELF_T_VNEED);
3040 
3041   /* Get the verdef_data without verdaux.  */
3042   verdef_data = elf_getdata_rawchunk (
3043       ebl->elf, offs[i_verdef], addrs[i_verdefnum] * sizeof (Elf64_Verdef),
3044       ELF_T_VDEF);
3045   size_t verdauxnum = 0;
3046   size_t vd_next_offset = 0;
3047 
3048   for (size_t i = 0; i < addrs[i_verdefnum]; i++)
3049     {
3050       GElf_Verdef *verdef
3051           = (GElf_Verdef *)(verdef_data->d_buf + vd_next_offset);
3052       verdauxnum += verdef->vd_cnt;
3053       vd_next_offset += verdef->vd_next;
3054     }
3055 
3056   /* Update the verdef_data to include the verdaux.  */
3057   verdef_data = elf_getdata_rawchunk (
3058       ebl->elf, offs[i_verdef],
3059       (addrs[i_verdefnum] + verdauxnum) * sizeof (GElf_Verdef), ELF_T_VDEF);
3060 
3061   unsigned int nsyms = (unsigned int)syments;
3062   process_symtab (ebl, nsyms, 0, 0, 0, symdata, versym_data, symstrdata,
3063                   verneed_data, verdef_data, NULL);
3064   return true;
3065 }
3066 
3067 
3068 /* Print version information.  */
3069 static void
print_verinfo(Ebl * ebl)3070 print_verinfo (Ebl *ebl)
3071 {
3072   /* Find the version information sections.  For this we have to
3073      search through the section table.  */
3074   Elf_Scn *scn = NULL;
3075 
3076   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3077     {
3078       /* Handle the section if it is part of the versioning handling.  */
3079       GElf_Shdr shdr_mem;
3080       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3081 
3082       if (likely (shdr != NULL))
3083 	{
3084 	  if (shdr->sh_type == SHT_GNU_verneed)
3085 	    handle_verneed (ebl, scn, shdr);
3086 	  else if (shdr->sh_type == SHT_GNU_verdef)
3087 	    handle_verdef (ebl, scn, shdr);
3088 	  else if (shdr->sh_type == SHT_GNU_versym)
3089 	    handle_versym (ebl, scn, shdr);
3090 	}
3091     }
3092 }
3093 
3094 
3095 static const char *
get_ver_flags(unsigned int flags)3096 get_ver_flags (unsigned int flags)
3097 {
3098   static char buf[32];
3099   char *endp;
3100 
3101   if (flags == 0)
3102     return _("none");
3103 
3104   if (flags & VER_FLG_BASE)
3105     endp = stpcpy (buf, "BASE ");
3106   else
3107     endp = buf;
3108 
3109   if (flags & VER_FLG_WEAK)
3110     {
3111       if (endp != buf)
3112 	endp = stpcpy (endp, "| ");
3113 
3114       endp = stpcpy (endp, "WEAK ");
3115     }
3116 
3117   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
3118     {
3119       strncpy (endp, _("| <unknown>"), buf + sizeof (buf) - endp);
3120       buf[sizeof (buf) - 1] = '\0';
3121     }
3122 
3123   return buf;
3124 }
3125 
3126 
3127 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)3128 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
3129 {
3130   int class = gelf_getclass (ebl->elf);
3131 
3132   /* Get the data of the section.  */
3133   Elf_Data *data = elf_getdata (scn, NULL);
3134   if (data == NULL)
3135     return;
3136 
3137   /* Get the section header string table index.  */
3138   size_t shstrndx;
3139   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3140     error_exit (0, _("cannot get section header string table index"));
3141 
3142   GElf_Shdr glink_mem;
3143   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3144 				   &glink_mem);
3145   if (glink == NULL)
3146     error_exit (0, _("invalid sh_link value in section %zu"),
3147 		elf_ndxscn (scn));
3148 
3149   printf (ngettext ("\
3150 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
3151 		    "\
3152 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
3153 		    shdr->sh_info),
3154 	  (unsigned int) elf_ndxscn (scn),
3155 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
3156 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3157 	  shdr->sh_offset,
3158 	  (unsigned int) shdr->sh_link,
3159 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3160 
3161   unsigned int offset = 0;
3162   for (int cnt = shdr->sh_info; --cnt >= 0; )
3163     {
3164       /* Get the data at the next offset.  */
3165       GElf_Verneed needmem;
3166       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
3167       if (unlikely (need == NULL))
3168 	break;
3169 
3170       printf (_("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
3171 	      offset, (unsigned short int) need->vn_version,
3172 	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
3173 	      (unsigned short int) need->vn_cnt);
3174 
3175       unsigned int auxoffset = offset + need->vn_aux;
3176       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3177 	{
3178 	  GElf_Vernaux auxmem;
3179 	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
3180 	  if (unlikely (aux == NULL))
3181 	    break;
3182 
3183 	  printf (_("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
3184 		  auxoffset,
3185 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
3186 		  get_ver_flags (aux->vna_flags),
3187 		  (unsigned short int) aux->vna_other);
3188 
3189 	  if (aux->vna_next == 0)
3190 	    break;
3191 
3192 	  auxoffset += aux->vna_next;
3193 	}
3194 
3195       /* Find the next offset.  */
3196       if (need->vn_next == 0)
3197 	break;
3198 
3199       offset += need->vn_next;
3200     }
3201 }
3202 
3203 
3204 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)3205 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
3206 {
3207   /* Get the data of the section.  */
3208   Elf_Data *data = elf_getdata (scn, NULL);
3209   if (data == NULL)
3210     return;
3211 
3212   /* Get the section header string table index.  */
3213   size_t shstrndx;
3214   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3215     error_exit (0, _("cannot get section header string table index"));
3216 
3217   GElf_Shdr glink_mem;
3218   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3219 				   &glink_mem);
3220   if (glink == NULL)
3221     error_exit (0, _("invalid sh_link value in section %zu"),
3222 		elf_ndxscn (scn));
3223 
3224   int class = gelf_getclass (ebl->elf);
3225   printf (ngettext ("\
3226 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
3227 		    "\
3228 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
3229 		    shdr->sh_info),
3230 	  (unsigned int) elf_ndxscn (scn),
3231 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3232 	  shdr->sh_info,
3233 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3234 	  shdr->sh_offset,
3235 	  (unsigned int) shdr->sh_link,
3236 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3237 
3238   unsigned int offset = 0;
3239   for (int cnt = shdr->sh_info; --cnt >= 0; )
3240     {
3241       /* Get the data at the next offset.  */
3242       GElf_Verdef defmem;
3243       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
3244       if (unlikely (def == NULL))
3245 	break;
3246 
3247       unsigned int auxoffset = offset + def->vd_aux;
3248       GElf_Verdaux auxmem;
3249       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
3250       if (unlikely (aux == NULL))
3251 	break;
3252 
3253       printf (_("\
3254   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
3255 	      offset, def->vd_version,
3256 	      get_ver_flags (def->vd_flags),
3257 	      def->vd_ndx,
3258 	      def->vd_cnt,
3259 	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
3260 
3261       auxoffset += aux->vda_next;
3262       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
3263 	{
3264 	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
3265 	  if (unlikely (aux == NULL))
3266 	    break;
3267 
3268 	  printf (_("  %#06x: Parent %d: %s\n"),
3269 		  auxoffset, cnt2,
3270 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
3271 
3272 	  if (aux->vda_next == 0)
3273 	    break;
3274 
3275 	  auxoffset += aux->vda_next;
3276 	}
3277 
3278       /* Find the next offset.  */
3279       if (def->vd_next == 0)
3280 	break;
3281       offset += def->vd_next;
3282     }
3283 }
3284 
3285 
3286 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)3287 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
3288 {
3289   int class = gelf_getclass (ebl->elf);
3290   const char **vername;
3291   const char **filename;
3292 
3293   /* Get the data of the section.  */
3294   Elf_Data *data = elf_getdata (scn, NULL);
3295   if (data == NULL)
3296     return;
3297 
3298   /* Get the section header string table index.  */
3299   size_t shstrndx;
3300   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3301     error_exit (0, _("cannot get section header string table index"));
3302 
3303   /* We have to find the version definition section and extract the
3304      version names.  */
3305   Elf_Scn *defscn = NULL;
3306   Elf_Scn *needscn = NULL;
3307 
3308   Elf_Scn *verscn = NULL;
3309   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
3310     {
3311       GElf_Shdr vershdr_mem;
3312       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
3313 
3314       if (likely (vershdr != NULL))
3315 	{
3316 	  if (vershdr->sh_type == SHT_GNU_verdef)
3317 	    defscn = verscn;
3318 	  else if (vershdr->sh_type == SHT_GNU_verneed)
3319 	    needscn = verscn;
3320 	}
3321     }
3322 
3323   size_t nvername;
3324   if (defscn != NULL || needscn != NULL)
3325     {
3326       /* We have a version information (better should have).  Now get
3327 	 the version names.  First find the maximum version number.  */
3328       nvername = 0;
3329       if (defscn != NULL)
3330 	{
3331 	  /* Run through the version definitions and find the highest
3332 	     index.  */
3333 	  unsigned int offset = 0;
3334 	  Elf_Data *defdata;
3335 	  GElf_Shdr defshdrmem;
3336 	  GElf_Shdr *defshdr;
3337 
3338 	  defdata = elf_getdata (defscn, NULL);
3339 	  if (unlikely (defdata == NULL))
3340 	    return;
3341 
3342 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
3343 	  if (unlikely (defshdr == NULL))
3344 	    return;
3345 
3346 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3347 	    {
3348 	      GElf_Verdef defmem;
3349 	      GElf_Verdef *def;
3350 
3351 	      /* Get the data at the next offset.  */
3352 	      def = gelf_getverdef (defdata, offset, &defmem);
3353 	      if (unlikely (def == NULL))
3354 		break;
3355 
3356 	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
3357 
3358 	      if (def->vd_next == 0)
3359 		break;
3360 	      offset += def->vd_next;
3361 	    }
3362 	}
3363       if (needscn != NULL)
3364 	{
3365 	  unsigned int offset = 0;
3366 	  Elf_Data *needdata;
3367 	  GElf_Shdr needshdrmem;
3368 	  GElf_Shdr *needshdr;
3369 
3370 	  needdata = elf_getdata (needscn, NULL);
3371 	  if (unlikely (needdata == NULL))
3372 	    return;
3373 
3374 	  needshdr = gelf_getshdr (needscn, &needshdrmem);
3375 	  if (unlikely (needshdr == NULL))
3376 	    return;
3377 
3378 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3379 	    {
3380 	      GElf_Verneed needmem;
3381 	      GElf_Verneed *need;
3382 	      unsigned int auxoffset;
3383 	      int cnt2;
3384 
3385 	      /* Get the data at the next offset.  */
3386 	      need = gelf_getverneed (needdata, offset, &needmem);
3387 	      if (unlikely (need == NULL))
3388 		break;
3389 
3390 	      /* Run through the auxiliary entries.  */
3391 	      auxoffset = offset + need->vn_aux;
3392 	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
3393 		{
3394 		  GElf_Vernaux auxmem;
3395 		  GElf_Vernaux *aux;
3396 
3397 		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
3398 		  if (unlikely (aux == NULL))
3399 		    break;
3400 
3401 		  nvername = MAX (nvername,
3402 				  (size_t) (aux->vna_other & 0x7fff));
3403 
3404 		  if (aux->vna_next == 0)
3405 		    break;
3406 		  auxoffset += aux->vna_next;
3407 		}
3408 
3409 	      if (need->vn_next == 0)
3410 		break;
3411 	      offset += need->vn_next;
3412 	    }
3413 	}
3414 
3415       /* This is the number of versions we know about.  */
3416       ++nvername;
3417 
3418       /* Allocate the array.  */
3419       vername = (const char **) alloca (nvername * sizeof (const char *));
3420       memset(vername, 0, nvername * sizeof (const char *));
3421       filename = (const char **) alloca (nvername * sizeof (const char *));
3422       memset(filename, 0, nvername * sizeof (const char *));
3423 
3424       /* Run through the data structures again and collect the strings.  */
3425       if (defscn != NULL)
3426 	{
3427 	  /* Run through the version definitions and find the highest
3428 	     index.  */
3429 	  unsigned int offset = 0;
3430 	  Elf_Data *defdata;
3431 	  GElf_Shdr defshdrmem;
3432 	  GElf_Shdr *defshdr;
3433 
3434 	  defdata = elf_getdata (defscn, NULL);
3435 	  if (unlikely (defdata == NULL))
3436 	    return;
3437 
3438 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
3439 	  if (unlikely (defshdr == NULL))
3440 	    return;
3441 
3442 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3443 	    {
3444 
3445 	      /* Get the data at the next offset.  */
3446 	      GElf_Verdef defmem;
3447 	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3448 	      if (unlikely (def == NULL))
3449 		break;
3450 
3451 	      GElf_Verdaux auxmem;
3452 	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
3453 						   offset + def->vd_aux,
3454 						   &auxmem);
3455 	      if (unlikely (aux == NULL))
3456 		break;
3457 
3458 	      vername[def->vd_ndx & 0x7fff]
3459 		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3460 	      filename[def->vd_ndx & 0x7fff] = NULL;
3461 
3462 	      if (def->vd_next == 0)
3463 		break;
3464 	      offset += def->vd_next;
3465 	    }
3466 	}
3467       if (needscn != NULL)
3468 	{
3469 	  unsigned int offset = 0;
3470 
3471 	  Elf_Data *needdata = elf_getdata (needscn, NULL);
3472 	  GElf_Shdr needshdrmem;
3473 	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3474 	  if (unlikely (needdata == NULL || needshdr == NULL))
3475 	    return;
3476 
3477 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3478 	    {
3479 	      /* Get the data at the next offset.  */
3480 	      GElf_Verneed needmem;
3481 	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
3482 						    &needmem);
3483 	      if (unlikely (need == NULL))
3484 		break;
3485 
3486 	      /* Run through the auxiliary entries.  */
3487 	      unsigned int auxoffset = offset + need->vn_aux;
3488 	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3489 		{
3490 		  GElf_Vernaux auxmem;
3491 		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3492 						       &auxmem);
3493 		  if (unlikely (aux == NULL))
3494 		    break;
3495 
3496 		  vername[aux->vna_other & 0x7fff]
3497 		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3498 		  filename[aux->vna_other & 0x7fff]
3499 		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3500 
3501 		  if (aux->vna_next == 0)
3502 		    break;
3503 		  auxoffset += aux->vna_next;
3504 		}
3505 
3506 	      if (need->vn_next == 0)
3507 		break;
3508 	      offset += need->vn_next;
3509 	    }
3510 	}
3511     }
3512   else
3513     {
3514       vername = NULL;
3515       nvername = 1;
3516       filename = NULL;
3517     }
3518 
3519   GElf_Shdr glink_mem;
3520   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3521 				   &glink_mem);
3522   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3523   if (glink == NULL)
3524     error_exit (0, _("invalid sh_link value in section %zu"),
3525 		elf_ndxscn (scn));
3526 
3527   /* Print the header.  */
3528   printf (ngettext ("\
3529 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
3530 		    "\
3531 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
3532 		    shdr->sh_size / sh_entsize),
3533 	  (unsigned int) elf_ndxscn (scn),
3534 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3535 	  (int) (shdr->sh_size / sh_entsize),
3536 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3537 	  shdr->sh_offset,
3538 	  (unsigned int) shdr->sh_link,
3539 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3540 
3541   /* Now we can finally look at the actual contents of this section.  */
3542   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3543     {
3544       if (cnt % 2 == 0)
3545 	printf ("\n %4d:", cnt);
3546 
3547       GElf_Versym symmem;
3548       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3549       if (sym == NULL)
3550 	break;
3551 
3552       switch (*sym)
3553 	{
3554 	  ssize_t n;
3555 	case 0:
3556 	  fputs_unlocked (_("   0 *local*                     "),
3557 			  stdout);
3558 	  break;
3559 
3560 	case 1:
3561 	  fputs_unlocked (_("   1 *global*                    "),
3562 			  stdout);
3563 	  break;
3564 
3565 	default:
3566 	  n = printf ("%4d%c%s",
3567 		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3568 		      (vername != NULL
3569 		       && (unsigned int) (*sym & 0x7fff) < nvername)
3570 		      ? vername[*sym & 0x7fff] : "???");
3571 	  if ((unsigned int) (*sym & 0x7fff) < nvername
3572 	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
3573 	    n += printf ("(%s)", filename[*sym & 0x7fff]);
3574 	  printf ("%*s", MAX (0, 33 - (int) n), " ");
3575 	  break;
3576 	}
3577     }
3578   putchar_unlocked ('\n');
3579 }
3580 
3581 
3582 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)3583 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3584 		 uint_fast32_t maxlength, Elf32_Word nbucket,
3585 		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3586 {
3587   uint32_t *counts = xcalloc (maxlength + 1, sizeof (uint32_t));
3588 
3589   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3590     ++counts[lengths[cnt]];
3591 
3592   GElf_Shdr glink_mem;
3593   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3594 					       shdr->sh_link),
3595 				   &glink_mem);
3596   if (glink == NULL)
3597     {
3598       error (0, 0, _("invalid sh_link value in section %zu"),
3599 	     elf_ndxscn (scn));
3600       return;
3601     }
3602 
3603   printf (ngettext ("\
3604 \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",
3605 		    "\
3606 \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",
3607 		    nbucket),
3608 	  (unsigned int) elf_ndxscn (scn),
3609 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3610 	  (int) nbucket,
3611 	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3612 	  shdr->sh_addr,
3613 	  shdr->sh_offset,
3614 	  (unsigned int) shdr->sh_link,
3615 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3616 
3617   if (extrastr != NULL)
3618     fputs (extrastr, stdout);
3619 
3620   if (likely (nbucket > 0))
3621     {
3622       uint64_t success = 0;
3623 
3624       /* xgettext:no-c-format */
3625       fputs_unlocked (_("\
3626  Length  Number  % of total  Coverage\n"), stdout);
3627       printf (_("      0  %6" PRIu32 "      %5.1f%%\n"),
3628 	      counts[0], (counts[0] * 100.0) / nbucket);
3629 
3630       uint64_t nzero_counts = 0;
3631       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3632 	{
3633 	  nzero_counts += counts[cnt] * cnt;
3634 	  printf (_("\
3635 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
3636 		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3637 		  (nzero_counts * 100.0) / nsyms);
3638 	}
3639 
3640       Elf32_Word acc = 0;
3641       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3642 	{
3643 	  acc += cnt;
3644 	  success += counts[cnt] * acc;
3645 	}
3646 
3647       printf (_("\
3648  Average number of tests:   successful lookup: %f\n\
3649 			  unsuccessful lookup: %f\n"),
3650 	      (double) success / (double) nzero_counts,
3651 	      (double) nzero_counts / (double) nbucket);
3652     }
3653 
3654   free (counts);
3655 }
3656 
3657 
3658 /* This function handles the traditional System V-style hash table format.  */
3659 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3660 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3661 {
3662   Elf_Data *data = elf_getdata (scn, NULL);
3663   if (unlikely (data == NULL))
3664     {
3665       error (0, 0, _("cannot get data for section %d: %s"),
3666 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3667       return;
3668     }
3669 
3670   if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3671     {
3672     invalid_data:
3673       error (0, 0, _("invalid data in sysv.hash section %d"),
3674 	     (int) elf_ndxscn (scn));
3675       return;
3676     }
3677 
3678   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3679   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3680 
3681   uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3682   if (used_buf > data->d_size)
3683     goto invalid_data;
3684 
3685   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3686   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3687 
3688   uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3689 
3690   uint_fast32_t maxlength = 0;
3691   uint_fast32_t nsyms = 0;
3692   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3693     {
3694       Elf32_Word inner = bucket[cnt];
3695       Elf32_Word chain_len = 0;
3696       while (inner > 0 && inner < nchain)
3697 	{
3698 	  ++nsyms;
3699 	  ++chain_len;
3700 	  if (chain_len > nchain)
3701 	    {
3702 	      error (0, 0, _("invalid chain in sysv.hash section %d"),
3703 		     (int) elf_ndxscn (scn));
3704 	      free (lengths);
3705 	      return;
3706 	    }
3707 	  if (maxlength < ++lengths[cnt])
3708 	    ++maxlength;
3709 
3710 	  inner = chain[inner];
3711 	}
3712     }
3713 
3714   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3715 		   lengths, NULL);
3716 
3717   free (lengths);
3718 }
3719 
3720 
3721 /* This function handles the incorrect, System V-style hash table
3722    format some 64-bit architectures use.  */
3723 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3724 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3725 {
3726   Elf_Data *data = elf_getdata (scn, NULL);
3727   if (unlikely (data == NULL))
3728     {
3729       error (0, 0, _("cannot get data for section %d: %s"),
3730 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3731       return;
3732     }
3733 
3734   if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3735     {
3736     invalid_data:
3737       error (0, 0, _("invalid data in sysv.hash64 section %d"),
3738 	     (int) elf_ndxscn (scn));
3739       return;
3740     }
3741 
3742   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3743   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3744 
3745   uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3746   if (maxwords < 2
3747       || maxwords - 2 < nbucket
3748       || maxwords - 2 - nbucket < nchain)
3749     goto invalid_data;
3750 
3751   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3752   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3753 
3754   uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3755 
3756   uint_fast32_t maxlength = 0;
3757   uint_fast32_t nsyms = 0;
3758   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3759     {
3760       Elf64_Xword inner = bucket[cnt];
3761       Elf64_Xword chain_len = 0;
3762       while (inner > 0 && inner < nchain)
3763 	{
3764 	  ++nsyms;
3765 	  ++chain_len;
3766 	  if (chain_len > nchain)
3767 	    {
3768 	      error (0, 0, _("invalid chain in sysv.hash64 section %d"),
3769 		     (int) elf_ndxscn (scn));
3770 	      free (lengths);
3771 	      return;
3772 	    }
3773 	  if (maxlength < ++lengths[cnt])
3774 	    ++maxlength;
3775 
3776 	  inner = chain[inner];
3777 	}
3778     }
3779 
3780   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3781 		   lengths, NULL);
3782 
3783   free (lengths);
3784 }
3785 
3786 
3787 /* This function handles the GNU-style hash table format.  */
3788 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3789 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3790 {
3791   uint32_t *lengths = NULL;
3792   Elf_Data *data = elf_getdata (scn, NULL);
3793   if (unlikely (data == NULL))
3794     {
3795       error (0, 0, _("cannot get data for section %d: %s"),
3796 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3797       return;
3798     }
3799 
3800   if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3801     {
3802     invalid_data:
3803       free (lengths);
3804       error (0, 0, _("invalid data in gnu.hash section %d"),
3805 	     (int) elf_ndxscn (scn));
3806       return;
3807     }
3808 
3809   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3810   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3811 
3812   /* Next comes the size of the bitmap.  It's measured in words for
3813      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
3814      64 bit archs.  There is always a bloom filter present, so zero is
3815      an invalid value.  */
3816   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3817   if (gelf_getclass (ebl->elf) == ELFCLASS64)
3818     bitmask_words *= 2;
3819 
3820   if (bitmask_words == 0)
3821     goto invalid_data;
3822 
3823   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3824 
3825   /* Is there still room for the sym chain?
3826      Use uint64_t calculation to prevent 32bit overflow.  */
3827   uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3828   uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3829   if (used_buf > data->d_size)
3830     goto invalid_data;
3831 
3832   lengths = xcalloc (nbucket, sizeof (uint32_t));
3833 
3834   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3835   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3836   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3837 						    + nbucket];
3838 
3839   /* Compute distribution of chain lengths.  */
3840   uint_fast32_t maxlength = 0;
3841   uint_fast32_t nsyms = 0;
3842   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3843     if (bucket[cnt] != 0)
3844       {
3845 	Elf32_Word inner = bucket[cnt] - symbias;
3846 	do
3847 	  {
3848 	    ++nsyms;
3849 	    if (maxlength < ++lengths[cnt])
3850 	      ++maxlength;
3851 	    if (inner >= max_nsyms)
3852 	      goto invalid_data;
3853 	  }
3854 	while ((chain[inner++] & 1) == 0);
3855       }
3856 
3857   /* Count bits in bitmask.  */
3858   uint_fast32_t nbits = 0;
3859   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3860     {
3861       uint_fast32_t word = bitmask[cnt];
3862 
3863       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3864       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3865       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3866       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3867       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3868     }
3869 
3870   char *str = xasprintf (_("\
3871  Symbol Bias: %u\n\
3872  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
3873 			 (unsigned int) symbias,
3874 			 bitmask_words * sizeof (Elf32_Word),
3875 			 ((nbits * 100 + 50)
3876 			  / (uint_fast32_t) (bitmask_words
3877 					      * sizeof (Elf32_Word) * 8)),
3878 			  (unsigned int) shift);
3879 
3880   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3881 		   lengths, str);
3882 
3883   free (str);
3884   free (lengths);
3885 }
3886 
3887 
3888 /* Find the symbol table(s).  For this we have to search through the
3889    section table.  */
3890 static void
handle_hash(Ebl * ebl)3891 handle_hash (Ebl *ebl)
3892 {
3893   /* Get the section header string table index.  */
3894   size_t shstrndx;
3895   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3896     error_exit (0, _("cannot get section header string table index"));
3897 
3898   Elf_Scn *scn = NULL;
3899   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3900     {
3901       /* Handle the section if it is a symbol table.  */
3902       GElf_Shdr shdr_mem;
3903       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3904 
3905       if (likely (shdr != NULL))
3906 	{
3907 	  if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3908 	      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3909 	    {
3910 	      if (elf_compress (scn, 0, 0) < 0)
3911 		printf ("WARNING: %s [%zd]\n",
3912 			_("Couldn't uncompress section"),
3913 			elf_ndxscn (scn));
3914 	      shdr = gelf_getshdr (scn, &shdr_mem);
3915 	      if (unlikely (shdr == NULL))
3916 		error_exit (0, _("cannot get section [%zd] header: %s"),
3917 			    elf_ndxscn (scn), elf_errmsg (-1));
3918 	    }
3919 
3920 	  if (shdr->sh_type == SHT_HASH)
3921 	    {
3922 	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3923 		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3924 	      else
3925 		handle_sysv_hash (ebl, scn, shdr, shstrndx);
3926 	    }
3927 	  else if (shdr->sh_type == SHT_GNU_HASH)
3928 	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
3929 	}
3930     }
3931 }
3932 
3933 
3934 static void
print_liblist(Ebl * ebl)3935 print_liblist (Ebl *ebl)
3936 {
3937   /* Find the library list sections.  For this we have to search
3938      through the section table.  */
3939   Elf_Scn *scn = NULL;
3940 
3941   /* Get the section header string table index.  */
3942   size_t shstrndx;
3943   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3944     error_exit (0, _("cannot get section header string table index"));
3945 
3946   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3947     {
3948       GElf_Shdr shdr_mem;
3949       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3950 
3951       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3952 	{
3953 	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3954 	  int nentries = shdr->sh_size / sh_entsize;
3955 	  printf (ngettext ("\
3956 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3957 			    "\
3958 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3959 			    nentries),
3960 		  elf_ndxscn (scn),
3961 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3962 		  shdr->sh_offset,
3963 		  nentries);
3964 
3965 	  Elf_Data *data = elf_getdata (scn, NULL);
3966 	  if (data == NULL)
3967 	    return;
3968 
3969 	  puts (_("\
3970        Library                       Time Stamp          Checksum Version Flags"));
3971 
3972 	  for (int cnt = 0; cnt < nentries; ++cnt)
3973 	    {
3974 	      GElf_Lib lib_mem;
3975 	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3976 	      if (unlikely (lib == NULL))
3977 		continue;
3978 
3979 	      time_t t = (time_t) lib->l_time_stamp;
3980 	      struct tm *tm = gmtime (&t);
3981 	      if (unlikely (tm == NULL))
3982 		continue;
3983 
3984 	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3985 		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3986 		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3987 		      tm->tm_hour, tm->tm_min, tm->tm_sec,
3988 		      (unsigned int) lib->l_checksum,
3989 		      (unsigned int) lib->l_version,
3990 		      (unsigned int) lib->l_flags);
3991 	    }
3992 	}
3993     }
3994 }
3995 
3996 static inline size_t
left(Elf_Data * data,const unsigned char * p)3997 left (Elf_Data *data,
3998       const unsigned char *p)
3999 {
4000   return (const unsigned char *) data->d_buf + data->d_size - p;
4001 }
4002 
4003 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)4004 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
4005 {
4006   /* Find the object attributes sections.  For this we have to search
4007      through the section table.  */
4008   Elf_Scn *scn = NULL;
4009 
4010   /* Get the section header string table index.  */
4011   size_t shstrndx;
4012   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
4013     error_exit (0, _("cannot get section header string table index"));
4014 
4015   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
4016     {
4017       GElf_Shdr shdr_mem;
4018       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
4019 
4020       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
4021 			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
4022 			       || ehdr->e_machine != EM_ARM)
4023 			   && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
4024 			       || ehdr->e_machine != EM_CSKY)
4025 			   && (shdr->sh_type != SHT_RISCV_ATTRIBUTES
4026 			       || ehdr->e_machine != EM_RISCV)))
4027 	continue;
4028 
4029       printf (_("\
4030 \nObject attributes section [%2zu] '%s' of %" PRIu64
4031 		       " bytes at offset %#0" PRIx64 ":\n"),
4032 	      elf_ndxscn (scn),
4033 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
4034 	      shdr->sh_size, shdr->sh_offset);
4035 
4036       Elf_Data *data = elf_rawdata (scn, NULL);
4037       if (unlikely (data == NULL || data->d_size == 0))
4038 	return;
4039 
4040       const unsigned char *p = data->d_buf;
4041 
4042       /* There is only one 'version', A.  */
4043       if (unlikely (*p++ != 'A'))
4044 	return;
4045 
4046       fputs_unlocked (_("  Owner          Size\n"), stdout);
4047 
4048       /* Loop over the sections.  */
4049       while (left (data, p) >= 4)
4050 	{
4051 	  /* Section length.  */
4052 	  uint32_t len;
4053 	  memcpy (&len, p, sizeof len);
4054 
4055 	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
4056 	    CONVERT (len);
4057 
4058 	  if (unlikely (len > left (data, p)))
4059 	    break;
4060 
4061 	  /* Section vendor name.  */
4062 	  const unsigned char *name = p + sizeof len;
4063 	  p += len;
4064 
4065 	  unsigned const char *q = memchr (name, '\0', len);
4066 	  if (unlikely (q == NULL))
4067 	    break;
4068 	  ++q;
4069 
4070 	  printf (_("  %-13s  %4" PRIu32 "\n"), name, len);
4071 
4072 	  bool gnu_vendor = (q - name == sizeof "gnu"
4073 			     && !memcmp (name, "gnu", sizeof "gnu"));
4074 
4075 	  /* Loop over subsections.  */
4076 	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
4077 	      || gnu_vendor)
4078 	    while (q < p)
4079 	      {
4080 		const unsigned char *const sub = q;
4081 
4082 		unsigned int subsection_tag;
4083 		get_uleb128 (subsection_tag, q, p);
4084 		if (unlikely (q >= p))
4085 		  break;
4086 
4087 		uint32_t subsection_len;
4088 		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
4089 		  break;
4090 
4091 		memcpy (&subsection_len, q, sizeof subsection_len);
4092 
4093 		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
4094 		  CONVERT (subsection_len);
4095 
4096 		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
4097 		if (unlikely (subsection_len == 0
4098 			      || subsection_len >= (uint32_t) PTRDIFF_MAX
4099 			      || p - sub < (ptrdiff_t) subsection_len))
4100 		  break;
4101 
4102 		const unsigned char *r = q + sizeof subsection_len;
4103 		q = sub + subsection_len;
4104 
4105 		switch (subsection_tag)
4106 		  {
4107 		  default:
4108 		    /* Unknown subsection, print and skip.  */
4109 		    printf (_("    %-4u %12" PRIu32 "\n"),
4110 			    subsection_tag, subsection_len);
4111 		    break;
4112 
4113 		  case 1:	/* Tag_File */
4114 		    printf (_("    File: %11" PRIu32 "\n"),
4115 			    subsection_len);
4116 
4117 		    while (r < q)
4118 		      {
4119 			unsigned int tag;
4120 			get_uleb128 (tag, r, q);
4121 			if (unlikely (r >= q))
4122 			  break;
4123 
4124 			/* GNU style tags have either a uleb128 value,
4125 			   when lowest bit is not set, or a string
4126 			   when the lowest bit is set.
4127 			   "compatibility" (32) is special.  It has
4128 			   both a string and a uleb128 value.  For
4129 			   non-gnu we assume 6 till 31 only take ints.
4130 			   XXX see arm backend, do we need a separate
4131 			   hook?  */
4132 			uint64_t value = 0;
4133 			const char *string = NULL;
4134 			if (tag == 32 || (tag & 1) == 0
4135 			    || (! gnu_vendor && (tag > 5 && tag < 32)))
4136 			  {
4137 			    // Note r >= q check above.
4138 			    get_uleb128 (value, r, q);
4139 			    if (r > q)
4140 			      break;
4141 			  }
4142 			if (tag == 32
4143 			    || ((tag & 1) != 0
4144 				&& (gnu_vendor
4145 				    || (! gnu_vendor && tag > 32)))
4146 			    || (! gnu_vendor && tag > 3 && tag < 6))
4147 			  {
4148 			    string = (const char *) r;
4149 			    r = memchr (r, '\0', q - r);
4150 			    if (r == NULL)
4151 			      break;
4152 			    ++r;
4153 			  }
4154 
4155 			const char *tag_name = NULL;
4156 			const char *value_name = NULL;
4157 			ebl_check_object_attribute (ebl, (const char *) name,
4158 						    tag, value,
4159 						    &tag_name, &value_name);
4160 
4161 			if (tag_name != NULL)
4162 			  {
4163 			    if (tag == 32)
4164 			      printf (_("      %s: %" PRId64 ", %s\n"),
4165 				      tag_name, value, string);
4166 			    else if (string == NULL && value_name == NULL)
4167 			      printf (_("      %s: %" PRId64 "\n"),
4168 				      tag_name, value);
4169 			    else
4170 			      printf (_("      %s: %s\n"),
4171 				      tag_name, string ?: value_name);
4172 			  }
4173 			else
4174 			  {
4175 			    /* For "gnu" vendor 32 "compatibility" has
4176 			       already been handled above.  */
4177 			    assert (tag != 32
4178 				    || strcmp ((const char *) name, "gnu"));
4179 			    if (string == NULL)
4180 			      printf (_("      %u: %" PRId64 "\n"),
4181 				      tag, value);
4182 			    else
4183 			      printf (_("      %u: %s\n"),
4184 				      tag, string);
4185 			  }
4186 		      }
4187 		  }
4188 	      }
4189 	}
4190     }
4191 }
4192 
4193 /* Returns either the (relocated) data from the Dwarf, or tries to get
4194    the "raw" (uncompressed) data from the Elf section. Produces a
4195    warning if the data cannot be found (or decompressed).  */
4196 static Elf_Data *
get_debug_elf_data(Dwarf * dbg,Ebl * ebl,int idx,Elf_Scn * scn)4197 get_debug_elf_data (Dwarf *dbg, Ebl *ebl, int idx, Elf_Scn *scn)
4198 {
4199   /* We prefer to get the section data from the Dwarf because that
4200      might have been relocated already.  Note this is subtly wrong if
4201      there are multiple sections with the same .debug name.  */
4202   if (dbg->sectiondata[idx] != NULL)
4203     return dbg->sectiondata[idx];
4204 
4205   GElf_Shdr shdr_mem;
4206   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
4207   if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
4208     {
4209       if (elf_compress (scn, 0, 0) < 0)
4210 	{
4211 	  error (0, 0, "%s [%zd] '%s'\n",
4212 		 _("Couldn't uncompress section"),
4213 		 elf_ndxscn (scn), section_name (ebl, shdr));
4214 	  return NULL;
4215 	}
4216     }
4217 
4218   Elf_Data *data = elf_getdata (scn, NULL);
4219   if (data == NULL)
4220     error (0, 0, "%s [%zd] '%s': %s\n",
4221 	   _("Couldn't get data from section"),
4222 	   elf_ndxscn (scn), section_name (ebl, shdr), elf_errmsg (-1));
4223 
4224   return elf_getdata (scn, NULL);
4225 }
4226 
4227 static void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)4228 print_dwarf_addr (Dwfl_Module *dwflmod,
4229 		  int address_size, Dwarf_Addr address, Dwarf_Addr raw)
4230 {
4231   /* See if there is a name we can give for this address.  */
4232   GElf_Sym sym;
4233   GElf_Off off = 0;
4234   const char *name = (print_address_names && ! print_unresolved_addresses)
4235     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
4236     : NULL;
4237 
4238   const char *scn;
4239   if (print_unresolved_addresses)
4240     {
4241       address = raw;
4242       scn = NULL;
4243     }
4244   else
4245     {
4246       /* Relativize the address.  */
4247       int n = dwfl_module_relocations (dwflmod);
4248       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
4249 
4250       /* In an ET_REL file there is a section name to refer to.  */
4251       scn = (i < 0 ? NULL
4252 	     : dwfl_module_relocation_info (dwflmod, i, NULL));
4253     }
4254 
4255   if ((name != NULL
4256        ? (off != 0
4257 	  ? (scn != NULL
4258 	     ? (address_size == 0
4259 		? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
4260 			  scn, address, name, off)
4261 		: printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
4262 			  scn, 2 + address_size * 2, address,
4263 			  name, off))
4264 	     : (address_size == 0
4265 		? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
4266 			  address, name, off)
4267 		: printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
4268 			  2 + address_size * 2, address,
4269 			  name, off)))
4270 	  : (scn != NULL
4271 	     ? (address_size == 0
4272 		? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
4273 		: printf ("%s+%#0*" PRIx64 " <%s>",
4274 			   scn, 2 + address_size * 2, address, name))
4275 	     : (address_size == 0
4276 		? printf ("%#" PRIx64 " <%s>", address, name)
4277 		: printf ("%#0*" PRIx64 " <%s>",
4278 			  2 + address_size * 2, address, name))))
4279        : (scn != NULL
4280 	  ? (address_size == 0
4281 	     ? printf ("%s+%#" PRIx64, scn, address)
4282 	     : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
4283 	  : (address_size == 0
4284 	     ? printf ("%#" PRIx64, address)
4285 	     : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
4286     error_exit (0, _("sprintf failure"));
4287 }
4288 
4289 
4290 static const char *
dwarf_tag_string(unsigned int tag)4291 dwarf_tag_string (unsigned int tag)
4292 {
4293   switch (tag)
4294     {
4295 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
4296       DWARF_ALL_KNOWN_DW_TAG
4297 #undef DWARF_ONE_KNOWN_DW_TAG
4298     default:
4299       return NULL;
4300     }
4301 }
4302 
4303 
4304 static const char *
dwarf_attr_string(unsigned int attrnum)4305 dwarf_attr_string (unsigned int attrnum)
4306 {
4307   switch (attrnum)
4308     {
4309 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
4310       DWARF_ALL_KNOWN_DW_AT
4311 #undef DWARF_ONE_KNOWN_DW_AT
4312     default:
4313       return NULL;
4314     }
4315 }
4316 
4317 
4318 static const char *
dwarf_form_string(unsigned int form)4319 dwarf_form_string (unsigned int form)
4320 {
4321   switch (form)
4322     {
4323 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
4324       DWARF_ALL_KNOWN_DW_FORM
4325 #undef DWARF_ONE_KNOWN_DW_FORM
4326     default:
4327       return NULL;
4328     }
4329 }
4330 
4331 
4332 static const char *
dwarf_lang_string(unsigned int lang)4333 dwarf_lang_string (unsigned int lang)
4334 {
4335   switch (lang)
4336     {
4337 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
4338       DWARF_ALL_KNOWN_DW_LANG
4339 #undef DWARF_ONE_KNOWN_DW_LANG
4340     default:
4341       return NULL;
4342     }
4343 }
4344 
4345 
4346 static const char *
dwarf_inline_string(unsigned int code)4347 dwarf_inline_string (unsigned int code)
4348 {
4349   static const char *const known[] =
4350     {
4351 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
4352       DWARF_ALL_KNOWN_DW_INL
4353 #undef DWARF_ONE_KNOWN_DW_INL
4354     };
4355 
4356   if (likely (code < sizeof (known) / sizeof (known[0])))
4357     return known[code];
4358 
4359   return NULL;
4360 }
4361 
4362 
4363 static const char *
dwarf_encoding_string(unsigned int code)4364 dwarf_encoding_string (unsigned int code)
4365 {
4366   static const char *const known[] =
4367     {
4368 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
4369       DWARF_ALL_KNOWN_DW_ATE
4370 #undef DWARF_ONE_KNOWN_DW_ATE
4371     };
4372 
4373   if (likely (code < sizeof (known) / sizeof (known[0])))
4374     return known[code];
4375 
4376   return NULL;
4377 }
4378 
4379 
4380 static const char *
dwarf_access_string(unsigned int code)4381 dwarf_access_string (unsigned int code)
4382 {
4383   static const char *const known[] =
4384     {
4385 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
4386       DWARF_ALL_KNOWN_DW_ACCESS
4387 #undef DWARF_ONE_KNOWN_DW_ACCESS
4388     };
4389 
4390   if (likely (code < sizeof (known) / sizeof (known[0])))
4391     return known[code];
4392 
4393   return NULL;
4394 }
4395 
4396 
4397 static const char *
dwarf_defaulted_string(unsigned int code)4398 dwarf_defaulted_string (unsigned int code)
4399 {
4400   static const char *const known[] =
4401     {
4402 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
4403       DWARF_ALL_KNOWN_DW_DEFAULTED
4404 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
4405     };
4406 
4407   if (likely (code < sizeof (known) / sizeof (known[0])))
4408     return known[code];
4409 
4410   return NULL;
4411 }
4412 
4413 
4414 static const char *
dwarf_visibility_string(unsigned int code)4415 dwarf_visibility_string (unsigned int code)
4416 {
4417   static const char *const known[] =
4418     {
4419 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
4420       DWARF_ALL_KNOWN_DW_VIS
4421 #undef DWARF_ONE_KNOWN_DW_VIS
4422     };
4423 
4424   if (likely (code < sizeof (known) / sizeof (known[0])))
4425     return known[code];
4426 
4427   return NULL;
4428 }
4429 
4430 
4431 static const char *
dwarf_virtuality_string(unsigned int code)4432 dwarf_virtuality_string (unsigned int code)
4433 {
4434   static const char *const known[] =
4435     {
4436 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
4437       DWARF_ALL_KNOWN_DW_VIRTUALITY
4438 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
4439     };
4440 
4441   if (likely (code < sizeof (known) / sizeof (known[0])))
4442     return known[code];
4443 
4444   return NULL;
4445 }
4446 
4447 
4448 static const char *
dwarf_identifier_case_string(unsigned int code)4449 dwarf_identifier_case_string (unsigned int code)
4450 {
4451   static const char *const known[] =
4452     {
4453 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
4454       DWARF_ALL_KNOWN_DW_ID
4455 #undef DWARF_ONE_KNOWN_DW_ID
4456     };
4457 
4458   if (likely (code < sizeof (known) / sizeof (known[0])))
4459     return known[code];
4460 
4461   return NULL;
4462 }
4463 
4464 
4465 static const char *
dwarf_calling_convention_string(unsigned int code)4466 dwarf_calling_convention_string (unsigned int code)
4467 {
4468   static const char *const known[] =
4469     {
4470 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4471       DWARF_ALL_KNOWN_DW_CC
4472 #undef DWARF_ONE_KNOWN_DW_CC
4473     };
4474 
4475   if (likely (code < sizeof (known) / sizeof (known[0])))
4476     return known[code];
4477 
4478   return NULL;
4479 }
4480 
4481 
4482 static const char *
dwarf_ordering_string(unsigned int code)4483 dwarf_ordering_string (unsigned int code)
4484 {
4485   static const char *const known[] =
4486     {
4487 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4488       DWARF_ALL_KNOWN_DW_ORD
4489 #undef DWARF_ONE_KNOWN_DW_ORD
4490     };
4491 
4492   if (likely (code < sizeof (known) / sizeof (known[0])))
4493     return known[code];
4494 
4495   return NULL;
4496 }
4497 
4498 
4499 static const char *
dwarf_discr_list_string(unsigned int code)4500 dwarf_discr_list_string (unsigned int code)
4501 {
4502   static const char *const known[] =
4503     {
4504 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4505       DWARF_ALL_KNOWN_DW_DSC
4506 #undef DWARF_ONE_KNOWN_DW_DSC
4507     };
4508 
4509   if (likely (code < sizeof (known) / sizeof (known[0])))
4510     return known[code];
4511 
4512   return NULL;
4513 }
4514 
4515 
4516 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4517 dwarf_locexpr_opcode_string (unsigned int code)
4518 {
4519   static const char *const known[] =
4520     {
4521       /* Normally we can't afford building huge table of 64K entries,
4522 	 most of them zero, just because there are a couple defined
4523 	 values at the far end.  In case of opcodes, it's OK.  */
4524 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4525       DWARF_ALL_KNOWN_DW_OP
4526 #undef DWARF_ONE_KNOWN_DW_OP
4527     };
4528 
4529   if (likely (code < sizeof (known) / sizeof (known[0])))
4530     return known[code];
4531 
4532   return NULL;
4533 }
4534 
4535 
4536 static const char *
dwarf_unit_string(unsigned int type)4537 dwarf_unit_string (unsigned int type)
4538 {
4539   switch (type)
4540     {
4541 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4542       DWARF_ALL_KNOWN_DW_UT
4543 #undef DWARF_ONE_KNOWN_DW_UT
4544     default:
4545       return NULL;
4546     }
4547 }
4548 
4549 
4550 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4551 dwarf_range_list_encoding_string (unsigned int kind)
4552 {
4553   switch (kind)
4554     {
4555 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4556       DWARF_ALL_KNOWN_DW_RLE
4557 #undef DWARF_ONE_KNOWN_DW_RLE
4558     default:
4559       return NULL;
4560     }
4561 }
4562 
4563 
4564 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4565 dwarf_loc_list_encoding_string (unsigned int kind)
4566 {
4567   switch (kind)
4568     {
4569 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4570       DWARF_ALL_KNOWN_DW_LLE
4571 #undef DWARF_ONE_KNOWN_DW_LLE
4572     /* DW_LLE_GNU_view_pair is special/incompatible with default codes.  */
4573     case DW_LLE_GNU_view_pair: return "GNU_view_pair";
4574     default:
4575       return NULL;
4576     }
4577 }
4578 
4579 
4580 static const char *
dwarf_line_content_description_string(unsigned int kind)4581 dwarf_line_content_description_string (unsigned int kind)
4582 {
4583   switch (kind)
4584     {
4585 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4586       DWARF_ALL_KNOWN_DW_LNCT
4587 #undef DWARF_ONE_KNOWN_DW_LNCT
4588     default:
4589       return NULL;
4590     }
4591 }
4592 
4593 
4594 /* Used by all dwarf_foo_name functions.  */
4595 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4596 string_or_unknown (const char *known, unsigned int code,
4597                    unsigned int lo_user, unsigned int hi_user,
4598 		   bool print_unknown_num)
4599 {
4600   static char unknown_buf[20];
4601 
4602   if (likely (known != NULL))
4603     return known;
4604 
4605   if (lo_user != 0 && code >= lo_user && code <= hi_user)
4606     {
4607       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4608 		code - lo_user);
4609       return unknown_buf;
4610     }
4611 
4612   if (print_unknown_num)
4613     {
4614       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4615       return unknown_buf;
4616     }
4617 
4618   return "???";
4619 }
4620 
4621 
4622 static const char *
dwarf_tag_name(unsigned int tag)4623 dwarf_tag_name (unsigned int tag)
4624 {
4625   const char *ret = dwarf_tag_string (tag);
4626   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4627 }
4628 
4629 static const char *
dwarf_attr_name(unsigned int attr)4630 dwarf_attr_name (unsigned int attr)
4631 {
4632   const char *ret = dwarf_attr_string (attr);
4633   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4634 }
4635 
4636 
4637 static const char *
dwarf_form_name(unsigned int form)4638 dwarf_form_name (unsigned int form)
4639 {
4640   const char *ret = dwarf_form_string (form);
4641   return string_or_unknown (ret, form, 0, 0, true);
4642 }
4643 
4644 
4645 static const char *
dwarf_lang_name(unsigned int lang)4646 dwarf_lang_name (unsigned int lang)
4647 {
4648   const char *ret = dwarf_lang_string (lang);
4649   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4650 }
4651 
4652 
4653 static const char *
dwarf_inline_name(unsigned int code)4654 dwarf_inline_name (unsigned int code)
4655 {
4656   const char *ret = dwarf_inline_string (code);
4657   return string_or_unknown (ret, code, 0, 0, false);
4658 }
4659 
4660 
4661 static const char *
dwarf_encoding_name(unsigned int code)4662 dwarf_encoding_name (unsigned int code)
4663 {
4664   const char *ret = dwarf_encoding_string (code);
4665   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4666 }
4667 
4668 
4669 static const char *
dwarf_access_name(unsigned int code)4670 dwarf_access_name (unsigned int code)
4671 {
4672   const char *ret = dwarf_access_string (code);
4673   return string_or_unknown (ret, code, 0, 0, false);
4674 }
4675 
4676 
4677 static const char *
dwarf_defaulted_name(unsigned int code)4678 dwarf_defaulted_name (unsigned int code)
4679 {
4680   const char *ret = dwarf_defaulted_string (code);
4681   return string_or_unknown (ret, code, 0, 0, false);
4682 }
4683 
4684 
4685 static const char *
dwarf_visibility_name(unsigned int code)4686 dwarf_visibility_name (unsigned int code)
4687 {
4688   const char *ret = dwarf_visibility_string (code);
4689   return string_or_unknown (ret, code, 0, 0, false);
4690 }
4691 
4692 
4693 static const char *
dwarf_virtuality_name(unsigned int code)4694 dwarf_virtuality_name (unsigned int code)
4695 {
4696   const char *ret = dwarf_virtuality_string (code);
4697   return string_or_unknown (ret, code, 0, 0, false);
4698 }
4699 
4700 
4701 static const char *
dwarf_identifier_case_name(unsigned int code)4702 dwarf_identifier_case_name (unsigned int code)
4703 {
4704   const char *ret = dwarf_identifier_case_string (code);
4705   return string_or_unknown (ret, code, 0, 0, false);
4706 }
4707 
4708 
4709 static const char *
dwarf_calling_convention_name(unsigned int code)4710 dwarf_calling_convention_name (unsigned int code)
4711 {
4712   const char *ret = dwarf_calling_convention_string (code);
4713   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4714 }
4715 
4716 
4717 static const char *
dwarf_ordering_name(unsigned int code)4718 dwarf_ordering_name (unsigned int code)
4719 {
4720   const char *ret = dwarf_ordering_string (code);
4721   return string_or_unknown (ret, code, 0, 0, false);
4722 }
4723 
4724 
4725 static const char *
dwarf_discr_list_name(unsigned int code)4726 dwarf_discr_list_name (unsigned int code)
4727 {
4728   const char *ret = dwarf_discr_list_string (code);
4729   return string_or_unknown (ret, code, 0, 0, false);
4730 }
4731 
4732 
4733 static const char *
dwarf_unit_name(unsigned int type)4734 dwarf_unit_name (unsigned int type)
4735 {
4736   const char *ret = dwarf_unit_string (type);
4737   return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4738 }
4739 
4740 
4741 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4742 dwarf_range_list_encoding_name (unsigned int kind)
4743 {
4744   const char *ret = dwarf_range_list_encoding_string (kind);
4745   return string_or_unknown (ret, kind, 0, 0, false);
4746 }
4747 
4748 
4749 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4750 dwarf_loc_list_encoding_name (unsigned int kind)
4751 {
4752   const char *ret = dwarf_loc_list_encoding_string (kind);
4753   return string_or_unknown (ret, kind, 0, 0, false);
4754 }
4755 
4756 
4757 static const char *
dwarf_line_content_description_name(unsigned int kind)4758 dwarf_line_content_description_name (unsigned int kind)
4759 {
4760   const char *ret = dwarf_line_content_description_string (kind);
4761   return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4762 			    false);
4763 }
4764 
4765 
4766 static void
print_block(size_t n,const void * block)4767 print_block (size_t n, const void *block)
4768 {
4769   if (n == 0)
4770     puts (_("empty block"));
4771   else
4772     {
4773       printf (_("%zu byte block:"), n);
4774       const unsigned char *data = block;
4775       do
4776 	printf (" %02x", *data++);
4777       while (--n > 0);
4778       putchar ('\n');
4779     }
4780 }
4781 
4782 static void
print_bytes(size_t n,const unsigned char * bytes)4783 print_bytes (size_t n, const unsigned char *bytes)
4784 {
4785   while (n-- > 0)
4786     {
4787       printf ("%02x", *bytes++);
4788       if (n > 0)
4789 	printf (" ");
4790     }
4791 }
4792 
4793 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4794 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4795 {
4796   if (cu == NULL)
4797     return -1;
4798 
4799   Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4800   if (debug_addr == NULL)
4801     return -1;
4802 
4803   Dwarf_Off base = __libdw_cu_addr_base (cu);
4804   Dwarf_Word off = idx * cu->address_size;
4805   if (base > debug_addr->d_size
4806       || off > debug_addr->d_size - base
4807       || cu->address_size > debug_addr->d_size - base - off)
4808     return -1;
4809 
4810   const unsigned char *addrp = debug_addr->d_buf + base + off;
4811   if (cu->address_size == 4)
4812     *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4813   else
4814     *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4815 
4816   return 0;
4817 }
4818 
4819 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)4820 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4821 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4822 	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4823 {
4824   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4825 
4826   if (len == 0)
4827     {
4828       printf ("%*s(empty)\n", indent, "");
4829       return;
4830     }
4831 
4832 #define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
4833 #define CONSUME(n)	NEED (n); else len -= (n)
4834 
4835   Dwarf_Word offset = 0;
4836   while (len-- > 0)
4837     {
4838       uint_fast8_t op = *data++;
4839 
4840       const char *op_name = dwarf_locexpr_opcode_string (op);
4841       if (unlikely (op_name == NULL))
4842 	{
4843 	  static char buf[20];
4844 	  if (op >= DW_OP_lo_user)
4845 	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4846 	  else
4847 	    snprintf (buf, sizeof buf, "??? (%#x)", op);
4848 	  op_name = buf;
4849 	}
4850 
4851       switch (op)
4852 	{
4853 	case DW_OP_addr:;
4854 	  /* Address operand.  */
4855 	  Dwarf_Word addr;
4856 	  NEED (addrsize);
4857 	  if (addrsize == 4)
4858 	    addr = read_4ubyte_unaligned (dbg, data);
4859 	  else if (addrsize == 8)
4860 	    addr = read_8ubyte_unaligned (dbg, data);
4861 	  else
4862 	    goto invalid;
4863 	  data += addrsize;
4864 	  CONSUME (addrsize);
4865 
4866 	  printf ("%*s[%2" PRIuMAX "] %s ",
4867 		  indent, "", (uintmax_t) offset, op_name);
4868 	  print_dwarf_addr (dwflmod, 0, addr, addr);
4869 	  printf ("\n");
4870 
4871 	  offset += 1 + addrsize;
4872 	  break;
4873 
4874 	case DW_OP_call_ref:
4875 	case DW_OP_GNU_variable_value:
4876 	  /* Offset operand.  */
4877 	  if (ref_size != 4 && ref_size != 8)
4878 	    goto invalid; /* Cannot be used in CFA.  */
4879 	  NEED (ref_size);
4880 	  if (ref_size == 4)
4881 	    addr = read_4ubyte_unaligned (dbg, data);
4882 	  else
4883 	    addr = read_8ubyte_unaligned (dbg, data);
4884 	  data += ref_size;
4885 	  CONSUME (ref_size);
4886 	  /* addr is a DIE offset, so format it as one.  */
4887 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4888 		  indent, "", (uintmax_t) offset,
4889 		  op_name, (uintmax_t) addr);
4890 	  offset += 1 + ref_size;
4891 	  break;
4892 
4893 	case DW_OP_deref_size:
4894 	case DW_OP_xderef_size:
4895 	case DW_OP_pick:
4896 	case DW_OP_const1u:
4897 	  // XXX value might be modified by relocation
4898 	  NEED (1);
4899 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4900 		  indent, "", (uintmax_t) offset,
4901 		  op_name, *((uint8_t *) data));
4902 	  ++data;
4903 	  --len;
4904 	  offset += 2;
4905 	  break;
4906 
4907 	case DW_OP_const2u:
4908 	  NEED (2);
4909 	  // XXX value might be modified by relocation
4910 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4911 		  indent, "", (uintmax_t) offset,
4912 		  op_name, read_2ubyte_unaligned (dbg, data));
4913 	  CONSUME (2);
4914 	  data += 2;
4915 	  offset += 3;
4916 	  break;
4917 
4918 	case DW_OP_const4u:
4919 	  NEED (4);
4920 	  // XXX value might be modified by relocation
4921 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4922 		  indent, "", (uintmax_t) offset,
4923 		  op_name, read_4ubyte_unaligned (dbg, data));
4924 	  CONSUME (4);
4925 	  data += 4;
4926 	  offset += 5;
4927 	  break;
4928 
4929 	case DW_OP_const8u:
4930 	  NEED (8);
4931 	  // XXX value might be modified by relocation
4932 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4933 		  indent, "", (uintmax_t) offset,
4934 		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4935 	  CONSUME (8);
4936 	  data += 8;
4937 	  offset += 9;
4938 	  break;
4939 
4940 	case DW_OP_const1s:
4941 	  NEED (1);
4942 	  // XXX value might be modified by relocation
4943 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4944 		  indent, "", (uintmax_t) offset,
4945 		  op_name, *((int8_t *) data));
4946 	  ++data;
4947 	  --len;
4948 	  offset += 2;
4949 	  break;
4950 
4951 	case DW_OP_const2s:
4952 	  NEED (2);
4953 	  // XXX value might be modified by relocation
4954 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4955 		  indent, "", (uintmax_t) offset,
4956 		  op_name, read_2sbyte_unaligned (dbg, data));
4957 	  CONSUME (2);
4958 	  data += 2;
4959 	  offset += 3;
4960 	  break;
4961 
4962 	case DW_OP_const4s:
4963 	  NEED (4);
4964 	  // XXX value might be modified by relocation
4965 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4966 		  indent, "", (uintmax_t) offset,
4967 		  op_name, read_4sbyte_unaligned (dbg, data));
4968 	  CONSUME (4);
4969 	  data += 4;
4970 	  offset += 5;
4971 	  break;
4972 
4973 	case DW_OP_const8s:
4974 	  NEED (8);
4975 	  // XXX value might be modified by relocation
4976 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4977 		  indent, "", (uintmax_t) offset,
4978 		  op_name, read_8sbyte_unaligned (dbg, data));
4979 	  CONSUME (8);
4980 	  data += 8;
4981 	  offset += 9;
4982 	  break;
4983 
4984 	case DW_OP_piece:
4985 	case DW_OP_regx:
4986 	case DW_OP_plus_uconst:
4987 	case DW_OP_constu:;
4988 	  const unsigned char *start = data;
4989 	  uint64_t uleb;
4990 	  NEED (1);
4991 	  get_uleb128 (uleb, data, data + len);
4992 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4993 		  indent, "", (uintmax_t) offset, op_name, uleb);
4994 	  CONSUME (data - start);
4995 	  offset += 1 + (data - start);
4996 	  break;
4997 
4998 	case DW_OP_addrx:
4999 	case DW_OP_GNU_addr_index:
5000 	case DW_OP_constx:
5001 	case DW_OP_GNU_const_index:;
5002 	  start = data;
5003 	  NEED (1);
5004 	  get_uleb128 (uleb, data, data + len);
5005 	  printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
5006 		  indent, "", (uintmax_t) offset, op_name, uleb);
5007 	  CONSUME (data - start);
5008 	  offset += 1 + (data - start);
5009 	  if (get_indexed_addr (cu, uleb, &addr) != 0)
5010 	    printf ("???\n");
5011 	  else
5012 	    {
5013 	      print_dwarf_addr (dwflmod, 0, addr, addr);
5014 	      printf ("\n");
5015 	    }
5016 	  break;
5017 
5018 	case DW_OP_bit_piece:
5019 	  start = data;
5020 	  uint64_t uleb2;
5021 	  NEED (1);
5022 	  get_uleb128 (uleb, data, data + len);
5023 	  NEED (1);
5024 	  get_uleb128 (uleb2, data, data + len);
5025 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
5026 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
5027 	  CONSUME (data - start);
5028 	  offset += 1 + (data - start);
5029 	  break;
5030 
5031 	case DW_OP_fbreg:
5032 	case DW_OP_breg0 ... DW_OP_breg31:
5033 	case DW_OP_consts:
5034 	  start = data;
5035 	  int64_t sleb;
5036 	  NEED (1);
5037 	  get_sleb128 (sleb, data, data + len);
5038 	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
5039 		  indent, "", (uintmax_t) offset, op_name, sleb);
5040 	  CONSUME (data - start);
5041 	  offset += 1 + (data - start);
5042 	  break;
5043 
5044 	case DW_OP_bregx:
5045 	  start = data;
5046 	  NEED (1);
5047 	  get_uleb128 (uleb, data, data + len);
5048 	  NEED (1);
5049 	  get_sleb128 (sleb, data, data + len);
5050 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
5051 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
5052 	  CONSUME (data - start);
5053 	  offset += 1 + (data - start);
5054 	  break;
5055 
5056 	case DW_OP_call2:
5057 	  NEED (2);
5058 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
5059 		  indent, "", (uintmax_t) offset, op_name,
5060 		  read_2ubyte_unaligned (dbg, data));
5061 	  CONSUME (2);
5062 	  data += 2;
5063 	  offset += 3;
5064 	  break;
5065 
5066 	case DW_OP_call4:
5067 	  NEED (4);
5068 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
5069 		  indent, "", (uintmax_t) offset, op_name,
5070 		  read_4ubyte_unaligned (dbg, data));
5071 	  CONSUME (4);
5072 	  data += 4;
5073 	  offset += 5;
5074 	  break;
5075 
5076 	case DW_OP_skip:
5077 	case DW_OP_bra:
5078 	  NEED (2);
5079 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
5080 		  indent, "", (uintmax_t) offset, op_name,
5081 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
5082 	  CONSUME (2);
5083 	  data += 2;
5084 	  offset += 3;
5085 	  break;
5086 
5087 	case DW_OP_implicit_value:
5088 	  start = data;
5089 	  NEED (1);
5090 	  get_uleb128 (uleb, data, data + len);
5091 	  printf ("%*s[%2" PRIuMAX "] %s: ",
5092 		  indent, "", (uintmax_t) offset, op_name);
5093 	  NEED (uleb);
5094 	  print_block (uleb, data);
5095 	  data += uleb;
5096 	  CONSUME (data - start);
5097 	  offset += 1 + (data - start);
5098 	  break;
5099 
5100 	case DW_OP_implicit_pointer:
5101 	case DW_OP_GNU_implicit_pointer:
5102 	  /* DIE offset operand.  */
5103 	  start = data;
5104 	  NEED (ref_size);
5105 	  if (ref_size != 4 && ref_size != 8)
5106 	    goto invalid; /* Cannot be used in CFA.  */
5107 	  if (ref_size == 4)
5108 	    addr = read_4ubyte_unaligned (dbg, data);
5109 	  else
5110 	    addr = read_8ubyte_unaligned (dbg, data);
5111 	  data += ref_size;
5112 	  /* Byte offset operand.  */
5113 	  NEED (1);
5114 	  get_sleb128 (sleb, data, data + len);
5115 
5116 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
5117 		  indent, "", (intmax_t) offset,
5118 		  op_name, (uintmax_t) addr, sleb);
5119 	  CONSUME (data - start);
5120 	  offset += 1 + (data - start);
5121 	  break;
5122 
5123 	case DW_OP_entry_value:
5124 	case DW_OP_GNU_entry_value:
5125 	  /* Size plus expression block.  */
5126 	  start = data;
5127 	  NEED (1);
5128 	  get_uleb128 (uleb, data, data + len);
5129 	  printf ("%*s[%2" PRIuMAX "] %s:\n",
5130 		  indent, "", (uintmax_t) offset, op_name);
5131 	  NEED (uleb);
5132 	  print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
5133 		     addrsize, offset_size, cu, uleb, data);
5134 	  data += uleb;
5135 	  CONSUME (data - start);
5136 	  offset += 1 + (data - start);
5137 	  break;
5138 
5139 	case DW_OP_const_type:
5140 	case DW_OP_GNU_const_type:
5141 	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
5142 	     unsigned size plus block.  */
5143 	  start = data;
5144 	  NEED (1);
5145 	  get_uleb128 (uleb, data, data + len);
5146 	  if (! print_unresolved_addresses && cu != NULL)
5147 	    uleb += cu->start;
5148 	  NEED (1);
5149 	  uint8_t usize = *(uint8_t *) data++;
5150 	  NEED (usize);
5151 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
5152 		  indent, "", (uintmax_t) offset, op_name, uleb);
5153 	  print_block (usize, data);
5154 	  data += usize;
5155 	  CONSUME (data - start);
5156 	  offset += 1 + (data - start);
5157 	  break;
5158 
5159 	case DW_OP_regval_type:
5160 	case DW_OP_GNU_regval_type:
5161 	  /* uleb128 register number, uleb128 CU relative
5162 	     DW_TAG_base_type DIE offset.  */
5163 	  start = data;
5164 	  NEED (1);
5165 	  get_uleb128 (uleb, data, data + len);
5166 	  NEED (1);
5167 	  get_uleb128 (uleb2, data, data + len);
5168 	  if (! print_unresolved_addresses && cu != NULL)
5169 	    uleb2 += cu->start;
5170 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
5171 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
5172 	  CONSUME (data - start);
5173 	  offset += 1 + (data - start);
5174 	  break;
5175 
5176 	case DW_OP_deref_type:
5177 	case DW_OP_GNU_deref_type:
5178 	  /* 1-byte unsigned size of value, uleb128 CU relative
5179 	     DW_TAG_base_type DIE offset.  */
5180 	  start = data;
5181 	  NEED (1);
5182 	  usize = *(uint8_t *) data++;
5183 	  NEED (1);
5184 	  get_uleb128 (uleb, data, data + len);
5185 	  if (! print_unresolved_addresses && cu != NULL)
5186 	    uleb += cu->start;
5187 	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
5188 		  indent, "", (uintmax_t) offset,
5189 		  op_name, usize, uleb);
5190 	  CONSUME (data - start);
5191 	  offset += 1 + (data - start);
5192 	  break;
5193 
5194 	case DW_OP_xderef_type:
5195 	  /* 1-byte unsigned size of value, uleb128 base_type DIE offset.  */
5196 	  start = data;
5197 	  NEED (1);
5198 	  usize = *(uint8_t *) data++;
5199 	  NEED (1);
5200 	  get_uleb128 (uleb, data, data + len);
5201 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
5202 		  indent, "", (uintmax_t) offset,
5203 		  op_name, usize, uleb);
5204 	  CONSUME (data - start);
5205 	  offset += 1 + (data - start);
5206 	  break;
5207 
5208 	case DW_OP_convert:
5209 	case DW_OP_GNU_convert:
5210 	case DW_OP_reinterpret:
5211 	case DW_OP_GNU_reinterpret:
5212 	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
5213 	     for conversion to untyped.  */
5214 	  start = data;
5215 	  NEED (1);
5216 	  get_uleb128 (uleb, data, data + len);
5217 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
5218 	    uleb += cu->start;
5219 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
5220 		  indent, "", (uintmax_t) offset, op_name, uleb);
5221 	  CONSUME (data - start);
5222 	  offset += 1 + (data - start);
5223 	  break;
5224 
5225 	case DW_OP_GNU_parameter_ref:
5226 	  /* 4 byte CU relative reference to the abstract optimized away
5227 	     DW_TAG_formal_parameter.  */
5228 	  NEED (4);
5229 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
5230 	  if (! print_unresolved_addresses && cu != NULL)
5231 	    param_off += cu->start;
5232 	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
5233 		  indent, "", (uintmax_t) offset, op_name, param_off);
5234 	  CONSUME (4);
5235 	  data += 4;
5236 	  offset += 5;
5237 	  break;
5238 
5239 	default:
5240 	  /* No Operand.  */
5241 	  printf ("%*s[%2" PRIuMAX "] %s\n",
5242 		  indent, "", (uintmax_t) offset, op_name);
5243 	  ++offset;
5244 	  break;
5245 	}
5246 
5247       indent = indentrest;
5248       continue;
5249 
5250     invalid:
5251       printf (_("%*s[%2" PRIuMAX "] %s  <TRUNCATED>\n"),
5252 	      indent, "", (uintmax_t) offset, op_name);
5253       break;
5254     }
5255 }
5256 
5257 
5258 /* Turn the addresses into file offsets by using the phdrs.  */
5259 static void
find_offsets(Elf * elf,GElf_Addr main_bias,size_t n,GElf_Addr addrs[n],GElf_Off offs[n])5260 find_offsets(Elf *elf, GElf_Addr main_bias, size_t n,
5261                   GElf_Addr addrs[n], GElf_Off offs[n])
5262 {
5263   size_t unsolved = n;
5264   for (size_t i = 0; i < phnum; ++i) {
5265     GElf_Phdr phdr_mem;
5266     GElf_Phdr *phdr = gelf_getphdr(elf, i, &phdr_mem);
5267     if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
5268       for (size_t j = 0; j < n; ++j)
5269         if (offs[j] == 0 && addrs[j] >= phdr->p_vaddr + main_bias &&
5270             addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz) {
5271           offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
5272           if (--unsolved == 0)
5273             break;
5274         }
5275   }
5276 }
5277 
5278 /* The dynamic segment (type PT_DYNAMIC), contains the .dynamic section.
5279    And .dynamic section contains an array of the dynamic structures.
5280    We use the array to get:
5281     DT_STRTAB: the address of the string table
5282     DT_SYMTAB: the address of the symbol table
5283     DT_STRSZ: the size, in bytes, of the string table
5284     ...  */
5285 static void
get_dynscn_addrs(Elf * elf,GElf_Phdr * phdr,GElf_Addr addrs[i_max])5286 get_dynscn_addrs(Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max])
5287 {
5288   Elf_Data *data = elf_getdata_rawchunk(
5289     elf, phdr->p_offset, phdr->p_filesz, ELF_T_DYN);
5290 
5291   int dyn_idx = 0;
5292   for (;; ++dyn_idx) {
5293     GElf_Dyn dyn_mem;
5294     GElf_Dyn *dyn = gelf_getdyn(data, dyn_idx, &dyn_mem);
5295     /* DT_NULL Marks end of dynamic section.  */
5296     if (dyn == NULL || dyn->d_tag == DT_NULL)
5297       break;
5298 
5299     switch (dyn->d_tag) {
5300     case DT_SYMTAB:
5301       addrs[i_symtab] = dyn->d_un.d_ptr;
5302       break;
5303 
5304     case DT_HASH:
5305       addrs[i_hash] = dyn->d_un.d_ptr;
5306       break;
5307 
5308     case DT_GNU_HASH:
5309       addrs[i_gnu_hash] = dyn->d_un.d_ptr;
5310       break;
5311 
5312     case DT_STRTAB:
5313       addrs[i_strtab] = dyn->d_un.d_ptr;
5314       break;
5315 
5316     case DT_VERSYM:
5317       addrs[i_versym] = dyn->d_un.d_ptr;
5318       break;
5319 
5320     case DT_VERDEF:
5321       addrs[i_verdef] = dyn->d_un.d_ptr;
5322       break;
5323 
5324     case DT_VERDEFNUM:
5325       addrs[i_verdefnum] = dyn->d_un.d_val;
5326       break;
5327 
5328     case DT_VERNEED:
5329       addrs[i_verneed] = dyn->d_un.d_ptr;
5330       break;
5331 
5332     case DT_VERNEEDNUM:
5333       addrs[i_verneednum] = dyn->d_un.d_val;
5334       break;
5335 
5336     case DT_STRSZ:
5337       addrs[i_strsz] = dyn->d_un.d_val;
5338       break;
5339 
5340     case DT_SYMTAB_SHNDX:
5341       addrs[i_symtab_shndx] = dyn->d_un.d_ptr;
5342       break;
5343     }
5344   }
5345 }
5346 
5347 
5348 /* Use dynamic segment to get data for the string table section.  */
5349 static Elf_Data *
get_dynscn_strtab(Elf * elf,GElf_Phdr * phdr)5350 get_dynscn_strtab(Elf *elf, GElf_Phdr *phdr)
5351 {
5352   Elf_Data *strtab_data;
5353   GElf_Addr addrs[i_max] = {0,};
5354   GElf_Off offs[i_max] = {0,};
5355   get_dynscn_addrs(elf, phdr, addrs);
5356   find_offsets(elf, 0, i_max, addrs, offs);
5357   strtab_data = elf_getdata_rawchunk(
5358           elf, offs[i_strtab], addrs[i_strsz], ELF_T_BYTE);
5359   return strtab_data;
5360 }
5361 
5362 
5363 struct listptr
5364 {
5365   Dwarf_Off offset:(64 - 3);
5366   bool addr64:1;
5367   bool dwarf64:1;
5368   bool warned:1;
5369   struct Dwarf_CU *cu;
5370   unsigned int attr;
5371 };
5372 
5373 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
5374 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
5375 
5376 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)5377 cudie_base (Dwarf_Die *cudie)
5378 {
5379   Dwarf_Addr base;
5380   /* Find the base address of the compilation unit.  It will normally
5381      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
5382      address could be overridden by DW_AT_entry_pc.  It's been
5383      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
5384      compilation units with discontinuous ranges.  */
5385   if (unlikely (dwarf_lowpc (cudie, &base) != 0))
5386     {
5387       Dwarf_Attribute attr_mem;
5388       if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
5389 			  &base) != 0)
5390 	base = 0;
5391     }
5392   return base;
5393 }
5394 
5395 static Dwarf_Addr
listptr_base(struct listptr * p)5396 listptr_base (struct listptr *p)
5397 {
5398   Dwarf_Die cu = CUDIE (p->cu);
5399   return cudie_base (&cu);
5400 }
5401 
5402 /* To store the name used in compare_listptr */
5403 static const char *sort_listptr_name;
5404 
5405 static int
compare_listptr(const void * a,const void * b)5406 compare_listptr (const void *a, const void *b)
5407 {
5408   const char *name = sort_listptr_name;
5409   struct listptr *p1 = (void *) a;
5410   struct listptr *p2 = (void *) b;
5411 
5412   if (p1->offset < p2->offset)
5413     return -1;
5414   if (p1->offset > p2->offset)
5415     return 1;
5416 
5417   if (!p1->warned && !p2->warned)
5418     {
5419       if (p1->addr64 != p2->addr64)
5420 	{
5421 	  p1->warned = p2->warned = true;
5422 	  error (0, 0,
5423 		 _("%s %#" PRIx64 " used with different address sizes"),
5424 		 name, (uint64_t) p1->offset);
5425 	}
5426       if (p1->dwarf64 != p2->dwarf64)
5427 	{
5428 	  p1->warned = p2->warned = true;
5429 	  error (0, 0,
5430 		 _("%s %#" PRIx64 " used with different offset sizes"),
5431 		 name, (uint64_t) p1->offset);
5432 	}
5433       if (listptr_base (p1) != listptr_base (p2))
5434 	{
5435 	  p1->warned = p2->warned = true;
5436 	  error (0, 0,
5437 		 _("%s %#" PRIx64 " used with different base addresses"),
5438 		 name, (uint64_t) p1->offset);
5439 	}
5440       if (p1->attr != p2 ->attr)
5441 	{
5442 	  p1->warned = p2->warned = true;
5443 	  error (0, 0,
5444 		 _("%s %#" PRIx64
5445 			  " used with different attribute %s and %s"),
5446 		 name, (uint64_t) p1->offset, dwarf_attr_name (p1->attr),
5447 		 dwarf_attr_name (p2->attr));
5448 	}
5449     }
5450 
5451   return 0;
5452 }
5453 
5454 struct listptr_table
5455 {
5456   size_t n;
5457   size_t alloc;
5458   struct listptr *table;
5459 };
5460 
5461 static struct listptr_table known_locsptr;
5462 static struct listptr_table known_loclistsptr;
5463 static struct listptr_table known_rangelistptr;
5464 static struct listptr_table known_rnglistptr;
5465 static struct listptr_table known_addrbases;
5466 static struct listptr_table known_stroffbases;
5467 
5468 static void
reset_listptr(struct listptr_table * table)5469 reset_listptr (struct listptr_table *table)
5470 {
5471   free (table->table);
5472   table->table = NULL;
5473   table->n = table->alloc = 0;
5474 }
5475 
5476 /* Returns false if offset doesn't fit.  See struct listptr.  */
5477 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)5478 notice_listptr (enum section_e section, struct listptr_table *table,
5479 		uint_fast8_t address_size, uint_fast8_t offset_size,
5480 		struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
5481 {
5482   if (print_debug_sections & section)
5483     {
5484       if (table->n == table->alloc)
5485 	{
5486 	  if (table->alloc == 0)
5487 	    table->alloc = 128;
5488 	  else
5489 	    table->alloc *= 2;
5490 	  table->table = xrealloc (table->table,
5491 				   table->alloc * sizeof table->table[0]);
5492 	}
5493 
5494       struct listptr *p = &table->table[table->n++];
5495 
5496       *p = (struct listptr)
5497 	{
5498 	  .addr64 = address_size == 8,
5499 	  .dwarf64 = offset_size == 8,
5500 	  .offset = offset,
5501 	  .cu = cu,
5502 	  .attr = attr
5503 	};
5504 
5505       if (p->offset != offset)
5506 	{
5507 	  table->n--;
5508 	  return false;
5509 	}
5510     }
5511   return true;
5512 }
5513 
5514 static void
sort_listptr(struct listptr_table * table,const char * name)5515 sort_listptr (struct listptr_table *table, const char *name)
5516 {
5517   if (table->n > 0)
5518     {
5519       sort_listptr_name = name;
5520       qsort (table->table, table->n, sizeof table->table[0],
5521 	     &compare_listptr);
5522     }
5523 }
5524 
5525 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)5526 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
5527 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
5528 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
5529 		   unsigned char **readp, unsigned char *endp,
5530 		   unsigned int *attr)
5531 {
5532   if (table->n == 0)
5533     return false;
5534 
5535   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
5536     ++*idxp;
5537 
5538   struct listptr *p = &table->table[*idxp];
5539 
5540   if (*idxp == table->n
5541       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
5542     {
5543       *readp = endp;
5544       printf (_(" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
5545 	      offset);
5546       return true;
5547     }
5548 
5549   if (p->offset != (Dwarf_Off) offset)
5550     {
5551       *readp += p->offset - offset;
5552       printf (_(" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
5553 	      offset, (Dwarf_Off) p->offset - offset);
5554       return true;
5555     }
5556 
5557   if (address_sizep != NULL)
5558     *address_sizep = listptr_address_size (p);
5559   if (offset_sizep != NULL)
5560     *offset_sizep = listptr_offset_size (p);
5561   if (base != NULL)
5562     *base = listptr_base (p);
5563   if (cu != NULL)
5564     *cu = p->cu;
5565   if (attr != NULL)
5566     *attr = p->attr;
5567 
5568   return false;
5569 }
5570 
5571 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t * idxp,Dwarf_Off off)5572 next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off)
5573 {
5574   /* Note that multiple attributes could in theory point to the same loclist
5575      offset, so make sure we pick one that is bigger than the current one.
5576      The table is sorted on offset.  */
5577   if (*idxp < table->n)
5578     {
5579       while (++*idxp < table->n)
5580 	{
5581 	  Dwarf_Off next = table->table[*idxp].offset;
5582 	  if (next > off)
5583 	    return next;
5584 	}
5585     }
5586   return 0;
5587 }
5588 
5589 /* Returns the listptr associated with the given index, or NULL.  */
5590 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5591 get_listptr (struct listptr_table *table, size_t idx)
5592 {
5593   if (idx >= table->n)
5594     return NULL;
5595   return &table->table[idx];
5596 }
5597 
5598 /* Returns the next index, base address and CU associated with the
5599    list unit offsets.  If there is none false is returned, otherwise
5600    true.  Assumes the table has been sorted.  */
5601 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5602 listptr_cu (struct listptr_table *table, size_t *idxp,
5603 	    Dwarf_Off start, Dwarf_Off end,
5604 	    Dwarf_Addr *base, struct Dwarf_CU **cu)
5605 {
5606   while (*idxp < table->n
5607 	 && table->table[*idxp].offset < start)
5608     ++*idxp;
5609 
5610   if (*idxp < table->n
5611       && table->table[*idxp].offset >= start
5612       && table->table[*idxp].offset < end)
5613     {
5614       struct listptr *p = &table->table[*idxp];
5615       *base = listptr_base (p);
5616       *cu = p->cu;
5617       return true;
5618     }
5619 
5620   return false;
5621 }
5622 
5623 /* Returns the next index with the current CU for the given attribute.
5624    If there is none false is returned, otherwise true.  Assumes the
5625    table has been sorted.  */
5626 static bool
listptr_attr(struct listptr_table * table,size_t idxp,Dwarf_Off offset,unsigned int attr)5627 listptr_attr (struct listptr_table *table, size_t idxp,
5628 	      Dwarf_Off offset, unsigned int attr)
5629 {
5630   struct listptr *listptr;
5631   do
5632     {
5633       listptr = get_listptr (table, idxp);
5634       if (listptr == NULL)
5635 	return false;
5636 
5637       if (listptr->offset == offset && listptr->attr == attr)
5638 	return true;
5639 
5640       idxp++;
5641     }
5642   while (listptr->offset <= offset);
5643 
5644   return false;
5645 }
5646 
5647 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5648 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5649 			    Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5650 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5651 {
5652   Elf_Data *elf_data = get_debug_elf_data (dbg, ebl, IDX_debug_abbrev, scn);
5653   if (elf_data == NULL)
5654     return;
5655 
5656   const size_t sh_size = elf_data->d_size;
5657 
5658   printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5659 		   " [ Code]\n"),
5660 	  elf_ndxscn (scn), section_name (ebl, shdr),
5661 	  (uint64_t) shdr->sh_offset);
5662 
5663   Dwarf_Off offset = 0;
5664   while (offset < sh_size)
5665     {
5666       printf (_("\nAbbreviation section at offset %" PRIu64 ":\n"),
5667 	      offset);
5668 
5669       while (1)
5670 	{
5671 	  size_t length;
5672 	  Dwarf_Abbrev abbrev;
5673 
5674 	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5675 	  if (res != 0)
5676 	    {
5677 	      if (unlikely (res < 0))
5678 		{
5679 		  printf (_("\
5680  *** error while reading abbreviation: %s\n"),
5681 			  dwarf_errmsg (-1));
5682 		  return;
5683 		}
5684 
5685 	      /* This is the NUL byte at the end of the section.  */
5686 	      ++offset;
5687 	      break;
5688 	    }
5689 
5690 	  /* We know these calls can never fail.  */
5691 	  unsigned int code = dwarf_getabbrevcode (&abbrev);
5692 	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
5693 	  int has_children = dwarf_abbrevhaschildren (&abbrev);
5694 
5695 	  printf (_(" [%5u] offset: %" PRId64
5696 			   ", children: %s, tag: %s\n"),
5697 		  code, (int64_t) offset,
5698 		  has_children ? yes_str : no_str,
5699 		  dwarf_tag_name (tag));
5700 
5701 	  size_t cnt = 0;
5702 	  unsigned int name;
5703 	  unsigned int form;
5704 	  Dwarf_Sword data;
5705 	  Dwarf_Off enoffset;
5706 	  while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5707 					   &data, &enoffset) == 0)
5708 	    {
5709 	      printf ("          attr: %s, form: %s",
5710 		      dwarf_attr_name (name), dwarf_form_name (form));
5711 	      if (form == DW_FORM_implicit_const)
5712 		printf (" (%" PRId64 ")", data);
5713 	      printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5714 	      ++cnt;
5715 	    }
5716 
5717 	  offset += length;
5718 	}
5719     }
5720 }
5721 
5722 
5723 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5724 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5725 			  Ebl *ebl, GElf_Ehdr *ehdr,
5726 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5727 {
5728   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_addr, scn);
5729   if (data == NULL)
5730     return;
5731 
5732   printf (_("\
5733 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5734 	  elf_ndxscn (scn), section_name (ebl, shdr),
5735 	  (uint64_t) shdr->sh_offset);
5736 
5737   if (shdr->sh_size == 0)
5738     return;
5739 
5740   size_t idx = 0;
5741   sort_listptr (&known_addrbases, "addr_base");
5742 
5743   const unsigned char *start = (const unsigned char *) data->d_buf;
5744   const unsigned char *readp = start;
5745   const unsigned char *readendp = ((const unsigned char *) data->d_buf
5746 				   + data->d_size);
5747 
5748   while (readp < readendp)
5749     {
5750       /* We cannot really know whether or not there is an header.  The
5751 	 DebugFission extension to DWARF4 doesn't add one.  The DWARF5
5752 	 .debug_addr variant does.  Whether or not we have an header,
5753 	 DW_AT_[GNU_]addr_base points at "index 0".  So if the current
5754 	 offset equals the CU addr_base then we can just start
5755 	 printing addresses.  If there is no CU with an exact match
5756 	 then we'll try to parse the header first.  */
5757       Dwarf_Off off = (Dwarf_Off) (readp
5758 				   - (const unsigned char *) data->d_buf);
5759 
5760       printf ("Table at offset %" PRIx64 " ", off);
5761 
5762       struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5763       const unsigned char *next_unitp;
5764 
5765       uint64_t unit_length;
5766       uint16_t version;
5767       uint8_t address_size;
5768       uint8_t segment_size;
5769       if (listptr == NULL)
5770 	{
5771 	  error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5772 		 off);
5773 
5774 	  /* We will have to assume it is just addresses to the end... */
5775 	  address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5776 	  next_unitp = readendp;
5777 	  printf ("Unknown CU:\n");
5778 	}
5779       else
5780 	{
5781 	  Dwarf_Die cudie;
5782 	  if (dwarf_cu_die (listptr->cu, &cudie,
5783 			    NULL, NULL, NULL, NULL,
5784 			    NULL, NULL) == NULL)
5785 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5786 	  else
5787 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5788 
5789 	  if (listptr->offset == off)
5790 	    {
5791 	      address_size = listptr_address_size (listptr);
5792 	      segment_size = 0;
5793 	      version = 4;
5794 
5795 	      /* The addresses start here, but where do they end?  */
5796 	      listptr = get_listptr (&known_addrbases, idx);
5797 	      if (listptr == NULL)
5798 		next_unitp = readendp;
5799 	      else if (listptr->cu->version < 5)
5800 		{
5801 		  next_unitp = start + listptr->offset;
5802 		  if (listptr->offset < off || listptr->offset > data->d_size)
5803 		    {
5804 		      error (0, 0,
5805 			     "Warning: Bad address base for next unit at %"
5806 			     PRIx64, off);
5807 		      next_unitp = readendp;
5808 		    }
5809 		}
5810 	      else
5811 		{
5812 		  /* Tricky, we don't have a header for this unit, but
5813 		     there is one for the next.  We will have to
5814 		     "guess" how big it is and subtract it from the
5815 		     offset (because that points after the header).  */
5816 		  unsigned int offset_size = listptr_offset_size (listptr);
5817 		  Dwarf_Off next_off = (listptr->offset
5818 					- (offset_size == 4 ? 4 : 12) /* len */
5819 					- 2 /* version */
5820 					- 1 /* address size */
5821 					- 1); /* segment selector size */
5822 		  next_unitp = start + next_off;
5823 		  if (next_off < off || next_off > data->d_size)
5824 		    {
5825 		      error (0, 0,
5826 			     "Warning: Couldn't calculate .debug_addr "
5827 			     " unit length at %" PRIx64, off);
5828 		      next_unitp = readendp;
5829 		    }
5830 		}
5831 	      unit_length = (uint64_t) (next_unitp - readp);
5832 
5833 	      /* Pretend we have a header.  */
5834 	      printf ("\n");
5835 	      printf (_(" Length:         %8" PRIu64 "\n"),
5836 		      unit_length);
5837 	      printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
5838 	      printf (_(" Address size:   %8" PRIu64 "\n"),
5839 		      (uint64_t) address_size);
5840 	      printf (_(" Segment size:   %8" PRIu64 "\n"),
5841 		      (uint64_t) segment_size);
5842 	      printf ("\n");
5843 	    }
5844 	  else
5845 	    {
5846 	      /* OK, we have to parse an header first.  */
5847 	      unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5848 	      if (unlikely (unit_length == 0xffffffff))
5849 		{
5850 		  if (unlikely (readp > readendp - 8))
5851 		    {
5852 		    invalid_data:
5853 		      error (0, 0, "Invalid data");
5854 		      return;
5855 		    }
5856 		  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5857 		}
5858 	      printf ("\n");
5859 	      printf (_(" Length:         %8" PRIu64 "\n"),
5860 		      unit_length);
5861 
5862 	      /* We need at least 2-bytes (version) + 1-byte
5863 		 (addr_size) + 1-byte (segment_size) = 4 bytes to
5864 		 complete the header.  And this unit cannot go beyond
5865 		 the section data.  */
5866 	      if (readp > readendp - 4
5867 		  || unit_length < 4
5868 		  || unit_length > (uint64_t) (readendp - readp))
5869 		goto invalid_data;
5870 
5871 	      next_unitp = readp + unit_length;
5872 
5873 	      version = read_2ubyte_unaligned_inc (dbg, readp);
5874 	      printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
5875 
5876 	      if (version != 5)
5877 		{
5878 		  error (0, 0, _("Unknown version"));
5879 		  goto next_unit;
5880 		}
5881 
5882 	      address_size = *readp++;
5883 	      printf (_(" Address size:   %8" PRIu64 "\n"),
5884 		      (uint64_t) address_size);
5885 
5886 	      if (address_size != 4 && address_size != 8)
5887 		{
5888 		  error (0, 0, _("unsupported address size"));
5889 		  goto next_unit;
5890 		}
5891 
5892 	      segment_size = *readp++;
5893 	      printf (_(" Segment size:   %8" PRIu64 "\n"),
5894 		      (uint64_t) segment_size);
5895 	      printf ("\n");
5896 
5897 	      if (segment_size != 0)
5898 		{
5899 		  error (0, 0, _("unsupported segment size"));
5900 		  goto next_unit;
5901 		}
5902 
5903 	      if (listptr->offset != (Dwarf_Off) (readp - start))
5904 		{
5905 		  error (0, 0, "Address index doesn't start after header");
5906 		  goto next_unit;
5907 		}
5908 	    }
5909 	}
5910 
5911       int digits = 1;
5912       size_t addresses = (next_unitp - readp) / address_size;
5913       while (addresses >= 10)
5914 	{
5915 	  ++digits;
5916 	  addresses /= 10;
5917 	}
5918 
5919       unsigned int uidx = 0;
5920       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
5921       printf (" Addresses start at offset 0x%zx:\n", index_offset);
5922       while (readp <= next_unitp - address_size)
5923 	{
5924 	  Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5925 						     readp);
5926 	  printf (" [%*u] ", digits, uidx++);
5927 	  print_dwarf_addr (dwflmod, address_size, addr, addr);
5928 	  printf ("\n");
5929 	}
5930       printf ("\n");
5931 
5932       if (readp != next_unitp)
5933 	error (0, 0, "extra %zd bytes at end of unit",
5934 	       (size_t) (next_unitp - readp));
5935 
5936     next_unit:
5937       readp = next_unitp;
5938     }
5939 }
5940 
5941 /* Print content of DWARF .debug_aranges section.  We fortunately do
5942    not have to know a bit about the structure of the section, libdwarf
5943    takes care of it.  */
5944 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5945 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5946 			       GElf_Shdr *shdr, Dwarf *dbg)
5947 {
5948   Dwarf_Aranges *aranges;
5949   size_t cnt;
5950   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5951     {
5952       error (0, 0, _("cannot get .debug_aranges content: %s"),
5953 	     dwarf_errmsg (-1));
5954       return;
5955     }
5956 
5957   GElf_Shdr glink_mem;
5958   GElf_Shdr *glink;
5959   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5960   if (glink == NULL)
5961     {
5962       error (0, 0, _("invalid sh_link value in section %zu"),
5963 	     elf_ndxscn (scn));
5964       return;
5965     }
5966 
5967   printf (ngettext ("\
5968 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5969 		    "\
5970 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5971 		    cnt),
5972 	  elf_ndxscn (scn), section_name (ebl, shdr),
5973 	  (uint64_t) shdr->sh_offset, cnt);
5974 
5975   /* Compute floor(log16(cnt)).  */
5976   size_t tmp = cnt;
5977   int digits = 1;
5978   while (tmp >= 16)
5979     {
5980       ++digits;
5981       tmp >>= 4;
5982     }
5983 
5984   for (size_t n = 0; n < cnt; ++n)
5985     {
5986       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5987       if (unlikely (runp == NULL))
5988 	{
5989 	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5990 	  return;
5991 	}
5992 
5993       Dwarf_Addr start;
5994       Dwarf_Word length;
5995       Dwarf_Off offset;
5996 
5997       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5998 	printf (_(" [%*zu] ???\n"), digits, n);
5999       else
6000 	printf (_(" [%*zu] start: %0#*" PRIx64
6001 			 ", length: %5" PRIu64 ", CU DIE offset: %6"
6002 			 PRId64 "\n"),
6003 		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
6004 		(uint64_t) start, (uint64_t) length, (int64_t) offset);
6005     }
6006 }
6007 
6008 
6009 /* Print content of DWARF .debug_aranges section.  */
6010 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6011 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6012 			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
6013 			     GElf_Shdr *shdr, Dwarf *dbg)
6014 {
6015   if (decodedaranges)
6016     {
6017       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
6018       return;
6019     }
6020 
6021   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_aranges, scn);
6022   if (data == NULL)
6023     return;
6024 
6025   printf (_("\
6026 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6027 	  elf_ndxscn (scn), section_name (ebl, shdr),
6028 	  (uint64_t) shdr->sh_offset);
6029 
6030   const unsigned char *readp = data->d_buf;
6031   const unsigned char *readendp = readp + data->d_size;
6032 
6033   while (readp < readendp)
6034     {
6035       const unsigned char *hdrstart = readp;
6036       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
6037 
6038       printf (_("\nTable at offset %zu:\n"), start_offset);
6039       if (readp + 4 > readendp)
6040 	{
6041 	invalid_data:
6042 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
6043 		 elf_ndxscn (scn), section_name (ebl, shdr));
6044 	  return;
6045 	}
6046 
6047       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
6048       unsigned int length_bytes = 4;
6049       if (length == DWARF3_LENGTH_64_BIT)
6050 	{
6051 	  if (readp + 8 > readendp)
6052 	    goto invalid_data;
6053 	  length = read_8ubyte_unaligned_inc (dbg, readp);
6054 	  length_bytes = 8;
6055 	}
6056 
6057       const unsigned char *nexthdr = readp + length;
6058       printf (_("\n Length:        %6" PRIu64 "\n"),
6059 	      (uint64_t) length);
6060 
6061       if (unlikely (length > (size_t) (readendp - readp)))
6062 	goto invalid_data;
6063 
6064       if (length == 0)
6065 	continue;
6066 
6067       if (readp + 2 > readendp)
6068 	goto invalid_data;
6069       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
6070       printf (_(" DWARF version: %6" PRIuFAST16 "\n"),
6071 	      version);
6072       if (version != 2)
6073 	{
6074 	  error (0, 0, _("unsupported aranges version"));
6075 	  goto next_table;
6076 	}
6077 
6078       Dwarf_Word offset;
6079       if (readp + length_bytes > readendp)
6080 	goto invalid_data;
6081       if (length_bytes == 8)
6082 	offset = read_8ubyte_unaligned_inc (dbg, readp);
6083       else
6084 	offset = read_4ubyte_unaligned_inc (dbg, readp);
6085       printf (_(" CU offset:     %6" PRIx64 "\n"),
6086 	      (uint64_t) offset);
6087 
6088       if (readp + 1 > readendp)
6089 	goto invalid_data;
6090       unsigned int address_size = *readp++;
6091       printf (_(" Address size:  %6" PRIu64 "\n"),
6092 	      (uint64_t) address_size);
6093       if (address_size != 4 && address_size != 8)
6094 	{
6095 	  error (0, 0, _("unsupported address size"));
6096 	  goto next_table;
6097 	}
6098 
6099       if (readp + 1 > readendp)
6100 	goto invalid_data;
6101       unsigned int segment_size = *readp++;
6102       printf (_(" Segment size:  %6" PRIu64 "\n\n"),
6103 	      (uint64_t) segment_size);
6104       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
6105 	{
6106 	  error (0, 0, _("unsupported segment size"));
6107 	  goto next_table;
6108 	}
6109 
6110       /* Round the address to the next multiple of 2*address_size.  */
6111       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
6112 		% (2 * address_size));
6113 
6114       while (readp < nexthdr)
6115 	{
6116 	  Dwarf_Word range_address;
6117 	  Dwarf_Word range_length;
6118 	  Dwarf_Word segment = 0;
6119 	  if (readp + 2 * address_size + segment_size > readendp)
6120 	    goto invalid_data;
6121 	  if (address_size == 4)
6122 	    {
6123 	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
6124 	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
6125 	    }
6126 	  else
6127 	    {
6128 	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
6129 	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
6130 	    }
6131 
6132 	  if (segment_size == 4)
6133 	    segment = read_4ubyte_unaligned_inc (dbg, readp);
6134 	  else if (segment_size == 8)
6135 	    segment = read_8ubyte_unaligned_inc (dbg, readp);
6136 
6137 	  if (range_address == 0 && range_length == 0 && segment == 0)
6138 	    break;
6139 
6140 	  printf ("   ");
6141 	  print_dwarf_addr (dwflmod, address_size, range_address,
6142 			    range_address);
6143 	  printf ("..");
6144 	  print_dwarf_addr (dwflmod, address_size,
6145 			    range_address + range_length - 1,
6146 			    range_length);
6147 	  if (segment_size != 0)
6148 	    printf (" (%" PRIx64 ")\n", (uint64_t) segment);
6149 	  else
6150 	    printf ("\n");
6151 	}
6152 
6153     next_table:
6154       if (readp != nexthdr)
6155 	{
6156 	  size_t padding = nexthdr - readp;
6157 	  printf (_("   %zu padding bytes\n"), padding);
6158 	  readp = nexthdr;
6159 	}
6160     }
6161 }
6162 
6163 
6164 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
6165 
6166 /* Returns true and sets cu and cu_base if the given Dwarf is a split
6167    DWARF (.dwo) file.  */
6168 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)6169 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
6170 {
6171   uint64_t id;
6172   if (is_split_dwarf (dbg, &id, cu))
6173     {
6174       Dwarf_Die cudie;
6175       if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
6176 	{
6177 	  *cu_base = cudie_base (&cudie);
6178 	  return true;
6179 	}
6180     }
6181   return false;
6182 }
6183 
6184 /* Print content of DWARF .debug_rnglists section.  */
6185 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6186 print_debug_rnglists_section (Dwfl_Module *dwflmod,
6187 			      Ebl *ebl,
6188 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
6189 			      Elf_Scn *scn, GElf_Shdr *shdr,
6190 			      Dwarf *dbg __attribute__((unused)))
6191 {
6192   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_rnglists, scn);
6193   if (data == NULL)
6194     return;
6195 
6196   printf (_("\
6197 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6198 	  elf_ndxscn (scn), section_name (ebl, shdr),
6199 	  (uint64_t) shdr->sh_offset);
6200 
6201   /* For the listptr to get the base address/CU.  */
6202   sort_listptr (&known_rnglistptr, "rnglistptr");
6203   size_t listptr_idx = 0;
6204 
6205   const unsigned char *readp = data->d_buf;
6206   const unsigned char *const dataend = ((unsigned char *) data->d_buf
6207 					+ data->d_size);
6208   while (readp < dataend)
6209     {
6210       if (unlikely (readp > dataend - 4))
6211 	{
6212 	invalid_data:
6213 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
6214 		 elf_ndxscn (scn), section_name (ebl, shdr));
6215 	  return;
6216 	}
6217 
6218       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6219       printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
6220 	      (uint64_t) offset);
6221 
6222       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6223       unsigned int offset_size = 4;
6224       if (unlikely (unit_length == 0xffffffff))
6225 	{
6226 	  if (unlikely (readp > dataend - 8))
6227 	    goto invalid_data;
6228 
6229 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6230 	  offset_size = 8;
6231 	}
6232       printf (_(" Length:         %8" PRIu64 "\n"), unit_length);
6233 
6234       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
6235 	 bytes to complete the header.  And this unit cannot go beyond
6236 	 the section data.  */
6237       if (readp > dataend - 8
6238 	  || unit_length < 8
6239 	  || unit_length > (uint64_t) (dataend - readp))
6240 	goto invalid_data;
6241 
6242       const unsigned char *nexthdr = readp + unit_length;
6243 
6244       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
6245       printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
6246 
6247       if (version != 5)
6248 	{
6249 	  error (0, 0, _("Unknown version"));
6250 	  goto next_table;
6251 	}
6252 
6253       uint8_t address_size = *readp++;
6254       printf (_(" Address size:   %8" PRIu64 "\n"),
6255 	      (uint64_t) address_size);
6256 
6257       if (address_size != 4 && address_size != 8)
6258 	{
6259 	  error (0, 0, _("unsupported address size"));
6260 	  goto next_table;
6261 	}
6262 
6263       uint8_t segment_size = *readp++;
6264       printf (_(" Segment size:   %8" PRIu64 "\n"),
6265 	      (uint64_t) segment_size);
6266 
6267       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
6268         {
6269           error (0, 0, _("unsupported segment size"));
6270           goto next_table;
6271         }
6272 
6273       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
6274       printf (_(" Offset entries: %8" PRIu64 "\n"),
6275 	      (uint64_t) offset_entry_count);
6276 
6277       /* We need the CU that uses this unit to get the initial base address. */
6278       Dwarf_Addr cu_base = 0;
6279       struct Dwarf_CU *cu = NULL;
6280       if (listptr_cu (&known_rnglistptr, &listptr_idx,
6281 		      (Dwarf_Off) offset,
6282 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
6283 		      &cu_base, &cu)
6284 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
6285 	{
6286 	  Dwarf_Die cudie;
6287 	  if (dwarf_cu_die (cu, &cudie,
6288 			    NULL, NULL, NULL, NULL,
6289 			    NULL, NULL) == NULL)
6290 	    printf (_(" Unknown CU base: "));
6291 	  else
6292 	    printf (_(" CU [%6" PRIx64 "] base: "),
6293 		    dwarf_dieoffset (&cudie));
6294 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
6295 	  printf ("\n");
6296 	}
6297       else
6298 	printf (_(" Not associated with a CU.\n"));
6299 
6300       printf ("\n");
6301 
6302       const unsigned char *offset_array_start = readp;
6303       if (offset_entry_count > 0)
6304 	{
6305 	  uint64_t max_entries = (unit_length - 8) / offset_size;
6306 	  if (offset_entry_count > max_entries)
6307 	    {
6308 	      error (0, 0,
6309 		     _("too many offset entries for unit length"));
6310 	      offset_entry_count = max_entries;
6311 	    }
6312 
6313 	  printf (_("  Offsets starting at 0x%" PRIx64 ":\n"),
6314 		  (uint64_t) (offset_array_start
6315 			      - (unsigned char *) data->d_buf));
6316 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
6317 	    {
6318 	      printf ("   [%6" PRIu32 "] ", idx);
6319 	      if (offset_size == 4)
6320 		{
6321 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
6322 		  printf ("0x%" PRIx32 "\n", off);
6323 		}
6324 	      else
6325 		{
6326 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
6327 		  printf ("0x%" PRIx64 "\n", off);
6328 		}
6329 	    }
6330 	  printf ("\n");
6331 	}
6332 
6333       Dwarf_Addr base = cu_base;
6334       bool start_of_list = true;
6335       while (readp < nexthdr)
6336 	{
6337 	  uint8_t kind = *readp++;
6338 	  uint64_t op1, op2;
6339 
6340 	  /* Skip padding.  */
6341 	  if (start_of_list && kind == DW_RLE_end_of_list)
6342 	    continue;
6343 
6344 	  if (start_of_list)
6345 	    {
6346 	      base = cu_base;
6347 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
6348 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
6349 		      (uint64_t) (readp - offset_array_start - 1));
6350 	      start_of_list = false;
6351 	    }
6352 
6353 	  printf ("    %s", dwarf_range_list_encoding_name (kind));
6354 	  switch (kind)
6355 	    {
6356 	    case DW_RLE_end_of_list:
6357 	      start_of_list = true;
6358 	      printf ("\n\n");
6359 	      break;
6360 
6361 	    case DW_RLE_base_addressx:
6362 	      if ((uint64_t) (nexthdr - readp) < 1)
6363 		{
6364 		invalid_range:
6365 		  error (0, 0, _("invalid range list data"));
6366 		  goto next_table;
6367 		}
6368 	      get_uleb128 (op1, readp, nexthdr);
6369 	      printf (" %" PRIx64 "\n", op1);
6370 	      if (! print_unresolved_addresses)
6371 		{
6372 		  Dwarf_Addr addr;
6373 		  if (get_indexed_addr (cu, op1, &addr) != 0)
6374 		    printf ("      ???\n");
6375 		  else
6376 		    {
6377 		      printf ("      ");
6378 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
6379 		      printf ("\n");
6380 		    }
6381 		}
6382 	      break;
6383 
6384 	    case DW_RLE_startx_endx:
6385 	      if ((uint64_t) (nexthdr - readp) < 1)
6386 		goto invalid_range;
6387 	      get_uleb128 (op1, readp, nexthdr);
6388 	      if ((uint64_t) (nexthdr - readp) < 1)
6389 		goto invalid_range;
6390 	      get_uleb128 (op2, readp, nexthdr);
6391 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6392 	      if (! print_unresolved_addresses)
6393 		{
6394 		  Dwarf_Addr addr1;
6395 		  Dwarf_Addr addr2;
6396 		  if (get_indexed_addr (cu, op1, &addr1) != 0
6397 		      || get_indexed_addr (cu, op2, &addr2) != 0)
6398 		    {
6399 		      printf ("      ???..\n");
6400 		      printf ("      ???\n");
6401 		    }
6402 		  else
6403 		    {
6404 		      printf ("      ");
6405 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
6406 		      printf ("..\n      ");
6407 		      print_dwarf_addr (dwflmod, address_size,
6408 					addr2 - 1, addr2);
6409 		      printf ("\n");
6410 		    }
6411 		}
6412 	      break;
6413 
6414 	    case DW_RLE_startx_length:
6415 	      if ((uint64_t) (nexthdr - readp) < 1)
6416 		goto invalid_range;
6417 	      get_uleb128 (op1, readp, nexthdr);
6418 	      if ((uint64_t) (nexthdr - readp) < 1)
6419 		goto invalid_range;
6420 	      get_uleb128 (op2, readp, nexthdr);
6421 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6422 	      if (! print_unresolved_addresses)
6423 		{
6424 		  Dwarf_Addr addr1;
6425 		  Dwarf_Addr addr2;
6426 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
6427 		    {
6428 		      printf ("      ???..\n");
6429 		      printf ("      ???\n");
6430 		    }
6431 		  else
6432 		    {
6433 		      addr2 = addr1 + op2;
6434 		      printf ("      ");
6435 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
6436 		      printf ("..\n      ");
6437 		      print_dwarf_addr (dwflmod, address_size,
6438 					addr2 - 1, addr2);
6439 		      printf ("\n");
6440 		    }
6441 		}
6442 	      break;
6443 
6444 	    case DW_RLE_offset_pair:
6445 	      if ((uint64_t) (nexthdr - readp) < 1)
6446 		goto invalid_range;
6447 	      get_uleb128 (op1, readp, nexthdr);
6448 	      if ((uint64_t) (nexthdr - readp) < 1)
6449 		goto invalid_range;
6450 	      get_uleb128 (op2, readp, nexthdr);
6451 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6452 	      if (! print_unresolved_addresses)
6453 		{
6454 		  op1 += base;
6455 		  op2 += base;
6456 		  printf ("      ");
6457 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
6458 		  printf ("..\n      ");
6459 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6460 		  printf ("\n");
6461 		}
6462 	      break;
6463 
6464 	    case DW_RLE_base_address:
6465 	      if (address_size == 4)
6466 		{
6467 		  if ((uint64_t) (nexthdr - readp) < 4)
6468 		    goto invalid_range;
6469 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
6470 		}
6471 	      else
6472 		{
6473 		  if ((uint64_t) (nexthdr - readp) < 8)
6474 		    goto invalid_range;
6475 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
6476 		}
6477 	      base = op1;
6478 	      printf (" 0x%" PRIx64 "\n", base);
6479 	      if (! print_unresolved_addresses)
6480 		{
6481 		  printf ("      ");
6482 		  print_dwarf_addr (dwflmod, address_size, base, base);
6483 		  printf ("\n");
6484 		}
6485 	      break;
6486 
6487 	    case DW_RLE_start_end:
6488 	      if (address_size == 4)
6489 		{
6490 		  if ((uint64_t) (nexthdr - readp) < 8)
6491 		    goto invalid_range;
6492 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
6493 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
6494 		}
6495 	      else
6496 		{
6497 		  if ((uint64_t) (nexthdr - readp) < 16)
6498 		    goto invalid_range;
6499 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
6500 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
6501 		}
6502 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
6503 	      if (! print_unresolved_addresses)
6504 		{
6505 		  printf ("      ");
6506 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
6507 		  printf ("..\n      ");
6508 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6509 		  printf ("\n");
6510 		}
6511 	      break;
6512 
6513 	    case DW_RLE_start_length:
6514 	      if (address_size == 4)
6515 		{
6516 		  if ((uint64_t) (nexthdr - readp) < 4)
6517 		    goto invalid_range;
6518 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
6519 		}
6520 	      else
6521 		{
6522 		  if ((uint64_t) (nexthdr - readp) < 8)
6523 		    goto invalid_range;
6524 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
6525 		}
6526 	      if ((uint64_t) (nexthdr - readp) < 1)
6527 		goto invalid_range;
6528 	      get_uleb128 (op2, readp, nexthdr);
6529 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
6530 	      if (! print_unresolved_addresses)
6531 		{
6532 		  op2 = op1 + op2;
6533 		  printf ("      ");
6534 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
6535 		  printf ("..\n      ");
6536 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6537 		  printf ("\n");
6538 		}
6539 	      break;
6540 
6541 	    default:
6542 	      goto invalid_range;
6543 	    }
6544 	}
6545 
6546     next_table:
6547       if (readp != nexthdr)
6548 	{
6549           size_t padding = nexthdr - readp;
6550           printf (_("   %zu padding bytes\n\n"), padding);
6551 	  readp = nexthdr;
6552 	}
6553     }
6554 }
6555 
6556 /* Print content of DWARF .debug_ranges section.  */
6557 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6558 print_debug_ranges_section (Dwfl_Module *dwflmod,
6559 			    Ebl *ebl, GElf_Ehdr *ehdr,
6560 			    Elf_Scn *scn, GElf_Shdr *shdr,
6561 			    Dwarf *dbg)
6562 {
6563   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_ranges, scn);
6564   if (data == NULL)
6565     return;
6566 
6567   printf (_("\
6568 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6569 	  elf_ndxscn (scn), section_name (ebl, shdr),
6570 	  (uint64_t) shdr->sh_offset);
6571 
6572   sort_listptr (&known_rangelistptr, "rangelistptr");
6573   size_t listptr_idx = 0;
6574 
6575   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6576 
6577   bool first = true;
6578   Dwarf_Addr base = 0;
6579   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6580   unsigned char *readp = data->d_buf;
6581   Dwarf_CU *last_cu = NULL;
6582   while (readp < endp)
6583     {
6584       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6585       Dwarf_CU *cu = last_cu;
6586 
6587       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6588 				      &address_size, NULL, &base, &cu,
6589 				      offset, &readp, endp, NULL))
6590 	continue;
6591 
6592       if (last_cu != cu)
6593 	{
6594 	  Dwarf_Die cudie;
6595 	  if (dwarf_cu_die (cu, &cudie,
6596 			    NULL, NULL, NULL, NULL,
6597 			    NULL, NULL) == NULL)
6598 	    printf (_("\n Unknown CU base: "));
6599 	  else
6600 	    printf (_("\n CU [%6" PRIx64 "] base: "),
6601 		    dwarf_dieoffset (&cudie));
6602 	  print_dwarf_addr (dwflmod, address_size, base, base);
6603 	  printf ("\n");
6604 	}
6605       last_cu = cu;
6606 
6607       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6608 	{
6609 	  printf (_(" [%6tx]  <INVALID DATA>\n"), offset);
6610 	  break;
6611 	}
6612 
6613       Dwarf_Addr begin;
6614       Dwarf_Addr end;
6615       if (address_size == 8)
6616 	{
6617 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
6618 	  end = read_8ubyte_unaligned_inc (dbg, readp);
6619 	}
6620       else
6621 	{
6622 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
6623 	  end = read_4ubyte_unaligned_inc (dbg, readp);
6624 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
6625 	    begin = (Dwarf_Addr) -1l;
6626 	}
6627 
6628       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
6629 	{
6630 	  if (first)
6631 	    printf (" [%6tx] ", offset);
6632 	  else
6633 	    printf ("          ");
6634 	  puts (_("base address"));
6635 	  printf ("          ");
6636 	  print_dwarf_addr (dwflmod, address_size, end, end);
6637 	  printf ("\n");
6638 	  base = end;
6639 	  first = false;
6640 	}
6641       else if (begin == 0 && end == 0) /* End of list entry.  */
6642 	{
6643 	  if (first)
6644 	    printf (_(" [%6tx] empty list\n"), offset);
6645 	  first = true;
6646 	}
6647       else
6648 	{
6649 	  /* We have an address range entry.  */
6650 	  if (first)		/* First address range entry in a list.  */
6651 	    printf (" [%6tx] ", offset);
6652 	  else
6653 	    printf ("          ");
6654 
6655 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6656 	  if (! print_unresolved_addresses)
6657 	    {
6658 	      printf ("          ");
6659 	      print_dwarf_addr (dwflmod, address_size, base + begin,
6660 			        base + begin);
6661 	      printf ("..\n          ");
6662 	      print_dwarf_addr (dwflmod, address_size,
6663 				base + end - 1, base + end);
6664 	      printf ("\n");
6665 	    }
6666 
6667 	  first = false;
6668 	}
6669     }
6670 }
6671 
6672 #define REGNAMESZ 16
6673 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6674 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6675 	       char name[REGNAMESZ], int *bits, int *type)
6676 {
6677   const char *set;
6678   const char *pfx;
6679   int ignore;
6680   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6681 				 bits ?: &ignore, type ?: &ignore);
6682   if (n <= 0)
6683     {
6684       if (loc != NULL)
6685 	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6686       else
6687 	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6688       if (bits != NULL)
6689 	*bits = loc != NULL ? loc->bits : 0;
6690       if (type != NULL)
6691 	*type = DW_ATE_unsigned;
6692       set = "??? unrecognized";
6693     }
6694   else
6695     {
6696       if (bits != NULL && *bits <= 0)
6697 	*bits = loc != NULL ? loc->bits : 0;
6698       if (type != NULL && *type == DW_ATE_void)
6699 	*type = DW_ATE_unsigned;
6700 
6701     }
6702   return set;
6703 }
6704 
6705 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6706 read_encoded (unsigned int encoding, const unsigned char *readp,
6707 	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6708 {
6709   if ((encoding & 0xf) == DW_EH_PE_absptr)
6710     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6711       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6712 
6713   switch (encoding & 0xf)
6714     {
6715     case DW_EH_PE_uleb128:
6716       if (readp >= endp)
6717 	goto invalid;
6718       get_uleb128 (*res, readp, endp);
6719       break;
6720     case DW_EH_PE_sleb128:
6721       if (readp >= endp)
6722 	goto invalid;
6723       get_sleb128 (*res, readp, endp);
6724       break;
6725     case DW_EH_PE_udata2:
6726       if (readp + 2 > endp)
6727 	goto invalid;
6728       *res = read_2ubyte_unaligned_inc (dbg, readp);
6729       break;
6730     case DW_EH_PE_udata4:
6731       if (readp + 4 > endp)
6732 	goto invalid;
6733       *res = read_4ubyte_unaligned_inc (dbg, readp);
6734       break;
6735     case DW_EH_PE_udata8:
6736       if (readp + 8 > endp)
6737 	goto invalid;
6738       *res = read_8ubyte_unaligned_inc (dbg, readp);
6739       break;
6740     case DW_EH_PE_sdata2:
6741       if (readp + 2 > endp)
6742 	goto invalid;
6743       *res = read_2sbyte_unaligned_inc (dbg, readp);
6744       break;
6745     case DW_EH_PE_sdata4:
6746       if (readp + 4 > endp)
6747 	goto invalid;
6748       *res = read_4sbyte_unaligned_inc (dbg, readp);
6749       break;
6750     case DW_EH_PE_sdata8:
6751       if (readp + 8 > endp)
6752 	goto invalid;
6753       *res = read_8sbyte_unaligned_inc (dbg, readp);
6754       break;
6755     default:
6756     invalid:
6757       error (1, 0,
6758 	     _("invalid encoding"));
6759     }
6760 
6761   return readp;
6762 }
6763 
6764 static const char *
regname(Ebl * ebl,unsigned int regno,char * regnamebuf)6765 regname (Ebl *ebl, unsigned int regno, char *regnamebuf)
6766 {
6767   register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6768 
6769   return regnamebuf;
6770 }
6771 
6772 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Dwarf * dbg)6773 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6774 		   Dwarf_Word vma_base, unsigned int code_align,
6775 		   int data_align,
6776 		   unsigned int version, unsigned int ptr_size,
6777 		   unsigned int encoding,
6778 		   Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
6779 {
6780   char regnamebuf[REGNAMESZ];
6781 
6782   puts ("\n   Program:");
6783   Dwarf_Word pc = vma_base;
6784   while (readp < endp)
6785     {
6786       unsigned int opcode = *readp++;
6787 
6788       if (opcode < DW_CFA_advance_loc)
6789 	/* Extended opcode.  */
6790 	switch (opcode)
6791 	  {
6792 	    uint64_t op1;
6793 	    int64_t sop1;
6794 	    uint64_t op2;
6795 	    int64_t sop2;
6796 
6797 	  case DW_CFA_nop:
6798 	    puts ("     nop");
6799 	    break;
6800 	  case DW_CFA_set_loc:
6801 	    if ((uint64_t) (endp - readp) < 1)
6802 	      goto invalid;
6803 	    readp = read_encoded (encoding, readp, endp, &op1, dbg);
6804 	    printf ("     set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6805 		    op1, pc = vma_base + op1);
6806 	    break;
6807 	  case DW_CFA_advance_loc1:
6808 	    if ((uint64_t) (endp - readp) < 1)
6809 	      goto invalid;
6810 	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
6811 		    *readp, pc += *readp * code_align);
6812 	    ++readp;
6813 	    break;
6814 	  case DW_CFA_advance_loc2:
6815 	    if ((uint64_t) (endp - readp) < 2)
6816 	      goto invalid;
6817 	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
6818 	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6819 		    op1, pc += op1 * code_align);
6820 	    break;
6821 	  case DW_CFA_advance_loc4:
6822 	    if ((uint64_t) (endp - readp) < 4)
6823 	      goto invalid;
6824 	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
6825 	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6826 		    op1, pc += op1 * code_align);
6827 	    break;
6828 	  case DW_CFA_offset_extended:
6829 	    if ((uint64_t) (endp - readp) < 1)
6830 	      goto invalid;
6831 	    get_uleb128 (op1, readp, endp);
6832 	    if ((uint64_t) (endp - readp) < 1)
6833 	      goto invalid;
6834 	    get_uleb128 (op2, readp, endp);
6835 	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6836 		    "\n",
6837 		    op1, regname (ebl, op1, regnamebuf), op2 * data_align);
6838 	    break;
6839 	  case DW_CFA_restore_extended:
6840 	    if ((uint64_t) (endp - readp) < 1)
6841 	      goto invalid;
6842 	    get_uleb128 (op1, readp, endp);
6843 	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
6844 		    op1, regname (ebl, op1, regnamebuf));
6845 	    break;
6846 	  case DW_CFA_undefined:
6847 	    if ((uint64_t) (endp - readp) < 1)
6848 	      goto invalid;
6849 	    get_uleb128 (op1, readp, endp);
6850 	    printf ("     undefined r%" PRIu64 " (%s)\n", op1,
6851 		    regname (ebl, op1, regnamebuf));
6852 	    break;
6853 	  case DW_CFA_same_value:
6854 	    if ((uint64_t) (endp - readp) < 1)
6855 	      goto invalid;
6856 	    get_uleb128 (op1, readp, endp);
6857 	    printf ("     same_value r%" PRIu64 " (%s)\n", op1,
6858 		    regname (ebl, op1, regnamebuf));
6859 	    break;
6860 	  case DW_CFA_register:
6861 	    if ((uint64_t) (endp - readp) < 1)
6862 	      goto invalid;
6863 	    get_uleb128 (op1, readp, endp);
6864 	    if ((uint64_t) (endp - readp) < 1)
6865 	      goto invalid;
6866 	    get_uleb128 (op2, readp, endp);
6867 	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6868 		    op1, regname (ebl, op1, regnamebuf), op2,
6869 		    regname (ebl, op2, regnamebuf));
6870 	    break;
6871 	  case DW_CFA_remember_state:
6872 	    puts ("     remember_state");
6873 	    break;
6874 	  case DW_CFA_restore_state:
6875 	    puts ("     restore_state");
6876 	    break;
6877 	  case DW_CFA_def_cfa:
6878 	    if ((uint64_t) (endp - readp) < 1)
6879 	      goto invalid;
6880 	    get_uleb128 (op1, readp, endp);
6881 	    if ((uint64_t) (endp - readp) < 1)
6882 	      goto invalid;
6883 	    get_uleb128 (op2, readp, endp);
6884 	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6885 		    op1, regname (ebl, op1, regnamebuf), op2);
6886 	    break;
6887 	  case DW_CFA_def_cfa_register:
6888 	    if ((uint64_t) (endp - readp) < 1)
6889 	      goto invalid;
6890 	    get_uleb128 (op1, readp, endp);
6891 	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
6892 		    op1, regname (ebl, op1, regnamebuf));
6893 	    break;
6894 	  case DW_CFA_def_cfa_offset:
6895 	    if ((uint64_t) (endp - readp) < 1)
6896 	      goto invalid;
6897 	    get_uleb128 (op1, readp, endp);
6898 	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
6899 	    break;
6900 	  case DW_CFA_def_cfa_expression:
6901 	    if ((uint64_t) (endp - readp) < 1)
6902 	      goto invalid;
6903 	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
6904 	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
6905 	    if ((uint64_t) (endp - readp) < op1)
6906 	      {
6907 	    invalid:
6908 	        fputs (_("         <INVALID DATA>\n"), stdout);
6909 		return;
6910 	      }
6911 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6912 		       op1, readp);
6913 	    readp += op1;
6914 	    break;
6915 	  case DW_CFA_expression:
6916 	    if ((uint64_t) (endp - readp) < 1)
6917 	      goto invalid;
6918 	    get_uleb128 (op1, readp, endp);
6919 	    if ((uint64_t) (endp - readp) < 1)
6920 	      goto invalid;
6921 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6922 	    printf ("     expression r%" PRIu64 " (%s) \n",
6923 		    op1, regname (ebl, op1, regnamebuf));
6924 	    if ((uint64_t) (endp - readp) < op2)
6925 	      goto invalid;
6926 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6927 		       op2, readp);
6928 	    readp += op2;
6929 	    break;
6930 	  case DW_CFA_offset_extended_sf:
6931 	    if ((uint64_t) (endp - readp) < 1)
6932 	      goto invalid;
6933 	    get_uleb128 (op1, readp, endp);
6934 	    if ((uint64_t) (endp - readp) < 1)
6935 	      goto invalid;
6936 	    get_sleb128 (sop2, readp, endp);
6937 	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6938 		    PRId64 "\n",
6939 		    op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6940 	    break;
6941 	  case DW_CFA_def_cfa_sf:
6942 	    if ((uint64_t) (endp - readp) < 1)
6943 	      goto invalid;
6944 	    get_uleb128 (op1, readp, endp);
6945 	    if ((uint64_t) (endp - readp) < 1)
6946 	      goto invalid;
6947 	    get_sleb128 (sop2, readp, endp);
6948 	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6949 		    op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6950 	    break;
6951 	  case DW_CFA_def_cfa_offset_sf:
6952 	    if ((uint64_t) (endp - readp) < 1)
6953 	      goto invalid;
6954 	    get_sleb128 (sop1, readp, endp);
6955 	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6956 	    break;
6957 	  case DW_CFA_val_offset:
6958 	    if ((uint64_t) (endp - readp) < 1)
6959 	      goto invalid;
6960 	    get_uleb128 (op1, readp, endp);
6961 	    if ((uint64_t) (endp - readp) < 1)
6962 	      goto invalid;
6963 	    get_uleb128 (op2, readp, endp);
6964 	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6965 		    op1, op2 * data_align);
6966 	    break;
6967 	  case DW_CFA_val_offset_sf:
6968 	    if ((uint64_t) (endp - readp) < 1)
6969 	      goto invalid;
6970 	    get_uleb128 (op1, readp, endp);
6971 	    if ((uint64_t) (endp - readp) < 1)
6972 	      goto invalid;
6973 	    get_sleb128 (sop2, readp, endp);
6974 	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6975 		    op1, sop2 * data_align);
6976 	    break;
6977 	  case DW_CFA_val_expression:
6978 	    if ((uint64_t) (endp - readp) < 1)
6979 	      goto invalid;
6980 	    get_uleb128 (op1, readp, endp);
6981 	    if ((uint64_t) (endp - readp) < 1)
6982 	      goto invalid;
6983 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
6984 	    printf ("     val_expression r%" PRIu64 " (%s)\n",
6985 		    op1, regname (ebl, op1, regnamebuf));
6986 	    if ((uint64_t) (endp - readp) < op2)
6987 	      goto invalid;
6988 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6989 		       NULL, op2, readp);
6990 	    readp += op2;
6991 	    break;
6992 	  case DW_CFA_MIPS_advance_loc8:
6993 	    if ((uint64_t) (endp - readp) < 8)
6994 	      goto invalid;
6995 	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
6996 	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6997 		    op1, pc += op1 * code_align);
6998 	    break;
6999 	  case DW_CFA_GNU_window_save:  /* DW_CFA_AARCH64_negate_ra_state  */
7000 	    if (ehdr->e_machine == EM_AARCH64)
7001 	      puts ("     AARCH64_negate_ra_state");
7002 	    else
7003 	      puts ("     GNU_window_save");
7004 	    break;
7005 	  case DW_CFA_GNU_args_size:
7006 	    if ((uint64_t) (endp - readp) < 1)
7007 	      goto invalid;
7008 	    get_uleb128 (op1, readp, endp);
7009 	    printf ("     args_size %" PRIu64 "\n", op1);
7010 	    break;
7011 	  default:
7012 	    printf ("     ??? (%u)\n", opcode);
7013 	    break;
7014 	  }
7015       else if (opcode < DW_CFA_offset)
7016 	printf ("     advance_loc %u to %#" PRIx64 "\n",
7017 		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
7018       else if (opcode < DW_CFA_restore)
7019 	{
7020 	  uint64_t offset;
7021 	  if ((uint64_t) (endp - readp) < 1)
7022 	    goto invalid;
7023 	  get_uleb128 (offset, readp, endp);
7024 	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
7025 		  opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf),
7026 		  offset * data_align);
7027 	}
7028       else
7029 	printf ("     restore r%u (%s)\n",
7030 		opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf));
7031     }
7032 }
7033 
7034 
7035 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)7036 encoded_ptr_size (int encoding, unsigned int ptr_size)
7037 {
7038   switch (encoding & 7)
7039     {
7040     case DW_EH_PE_udata4:
7041       return 4;
7042     case DW_EH_PE_udata8:
7043       return 8;
7044     case 0:
7045       return ptr_size;
7046     }
7047 
7048   fprintf (stderr, "Unsupported pointer encoding: %#x, "
7049 	   "assuming pointer size of %d.\n", encoding, ptr_size);
7050   return ptr_size;
7051 }
7052 
7053 
7054 static unsigned int
print_encoding(unsigned int val)7055 print_encoding (unsigned int val)
7056 {
7057   switch (val & 0xf)
7058     {
7059     case DW_EH_PE_absptr:
7060       fputs ("absptr", stdout);
7061       break;
7062     case DW_EH_PE_uleb128:
7063       fputs ("uleb128", stdout);
7064       break;
7065     case DW_EH_PE_udata2:
7066       fputs ("udata2", stdout);
7067       break;
7068     case DW_EH_PE_udata4:
7069       fputs ("udata4", stdout);
7070       break;
7071     case DW_EH_PE_udata8:
7072       fputs ("udata8", stdout);
7073       break;
7074     case DW_EH_PE_sleb128:
7075       fputs ("sleb128", stdout);
7076       break;
7077     case DW_EH_PE_sdata2:
7078       fputs ("sdata2", stdout);
7079       break;
7080     case DW_EH_PE_sdata4:
7081       fputs ("sdata4", stdout);
7082       break;
7083     case DW_EH_PE_sdata8:
7084       fputs ("sdata8", stdout);
7085       break;
7086     default:
7087       /* We did not use any of the bits after all.  */
7088       return val;
7089     }
7090 
7091   return val & ~0xf;
7092 }
7093 
7094 
7095 static unsigned int
print_relinfo(unsigned int val)7096 print_relinfo (unsigned int val)
7097 {
7098   switch (val & 0x70)
7099     {
7100     case DW_EH_PE_pcrel:
7101       fputs ("pcrel", stdout);
7102       break;
7103     case DW_EH_PE_textrel:
7104       fputs ("textrel", stdout);
7105       break;
7106     case DW_EH_PE_datarel:
7107       fputs ("datarel", stdout);
7108       break;
7109     case DW_EH_PE_funcrel:
7110       fputs ("funcrel", stdout);
7111       break;
7112     case DW_EH_PE_aligned:
7113       fputs ("aligned", stdout);
7114       break;
7115     default:
7116       return val;
7117     }
7118 
7119   return val & ~0x70;
7120 }
7121 
7122 
7123 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)7124 print_encoding_base (const char *pfx, unsigned int fde_encoding)
7125 {
7126   printf ("(%s", pfx);
7127 
7128   if (fde_encoding == DW_EH_PE_omit)
7129     puts ("omit)");
7130   else
7131     {
7132       unsigned int w = fde_encoding;
7133 
7134       w = print_encoding (w);
7135 
7136       if (w & 0x70)
7137 	{
7138 	  if (w != fde_encoding)
7139 	    fputc_unlocked (' ', stdout);
7140 
7141 	  w = print_relinfo (w);
7142 	}
7143 
7144       if (w != 0)
7145 	printf ("%s%x", w != fde_encoding ? " " : "", w);
7146 
7147       puts (")");
7148     }
7149 }
7150 
7151 
7152 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7153 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7154 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7155 {
7156   size_t shstrndx;
7157   /* We know this call will succeed since it did in the caller.  */
7158   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
7159   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
7160 
7161   /* Needed if we find PC-relative addresses.  */
7162   GElf_Addr bias;
7163   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
7164     {
7165       error (0, 0, _("cannot get ELF: %s"), dwfl_errmsg (-1));
7166       return;
7167     }
7168 
7169   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
7170   Elf_Data *data;
7171   if (is_eh_frame)
7172     {
7173       data = elf_rawdata (scn, NULL);
7174       if (data == NULL)
7175 	{
7176 	  error (0, 0, _("cannot get %s content: %s"),
7177 		 scnname, elf_errmsg (-1));
7178 	  return;
7179 	}
7180     }
7181   else
7182     {
7183       data = get_debug_elf_data (dbg, ebl, IDX_debug_frame, scn);
7184       if (data == NULL)
7185 	return;
7186     }
7187 
7188   if (is_eh_frame)
7189     printf (_("\
7190 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7191 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
7192   else
7193     printf (_("\
7194 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7195 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
7196 
7197   struct cieinfo
7198   {
7199     ptrdiff_t cie_offset;
7200     const char *augmentation;
7201     unsigned int code_alignment_factor;
7202     unsigned int data_alignment_factor;
7203     uint8_t address_size;
7204     uint8_t fde_encoding;
7205     uint8_t lsda_encoding;
7206     struct cieinfo *next;
7207   } *cies = NULL;
7208 
7209   const unsigned char *readp = data->d_buf;
7210   const unsigned char *const dataend = ((unsigned char *) data->d_buf
7211 					+ data->d_size);
7212   while (readp < dataend)
7213     {
7214       if (unlikely (readp + 4 > dataend))
7215 	{
7216 	invalid_data:
7217 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
7218 		     elf_ndxscn (scn), scnname);
7219 	      return;
7220 	}
7221 
7222       /* At the beginning there must be a CIE.  There can be multiple,
7223 	 hence we test tis in a loop.  */
7224       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
7225 
7226       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
7227       unsigned int length = 4;
7228       if (unlikely (unit_length == 0xffffffff))
7229 	{
7230 	  if (unlikely (readp + 8 > dataend))
7231 	    goto invalid_data;
7232 
7233 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
7234 	  length = 8;
7235 	}
7236 
7237       if (unlikely (unit_length == 0))
7238 	{
7239 	  printf (_("\n [%6tx] Zero terminator\n"), offset);
7240 	  continue;
7241 	}
7242 
7243       Dwarf_Word maxsize = dataend - readp;
7244       if (unlikely (unit_length > maxsize))
7245 	goto invalid_data;
7246 
7247       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7248 
7249       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
7250       const unsigned char *const cieend = readp + unit_length;
7251       if (unlikely (cieend > dataend))
7252 	goto invalid_data;
7253 
7254       Dwarf_Off cie_id;
7255       if (length == 4)
7256 	{
7257 	  if (unlikely (cieend - readp < 4))
7258 	    goto invalid_data;
7259 	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
7260 	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
7261 	    cie_id = DW_CIE_ID_64;
7262 	}
7263       else
7264 	{
7265 	  if (unlikely (cieend - readp < 8))
7266 	    goto invalid_data;
7267 	  cie_id = read_8ubyte_unaligned_inc (dbg, readp);
7268 	}
7269 
7270       uint_fast8_t version = 2;
7271       unsigned int code_alignment_factor;
7272       int data_alignment_factor;
7273       unsigned int fde_encoding = 0;
7274       unsigned int lsda_encoding = 0;
7275       Dwarf_Word initial_location = 0;
7276       Dwarf_Word vma_base = 0;
7277 
7278       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
7279 	{
7280 	  if (unlikely (cieend - readp < 2))
7281 	    goto invalid_data;
7282 	  version = *readp++;
7283 	  const char *const augmentation = (const char *) readp;
7284 	  readp = memchr (readp, '\0', cieend - readp);
7285 	  if (unlikely (readp == NULL))
7286 	    goto invalid_data;
7287 	  ++readp;
7288 
7289 	  uint_fast8_t segment_size = 0;
7290 	  if (version >= 4)
7291 	    {
7292 	      if (cieend - readp < 5)
7293 		goto invalid_data;
7294 	      ptr_size = *readp++;
7295 	      segment_size = *readp++;
7296 	    }
7297 
7298 	  if (cieend - readp < 1)
7299 	    goto invalid_data;
7300 	  get_uleb128 (code_alignment_factor, readp, cieend);
7301 	  if (cieend - readp < 1)
7302 	    goto invalid_data;
7303 	  get_sleb128 (data_alignment_factor, readp, cieend);
7304 
7305 	  /* In some variant for unwind data there is another field.  */
7306 	  if (strcmp (augmentation, "eh") == 0)
7307 	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7308 
7309 	  unsigned int return_address_register;
7310 	  if (cieend - readp < 1)
7311 	    goto invalid_data;
7312 	  if (unlikely (version == 1))
7313 	    return_address_register = *readp++;
7314 	  else
7315 	    get_uleb128 (return_address_register, readp, cieend);
7316 
7317 	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
7318 		  "   CIE_id:                   %" PRIu64 "\n"
7319 		  "   version:                  %u\n"
7320 		  "   augmentation:             \"%s\"\n",
7321 		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
7322 		  version, augmentation);
7323 	  if (version >= 4)
7324 	    printf ("   address_size:             %u\n"
7325 		    "   segment_size:             %u\n",
7326 		    ptr_size, segment_size);
7327 	  printf ("   code_alignment_factor:    %u\n"
7328 		  "   data_alignment_factor:    %d\n"
7329 		  "   return_address_register:  %u\n",
7330 		  code_alignment_factor,
7331 		  data_alignment_factor, return_address_register);
7332 
7333 	  if (augmentation[0] == 'z')
7334 	    {
7335 	      if (cieend - readp < 1)
7336 		goto invalid_data;
7337 
7338 	      unsigned int augmentationlen;
7339 	      get_uleb128 (augmentationlen, readp, cieend);
7340 
7341 	      if (augmentationlen > (size_t) (cieend - readp))
7342 		{
7343 		  error (0, 0, _("invalid augmentation length"));
7344 		  readp = cieend;
7345 		  continue;
7346 		}
7347 
7348 	      const char *hdr = "Augmentation data:";
7349 	      const char *cp = augmentation + 1;
7350 	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
7351 		{
7352 		  printf ("   %-26s%#x ", hdr, *readp);
7353 		  hdr = "";
7354 
7355 		  if (*cp == 'R')
7356 		    {
7357 		      fde_encoding = *readp++;
7358 		      print_encoding_base (_("FDE address encoding: "),
7359 					   fde_encoding);
7360 		    }
7361 		  else if (*cp == 'L')
7362 		    {
7363 		      lsda_encoding = *readp++;
7364 		      print_encoding_base (_("LSDA pointer encoding: "),
7365 					   lsda_encoding);
7366 		    }
7367 		  else if (*cp == 'P')
7368 		    {
7369 		      /* Personality.  This field usually has a relocation
7370 			 attached pointing to __gcc_personality_v0.  */
7371 		      const unsigned char *startp = readp;
7372 		      unsigned int encoding = *readp++;
7373 		      uint64_t val = 0;
7374 		      readp = read_encoded (encoding, readp,
7375 					    readp - 1 + augmentationlen,
7376 					    &val, dbg);
7377 
7378 		      while (++startp < readp)
7379 			printf ("%#x ", *startp);
7380 
7381 		      putchar ('(');
7382 		      print_encoding (encoding);
7383 		      putchar (' ');
7384 		      switch (encoding & 0xf)
7385 			{
7386 			case DW_EH_PE_sleb128:
7387 			case DW_EH_PE_sdata2:
7388 			case DW_EH_PE_sdata4:
7389 			  printf ("%" PRId64 ")\n", val);
7390 			  break;
7391 			default:
7392 			  printf ("%#" PRIx64 ")\n", val);
7393 			  break;
7394 			}
7395 		    }
7396 		  else
7397 		    printf ("(%x)\n", *readp++);
7398 
7399 		  ++cp;
7400 		}
7401 	    }
7402 
7403 	  if (likely (ptr_size == 4 || ptr_size == 8))
7404 	    {
7405 	      struct cieinfo *newp = alloca (sizeof (*newp));
7406 	      newp->cie_offset = offset;
7407 	      newp->augmentation = augmentation;
7408 	      newp->fde_encoding = fde_encoding;
7409 	      newp->lsda_encoding = lsda_encoding;
7410 	      newp->address_size = ptr_size;
7411 	      newp->code_alignment_factor = code_alignment_factor;
7412 	      newp->data_alignment_factor = data_alignment_factor;
7413 	      newp->next = cies;
7414 	      cies = newp;
7415 	    }
7416 	}
7417       else
7418 	{
7419 	  struct cieinfo *cie = cies;
7420 	  while (cie != NULL)
7421 	    if (is_eh_frame
7422 		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
7423 		: cie_id == (Dwarf_Off) cie->cie_offset)
7424 	      break;
7425 	    else
7426 	      cie = cie->next;
7427 	  if (unlikely (cie == NULL))
7428 	    {
7429 	      puts ("invalid CIE reference in FDE");
7430 	      return;
7431 	    }
7432 
7433 	  /* Initialize from CIE data.  */
7434 	  fde_encoding = cie->fde_encoding;
7435 	  lsda_encoding = cie->lsda_encoding;
7436 	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
7437 	  code_alignment_factor = cie->code_alignment_factor;
7438 	  data_alignment_factor = cie->data_alignment_factor;
7439 
7440 	  const unsigned char *base = readp;
7441 	  // XXX There are sometimes relocations for this value
7442 	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
7443 	  Dwarf_Word address_range
7444 	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
7445 
7446 	  /* pcrel for an FDE address is relative to the runtime
7447 	     address of the start_address field itself.  Sign extend
7448 	     if necessary to make sure the calculation is done on the
7449 	     full 64 bit address even when initial_location only holds
7450 	     the lower 32 bits.  */
7451 	  Dwarf_Addr pc_start = initial_location;
7452 	  if (ptr_size == 4)
7453 	    pc_start = (uint64_t) (int32_t) pc_start;
7454 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7455 	    pc_start += ((uint64_t) shdr->sh_addr
7456 			 + (base - (const unsigned char *) data->d_buf)
7457 			 - bias);
7458 
7459 	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
7460 		  "   CIE_pointer:              %" PRIu64 "\n"
7461 		  "   initial_location:         ",
7462 		  offset, (uint64_t) unit_length,
7463 		  cie->cie_offset, (uint64_t) cie_id);
7464 	  print_dwarf_addr (dwflmod, cie->address_size,
7465 			    pc_start, initial_location);
7466 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7467 	    {
7468 	      vma_base = (((uint64_t) shdr->sh_offset
7469 			   + (base - (const unsigned char *) data->d_buf)
7470 			   + (uint64_t) initial_location)
7471 			  & (ptr_size == 4
7472 			     ? UINT64_C (0xffffffff)
7473 			     : UINT64_C (0xffffffffffffffff)));
7474 	      printf (_(" (offset: %#" PRIx64 ")"),
7475 		      (uint64_t) vma_base);
7476 	    }
7477 
7478 	  printf ("\n   address_range:            %#" PRIx64,
7479 		  (uint64_t) address_range);
7480 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7481 	    printf (_(" (end offset: %#" PRIx64 ")"),
7482 		    ((uint64_t) vma_base + (uint64_t) address_range)
7483 		    & (ptr_size == 4
7484 		       ? UINT64_C (0xffffffff)
7485 		       : UINT64_C (0xffffffffffffffff)));
7486 	  putchar ('\n');
7487 
7488 	  if (cie->augmentation[0] == 'z')
7489 	    {
7490 	      unsigned int augmentationlen;
7491 	      if (cieend - readp < 1)
7492 		goto invalid_data;
7493 	      get_uleb128 (augmentationlen, readp, cieend);
7494 
7495 	      if (augmentationlen > (size_t) (cieend - readp))
7496 		{
7497 		  error (0, 0, _("invalid augmentation length"));
7498 		  readp = cieend;
7499 		  continue;
7500 		}
7501 
7502 	      if (augmentationlen > 0)
7503 		{
7504 		  const char *hdr = "Augmentation data:";
7505 		  const char *cp = cie->augmentation + 1;
7506 		  unsigned int u = 0;
7507 		  while (*cp != '\0'
7508 			 && cp < cie->augmentation + augmentationlen + 1)
7509 		    {
7510 		      if (*cp == 'L')
7511 			{
7512 			  uint64_t lsda_pointer;
7513 			  const unsigned char *p
7514 			    = read_encoded (lsda_encoding, &readp[u],
7515 					    &readp[augmentationlen],
7516 					    &lsda_pointer, dbg);
7517 			  u = p - readp;
7518 			  printf (_("\
7519    %-26sLSDA pointer: %#" PRIx64 "\n"),
7520 				  hdr, lsda_pointer);
7521 			  hdr = "";
7522 			}
7523 		      ++cp;
7524 		    }
7525 
7526 		  while (u < augmentationlen)
7527 		    {
7528 		      printf ("   %-26s%#x\n", hdr, readp[u++]);
7529 		      hdr = "";
7530 		    }
7531 		}
7532 
7533 	      readp += augmentationlen;
7534 	    }
7535 	}
7536 
7537       /* Handle the initialization instructions.  */
7538       if (ptr_size != 4 && ptr_size !=8)
7539 	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
7540       else
7541 	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
7542 			   data_alignment_factor, version, ptr_size,
7543 			   fde_encoding, dwflmod, ebl, ehdr, dbg);
7544       readp = cieend;
7545     }
7546 }
7547 
7548 
7549 /* Returns the signedness (or false if it cannot be determined) and
7550    the byte size (or zero if it cannot be gotten) of the given DIE
7551    DW_AT_type attribute.  Uses dwarf_peel_type and dwarf_aggregate_size.  */
7552 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)7553 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
7554 {
7555   Dwarf_Attribute attr;
7556   Dwarf_Die type;
7557 
7558   *bytes = 0;
7559   *is_signed = false;
7560 
7561   if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
7562 								DW_AT_type,
7563 								&attr), &type),
7564 		       &type) == 0)
7565     {
7566       Dwarf_Word val;
7567       *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
7568 						 &attr), &val) == 0
7569 		    && (val == DW_ATE_signed || val == DW_ATE_signed_char));
7570 
7571       if (dwarf_aggregate_size (&type, &val) == 0)
7572 	*bytes = val;
7573     }
7574 }
7575 
7576 struct attrcb_args
7577 {
7578   Dwfl_Module *dwflmod;
7579   Dwarf *dbg;
7580   Dwarf_Die *dies;
7581   int level;
7582   bool silent;
7583   bool is_split;
7584   unsigned int version;
7585   unsigned int addrsize;
7586   unsigned int offset_size;
7587   struct Dwarf_CU *cu;
7588 };
7589 
7590 
7591 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)7592 attr_callback (Dwarf_Attribute *attrp, void *arg)
7593 {
7594   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
7595   const int level = cbargs->level;
7596   Dwarf_Die *die = &cbargs->dies[level];
7597   bool is_split = cbargs->is_split;
7598 
7599   unsigned int attr = dwarf_whatattr (attrp);
7600   if (unlikely (attr == 0))
7601     {
7602       if (!cbargs->silent)
7603 	error (0, 0, _("DIE [%" PRIx64 "] "
7604 			      "cannot get attribute code: %s"),
7605 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7606       return DWARF_CB_ABORT;
7607     }
7608 
7609   unsigned int form = dwarf_whatform (attrp);
7610   if (unlikely (form == 0))
7611     {
7612       if (!cbargs->silent)
7613 	error (0, 0, _("DIE [%" PRIx64 "] "
7614 			      "cannot get attribute form: %s"),
7615 	       dwarf_dieoffset (die), dwarf_errmsg (-1));
7616       return DWARF_CB_ABORT;
7617     }
7618 
7619   switch (form)
7620     {
7621     case DW_FORM_addr:
7622     case DW_FORM_addrx:
7623     case DW_FORM_addrx1:
7624     case DW_FORM_addrx2:
7625     case DW_FORM_addrx3:
7626     case DW_FORM_addrx4:
7627     case DW_FORM_GNU_addr_index:
7628       if (!cbargs->silent)
7629 	{
7630 	  Dwarf_Addr addr;
7631 	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7632 	    {
7633 	    attrval_out:
7634 	      if (!cbargs->silent)
7635 		error (0, 0, _("DIE [%" PRIx64 "] "
7636 				      "cannot get attribute '%s' (%s) value: "
7637 				      "%s"),
7638 		       dwarf_dieoffset (die),
7639 		       dwarf_attr_name (attr),
7640 		       dwarf_form_name (form),
7641 		       dwarf_errmsg (-1));
7642 	      /* Don't ABORT, it might be other attributes can be resolved.  */
7643 	      return DWARF_CB_OK;
7644 	    }
7645 	  if (form != DW_FORM_addr )
7646 	    {
7647 	      Dwarf_Word word;
7648 	      if (dwarf_formudata (attrp, &word) != 0)
7649 		goto attrval_out;
7650 	      printf ("           %*s%-20s (%s) [%" PRIx64 "] ",
7651 		      (int) (level * 2), "", dwarf_attr_name (attr),
7652 		      dwarf_form_name (form), word);
7653 	    }
7654 	  else
7655 	    printf ("           %*s%-20s (%s) ",
7656 		    (int) (level * 2), "", dwarf_attr_name (attr),
7657 		    dwarf_form_name (form));
7658 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7659 	  printf ("\n");
7660 	}
7661       break;
7662 
7663     case DW_FORM_indirect:
7664     case DW_FORM_strp:
7665     case DW_FORM_line_strp:
7666     case DW_FORM_strx:
7667     case DW_FORM_strx1:
7668     case DW_FORM_strx2:
7669     case DW_FORM_strx3:
7670     case DW_FORM_strx4:
7671     case DW_FORM_string:
7672     case DW_FORM_GNU_strp_alt:
7673     case DW_FORM_GNU_str_index:
7674       if (cbargs->silent)
7675 	break;
7676       const char *str = dwarf_formstring (attrp);
7677       if (unlikely (str == NULL))
7678 	goto attrval_out;
7679       printf ("           %*s%-20s (%s) \"%s\"\n",
7680 	      (int) (level * 2), "", dwarf_attr_name (attr),
7681 	      dwarf_form_name (form), str);
7682       break;
7683 
7684     case DW_FORM_ref_addr:
7685     case DW_FORM_ref_udata:
7686     case DW_FORM_ref8:
7687     case DW_FORM_ref4:
7688     case DW_FORM_ref2:
7689     case DW_FORM_ref1:
7690     case DW_FORM_GNU_ref_alt:
7691     case DW_FORM_ref_sup4:
7692     case DW_FORM_ref_sup8:
7693       if (cbargs->silent)
7694 	break;
7695       Dwarf_Die ref;
7696       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7697 	goto attrval_out;
7698 
7699       printf ("           %*s%-20s (%s) ",
7700 	      (int) (level * 2), "", dwarf_attr_name (attr),
7701 	      dwarf_form_name (form));
7702       if (is_split)
7703 	printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7704       else
7705 	printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7706       break;
7707 
7708     case DW_FORM_ref_sig8:
7709       if (cbargs->silent)
7710 	break;
7711       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
7712 	      (int) (level * 2), "", dwarf_attr_name (attr),
7713 	      dwarf_form_name (form),
7714 	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7715       break;
7716 
7717     case DW_FORM_sec_offset:
7718     case DW_FORM_rnglistx:
7719     case DW_FORM_loclistx:
7720     case DW_FORM_implicit_const:
7721     case DW_FORM_udata:
7722     case DW_FORM_sdata:
7723     case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7724     case DW_FORM_data4:
7725     case DW_FORM_data2:
7726     case DW_FORM_data1:;
7727       Dwarf_Word num;
7728       if (unlikely (dwarf_formudata (attrp, &num) != 0))
7729 	goto attrval_out;
7730 
7731       const char *valuestr = NULL;
7732       bool as_hex_id = false;
7733       switch (attr)
7734 	{
7735 	  /* This case can take either a constant or a loclistptr.  */
7736 	case DW_AT_data_member_location:
7737 	  if (form != DW_FORM_sec_offset
7738 	      && (cbargs->version >= 4
7739 		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7740 	    {
7741 	      if (!cbargs->silent)
7742 		printf ("           %*s%-20s (%s) %" PRIuMAX "\n",
7743 			(int) (level * 2), "", dwarf_attr_name (attr),
7744 			dwarf_form_name (form), (uintmax_t) num);
7745 	      return DWARF_CB_OK;
7746 	    }
7747 	  FALLTHROUGH;
7748 
7749 	/* These cases always take a loclist[ptr] and no constant. */
7750 	case DW_AT_location:
7751 	case DW_AT_data_location:
7752 	case DW_AT_vtable_elem_location:
7753 	case DW_AT_string_length:
7754 	case DW_AT_use_location:
7755 	case DW_AT_frame_base:
7756 	case DW_AT_return_addr:
7757 	case DW_AT_static_link:
7758 	case DW_AT_segment:
7759 	case DW_AT_GNU_call_site_value:
7760 	case DW_AT_GNU_call_site_data_value:
7761 	case DW_AT_GNU_call_site_target:
7762 	case DW_AT_GNU_call_site_target_clobbered:
7763 	case DW_AT_GNU_locviews:
7764 	  {
7765 	    bool nlpt;
7766 	    if (cbargs->cu->version < 5)
7767 	      {
7768 		if (! cbargs->is_split)
7769 		  {
7770 		    nlpt = notice_listptr (section_loc, &known_locsptr,
7771 					   cbargs->addrsize,
7772 					   cbargs->offset_size,
7773 					   cbargs->cu, num, attr);
7774 		  }
7775 		else
7776 		  nlpt = true;
7777 	      }
7778 	    else
7779 	      {
7780 		/* Only register for a real section offset.  Otherwise
7781 		   it is a DW_FORM_loclistx which is just an index
7782 		   number and we should already have registered the
7783 		   section offset for the index when we saw the
7784 		   DW_AT_loclists_base CU attribute.  */
7785 		if (form == DW_FORM_sec_offset)
7786 		  nlpt = notice_listptr (section_loc, &known_loclistsptr,
7787 					 cbargs->addrsize, cbargs->offset_size,
7788 					 cbargs->cu, num, attr);
7789 		else
7790 		  nlpt = true;
7791 
7792 	      }
7793 
7794 	    if (!cbargs->silent)
7795 	      {
7796 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7797 		  printf ("           %*s%-20s (%s) location list [%6"
7798 			  PRIxMAX "]%s\n",
7799 			  (int) (level * 2), "", dwarf_attr_name (attr),
7800 			  dwarf_form_name (form), (uintmax_t) num,
7801 			  nlpt ? "" : " <WARNING offset too big>");
7802 		else
7803 		  printf ("           %*s%-20s (%s) location index [%6"
7804 			  PRIxMAX "]\n",
7805 			  (int) (level * 2), "", dwarf_attr_name (attr),
7806 			  dwarf_form_name (form), (uintmax_t) num);
7807 	      }
7808 	  }
7809 	  return DWARF_CB_OK;
7810 
7811 	case DW_AT_loclists_base:
7812 	  {
7813 	    bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7814                                         cbargs->addrsize, cbargs->offset_size,
7815                                         cbargs->cu, num, attr);
7816 
7817 	    if (!cbargs->silent)
7818 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7819 		      (int) (level * 2), "", dwarf_attr_name (attr),
7820 		      dwarf_form_name (form), (uintmax_t) num,
7821 		      nlpt ? "" : " <WARNING offset too big>");
7822 	  }
7823 	  return DWARF_CB_OK;
7824 
7825 	case DW_AT_ranges:
7826 	case DW_AT_start_scope:
7827 	  {
7828 	    bool nlpt;
7829 	    if (cbargs->cu->version < 5)
7830 	      nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7831 				     cbargs->addrsize, cbargs->offset_size,
7832 				     cbargs->cu, num, attr);
7833 	    else
7834 	      {
7835 		/* Only register for a real section offset.  Otherwise
7836 		   it is a DW_FORM_rangelistx which is just an index
7837 		   number and we should already have registered the
7838 		   section offset for the index when we saw the
7839 		   DW_AT_rnglists_base CU attribute.  */
7840 		if (form == DW_FORM_sec_offset)
7841 		  nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7842 					 cbargs->addrsize, cbargs->offset_size,
7843 					 cbargs->cu, num, attr);
7844 		else
7845 		  nlpt = true;
7846 	      }
7847 
7848 	    if (!cbargs->silent)
7849 	      {
7850 		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7851 		  printf ("           %*s%-20s (%s) range list [%6"
7852 			  PRIxMAX "]%s\n",
7853 			  (int) (level * 2), "", dwarf_attr_name (attr),
7854 			  dwarf_form_name (form), (uintmax_t) num,
7855 			  nlpt ? "" : " <WARNING offset too big>");
7856 		else
7857 		  printf ("           %*s%-20s (%s) range index [%6"
7858 			  PRIxMAX "]\n",
7859 			  (int) (level * 2), "", dwarf_attr_name (attr),
7860 			  dwarf_form_name (form), (uintmax_t) num);
7861 	      }
7862 	  }
7863 	  return DWARF_CB_OK;
7864 
7865 	case DW_AT_rnglists_base:
7866 	  {
7867 	    bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7868 					cbargs->addrsize, cbargs->offset_size,
7869 					cbargs->cu, num, attr);
7870 	    if (!cbargs->silent)
7871 	      printf ("           %*s%-20s (%s) range list [%6"
7872 		      PRIxMAX "]%s\n",
7873 		      (int) (level * 2), "", dwarf_attr_name (attr),
7874 		      dwarf_form_name (form), (uintmax_t) num,
7875 		      nlpt ? "" : " <WARNING offset too big>");
7876 	  }
7877 	  return DWARF_CB_OK;
7878 
7879 	case DW_AT_addr_base:
7880 	case DW_AT_GNU_addr_base:
7881 	  {
7882 	    bool addrbase = notice_listptr (section_addr, &known_addrbases,
7883 					    cbargs->addrsize,
7884 					    cbargs->offset_size,
7885 					    cbargs->cu, num, attr);
7886 	    if (!cbargs->silent)
7887 	      printf ("           %*s%-20s (%s) address base [%6"
7888 		      PRIxMAX "]%s\n",
7889 		      (int) (level * 2), "", dwarf_attr_name (attr),
7890 		      dwarf_form_name (form), (uintmax_t) num,
7891 		      addrbase ? "" : " <WARNING offset too big>");
7892 	  }
7893 	  return DWARF_CB_OK;
7894 
7895 	case DW_AT_str_offsets_base:
7896 	  {
7897 	    bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7898 					      cbargs->addrsize,
7899 					      cbargs->offset_size,
7900 					      cbargs->cu, num, attr);
7901 	    if (!cbargs->silent)
7902 	      printf ("           %*s%-20s (%s) str offsets base [%6"
7903 		      PRIxMAX "]%s\n",
7904 		      (int) (level * 2), "", dwarf_attr_name (attr),
7905 		      dwarf_form_name (form), (uintmax_t) num,
7906 		      stroffbase ? "" : " <WARNING offset too big>");
7907 	  }
7908 	  return DWARF_CB_OK;
7909 
7910 	case DW_AT_language:
7911 	  valuestr = dwarf_lang_name (num);
7912 	  break;
7913 	case DW_AT_encoding:
7914 	  valuestr = dwarf_encoding_name (num);
7915 	  break;
7916 	case DW_AT_accessibility:
7917 	  valuestr = dwarf_access_name (num);
7918 	  break;
7919 	case DW_AT_defaulted:
7920 	  valuestr = dwarf_defaulted_name (num);
7921 	  break;
7922 	case DW_AT_visibility:
7923 	  valuestr = dwarf_visibility_name (num);
7924 	  break;
7925 	case DW_AT_virtuality:
7926 	  valuestr = dwarf_virtuality_name (num);
7927 	  break;
7928 	case DW_AT_identifier_case:
7929 	  valuestr = dwarf_identifier_case_name (num);
7930 	  break;
7931 	case DW_AT_calling_convention:
7932 	  valuestr = dwarf_calling_convention_name (num);
7933 	  break;
7934 	case DW_AT_inline:
7935 	  valuestr = dwarf_inline_name (num);
7936 	  break;
7937 	case DW_AT_ordering:
7938 	  valuestr = dwarf_ordering_name (num);
7939 	  break;
7940 	case DW_AT_decl_file:
7941 	case DW_AT_call_file:
7942 	  {
7943 	    if (cbargs->silent)
7944 	      break;
7945 
7946 	    /* Try to get the actual file, the current interface only
7947 	       gives us full paths, but we only want to show the file
7948 	       name for now.  */
7949 	    Dwarf_Die cudie;
7950 	    if (dwarf_cu_die (cbargs->cu, &cudie,
7951 			      NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7952 	      {
7953 		Dwarf_Files *files;
7954 		size_t nfiles;
7955 		if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7956 		  {
7957 		    valuestr = dwarf_filesrc (files, num, NULL, NULL);
7958 		    if (valuestr != NULL)
7959 		      {
7960 			char *filename = strrchr (valuestr, '/');
7961 			if (filename != NULL)
7962 			  valuestr = filename + 1;
7963 		      }
7964 		    else
7965 		      error (0, 0, _("invalid file (%" PRId64 "): %s"),
7966 			     num, dwarf_errmsg (-1));
7967 		  }
7968 		else
7969 		  error (0, 0, _("no srcfiles for CU [%" PRIx64 "]"),
7970 			 dwarf_dieoffset (&cudie));
7971 	      }
7972 	    else
7973 	     error (0, 0, _("couldn't get DWARF CU: %s"),
7974 		    dwarf_errmsg (-1));
7975 	    if (valuestr == NULL)
7976 	      valuestr = "???";
7977 	  }
7978 	  break;
7979 	case DW_AT_GNU_dwo_id:
7980 	  as_hex_id = true;
7981 	  break;
7982 
7983 	default:
7984 	  /* Nothing.  */
7985 	  break;
7986 	}
7987 
7988       if (cbargs->silent)
7989 	break;
7990 
7991       /* When highpc is in constant form it is relative to lowpc.
7992 	 In that case also show the address.  */
7993       Dwarf_Addr highpc;
7994       if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7995 	{
7996 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (",
7997 		  (int) (level * 2), "", dwarf_attr_name (attr),
7998 		  dwarf_form_name (form), (uintmax_t) num);
7999 	  print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
8000 	  printf (")\n");
8001 	}
8002       else
8003 	{
8004 	  if (as_hex_id)
8005 	    {
8006 	      printf ("           %*s%-20s (%s) 0x%.16" PRIx64 "\n",
8007 		      (int) (level * 2), "", dwarf_attr_name (attr),
8008 		      dwarf_form_name (form), num);
8009 	    }
8010 	  else
8011 	    {
8012 	      Dwarf_Sword snum = 0;
8013 	      bool is_signed;
8014 	      int bytes = 0;
8015 	      if (attr == DW_AT_const_value)
8016 		die_type_sign_bytes (die, &is_signed, &bytes);
8017 	      else
8018 		is_signed = (form == DW_FORM_sdata
8019 			     || form == DW_FORM_implicit_const);
8020 
8021 	      if (is_signed)
8022 		if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
8023 		  goto attrval_out;
8024 
8025 	      if (valuestr == NULL)
8026 		{
8027 		  printf ("           %*s%-20s (%s) ",
8028 			  (int) (level * 2), "", dwarf_attr_name (attr),
8029 			  dwarf_form_name (form));
8030 		}
8031 	      else
8032 		{
8033 		  printf ("           %*s%-20s (%s) %s (",
8034 			  (int) (level * 2), "", dwarf_attr_name (attr),
8035 			  dwarf_form_name (form), valuestr);
8036 		}
8037 
8038 	      switch (bytes)
8039 		{
8040 		case 1:
8041 		  if (is_signed)
8042 		    printf ("%" PRId8, (int8_t) snum);
8043 		  else
8044 		    printf ("%" PRIu8, (uint8_t) num);
8045 		  break;
8046 
8047 		case 2:
8048 		  if (is_signed)
8049 		    printf ("%" PRId16, (int16_t) snum);
8050 		  else
8051 		    printf ("%" PRIu16, (uint16_t) num);
8052 		  break;
8053 
8054 		case 4:
8055 		  if (is_signed)
8056 		    printf ("%" PRId32, (int32_t) snum);
8057 		  else
8058 		    printf ("%" PRIu32, (uint32_t) num);
8059 		  break;
8060 
8061 		case 8:
8062 		  if (is_signed)
8063 		    printf ("%" PRId64, (int64_t) snum);
8064 		  else
8065 		    printf ("%" PRIu64, (uint64_t) num);
8066 		  break;
8067 
8068 		default:
8069 		  if (is_signed)
8070 		    printf ("%" PRIdMAX, (intmax_t) snum);
8071 		  else
8072 		    printf ("%" PRIuMAX, (uintmax_t) num);
8073 		  break;
8074 		}
8075 
8076 	      /* Make clear if we switched from a signed encoding to
8077 		 an unsigned value.  */
8078 	      if (attr == DW_AT_const_value
8079 		  && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
8080 		  && !is_signed)
8081 		printf (" (%" PRIdMAX ")", (intmax_t) num);
8082 
8083 	      if (valuestr == NULL)
8084 		printf ("\n");
8085 	      else
8086 		printf (")\n");
8087 	    }
8088 	}
8089       break;
8090 
8091     case DW_FORM_flag:
8092       if (cbargs->silent)
8093 	break;
8094       bool flag;
8095       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
8096 	goto attrval_out;
8097 
8098       printf ("           %*s%-20s (%s) %s\n",
8099 	      (int) (level * 2), "", dwarf_attr_name (attr),
8100 	      dwarf_form_name (form), flag ? yes_str : no_str);
8101       break;
8102 
8103     case DW_FORM_flag_present:
8104       if (cbargs->silent)
8105 	break;
8106       printf ("           %*s%-20s (%s) %s\n",
8107 	      (int) (level * 2), "", dwarf_attr_name (attr),
8108 	      dwarf_form_name (form), yes_str);
8109       break;
8110 
8111     case DW_FORM_exprloc:
8112     case DW_FORM_block4:
8113     case DW_FORM_block2:
8114     case DW_FORM_block1:
8115     case DW_FORM_block:
8116     case DW_FORM_data16: /* DWARF5 calls this a constant class.  */
8117       if (cbargs->silent)
8118 	break;
8119       Dwarf_Block block;
8120       if (unlikely (dwarf_formblock (attrp, &block) != 0))
8121 	goto attrval_out;
8122 
8123       printf ("           %*s%-20s (%s) ",
8124 	      (int) (level * 2), "", dwarf_attr_name (attr),
8125 	      dwarf_form_name (form));
8126 
8127       switch (attr)
8128 	{
8129 	default:
8130 	  if (form != DW_FORM_exprloc)
8131 	    {
8132 	      print_block (block.length, block.data);
8133 	      break;
8134 	    }
8135 	  FALLTHROUGH;
8136 
8137 	case DW_AT_location:
8138 	case DW_AT_data_location:
8139 	case DW_AT_data_member_location:
8140 	case DW_AT_vtable_elem_location:
8141 	case DW_AT_string_length:
8142 	case DW_AT_use_location:
8143 	case DW_AT_frame_base:
8144 	case DW_AT_return_addr:
8145 	case DW_AT_static_link:
8146 	case DW_AT_allocated:
8147 	case DW_AT_associated:
8148 	case DW_AT_bit_size:
8149 	case DW_AT_bit_offset:
8150 	case DW_AT_bit_stride:
8151 	case DW_AT_byte_size:
8152 	case DW_AT_byte_stride:
8153 	case DW_AT_count:
8154 	case DW_AT_lower_bound:
8155 	case DW_AT_upper_bound:
8156 	case DW_AT_GNU_call_site_value:
8157 	case DW_AT_GNU_call_site_data_value:
8158 	case DW_AT_GNU_call_site_target:
8159 	case DW_AT_GNU_call_site_target_clobbered:
8160 	  if (form == DW_FORM_exprloc
8161 	      || (form != DW_FORM_data16
8162 		  && attrp->cu->version < 4)) /* blocks were expressions.  */
8163 	    {
8164 	      putchar ('\n');
8165 	      print_ops (cbargs->dwflmod, cbargs->dbg,
8166 			 12 + level * 2, 12 + level * 2,
8167 			 cbargs->version, cbargs->addrsize, cbargs->offset_size,
8168 			 attrp->cu, block.length, block.data);
8169 	    }
8170 	  else
8171 	    print_block (block.length, block.data);
8172 	  break;
8173 
8174 	case DW_AT_discr_list:
8175 	  if (block.length == 0)
8176 	    puts ("<default>");
8177 	  else if (form != DW_FORM_data16)
8178 	    {
8179 	      const unsigned char *readp = block.data;
8180 	      const unsigned char *readendp = readp + block.length;
8181 
8182 	      /* See if we are dealing with a signed or unsigned
8183 		 values.  If the parent of this variant DIE is a
8184 		 variant_part then it will either have a discriminant
8185 		 which points to the member which type is the
8186 		 discriminant type.  Or the variant_part itself has a
8187 		 type representing the discriminant.  */
8188 	      bool is_signed = false;
8189 	      if (level > 0)
8190 		{
8191 		  Dwarf_Die *parent = &cbargs->dies[level - 1];
8192 		  if (dwarf_tag (die) == DW_TAG_variant
8193 		      && dwarf_tag (parent) == DW_TAG_variant_part)
8194 		    {
8195 		      Dwarf_Die member;
8196 		      Dwarf_Attribute discr_attr;
8197 		      int bytes;
8198 		      if (dwarf_formref_die (dwarf_attr (parent,
8199 							 DW_AT_discr,
8200 							 &discr_attr),
8201 					     &member) != NULL)
8202 			die_type_sign_bytes (&member, &is_signed, &bytes);
8203 		      else
8204 			die_type_sign_bytes (parent, &is_signed, &bytes);
8205 		    }
8206 		}
8207 	      while (readp < readendp)
8208 		{
8209 		  int d = (int) *readp++;
8210 		  printf ("%s ", dwarf_discr_list_name (d));
8211 		  if (readp >= readendp)
8212 		    goto attrval_out;
8213 
8214 		  Dwarf_Word val;
8215 		  Dwarf_Sword sval;
8216 		  if (d == DW_DSC_label)
8217 		    {
8218 		      if (is_signed)
8219 			{
8220 			  get_sleb128 (sval, readp, readendp);
8221 			  printf ("%" PRId64 "", sval);
8222 			}
8223 		      else
8224 			{
8225 			  get_uleb128 (val, readp, readendp);
8226 			  printf ("%" PRIu64 "", val);
8227 			}
8228 		    }
8229 		  else if (d == DW_DSC_range)
8230 		    {
8231 		      if (is_signed)
8232 			{
8233 			  get_sleb128 (sval, readp, readendp);
8234 			  printf ("%" PRId64 "..", sval);
8235 			  if (readp >= readendp)
8236 			    goto attrval_out;
8237 			  get_sleb128 (sval, readp, readendp);
8238 			  printf ("%" PRId64 "", sval);
8239 			}
8240 		      else
8241 			{
8242 			  get_uleb128 (val, readp, readendp);
8243 			  printf ("%" PRIu64 "..", val);
8244 			  if (readp >= readendp)
8245 			    goto attrval_out;
8246 			  get_uleb128 (val, readp, readendp);
8247 			  printf ("%" PRIu64 "", val);
8248 			}
8249 		    }
8250 		  else
8251 		    {
8252 		      print_block (readendp - readp, readp);
8253 		      break;
8254 		    }
8255 		  if (readp < readendp)
8256 		    printf (", ");
8257 		}
8258 	      putchar ('\n');
8259 	    }
8260 	  else
8261 	    print_block (block.length, block.data);
8262 	  break;
8263 	}
8264       break;
8265 
8266     default:
8267       if (cbargs->silent)
8268 	break;
8269       printf ("           %*s%-20s (%s) ???\n",
8270 	      (int) (level * 2), "", dwarf_attr_name (attr),
8271 	      dwarf_form_name (form));
8272       break;
8273     }
8274 
8275   return DWARF_CB_OK;
8276 }
8277 
8278 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)8279 print_debug_units (Dwfl_Module *dwflmod,
8280 		   Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
8281 		   Elf_Scn *scn, GElf_Shdr *shdr,
8282 		   Dwarf *dbg, bool debug_types)
8283 {
8284   const bool silent = !(print_debug_sections & section_info) && !debug_types;
8285   const char *secname = section_name (ebl, shdr);
8286 
8287   /* Check section actually exists.  */
8288   if (!silent)
8289     if (get_debug_elf_data (dbg, ebl,
8290 			    debug_types ? IDX_debug_types : IDX_debug_info,
8291 			    scn) == NULL)
8292       return;
8293 
8294   if (!silent)
8295     printf (_("\
8296 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
8297 	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
8298 
8299   /* If the section is empty we don't have to do anything.  */
8300   if (!silent && shdr->sh_size == 0)
8301     return;
8302 
8303   int maxdies = 20;
8304   Dwarf_Die *dies = xmalloc (maxdies * sizeof (Dwarf_Die));
8305 
8306   /* New compilation unit.  */
8307   Dwarf_Half version;
8308 
8309   Dwarf_Die result;
8310   Dwarf_Off abbroffset;
8311   uint8_t addrsize;
8312   uint8_t offsize;
8313   uint64_t unit_id;
8314   Dwarf_Off subdie_off;
8315 
8316   int unit_res;
8317   Dwarf_CU *cu;
8318   Dwarf_CU cu_mem;
8319   uint8_t unit_type;
8320   Dwarf_Die cudie;
8321 
8322   /* We cheat a little because we want to see only the CUs from .debug_info
8323      or .debug_types.  We know the Dwarf_CU struct layout.  Set it up at
8324      the end of .debug_info if we want .debug_types only.  Check the returned
8325      Dwarf_CU is still in the expected section.  */
8326   if (debug_types)
8327     {
8328       cu_mem.dbg = dbg;
8329       cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
8330       cu_mem.sec_idx = IDX_debug_info;
8331       cu = &cu_mem;
8332     }
8333   else
8334     cu = NULL;
8335 
8336  next_cu:
8337   unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
8338 			      &cudie, NULL);
8339   if (unit_res == 1)
8340     goto do_return;
8341 
8342   if (unit_res == -1)
8343     {
8344       if (!silent)
8345 	error (0, 0, _("cannot get next unit: %s"), dwarf_errmsg (-1));
8346       goto do_return;
8347     }
8348 
8349   if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
8350     goto do_return;
8351 
8352   dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
8353 		&unit_id, &subdie_off);
8354 
8355   if (!silent)
8356     {
8357       Dwarf_Off offset = cu->start;
8358       if (debug_types && version < 5)
8359 	{
8360 	  Dwarf_Die typedie;
8361 	  Dwarf_Off dieoffset;
8362 	  dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, cu->start
8363 							   + subdie_off,
8364 							   &typedie));
8365 	  printf (_(" Type unit at offset %" PRIu64 ":\n"
8366 			   " Version: %" PRIu16
8367 			   ", Abbreviation section offset: %" PRIu64
8368 			   ", Address size: %" PRIu8
8369 			   ", Offset size: %" PRIu8
8370 			   "\n Type signature: %#" PRIx64
8371 			   ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
8372 		  (uint64_t) offset, version, abbroffset, addrsize, offsize,
8373 		  unit_id, (uint64_t) subdie_off, dieoffset);
8374 	}
8375       else
8376 	{
8377 	  printf (_(" Compilation unit at offset %" PRIu64 ":\n"
8378 			   " Version: %" PRIu16
8379 			   ", Abbreviation section offset: %" PRIu64
8380 			   ", Address size: %" PRIu8
8381 			   ", Offset size: %" PRIu8 "\n"),
8382 		  (uint64_t) offset, version, abbroffset, addrsize, offsize);
8383 
8384 	  if (version >= 5 || (unit_type != DW_UT_compile
8385 			       && unit_type != DW_UT_partial))
8386 	    {
8387 	      printf (_(" Unit type: %s (%" PRIu8 ")"),
8388 			       dwarf_unit_name (unit_type), unit_type);
8389 	      if (unit_type == DW_UT_type
8390 		  || unit_type == DW_UT_skeleton
8391 		  || unit_type == DW_UT_split_compile
8392 		  || unit_type == DW_UT_split_type)
8393 		printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
8394 	      if (unit_type == DW_UT_type
8395 		  || unit_type == DW_UT_split_type)
8396 		{
8397 		  Dwarf_Die typedie;
8398 		  Dwarf_Off dieoffset;
8399 		  dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
8400 				 NULL, NULL, NULL);
8401 		  dieoffset = dwarf_dieoffset (&typedie);
8402 		  printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
8403 			  subdie_off, dieoffset);
8404 		}
8405 	      printf ("\n");
8406 	    }
8407 	}
8408     }
8409 
8410   if (version < 2 || version > 5
8411       || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
8412     {
8413       if (!silent)
8414 	error (0, 0, _("unknown version (%d) or unit type (%d)"),
8415 	       version, unit_type);
8416       goto next_cu;
8417     }
8418 
8419   struct attrcb_args args =
8420     {
8421       .dwflmod = dwflmod,
8422       .silent = silent,
8423       .version = version,
8424       .addrsize = addrsize,
8425       .offset_size = offsize
8426     };
8427 
8428   bool is_split = false;
8429   int level = 0;
8430   dies[0] = cudie;
8431   args.cu = dies[0].cu;
8432   args.dbg = dbg;
8433   args.is_split = is_split;
8434 
8435   /* We might return here again for the split CU subdie.  */
8436   do_cu:
8437   do
8438     {
8439       Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
8440       if (unlikely (offset == (Dwarf_Off) -1))
8441 	{
8442 	  if (!silent)
8443 	    error (0, 0, _("cannot get DIE offset: %s"),
8444 		   dwarf_errmsg (-1));
8445 	  goto do_return;
8446 	}
8447 
8448       int tag = dwarf_tag (&dies[level]);
8449       if (unlikely (tag == DW_TAG_invalid))
8450 	{
8451 	  if (!silent)
8452 	    error (0, 0, _("cannot get tag of DIE at offset [%" PRIx64
8453 				  "] in section '%s': %s"),
8454 		   (uint64_t) offset, secname, dwarf_errmsg (-1));
8455 	  goto do_return;
8456 	}
8457 
8458       if (!silent)
8459 	{
8460 	  unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
8461 	  if (is_split)
8462 	    printf (" {%6" PRIx64 "}  ", (uint64_t) offset);
8463 	  else
8464 	    printf (" [%6" PRIx64 "]  ", (uint64_t) offset);
8465 	  printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
8466 		  dwarf_tag_name (tag), code);
8467 	}
8468 
8469       /* Print the attribute values.  */
8470       args.level = level;
8471       args.dies = dies;
8472       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
8473 
8474       /* Make room for the next level's DIE.  */
8475       if (level + 1 == maxdies)
8476 	dies = xrealloc (dies, (maxdies += 10) * sizeof (Dwarf_Die));
8477 
8478       int res = dwarf_child (&dies[level], &dies[level + 1]);
8479       if (res > 0)
8480 	{
8481 	  while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
8482 	    if (level-- == 0)
8483 	      break;
8484 
8485 	  if (unlikely (res == -1))
8486 	    {
8487 	      if (!silent)
8488 		error (0, 0, _("cannot get next DIE: %s\n"),
8489 		       dwarf_errmsg (-1));
8490 	      goto do_return;
8491 	    }
8492 	}
8493       else if (unlikely (res < 0))
8494 	{
8495 	  if (!silent)
8496 	    error (0, 0, _("cannot get next DIE: %s"),
8497 		   dwarf_errmsg (-1));
8498 	  goto do_return;
8499 	}
8500       else
8501 	++level;
8502     }
8503   while (level >= 0);
8504 
8505   /* We might want to show the split compile unit if this was a skeleton.
8506      We need to scan it if we are requesting printing .debug_ranges for
8507      DWARF4 since GNU DebugFission uses "offsets" into the main ranges
8508      section.  */
8509   if (unit_type == DW_UT_skeleton
8510       && ((!silent && show_split_units)
8511 	  || (version < 5 && (print_debug_sections & section_ranges) != 0)))
8512     {
8513       Dwarf_Die subdie;
8514       if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
8515 	  || dwarf_tag (&subdie) == DW_TAG_invalid)
8516 	{
8517 	  if (!silent)
8518 	    {
8519 	      Dwarf_Attribute dwo_at;
8520 	      const char *dwo_name =
8521 		(dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
8522 					       &dwo_at))
8523 		 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
8524 						   &dwo_at))
8525 		     ?: "<unknown>"));
8526 	      fprintf (stderr,
8527 		       "Could not find split unit '%s', id: %" PRIx64 "\n",
8528 		       dwo_name, unit_id);
8529 	    }
8530 	}
8531       else
8532 	{
8533 	  Dwarf_CU *split_cu = subdie.cu;
8534 	  dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
8535 			&addrsize, &offsize, &unit_id, &subdie_off);
8536 	  Dwarf_Off offset = cu->start;
8537 
8538 	  if (!silent)
8539 	    {
8540 	      printf (_(" Split compilation unit at offset %"
8541 			       PRIu64 ":\n"
8542 			       " Version: %" PRIu16
8543 			       ", Abbreviation section offset: %" PRIu64
8544 			       ", Address size: %" PRIu8
8545 			       ", Offset size: %" PRIu8 "\n"),
8546 		      (uint64_t) offset, version, abbroffset,
8547 		      addrsize, offsize);
8548 	      printf (_(" Unit type: %s (%" PRIu8 ")"),
8549 		      dwarf_unit_name (unit_type), unit_type);
8550 	      printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
8551 	      printf ("\n");
8552 	    }
8553 
8554 	  unit_type = DW_UT_split_compile;
8555 	  is_split = true;
8556 	  level = 0;
8557 	  dies[0] = subdie;
8558 	  args.cu = dies[0].cu;
8559 	  args.dbg = split_cu->dbg;
8560 	  args.is_split = is_split;
8561 	  goto do_cu;
8562 	}
8563     }
8564 
8565   /* And again... */
8566   goto next_cu;
8567 
8568  do_return:
8569   free (dies);
8570 }
8571 
8572 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8573 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8574 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8575 {
8576   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
8577 }
8578 
8579 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8580 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8581 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8582 {
8583   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
8584 }
8585 
8586 
8587 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8588 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
8589 			    GElf_Ehdr *ehdr __attribute__ ((unused)),
8590 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8591 {
8592   printf (_("\
8593 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
8594 	  elf_ndxscn (scn), section_name (ebl, shdr),
8595 	  (uint64_t) shdr->sh_offset);
8596 
8597   size_t address_size
8598     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8599 
8600   Dwarf_Lines *lines;
8601   size_t nlines;
8602   Dwarf_Off off, next_off = 0;
8603   Dwarf_CU *cu = NULL;
8604   while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
8605 			   &lines, &nlines) == 0)
8606     {
8607       Dwarf_Die cudie;
8608       if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8609 				       NULL, NULL, NULL, NULL) == 0)
8610 	printf (" CU [%" PRIx64 "] %s\n",
8611 		dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8612       else
8613 	{
8614 	  /* DWARF5 lines can be independent of any CU, but they probably
8615 	     are used by some CU.  Determine the CU this block is for.  */
8616 	  Dwarf_Off cuoffset;
8617 	  Dwarf_Off ncuoffset = 0;
8618 	  size_t hsize;
8619 	  while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8620 			       NULL, NULL, NULL) == 0)
8621 	    {
8622 	      if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8623 		continue;
8624 	      Dwarf_Attribute stmt_list;
8625 	      if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8626 		continue;
8627 	      Dwarf_Word lineoff;
8628 	      if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8629 		continue;
8630 	      if (lineoff == off)
8631 		{
8632 		  /* Found the CU.  */
8633 		  cu = cudie.cu;
8634 		  break;
8635 		}
8636 	    }
8637 
8638 	  if (cu != NULL)
8639 	    printf (" CU [%" PRIx64 "] %s\n",
8640 		    dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8641 	  else
8642 	    printf (" No CU\n");
8643 	}
8644 
8645       printf ("  line:col SBPE* disc isa op address"
8646 	      " (Statement Block Prologue Epilogue *End)\n");
8647       const char *last_file = "";
8648       for (size_t n = 0; n < nlines; n++)
8649 	{
8650 	  Dwarf_Line *line = dwarf_onesrcline (lines, n);
8651 	  if (line == NULL)
8652 	    {
8653 	      printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8654 	      continue;
8655 	    }
8656 	  Dwarf_Word mtime, length;
8657 	  const char *file = dwarf_linesrc (line, &mtime, &length);
8658 	  if (file == NULL)
8659 	    {
8660 	      printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8661 	      last_file = "";
8662 	    }
8663 	  else if (strcmp (last_file, file) != 0)
8664 	    {
8665 	      printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8666 		      file, mtime, length);
8667 	      last_file = file;
8668 	    }
8669 
8670 	  int lineno, colno;
8671 	  bool statement, endseq, block, prologue_end, epilogue_begin;
8672 	  unsigned int lineop, isa, disc;
8673 	  Dwarf_Addr address;
8674 	  dwarf_lineaddr (line, &address);
8675 	  dwarf_lineno (line, &lineno);
8676 	  dwarf_linecol (line, &colno);
8677 	  dwarf_lineop_index (line, &lineop);
8678 	  dwarf_linebeginstatement (line, &statement);
8679 	  dwarf_lineendsequence (line, &endseq);
8680 	  dwarf_lineblock (line, &block);
8681 	  dwarf_lineprologueend (line, &prologue_end);
8682 	  dwarf_lineepiloguebegin (line, &epilogue_begin);
8683 	  dwarf_lineisa (line, &isa);
8684 	  dwarf_linediscriminator (line, &disc);
8685 
8686 	  /* End sequence is special, it is one byte past.  */
8687 	  printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8688 		  lineno, colno,
8689 		  (statement ? 'S' : ' '),
8690 		  (block ? 'B' : ' '),
8691 		  (prologue_end ? 'P' : ' '),
8692 		  (epilogue_begin ? 'E' : ' '),
8693 		  (endseq ? '*' : ' '),
8694 		  disc, isa, lineop);
8695 	  print_dwarf_addr (dwflmod, address_size,
8696 			    address - (endseq ? 1 : 0), address);
8697 	  printf ("\n");
8698 
8699 	  if (endseq)
8700 	    printf("\n");
8701 	}
8702     }
8703 }
8704 
8705 
8706 /* Print the value of a form.
8707    Returns new value of readp, or readendp on failure.  */
8708 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)8709 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8710 		 const unsigned char *readendp, unsigned int offset_len,
8711 		 Dwarf_Off str_offsets_base)
8712 {
8713   Dwarf_Word val;
8714   unsigned char *endp;
8715   Elf_Data *data;
8716   char *str;
8717   switch (form)
8718     {
8719     case DW_FORM_data1:
8720       if (readendp - readp < 1)
8721 	{
8722 	invalid_data:
8723 	  error (0, 0, "invalid data");
8724 	  return readendp;
8725 	}
8726       val = *readp++;
8727       printf (" %" PRIx8, (unsigned int) val);
8728       break;
8729 
8730     case DW_FORM_data2:
8731       if (readendp - readp < 2)
8732 	goto invalid_data;
8733       val = read_2ubyte_unaligned_inc (dbg, readp);
8734       printf(" %" PRIx16, (unsigned int) val);
8735       break;
8736 
8737     case DW_FORM_data4:
8738       if (readendp - readp < 4)
8739 	goto invalid_data;
8740       val = read_4ubyte_unaligned_inc (dbg, readp);
8741       printf (" %" PRIx32, (unsigned int) val);
8742       break;
8743 
8744     case DW_FORM_data8:
8745       if (readendp - readp < 8)
8746 	goto invalid_data;
8747       val = read_8ubyte_unaligned_inc (dbg, readp);
8748       printf (" %" PRIx64, val);
8749       break;
8750 
8751     case DW_FORM_sdata:
8752       if (readendp - readp < 1)
8753 	goto invalid_data;
8754       get_sleb128 (val, readp, readendp);
8755       printf (" %" PRIx64, val);
8756       break;
8757 
8758     case DW_FORM_udata:
8759       if (readendp - readp < 1)
8760 	goto invalid_data;
8761       get_uleb128 (val, readp, readendp);
8762       printf (" %" PRIx64, val);
8763       break;
8764 
8765     case DW_FORM_block:
8766       if (readendp - readp < 1)
8767 	goto invalid_data;
8768       get_uleb128 (val, readp, readendp);
8769       if ((size_t) (readendp - readp) < val)
8770 	goto invalid_data;
8771       print_bytes (val, readp);
8772       readp += val;
8773       break;
8774 
8775     case DW_FORM_block1:
8776       if (readendp - readp < 1)
8777 	goto invalid_data;
8778       val = *readp++;
8779       if ((size_t) (readendp - readp) < val)
8780 	goto invalid_data;
8781       print_bytes (val, readp);
8782       readp += val;
8783       break;
8784 
8785     case DW_FORM_block2:
8786       if (readendp - readp < 2)
8787 	goto invalid_data;
8788       val = read_2ubyte_unaligned_inc (dbg, readp);
8789       if ((size_t) (readendp - readp) < val)
8790 	goto invalid_data;
8791       print_bytes (val, readp);
8792       readp += val;
8793       break;
8794 
8795     case DW_FORM_block4:
8796       if (readendp - readp < 4)
8797 	goto invalid_data;
8798       val = read_4ubyte_unaligned_inc (dbg, readp);
8799       if ((size_t) (readendp - readp) < val)
8800 	goto invalid_data;
8801       print_bytes (val, readp);
8802       readp += val;
8803       break;
8804 
8805     case DW_FORM_data16:
8806       if (readendp - readp < 16)
8807 	goto invalid_data;
8808       print_bytes (16, readp);
8809       readp += 16;
8810       break;
8811 
8812     case DW_FORM_flag:
8813       if (readendp - readp < 1)
8814 	goto invalid_data;
8815       val = *readp++;
8816       printf ("%s", val != 0 ? yes_str : no_str);
8817       break;
8818 
8819     case DW_FORM_string:
8820       endp = memchr (readp, '\0', readendp - readp);
8821       if (endp == NULL)
8822 	goto invalid_data;
8823       printf ("%s", readp);
8824       readp = endp + 1;
8825       break;
8826 
8827     case DW_FORM_strp:
8828     case DW_FORM_line_strp:
8829     case DW_FORM_strp_sup:
8830       if ((size_t) (readendp - readp) < offset_len)
8831 	goto invalid_data;
8832       if (offset_len == 8)
8833 	val = read_8ubyte_unaligned_inc (dbg, readp);
8834       else
8835 	val = read_4ubyte_unaligned_inc (dbg, readp);
8836       if (form == DW_FORM_strp)
8837 	data = dbg->sectiondata[IDX_debug_str];
8838       else if (form == DW_FORM_line_strp)
8839 	data = dbg->sectiondata[IDX_debug_line_str];
8840       else /* form == DW_FORM_strp_sup */
8841 	{
8842 	  Dwarf *alt = dwarf_getalt (dbg);
8843 	  data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8844 	}
8845       if (data == NULL || val >= data->d_size
8846 	  || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8847 	str = "???";
8848       else
8849 	str = (char *) data->d_buf + val;
8850       printf ("%s (%" PRIu64 ")", str, val);
8851       break;
8852 
8853     case DW_FORM_sec_offset:
8854       if ((size_t) (readendp - readp) < offset_len)
8855 	goto invalid_data;
8856       if (offset_len == 8)
8857 	val = read_8ubyte_unaligned_inc (dbg, readp);
8858       else
8859 	val = read_4ubyte_unaligned_inc (dbg, readp);
8860       printf ("[%" PRIx64 "]", val);
8861       break;
8862 
8863     case DW_FORM_strx:
8864     case DW_FORM_GNU_str_index:
8865       if (readendp - readp < 1)
8866 	goto invalid_data;
8867       get_uleb128 (val, readp, readendp);
8868     strx_val:
8869       data = dbg->sectiondata[IDX_debug_str_offsets];
8870       if (data == NULL
8871 	  || data->d_size - str_offsets_base < val)
8872 	str = "???";
8873       else
8874 	{
8875 	  const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8876 	  const unsigned char *strreadendp = data->d_buf + data->d_size;
8877 	  if ((size_t) (strreadendp - strreadp) < offset_len)
8878 	    str = "???";
8879 	  else
8880 	    {
8881 	      Dwarf_Off idx;
8882 	      if (offset_len == 8)
8883 		idx = read_8ubyte_unaligned (dbg, strreadp);
8884 	      else
8885 		idx = read_4ubyte_unaligned (dbg, strreadp);
8886 
8887 	      data = dbg->sectiondata[IDX_debug_str];
8888 	      if (data == NULL || idx >= data->d_size
8889 		  || memchr (data->d_buf + idx, '\0',
8890 			     data->d_size - idx) == NULL)
8891 		str = "???";
8892 	      else
8893 		str = (char *) data->d_buf + idx;
8894 	    }
8895 	}
8896       printf ("%s (%" PRIu64 ")", str, val);
8897       break;
8898 
8899     case DW_FORM_strx1:
8900       if (readendp - readp < 1)
8901 	goto invalid_data;
8902       val = *readp++;
8903       goto strx_val;
8904 
8905     case DW_FORM_strx2:
8906       if (readendp - readp < 2)
8907 	goto invalid_data;
8908       val = read_2ubyte_unaligned_inc (dbg, readp);
8909       goto strx_val;
8910 
8911     case DW_FORM_strx3:
8912       if (readendp - readp < 3)
8913 	goto invalid_data;
8914       val = read_3ubyte_unaligned_inc (dbg, readp);
8915       goto strx_val;
8916 
8917     case DW_FORM_strx4:
8918       if (readendp - readp < 4)
8919 	goto invalid_data;
8920       val = read_4ubyte_unaligned_inc (dbg, readp);
8921       goto strx_val;
8922 
8923     default:
8924       error (0, 0, _("unknown form: %s"), dwarf_form_name (form));
8925       return readendp;
8926     }
8927 
8928   return readp;
8929 }
8930 
8931 /* Only used via run_advance_pc() macro */
8932 static inline void
run_advance_pc(unsigned int op_advance,unsigned int minimum_instr_len,unsigned int max_ops_per_instr,unsigned int * op_addr_advance,Dwarf_Word * address,unsigned int * op_index)8933 run_advance_pc (unsigned int op_advance,
8934                 unsigned int minimum_instr_len,
8935                 unsigned int max_ops_per_instr,
8936                 unsigned int *op_addr_advance,
8937                 Dwarf_Word *address,
8938                 unsigned int *op_index)
8939 {
8940   const unsigned int advanced_op_index = (*op_index) + op_advance;
8941 
8942   *op_addr_advance = minimum_instr_len * (advanced_op_index
8943                                          / max_ops_per_instr);
8944   *address = *address + *op_addr_advance;
8945   *op_index = advanced_op_index % max_ops_per_instr;
8946 }
8947 
8948 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8949 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8950 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8951 {
8952   if (decodedline)
8953     {
8954       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8955       return;
8956     }
8957 
8958   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_line, scn);
8959   if (data == NULL)
8960     return;
8961 
8962   printf (_("\
8963 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8964 	  elf_ndxscn (scn), section_name (ebl, shdr),
8965 	  (uint64_t) shdr->sh_offset);
8966 
8967   if (shdr->sh_size == 0)
8968     return;
8969 
8970   /* There is no functionality in libdw to read the information in the
8971      way it is represented here.  Hardcode the decoder.  */
8972 
8973   const unsigned char *linep = (const unsigned char *) data->d_buf;
8974   const unsigned char *lineendp;
8975 
8976   while (linep
8977 	 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8978     {
8979       size_t start_offset = linep - (const unsigned char *) data->d_buf;
8980 
8981       printf (_("\nTable at offset %zu:\n"), start_offset);
8982 
8983       if (unlikely (linep + 4 > lineendp))
8984 	goto invalid_data;
8985       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8986       unsigned int length = 4;
8987       if (unlikely (unit_length == 0xffffffff))
8988 	{
8989 	  if (unlikely (linep + 8 > lineendp))
8990 	    {
8991 	    invalid_data:
8992 	      error (0, 0, _("invalid data in section [%zu] '%s'"),
8993 		     elf_ndxscn (scn), section_name (ebl, shdr));
8994 	      return;
8995 	    }
8996 	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8997 	  length = 8;
8998 	}
8999 
9000       /* Check whether we have enough room in the section.  */
9001       if (unlikely (unit_length > (size_t) (lineendp - linep)))
9002 	goto invalid_data;
9003       lineendp = linep + unit_length;
9004 
9005       /* The next element of the header is the version identifier.  */
9006       if ((size_t) (lineendp - linep) < 2)
9007 	goto invalid_data;
9008       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
9009 
9010       size_t address_size
9011 	= elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9012       unsigned char segment_selector_size = 0;
9013       if (version > 4)
9014 	{
9015 	  if ((size_t) (lineendp - linep) < 2)
9016 	    goto invalid_data;
9017 	  address_size = *linep++;
9018 	  segment_selector_size = *linep++;
9019 	}
9020 
9021       /* Next comes the header length.  */
9022       Dwarf_Word header_length;
9023       if (length == 4)
9024 	{
9025 	  if ((size_t) (lineendp - linep) < 4)
9026 	    goto invalid_data;
9027 	  header_length = read_4ubyte_unaligned_inc (dbg, linep);
9028 	}
9029       else
9030 	{
9031 	  if ((size_t) (lineendp - linep) < 8)
9032 	    goto invalid_data;
9033 	  header_length = read_8ubyte_unaligned_inc (dbg, linep);
9034 	}
9035 
9036       const unsigned char *header_start = linep;
9037 
9038       /* Next the minimum instruction length.  */
9039       if ((size_t) (lineendp - linep) < 1)
9040 	goto invalid_data;
9041       uint_fast8_t minimum_instr_len = *linep++;
9042 
9043       /* Next the maximum operations per instruction, in version 4 format.  */
9044       uint_fast8_t max_ops_per_instr;
9045       if (version < 4)
9046 	max_ops_per_instr = 1;
9047       else
9048 	{
9049 	  if ((size_t) (lineendp - linep) < 1)
9050 	    goto invalid_data;
9051 	  max_ops_per_instr = *linep++;
9052 	}
9053 
9054       /* We need at least 4 more bytes.  */
9055       if ((size_t) (lineendp - linep) < 4)
9056 	goto invalid_data;
9057 
9058       /* Then the flag determining the default value of the is_stmt
9059 	 register.  */
9060       uint_fast8_t default_is_stmt = *linep++;
9061 
9062       /* Now the line base.  */
9063       int_fast8_t line_base = *linep++;
9064 
9065       /* And the line range.  */
9066       uint_fast8_t line_range = *linep++;
9067 
9068       /* The opcode base.  */
9069       uint_fast8_t opcode_base = *linep++;
9070 
9071       /* Print what we got so far.  */
9072       printf (_("\n"
9073 		       " Length:                         %" PRIu64 "\n"
9074 		       " DWARF version:                  %" PRIuFAST16 "\n"
9075 		       " Prologue length:                %" PRIu64 "\n"
9076 		       " Address size:                   %zd\n"
9077 		       " Segment selector size:          %zd\n"
9078 		       " Min instruction length:         %" PRIuFAST8 "\n"
9079 		       " Max operations per instruction: %" PRIuFAST8 "\n"
9080 		       " Initial value if 'is_stmt':     %" PRIuFAST8 "\n"
9081 		       " Line base:                      %" PRIdFAST8 "\n"
9082 		       " Line range:                     %" PRIuFAST8 "\n"
9083 		       " Opcode base:                    %" PRIuFAST8 "\n"
9084 		       "\n"
9085 		       "Opcodes:\n"),
9086 	      (uint64_t) unit_length, version, (uint64_t) header_length,
9087 	      address_size, (size_t) segment_selector_size,
9088 	      minimum_instr_len, max_ops_per_instr,
9089 	      default_is_stmt, line_base,
9090 	      line_range, opcode_base);
9091 
9092       if (version < 2 || version > 5)
9093 	{
9094 	  error (0, 0, _("cannot handle .debug_line version: %u\n"),
9095 		 (unsigned int) version);
9096 	  linep = lineendp;
9097 	  continue;
9098 	}
9099 
9100       if (address_size != 4 && address_size != 8)
9101 	{
9102 	  error (0, 0, _("cannot handle address size: %u\n"),
9103 		 (unsigned int) address_size);
9104 	  linep = lineendp;
9105 	  continue;
9106 	}
9107 
9108       if (segment_selector_size != 0)
9109 	{
9110 	  error (0, 0, _("cannot handle segment selector size: %u\n"),
9111 		 (unsigned int) segment_selector_size);
9112 	  linep = lineendp;
9113 	  continue;
9114 	}
9115 
9116       if (unlikely (linep + opcode_base - 1 >= lineendp))
9117 	{
9118 	invalid_unit:
9119 	  error (0, 0,
9120 		 _("invalid data at offset %tu in section [%zu] '%s'"),
9121 		 linep - (const unsigned char *) data->d_buf,
9122 		 elf_ndxscn (scn), section_name (ebl, shdr));
9123 	  linep = lineendp;
9124 	  continue;
9125 	}
9126       int opcode_base_l10 = 1;
9127       unsigned int tmp = opcode_base;
9128       while (tmp > 10)
9129 	{
9130 	  tmp /= 10;
9131 	  ++opcode_base_l10;
9132 	}
9133       const uint8_t *standard_opcode_lengths = linep - 1;
9134       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
9135 	printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
9136 			  "  [%*" PRIuFAST8 "]  %hhu arguments\n",
9137 			  (int) linep[cnt - 1]),
9138 		opcode_base_l10, cnt, linep[cnt - 1]);
9139       linep += opcode_base - 1;
9140 
9141       if (unlikely (linep >= lineendp))
9142 	goto invalid_unit;
9143 
9144       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
9145 
9146       puts (_("\nDirectory table:"));
9147       if (version > 4)
9148 	{
9149 	  struct encpair { uint16_t desc; uint16_t form; };
9150 	  struct encpair enc[256];
9151 
9152 	  printf (_("      ["));
9153 	  if ((size_t) (lineendp - linep) < 1)
9154 	    goto invalid_data;
9155 	  unsigned char directory_entry_format_count = *linep++;
9156 	  for (int i = 0; i < directory_entry_format_count; i++)
9157 	    {
9158 	      uint16_t desc, form;
9159 	      if ((size_t) (lineendp - linep) < 1)
9160 		goto invalid_data;
9161 	      get_uleb128 (desc, linep, lineendp);
9162 	      if ((size_t) (lineendp - linep) < 1)
9163 		goto invalid_data;
9164 	      get_uleb128 (form, linep, lineendp);
9165 
9166 	      enc[i].desc = desc;
9167 	      enc[i].form = form;
9168 
9169 	      printf ("%s(%s)",
9170 		      dwarf_line_content_description_name (desc),
9171 		      dwarf_form_name (form));
9172 	      if (i + 1 < directory_entry_format_count)
9173 		printf (", ");
9174 	    }
9175 	  printf ("]\n");
9176 
9177 	  uint64_t directories_count;
9178 	  if ((size_t) (lineendp - linep) < 1)
9179             goto invalid_data;
9180 	  get_uleb128 (directories_count, linep, lineendp);
9181 
9182 	  if (directory_entry_format_count == 0
9183 	      && directories_count != 0)
9184 	    goto invalid_data;
9185 
9186 	  for (uint64_t i = 0; i < directories_count; i++)
9187 	    {
9188 	      printf (" %-5" PRIu64 " ", i);
9189 	      for (int j = 0; j < directory_entry_format_count; j++)
9190 		{
9191 		  linep = print_form_data (dbg, enc[j].form,
9192 					   linep, lineendp, length,
9193 					   str_offsets_base);
9194 		  if (j + 1 < directory_entry_format_count)
9195 		    printf (", ");
9196 		}
9197 	      printf ("\n");
9198 	      if (linep >= lineendp)
9199 		goto invalid_unit;
9200 	    }
9201 	}
9202       else
9203 	{
9204 	  while (linep < lineendp && *linep != 0)
9205 	    {
9206 	      unsigned char *endp = memchr (linep, '\0', lineendp - linep);
9207 	      if (unlikely (endp == NULL))
9208 		goto invalid_unit;
9209 
9210 	      printf (" %s\n", (char *) linep);
9211 
9212 	      linep = endp + 1;
9213 	    }
9214 	  if (linep >= lineendp || *linep != 0)
9215 	    goto invalid_unit;
9216 	  /* Skip the final NUL byte.  */
9217 	  ++linep;
9218 	}
9219 
9220       if (unlikely (linep >= lineendp))
9221 	goto invalid_unit;
9222 
9223       puts (_("\nFile name table:"));
9224       if (version > 4)
9225 	{
9226 	  struct encpair { uint16_t desc; uint16_t form; };
9227 	  struct encpair enc[256];
9228 
9229 	  printf (_("      ["));
9230 	  if ((size_t) (lineendp - linep) < 1)
9231 	    goto invalid_data;
9232 	  unsigned char file_name_format_count = *linep++;
9233 	  for (int i = 0; i < file_name_format_count; i++)
9234 	    {
9235 	      uint64_t desc, form;
9236 	      if ((size_t) (lineendp - linep) < 1)
9237 		goto invalid_data;
9238 	      get_uleb128 (desc, linep, lineendp);
9239 	      if ((size_t) (lineendp - linep) < 1)
9240 		goto invalid_data;
9241 	      get_uleb128 (form, linep, lineendp);
9242 
9243 	      if (! libdw_valid_user_form (form))
9244 		goto invalid_data;
9245 
9246 	      enc[i].desc = desc;
9247 	      enc[i].form = form;
9248 
9249 	      printf ("%s(%s)",
9250 		      dwarf_line_content_description_name (desc),
9251 		      dwarf_form_name (form));
9252 	      if (i + 1 < file_name_format_count)
9253 		printf (", ");
9254 	    }
9255 	  printf ("]\n");
9256 
9257 	  uint64_t file_name_count;
9258 	  if ((size_t) (lineendp - linep) < 1)
9259             goto invalid_data;
9260 	  get_uleb128 (file_name_count, linep, lineendp);
9261 
9262 	  if (file_name_format_count == 0
9263 	      && file_name_count != 0)
9264 	    goto invalid_data;
9265 
9266 	  for (uint64_t i = 0; i < file_name_count; i++)
9267 	    {
9268 	      printf (" %-5" PRIu64 " ", i);
9269 	      for (int j = 0; j < file_name_format_count; j++)
9270 		{
9271 		  linep = print_form_data (dbg, enc[j].form,
9272 					   linep, lineendp, length,
9273 					   str_offsets_base);
9274 		  if (j + 1 < file_name_format_count)
9275 		    printf (", ");
9276 		}
9277 	      printf ("\n");
9278 	      if (linep > lineendp)
9279 		goto invalid_unit;
9280 	    }
9281 	}
9282       else
9283 	{
9284 	  puts (_(" Entry Dir   Time      Size      Name"));
9285 	  for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
9286 	    {
9287 	      /* First comes the file name.  */
9288 	      char *fname = (char *) linep;
9289 	      unsigned char *endp = memchr (fname, '\0', lineendp - linep);
9290 	      if (unlikely (endp == NULL))
9291 		goto invalid_unit;
9292 	      linep = endp + 1;
9293 
9294 	      /* Then the index.  */
9295 	      unsigned int diridx;
9296 	      if (lineendp - linep < 1)
9297 		goto invalid_unit;
9298 	      get_uleb128 (diridx, linep, lineendp);
9299 
9300 	      /* Next comes the modification time.  */
9301 	      unsigned int mtime;
9302 	      if (lineendp - linep < 1)
9303 		goto invalid_unit;
9304 	      get_uleb128 (mtime, linep, lineendp);
9305 
9306 	      /* Finally the length of the file.  */
9307 	      unsigned int fsize;
9308 	      if (lineendp - linep < 1)
9309 		goto invalid_unit;
9310 	      get_uleb128 (fsize, linep, lineendp);
9311 
9312 	      printf (" %-5u %-5u %-9u %-9u %s\n",
9313 		      cnt, diridx, mtime, fsize, fname);
9314 	    }
9315 	  if (linep >= lineendp || *linep != '\0')
9316 	    goto invalid_unit;
9317 	  /* Skip the final NUL byte.  */
9318 	  ++linep;
9319 	}
9320 
9321       unsigned int debug_str_offset = 0;
9322       if (unlikely (linep == header_start + header_length - 4))
9323 	{
9324 	  /* CUBINs contain an unsigned 4-byte offset */
9325 	  debug_str_offset = read_4ubyte_unaligned_inc (dbg, linep);
9326 	}
9327 
9328       if (linep == lineendp)
9329 	{
9330 	  puts (_("\nNo line number statements."));
9331 	  continue;
9332 	}
9333 
9334       puts (_("\nLine number statements:"));
9335       Dwarf_Word address = 0;
9336       unsigned int op_index = 0;
9337       size_t line = 1;
9338       uint_fast8_t is_stmt = default_is_stmt;
9339 
9340       /* Apply the "operation advance" from a special opcode
9341 	 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
9342       unsigned int op_addr_advance;
9343 #define advance_pc(op_advance) run_advance_pc(op_advance, minimum_instr_len, \
9344                       max_ops_per_instr, &op_addr_advance, &address, &op_index)
9345 
9346       if (max_ops_per_instr == 0)
9347 	{
9348 	  error (0, 0,
9349 		 _("invalid maximum operations per instruction is zero"));
9350 	  linep = lineendp;
9351 	  continue;
9352 	}
9353 
9354       while (linep < lineendp)
9355 	{
9356 	  size_t offset = linep - (const unsigned char *) data->d_buf;
9357 	  unsigned int u128;
9358 	  int s128;
9359 
9360 	  /* Read the opcode.  */
9361 	  unsigned int opcode = *linep++;
9362 
9363 	  printf (" [%6" PRIx64 "]", (uint64_t)offset);
9364 	  /* Is this a special opcode?  */
9365 	  if (likely (opcode >= opcode_base))
9366 	    {
9367 	      if (unlikely (line_range == 0))
9368 		goto invalid_unit;
9369 
9370 	      /* Yes.  Handling this is quite easy since the opcode value
9371 		 is computed with
9372 
9373 		 opcode = (desired line increment - line_base)
9374 			   + (line_range * address advance) + opcode_base
9375 	      */
9376 	      int line_increment = (line_base
9377 				    + (opcode - opcode_base) % line_range);
9378 
9379 	      /* Perform the increments.  */
9380 	      line += line_increment;
9381 	      advance_pc ((opcode - opcode_base) / line_range);
9382 
9383 	      printf (_(" special opcode %u: address+%u = "),
9384 		      opcode, op_addr_advance);
9385 	      print_dwarf_addr (dwflmod, 0, address, address);
9386 	      if (op_index > 0)
9387 		printf (_(", op_index = %u, line%+d = %zu\n"),
9388 			op_index, line_increment, line);
9389 	      else
9390 		printf (_(", line%+d = %zu\n"),
9391 			line_increment, line);
9392 	    }
9393 	  else if (opcode == 0)
9394 	    {
9395 	      /* This an extended opcode.  */
9396 	      if (unlikely (linep + 2 > lineendp))
9397 		goto invalid_unit;
9398 
9399 	      /* The length.  */
9400 	      unsigned int len = *linep++;
9401 
9402 	      if (unlikely (linep + len > lineendp))
9403 		goto invalid_unit;
9404 
9405 	      /* The sub-opcode.  */
9406 	      opcode = *linep++;
9407 
9408 	      printf (_(" extended opcode %u: "), opcode);
9409 
9410 	      switch (opcode)
9411 		{
9412 		case DW_LNE_end_sequence:
9413 		  puts (_(" end of sequence"));
9414 
9415 		  /* Reset the registers we care about.  */
9416 		  address = 0;
9417 		  op_index = 0;
9418 		  line = 1;
9419 		  is_stmt = default_is_stmt;
9420 		  break;
9421 
9422 		case DW_LNE_set_address:
9423 		  op_index = 0;
9424 		  if (unlikely ((size_t) (lineendp - linep) < address_size))
9425 		    goto invalid_unit;
9426 		  if (address_size == 4)
9427 		    address = read_4ubyte_unaligned_inc (dbg, linep);
9428 		  else
9429 		    address = read_8ubyte_unaligned_inc (dbg, linep);
9430 		  {
9431 		    printf (_(" set address to "));
9432 		    print_dwarf_addr (dwflmod, 0, address, address);
9433 		    printf ("\n");
9434 		  }
9435 		  break;
9436 
9437 		case DW_LNE_define_file:
9438 		  {
9439 		    char *fname = (char *) linep;
9440 		    unsigned char *endp = memchr (linep, '\0',
9441 						  lineendp - linep);
9442 		    if (unlikely (endp == NULL))
9443 		      goto invalid_unit;
9444 		    linep = endp + 1;
9445 
9446 		    unsigned int diridx;
9447 		    if (lineendp - linep < 1)
9448 		      goto invalid_unit;
9449 		    get_uleb128 (diridx, linep, lineendp);
9450 		    Dwarf_Word mtime;
9451 		    if (lineendp - linep < 1)
9452 		      goto invalid_unit;
9453 		    get_uleb128 (mtime, linep, lineendp);
9454 		    Dwarf_Word filelength;
9455 		    if (lineendp - linep < 1)
9456 		      goto invalid_unit;
9457 		    get_uleb128 (filelength, linep, lineendp);
9458 
9459 		    printf (_("\
9460  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
9461 			    diridx, (uint64_t) mtime, (uint64_t) filelength,
9462 			    fname);
9463 		  }
9464 		  break;
9465 
9466 		case DW_LNE_set_discriminator:
9467 		  /* Takes one ULEB128 parameter, the discriminator.  */
9468 		  if (unlikely (standard_opcode_lengths[opcode] != 1
9469 				|| lineendp - linep < 1))
9470 		    goto invalid_unit;
9471 
9472 		  get_uleb128 (u128, linep, lineendp);
9473 		  printf (_(" set discriminator to %u\n"), u128);
9474 		  break;
9475 
9476 		case DW_LNE_NVIDIA_inlined_call:
9477 		  {
9478 		    if (unlikely (linep >= lineendp))
9479 		      goto invalid_data;
9480 
9481 		    unsigned int context;
9482 		    get_uleb128 (context, linep, lineendp);
9483 
9484 		    if (unlikely (linep >= lineendp))
9485 		      goto invalid_data;
9486 
9487 		    unsigned int function_name;
9488 		    get_uleb128 (function_name, linep, lineendp);
9489 		    function_name += debug_str_offset;
9490 
9491 		    Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
9492 		    char *function_str;
9493 		    if (str_data == NULL || function_name >= str_data->d_size
9494 			|| memchr (str_data->d_buf + function_name, '\0',
9495 				   str_data->d_size - function_name) == NULL)
9496 		      function_str = "???";
9497 		    else
9498 		      function_str = (char *) str_data->d_buf + function_name;
9499 
9500 		    printf (_(" set inlined context %u,"
9501 		              " function name %s (0x%x)\n"),
9502 			    context, function_str, function_name);
9503 		    break;
9504 		  }
9505 
9506 		case DW_LNE_NVIDIA_set_function_name:
9507 		  {
9508 		    if (unlikely (linep >= lineendp))
9509 		      goto invalid_data;
9510 
9511 		    unsigned int function_name;
9512 		    get_uleb128 (function_name, linep, lineendp);
9513 		    function_name += debug_str_offset;
9514 
9515 		    Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
9516 		    char *function_str;
9517 		    if (str_data == NULL || function_name >= str_data->d_size
9518 			|| memchr (str_data->d_buf + function_name, '\0',
9519 				   str_data->d_size - function_name) == NULL)
9520 		      function_str = "???";
9521 		    else
9522 		      function_str = (char *) str_data->d_buf + function_name;
9523 
9524 		    printf (_(" set function name %s (0x%x)\n"),
9525 			    function_str, function_name);
9526 		  }
9527 		  break;
9528 
9529 		default:
9530 		  /* Unknown, ignore it.  */
9531 		  puts (_(" unknown opcode"));
9532 		  linep += len - 1;
9533 		  break;
9534 		}
9535 	    }
9536 	  else if (opcode <= DW_LNS_set_isa)
9537 	    {
9538 	      /* This is a known standard opcode.  */
9539 	      switch (opcode)
9540 		{
9541 		case DW_LNS_copy:
9542 		  /* Takes no argument.  */
9543 		  puts (_(" copy"));
9544 		  break;
9545 
9546 		case DW_LNS_advance_pc:
9547 		  /* Takes one uleb128 parameter which is added to the
9548 		     address.  */
9549 		  if (lineendp - linep < 1)
9550 		    goto invalid_unit;
9551 		  get_uleb128 (u128, linep, lineendp);
9552 		  advance_pc (u128);
9553 		  {
9554 		    printf (_(" advance address by %u to "),
9555 			    op_addr_advance);
9556 		    print_dwarf_addr (dwflmod, 0, address, address);
9557 		    if (op_index > 0)
9558 		      printf (_(", op_index to %u"), op_index);
9559 		    printf ("\n");
9560 		  }
9561 		  break;
9562 
9563 		case DW_LNS_advance_line:
9564 		  /* Takes one sleb128 parameter which is added to the
9565 		     line.  */
9566 		  if (lineendp - linep < 1)
9567 		    goto invalid_unit;
9568 		  get_sleb128 (s128, linep, lineendp);
9569 		  line += s128;
9570 		  printf (_("\
9571  advance line by constant %d to %" PRId64 "\n"),
9572 			  s128, (int64_t) line);
9573 		  break;
9574 
9575 		case DW_LNS_set_file:
9576 		  /* Takes one uleb128 parameter which is stored in file.  */
9577 		  if (lineendp - linep < 1)
9578 		    goto invalid_unit;
9579 		  get_uleb128 (u128, linep, lineendp);
9580 		  printf (_(" set file to %" PRIu64 "\n"),
9581 			  (uint64_t) u128);
9582 		  break;
9583 
9584 		case DW_LNS_set_column:
9585 		  /* Takes one uleb128 parameter which is stored in column.  */
9586 		  if (unlikely (standard_opcode_lengths[opcode] != 1
9587 				|| lineendp - linep < 1))
9588 		    goto invalid_unit;
9589 
9590 		  get_uleb128 (u128, linep, lineendp);
9591 		  printf (_(" set column to %" PRIu64 "\n"),
9592 			  (uint64_t) u128);
9593 		  break;
9594 
9595 		case DW_LNS_negate_stmt:
9596 		  /* Takes no argument.  */
9597 		  is_stmt = 1 - is_stmt;
9598 		  printf (_(" set '%s' to %" PRIuFAST8 "\n"),
9599 			  "is_stmt", is_stmt);
9600 		  break;
9601 
9602 		case DW_LNS_set_basic_block:
9603 		  /* Takes no argument.  */
9604 		  puts (_(" set basic block flag"));
9605 		  break;
9606 
9607 		case DW_LNS_const_add_pc:
9608 		  /* Takes no argument.  */
9609 
9610 		  if (unlikely (line_range == 0))
9611 		    goto invalid_unit;
9612 
9613 		  advance_pc ((255 - opcode_base) / line_range);
9614 		  {
9615 		    printf (_(" advance address by constant %u to "),
9616 			    op_addr_advance);
9617 		    print_dwarf_addr (dwflmod, 0, address, address);
9618 		    if (op_index > 0)
9619 		      printf (_(", op_index to %u"), op_index);
9620 		    printf ("\n");
9621 		  }
9622 		  break;
9623 
9624 		case DW_LNS_fixed_advance_pc:
9625 		  /* Takes one 16 bit parameter which is added to the
9626 		     address.  */
9627 		  if (unlikely (standard_opcode_lengths[opcode] != 1
9628 				|| lineendp - linep < 2))
9629 		    goto invalid_unit;
9630 
9631 		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
9632 		  address += u128;
9633 		  op_index = 0;
9634 		  {
9635 		    printf (_("\
9636  advance address by fixed value %u to \n"),
9637 			    u128);
9638 		    print_dwarf_addr (dwflmod, 0, address, address);
9639 		    printf ("\n");
9640 		  }
9641 		  break;
9642 
9643 		case DW_LNS_set_prologue_end:
9644 		  /* Takes no argument.  */
9645 		  puts (_(" set prologue end flag"));
9646 		  break;
9647 
9648 		case DW_LNS_set_epilogue_begin:
9649 		  /* Takes no argument.  */
9650 		  puts (_(" set epilogue begin flag"));
9651 		  break;
9652 
9653 		case DW_LNS_set_isa:
9654 		  /* Takes one uleb128 parameter which is stored in isa.  */
9655 		  if (unlikely (standard_opcode_lengths[opcode] != 1
9656 				|| lineendp - linep < 1))
9657 		    goto invalid_unit;
9658 
9659 		  get_uleb128 (u128, linep, lineendp);
9660 		  printf (_(" set isa to %u\n"), u128);
9661 		  break;
9662 		}
9663 	    }
9664 	  else
9665 	    {
9666 	      /* This is a new opcode the generator but not we know about.
9667 		 Read the parameters associated with it but then discard
9668 		 everything.  Read all the parameters for this opcode.  */
9669 	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
9670 				" unknown opcode with %" PRIu8 " parameters:",
9671 				standard_opcode_lengths[opcode]),
9672 		      standard_opcode_lengths[opcode]);
9673 	      for (int n = standard_opcode_lengths[opcode];
9674 		   n > 0 && linep < lineendp; --n)
9675 		{
9676 		  get_uleb128 (u128, linep, lineendp);
9677 		  if (n != standard_opcode_lengths[opcode])
9678 		    putc_unlocked (',', stdout);
9679 		  printf (" %u", u128);
9680 		}
9681 
9682 	      /* Next round, ignore this opcode.  */
9683 	      continue;
9684 	    }
9685 	}
9686     }
9687 
9688   /* There must only be one data block.  */
9689   assert (elf_getdata (scn, data) == NULL);
9690 }
9691 
9692 
9693 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9694 print_debug_loclists_section (Dwfl_Module *dwflmod,
9695 			      Ebl *ebl,
9696 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
9697 			      Elf_Scn *scn, GElf_Shdr *shdr,
9698 			      Dwarf *dbg)
9699 {
9700   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_loclists, scn);
9701   if (data == NULL)
9702     return;
9703 
9704   printf (_("\
9705 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9706 	  elf_ndxscn (scn), section_name (ebl, shdr),
9707 	  (uint64_t) shdr->sh_offset);
9708 
9709   /* For the listptr to get the base address/CU.  */
9710   sort_listptr (&known_loclistsptr, "loclistsptr");
9711   size_t listptr_idx = 0;
9712 
9713   const unsigned char *readp = data->d_buf;
9714   const unsigned char *const dataend = ((unsigned char *) data->d_buf
9715 					+ data->d_size);
9716   while (readp < dataend)
9717     {
9718       if (unlikely (readp > dataend - 4))
9719 	{
9720 	invalid_data:
9721 	  error (0, 0, _("invalid data in section [%zu] '%s'"),
9722 		 elf_ndxscn (scn), section_name (ebl, shdr));
9723 	  return;
9724 	}
9725 
9726       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9727       printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
9728 	      (uint64_t) offset);
9729 
9730       uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9731       unsigned int offset_size = 4;
9732       if (unlikely (unit_length == 0xffffffff))
9733 	{
9734 	  if (unlikely (readp > dataend - 8))
9735 	    goto invalid_data;
9736 
9737 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9738 	  offset_size = 8;
9739 	}
9740       printf (_(" Length:         %8" PRIu64 "\n"), unit_length);
9741 
9742       /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9743 	 bytes to complete the header.  And this unit cannot go beyond
9744 	 the section data.  */
9745       if (readp > dataend - 8
9746 	  || unit_length < 8
9747 	  || unit_length > (uint64_t) (dataend - readp))
9748 	goto invalid_data;
9749 
9750       const unsigned char *nexthdr = readp + unit_length;
9751 
9752       uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9753       printf (_(" DWARF version:  %8" PRIu16 "\n"), version);
9754 
9755       if (version != 5)
9756 	{
9757 	  error (0, 0, _("Unknown version"));
9758 	  goto next_table;
9759 	}
9760 
9761       uint8_t address_size = *readp++;
9762       printf (_(" Address size:   %8" PRIu64 "\n"),
9763 	      (uint64_t) address_size);
9764 
9765       if (address_size != 4 && address_size != 8)
9766 	{
9767 	  error (0, 0, _("unsupported address size"));
9768 	  goto next_table;
9769 	}
9770 
9771       uint8_t segment_size = *readp++;
9772       printf (_(" Segment size:   %8" PRIu64 "\n"),
9773 	      (uint64_t) segment_size);
9774 
9775       if (segment_size != 0)
9776         {
9777           error (0, 0, _("unsupported segment size"));
9778           goto next_table;
9779         }
9780 
9781       uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9782       printf (_(" Offset entries: %8" PRIu64 "\n"),
9783 	      (uint64_t) offset_entry_count);
9784 
9785       /* We need the CU that uses this unit to get the initial base address. */
9786       Dwarf_Addr cu_base = 0;
9787       struct Dwarf_CU *cu = NULL;
9788       if (listptr_cu (&known_loclistsptr, &listptr_idx,
9789 		      (Dwarf_Off) offset,
9790 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9791 		      &cu_base, &cu)
9792 	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
9793 	{
9794 	  Dwarf_Die cudie;
9795 	  if (dwarf_cu_die (cu, &cudie,
9796 			    NULL, NULL, NULL, NULL,
9797 			    NULL, NULL) == NULL)
9798 	    printf (_(" Unknown CU base: "));
9799 	  else
9800 	    printf (_(" CU [%6" PRIx64 "] base: "),
9801 		    dwarf_dieoffset (&cudie));
9802 	  print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9803 	  printf ("\n");
9804 	}
9805       else
9806 	printf (_(" Not associated with a CU.\n"));
9807 
9808       printf ("\n");
9809 
9810       const unsigned char *offset_array_start = readp;
9811       if (offset_entry_count > 0)
9812 	{
9813 	  uint64_t max_entries = (unit_length - 8) / offset_size;
9814 	  if (offset_entry_count > max_entries)
9815 	    {
9816 	      error (0, 0,
9817 		     _("too many offset entries for unit length"));
9818 	      offset_entry_count = max_entries;
9819 	    }
9820 
9821 	  printf (_("  Offsets starting at 0x%" PRIx64 ":\n"),
9822 		  (uint64_t) (offset_array_start
9823 			      - (unsigned char *) data->d_buf));
9824 	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9825 	    {
9826 	      printf ("   [%6" PRIu32 "] ", idx);
9827 	      if (offset_size == 4)
9828 		{
9829 		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9830 		  printf ("0x%" PRIx32 "\n", off);
9831 		}
9832 	      else
9833 		{
9834 		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9835 		  printf ("0x%" PRIx64 "\n", off);
9836 		}
9837 	    }
9838 	  printf ("\n");
9839 	}
9840 
9841       Dwarf_Addr base = cu_base;
9842       bool start_of_list = true;
9843       while (readp < nexthdr)
9844 	{
9845 	  Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf);
9846 	  if (listptr_attr (&known_loclistsptr, listptr_idx, off,
9847 			    DW_AT_GNU_locviews))
9848 	    {
9849 	      Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
9850 							&listptr_idx, off);
9851 	      const unsigned char *locp = readp;
9852 	      const unsigned char *locendp;
9853 	      if (next_off == 0
9854 		  || next_off > (size_t) (nexthdr - ((const unsigned char *)
9855 						     data->d_buf)))
9856 		locendp = nexthdr;
9857 	      else
9858 		locendp = (const unsigned char *) data->d_buf + next_off;
9859 
9860 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9861 		      (uint64_t) (readp - (unsigned char *) data->d_buf),
9862 		      (uint64_t) (readp - offset_array_start));
9863 
9864 	      while (locp < locendp)
9865 		{
9866 		  uint64_t v1, v2;
9867 		  get_uleb128 (v1, locp, locendp);
9868 		  if (locp >= locendp)
9869 		    {
9870 		      printf (_("    <INVALID DATA>\n"));
9871 		      break;
9872 		    }
9873 		  get_uleb128 (v2, locp, locendp);
9874 		  printf ("    view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9875 		}
9876 
9877 	      printf ("\n");
9878 	      readp = (unsigned char *) locendp;
9879 	      continue;
9880 	    }
9881 
9882 	  uint8_t kind = *readp++;
9883 	  uint64_t op1, op2, len;
9884 
9885 	  /* Skip padding.  */
9886 	  if (start_of_list && kind == DW_LLE_end_of_list)
9887 	    continue;
9888 
9889 	  if (start_of_list)
9890 	    {
9891 	      base = cu_base;
9892 	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9893 		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9894 		      (uint64_t) (readp - offset_array_start - 1));
9895 	      start_of_list = false;
9896 	    }
9897 
9898 	  printf ("    %s", dwarf_loc_list_encoding_name (kind));
9899 	  switch (kind)
9900 	    {
9901 	    case DW_LLE_end_of_list:
9902 	      start_of_list = true;
9903 	      printf ("\n\n");
9904 	      break;
9905 
9906 	    case DW_LLE_base_addressx:
9907 	      if ((uint64_t) (nexthdr - readp) < 1)
9908 		{
9909 		invalid_entry:
9910 		  error (0, 0, _("invalid loclists data"));
9911 		  goto next_table;
9912 		}
9913 	      get_uleb128 (op1, readp, nexthdr);
9914 	      printf (" %" PRIx64 "\n", op1);
9915 	      if (! print_unresolved_addresses)
9916 		{
9917 		  Dwarf_Addr addr;
9918 		  if (get_indexed_addr (cu, op1, &addr) != 0)
9919 		    printf ("      ???\n");
9920 		  else
9921 		    {
9922 		      printf ("      ");
9923 		      print_dwarf_addr (dwflmod, address_size, addr, addr);
9924 		      printf ("\n");
9925 		    }
9926 		}
9927 	      break;
9928 
9929 	    case DW_LLE_startx_endx:
9930 	      if ((uint64_t) (nexthdr - readp) < 1)
9931 		goto invalid_entry;
9932 	      get_uleb128 (op1, readp, nexthdr);
9933 	      if ((uint64_t) (nexthdr - readp) < 1)
9934 		goto invalid_entry;
9935 	      get_uleb128 (op2, readp, nexthdr);
9936 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9937 	      if (! print_unresolved_addresses)
9938 		{
9939 		  Dwarf_Addr addr1;
9940 		  Dwarf_Addr addr2;
9941 		  if (get_indexed_addr (cu, op1, &addr1) != 0
9942 		      || get_indexed_addr (cu, op2, &addr2) != 0)
9943 		    {
9944 		      printf ("      ???..\n");
9945 		      printf ("      ???\n");
9946 		    }
9947 		  else
9948 		    {
9949 		      printf ("      ");
9950 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9951 		      printf ("..\n      ");
9952 		      print_dwarf_addr (dwflmod, address_size,
9953 					addr2 - 1, addr2);
9954 		      printf ("\n");
9955 		    }
9956 		}
9957 	      if ((uint64_t) (nexthdr - readp) < 1)
9958 		goto invalid_entry;
9959 	      get_uleb128 (len, readp, nexthdr);
9960 	      if ((uint64_t) (nexthdr - readp) < len)
9961 		goto invalid_entry;
9962 	      print_ops (dwflmod, dbg, 8, 8, version,
9963 			 address_size, offset_size, cu, len, readp);
9964 	      readp += len;
9965 	      break;
9966 
9967 	    case DW_LLE_startx_length:
9968 	      if ((uint64_t) (nexthdr - readp) < 1)
9969 		goto invalid_entry;
9970 	      get_uleb128 (op1, readp, nexthdr);
9971 	      if ((uint64_t) (nexthdr - readp) < 1)
9972 		goto invalid_entry;
9973 	      get_uleb128 (op2, readp, nexthdr);
9974 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9975 	      if (! print_unresolved_addresses)
9976 		{
9977 		  Dwarf_Addr addr1;
9978 		  Dwarf_Addr addr2;
9979 		  if (get_indexed_addr (cu, op1, &addr1) != 0)
9980 		    {
9981 		      printf ("      ???..\n");
9982 		      printf ("      ???\n");
9983 		    }
9984 		  else
9985 		    {
9986 		      addr2 = addr1 + op2;
9987 		      printf ("      ");
9988 		      print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9989 		      printf ("..\n      ");
9990 		      print_dwarf_addr (dwflmod, address_size,
9991 					addr2 - 1, addr2);
9992 		      printf ("\n");
9993 		    }
9994 		}
9995 	      if ((uint64_t) (nexthdr - readp) < 1)
9996 		goto invalid_entry;
9997 	      get_uleb128 (len, readp, nexthdr);
9998 	      if ((uint64_t) (nexthdr - readp) < len)
9999 		goto invalid_entry;
10000 	      print_ops (dwflmod, dbg, 8, 8, version,
10001 			 address_size, offset_size, cu, len, readp);
10002 	      readp += len;
10003 	      break;
10004 
10005 	    case DW_LLE_offset_pair:
10006 	      if ((uint64_t) (nexthdr - readp) < 1)
10007 		goto invalid_entry;
10008 	      get_uleb128 (op1, readp, nexthdr);
10009 	      if ((uint64_t) (nexthdr - readp) < 1)
10010 		goto invalid_entry;
10011 	      get_uleb128 (op2, readp, nexthdr);
10012 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
10013 	      if (! print_unresolved_addresses)
10014 		{
10015 		  op1 += base;
10016 		  op2 += base;
10017 		  printf ("      ");
10018 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
10019 		  printf ("..\n      ");
10020 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
10021 		  printf ("\n");
10022 		}
10023 	      if ((uint64_t) (nexthdr - readp) < 1)
10024 		goto invalid_entry;
10025 	      get_uleb128 (len, readp, nexthdr);
10026 	      if ((uint64_t) (nexthdr - readp) < len)
10027 		goto invalid_entry;
10028 	      print_ops (dwflmod, dbg, 8, 8, version,
10029 			 address_size, offset_size, cu, len, readp);
10030 	      readp += len;
10031 	      break;
10032 
10033 	    case DW_LLE_default_location:
10034 	      if ((uint64_t) (nexthdr - readp) < 1)
10035 		goto invalid_entry;
10036 	      get_uleb128 (len, readp, nexthdr);
10037 	      if ((uint64_t) (nexthdr - readp) < len)
10038 		goto invalid_entry;
10039 	      print_ops (dwflmod, dbg, 8, 8, version,
10040 			 address_size, offset_size, cu, len, readp);
10041 	      readp += len;
10042 	      break;
10043 
10044 	    case DW_LLE_base_address:
10045 	      if (address_size == 4)
10046 		{
10047 		  if ((uint64_t) (nexthdr - readp) < 4)
10048 		    goto invalid_entry;
10049 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
10050 		}
10051 	      else
10052 		{
10053 		  if ((uint64_t) (nexthdr - readp) < 8)
10054 		    goto invalid_entry;
10055 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
10056 		}
10057 	      base = op1;
10058 	      printf (" 0x%" PRIx64 "\n", base);
10059 	      if (! print_unresolved_addresses)
10060 		{
10061 		  printf ("      ");
10062 		  print_dwarf_addr (dwflmod, address_size, base, base);
10063 		  printf ("\n");
10064 		}
10065 	      break;
10066 
10067 	    case DW_LLE_start_end:
10068 	      if (address_size == 4)
10069 		{
10070 		  if ((uint64_t) (nexthdr - readp) < 8)
10071 		    goto invalid_entry;
10072 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
10073 		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
10074 		}
10075 	      else
10076 		{
10077 		  if ((uint64_t) (nexthdr - readp) < 16)
10078 		    goto invalid_entry;
10079 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
10080 		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
10081 		}
10082 	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
10083 	      if (! print_unresolved_addresses)
10084 		{
10085 		  printf ("      ");
10086 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
10087 		  printf ("..\n      ");
10088 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
10089 		  printf ("\n");
10090 		}
10091 	      if ((uint64_t) (nexthdr - readp) < 1)
10092 		goto invalid_entry;
10093 	      get_uleb128 (len, readp, nexthdr);
10094 	      if ((uint64_t) (nexthdr - readp) < len)
10095 		goto invalid_entry;
10096 	      print_ops (dwflmod, dbg, 8, 8, version,
10097 			 address_size, offset_size, cu, len, readp);
10098 	      readp += len;
10099 	      break;
10100 
10101 	    case DW_LLE_start_length:
10102 	      if (address_size == 4)
10103 		{
10104 		  if ((uint64_t) (nexthdr - readp) < 4)
10105 		    goto invalid_entry;
10106 		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
10107 		}
10108 	      else
10109 		{
10110 		  if ((uint64_t) (nexthdr - readp) < 8)
10111 		    goto invalid_entry;
10112 		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
10113 		}
10114 	      if ((uint64_t) (nexthdr - readp) < 1)
10115 		goto invalid_entry;
10116 	      get_uleb128 (op2, readp, nexthdr);
10117 	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
10118 	      if (! print_unresolved_addresses)
10119 		{
10120 		  op2 = op1 + op2;
10121 		  printf ("      ");
10122 		  print_dwarf_addr (dwflmod, address_size, op1, op1);
10123 		  printf ("..\n      ");
10124 		  print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
10125 		  printf ("\n");
10126 		}
10127 	      if ((uint64_t) (nexthdr - readp) < 1)
10128 		goto invalid_entry;
10129 	      get_uleb128 (len, readp, nexthdr);
10130 	      if ((uint64_t) (nexthdr - readp) < len)
10131 		goto invalid_entry;
10132 	      print_ops (dwflmod, dbg, 8, 8, version,
10133 			 address_size, offset_size, cu, len, readp);
10134 	      readp += len;
10135 	      break;
10136 
10137 	    case DW_LLE_GNU_view_pair:
10138 	      if ((uint64_t) (nexthdr - readp) < 1)
10139 		goto invalid_entry;
10140 	      get_uleb128 (op1, readp, nexthdr);
10141 	      if ((uint64_t) (nexthdr - readp) < 1)
10142 		goto invalid_entry;
10143 	      get_uleb128 (op2, readp, nexthdr);
10144 	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
10145 	      break;
10146 
10147 	    default:
10148 	      goto invalid_entry;
10149 	    }
10150 	}
10151 
10152     next_table:
10153       if (readp != nexthdr)
10154 	{
10155           size_t padding = nexthdr - readp;
10156           printf (_("   %zu padding bytes\n\n"), padding);
10157 	  readp = nexthdr;
10158 	}
10159     }
10160 }
10161 
10162 
10163 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10164 print_debug_loc_section (Dwfl_Module *dwflmod,
10165 			 Ebl *ebl, GElf_Ehdr *ehdr,
10166 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10167 {
10168   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_loc, scn);
10169   if (data == NULL)
10170     return;
10171 
10172   printf (_("\
10173 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10174 	  elf_ndxscn (scn), section_name (ebl, shdr),
10175 	  (uint64_t) shdr->sh_offset);
10176 
10177   sort_listptr (&known_locsptr, "loclistptr");
10178   size_t listptr_idx = 0;
10179 
10180   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
10181   uint_fast8_t offset_size = 4;
10182 
10183   bool first = true;
10184   Dwarf_Addr base = 0;
10185   unsigned char *readp = data->d_buf;
10186   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
10187   Dwarf_CU *last_cu = NULL;
10188   while (readp < endp)
10189     {
10190       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
10191       Dwarf_CU *cu = last_cu;
10192       unsigned int attr = 0;
10193 
10194       if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
10195 				      &address_size, &offset_size, &base,
10196 				      &cu, offset, &readp, endp, &attr))
10197 	continue;
10198 
10199       if (last_cu != cu)
10200        {
10201 	Dwarf_Die cudie;
10202 	if (dwarf_cu_die (cu, &cudie,
10203 			  NULL, NULL, NULL, NULL,
10204 			  NULL, NULL) == NULL)
10205 	  printf (_("\n Unknown CU base: "));
10206 	else
10207 	  printf (_("\n CU [%6" PRIx64 "] base: "),
10208 		  dwarf_dieoffset (&cudie));
10209 	print_dwarf_addr (dwflmod, address_size, base, base);
10210 	printf ("\n");
10211        }
10212       last_cu = cu;
10213 
10214       if (attr == DW_AT_GNU_locviews)
10215 	{
10216 	  Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
10217 						    &listptr_idx, offset);
10218 	  const unsigned char *locp = readp;
10219 	  const unsigned char *locendp;
10220 	  if (next_off == 0
10221 	      || next_off > (size_t) (endp
10222 				      - (const unsigned char *) data->d_buf))
10223 	    locendp = endp;
10224 	  else
10225 	    locendp = (const unsigned char *) data->d_buf + next_off;
10226 
10227 	  while (locp < locendp)
10228 	    {
10229 	      uint64_t v1, v2;
10230 	      get_uleb128 (v1, locp, locendp);
10231 	      if (locp >= locendp)
10232 		{
10233 		  printf (_(" [%6tx]  <INVALID DATA>\n"), offset);
10234 		  break;
10235 		}
10236 	      get_uleb128 (v2, locp, locendp);
10237 	      if (first)		/* First view pair in a list.  */
10238 		printf (" [%6tx] ", offset);
10239 	      else
10240 		printf ("          ");
10241 	      printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
10242 	      first = false;
10243 	    }
10244 
10245 	  first = true;
10246 	  readp = (unsigned char *) locendp;
10247 	  continue;
10248 	}
10249 
10250       /* GNU DebugFission encoded addresses as addrx.  */
10251       bool is_debugfission = ((cu != NULL
10252 			       || split_dwarf_cu_base (dbg, &cu, &base))
10253 			      && (cu->version < 5
10254 				  && cu->unit_type == DW_UT_split_compile));
10255       if (!is_debugfission
10256 	  && unlikely (data->d_size - offset < (size_t) address_size * 2))
10257         {
10258 	invalid_data:
10259 	  printf (_(" [%6tx]  <INVALID DATA>\n"), offset);
10260 	  break;
10261 	}
10262 
10263       Dwarf_Addr begin;
10264       Dwarf_Addr end;
10265       bool use_base = true;
10266       if (is_debugfission)
10267 	{
10268 	  const unsigned char *locp = readp;
10269 	  const unsigned char *locendp = readp + data->d_size;
10270 	  if (locp >= locendp)
10271 	    goto invalid_data;
10272 
10273 	  Dwarf_Word idx;
10274 	  unsigned char code = *locp++;
10275 	  switch (code)
10276 	    {
10277 	    case DW_LLE_GNU_end_of_list_entry:
10278 	      begin = 0;
10279 	      end = 0;
10280 	      break;
10281 
10282 	    case DW_LLE_GNU_base_address_selection_entry:
10283 	      if (locp >= locendp)
10284 		goto invalid_data;
10285 	      begin = (Dwarf_Addr) -1;
10286 	      get_uleb128 (idx, locp, locendp);
10287 	      if (get_indexed_addr (cu, idx, &end) != 0)
10288 		end = idx; /* ... */
10289 	      break;
10290 
10291 	    case DW_LLE_GNU_start_end_entry:
10292 	      if (locp >= locendp)
10293 		goto invalid_data;
10294 	      get_uleb128 (idx, locp, locendp);
10295 	      if (get_indexed_addr (cu, idx, &begin) != 0)
10296 		begin = idx; /* ... */
10297 	      if (locp >= locendp)
10298 		goto invalid_data;
10299 	      get_uleb128 (idx, locp, locendp);
10300 	      if (get_indexed_addr (cu, idx, &end) != 0)
10301 		end = idx; /* ... */
10302 	      use_base = false;
10303 	      break;
10304 
10305 	    case DW_LLE_GNU_start_length_entry:
10306 	      if (locp >= locendp)
10307 		goto invalid_data;
10308 	      get_uleb128 (idx, locp, locendp);
10309 	      if (get_indexed_addr (cu, idx, &begin) != 0)
10310 		begin = idx; /* ... */
10311 	      if (locendp - locp < 4)
10312 		goto invalid_data;
10313 	      end = read_4ubyte_unaligned_inc (dbg, locp);
10314 	      end += begin;
10315 	      use_base = false;
10316 	      break;
10317 
10318 	    default:
10319 		goto invalid_data;
10320 	    }
10321 
10322 	  readp = (unsigned char *) locp;
10323 	}
10324       else if (address_size == 8)
10325 	{
10326 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
10327 	  end = read_8ubyte_unaligned_inc (dbg, readp);
10328 	}
10329       else
10330 	{
10331 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
10332 	  end = read_4ubyte_unaligned_inc (dbg, readp);
10333 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
10334 	    begin = (Dwarf_Addr) -1l;
10335 	}
10336 
10337       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
10338 	{
10339 	  if (first)
10340 	    printf (" [%6tx] ", offset);
10341 	  else
10342 	    printf ("          ");
10343 	  puts (_("base address"));
10344 	  printf ("          ");
10345 	  print_dwarf_addr (dwflmod, address_size, end, end);
10346 	  printf ("\n");
10347 	  base = end;
10348 	  first = false;
10349 	}
10350       else if (begin == 0 && end == 0) /* End of list entry.  */
10351 	{
10352 	  if (first)
10353 	    printf (_(" [%6tx] empty list\n"), offset);
10354 	  first = true;
10355 	}
10356       else
10357 	{
10358 	  /* We have a location expression entry.  */
10359 	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
10360 
10361 	  if (first)		/* First entry in a list.  */
10362 	    printf (" [%6tx] ", offset);
10363 	  else
10364 	    printf ("          ");
10365 
10366 	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
10367 	  if (! print_unresolved_addresses)
10368 	    {
10369 	      Dwarf_Addr dab = use_base ? base + begin : begin;
10370 	      Dwarf_Addr dae = use_base ? base + end : end;
10371 	      printf ("          ");
10372 	      print_dwarf_addr (dwflmod, address_size, dab, dab);
10373 	      printf ("..\n          ");
10374 	      print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
10375 	      printf ("\n");
10376 	    }
10377 
10378 	  if (endp - readp <= (ptrdiff_t) len)
10379 	    {
10380 	      fputs (_("   <INVALID DATA>\n"), stdout);
10381 	      break;
10382 	    }
10383 
10384 	  print_ops (dwflmod, dbg, 11, 11,
10385 		     cu != NULL ? cu->version : 3,
10386 		     address_size, offset_size, cu, len, readp);
10387 
10388 	  first = false;
10389 	  readp += len;
10390 	}
10391     }
10392 }
10393 
10394 struct mac_culist
10395 {
10396   Dwarf_Die die;
10397   Dwarf_Off offset;
10398   Dwarf_Files *files;
10399   struct mac_culist *next;
10400 };
10401 
10402 
10403 static int
mac_compare(const void * p1,const void * p2)10404 mac_compare (const void *p1, const void *p2)
10405 {
10406   struct mac_culist *m1 = (struct mac_culist *) p1;
10407   struct mac_culist *m2 = (struct mac_culist *) p2;
10408 
10409   if (m1->offset < m2->offset)
10410     return -1;
10411   if (m1->offset > m2->offset)
10412     return 1;
10413   return 0;
10414 }
10415 
10416 
10417 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10418 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10419 			     Ebl *ebl,
10420 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
10421 			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10422 {
10423   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_macinfo, scn);
10424   if (data == NULL)
10425     return;
10426 
10427   printf (_("\
10428 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10429 	  elf_ndxscn (scn), section_name (ebl, shdr),
10430 	  (uint64_t) shdr->sh_offset);
10431   putc_unlocked ('\n', stdout);
10432 
10433   /* There is no function in libdw to iterate over the raw content of
10434      the section but it is easy enough to do.  */
10435 
10436   /* Get the source file information for all CUs.  */
10437   Dwarf_Off offset;
10438   Dwarf_Off ncu = 0;
10439   size_t hsize;
10440   struct mac_culist *culist = NULL;
10441   size_t nculist = 0;
10442   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10443     {
10444       Dwarf_Die cudie;
10445       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10446 	continue;
10447 
10448       Dwarf_Attribute attr;
10449       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
10450 	continue;
10451 
10452       Dwarf_Word macoff;
10453       if (dwarf_formudata (&attr, &macoff) != 0)
10454 	continue;
10455 
10456       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10457       newp->die = cudie;
10458       newp->offset = macoff;
10459       newp->files = NULL;
10460       newp->next = culist;
10461       culist = newp;
10462       ++nculist;
10463     }
10464 
10465   /* Convert the list into an array for easier consumption.  */
10466   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
10467 							 * sizeof (*cus));
10468   /* Add sentinel.  */
10469   cus[nculist].offset = data->d_size;
10470   cus[nculist].files = (Dwarf_Files *) -1l;
10471   if (nculist > 0)
10472     {
10473       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
10474 	{
10475 	  assert (cnt < nculist);
10476 	  cus[cnt] = *culist;
10477 	  culist = culist->next;
10478 	}
10479 
10480       /* Sort the array according to the offset in the .debug_macinfo
10481 	 section.  Note we keep the sentinel at the end.  */
10482       qsort (cus, nculist, sizeof (*cus), mac_compare);
10483     }
10484 
10485   const unsigned char *readp = (const unsigned char *) data->d_buf;
10486   const unsigned char *readendp = readp + data->d_size;
10487   int level = 1;
10488 
10489   while (readp < readendp)
10490     {
10491       unsigned int opcode = *readp++;
10492       unsigned int u128;
10493       unsigned int u128_2;
10494       const unsigned char *endp;
10495 
10496       switch (opcode)
10497 	{
10498 	case DW_MACINFO_define:
10499 	case DW_MACINFO_undef:
10500 	case DW_MACINFO_vendor_ext:
10501 	  /*  For the first two opcodes the parameters are
10502 		line, string
10503 	      For the latter
10504 		number, string.
10505 	      We can treat these cases together.  */
10506 	  get_uleb128 (u128, readp, readendp);
10507 
10508 	  endp = memchr (readp, '\0', readendp - readp);
10509 	  if (unlikely (endp == NULL))
10510 	    {
10511 	      printf (_("\
10512 %*s*** non-terminated string at end of section"),
10513 		      level, "");
10514 	      return;
10515 	    }
10516 
10517 	  if (opcode == DW_MACINFO_define)
10518 	    printf ("%*s#define %s, line %u\n",
10519 		    level, "", (char *) readp, u128);
10520 	  else if (opcode == DW_MACINFO_undef)
10521 	    printf ("%*s#undef %s, line %u\n",
10522 		    level, "", (char *) readp, u128);
10523 	  else
10524 	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
10525 
10526 	  readp = endp + 1;
10527 	  break;
10528 
10529 	case DW_MACINFO_start_file:
10530 	  /* The two parameters are line and file index, in this order.  */
10531 	  get_uleb128 (u128, readp, readendp);
10532 	  if (readendp - readp < 1)
10533 	    {
10534 	      printf (_("\
10535 %*s*** missing DW_MACINFO_start_file argument at end of section"),
10536 		      level, "");
10537 	      return;
10538 	    }
10539 	  get_uleb128 (u128_2, readp, readendp);
10540 
10541 	  /* Find the CU DIE for this file.  */
10542 	  size_t macoff = readp - (const unsigned char *) data->d_buf;
10543 	  const char *fname = "???";
10544 	  if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
10545 	    {
10546 	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
10547 		++cus;
10548 
10549 	      if (cus[0].files == NULL
10550 		  && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
10551 		cus[0].files = (Dwarf_Files *) -1l;
10552 
10553 	      if (cus[0].files != (Dwarf_Files *) -1l)
10554 		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
10555 			 ?: "???");
10556 	    }
10557 
10558 	  printf ("%*sstart_file %u, [%u] %s\n",
10559 		  level, "", u128, u128_2, fname);
10560 	  ++level;
10561 	  break;
10562 
10563 	case DW_MACINFO_end_file:
10564 	  --level;
10565 	  printf ("%*send_file\n", level, "");
10566 	  /* Nothing more to do.  */
10567 	  break;
10568 
10569 	default:
10570 	  // XXX gcc seems to generate files with a trailing zero.
10571 	  if (unlikely (opcode != 0 || readp != readendp))
10572 	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
10573 	  break;
10574 	}
10575     }
10576 }
10577 
10578 
10579 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10580 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10581 			   Ebl *ebl,
10582 			   GElf_Ehdr *ehdr __attribute__ ((unused)),
10583 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10584 {
10585   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_macro, scn);
10586   if (data == NULL)
10587     return;
10588 
10589   printf (_("\
10590 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10591 	  elf_ndxscn (scn), section_name (ebl, shdr),
10592 	  (uint64_t) shdr->sh_offset);
10593   putc_unlocked ('\n', stdout);
10594 
10595   /* Get the source file information for all CUs.  Uses same
10596      datastructure as macinfo.  But uses offset field to directly
10597      match .debug_line offset.  And just stored in a list.  */
10598   Dwarf_Off offset;
10599   Dwarf_Off ncu = 0;
10600   size_t hsize;
10601   struct mac_culist *culist = NULL;
10602   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10603     {
10604       Dwarf_Die cudie;
10605       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10606 	continue;
10607 
10608       Dwarf_Attribute attr;
10609       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
10610 	continue;
10611 
10612       Dwarf_Word lineoff;
10613       if (dwarf_formudata (&attr, &lineoff) != 0)
10614 	continue;
10615 
10616       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10617       newp->die = cudie;
10618       newp->offset = lineoff;
10619       newp->files = NULL;
10620       newp->next = culist;
10621       culist = newp;
10622     }
10623 
10624   const unsigned char *readp = (const unsigned char *) data->d_buf;
10625   const unsigned char *readendp = readp + data->d_size;
10626 
10627   while (readp < readendp)
10628     {
10629       printf (_(" Offset:             0x%" PRIx64 "\n"),
10630 	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
10631 
10632       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
10633       // optional vendor extension macro entry table.
10634       if (readp + 2 > readendp)
10635 	{
10636 	invalid_data:
10637 	  error (0, 0, _("invalid data"));
10638 	  return;
10639 	}
10640       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
10641       printf (_(" Version:            %" PRIu16 "\n"), vers);
10642 
10643       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
10644       // 5 when it gets standardized.
10645       if (vers != 4 && vers != 5)
10646 	{
10647 	  printf (_("  unknown version, cannot parse section\n"));
10648 	  return;
10649 	}
10650 
10651       if (readp + 1 > readendp)
10652 	goto invalid_data;
10653       const unsigned char flag = *readp++;
10654       printf (_(" Flag:               0x%" PRIx8), flag);
10655       if (flag != 0)
10656 	{
10657 	  printf (" (");
10658 	  if ((flag & 0x01) != 0)
10659 	    {
10660 	      printf ("offset_size");
10661 	      if ((flag & 0xFE) !=  0)
10662 		printf (", ");
10663 	    }
10664 	  if ((flag & 0x02) != 0)
10665 	    {
10666 	      printf ("debug_line_offset");
10667 	      if ((flag & 0xFC) !=  0)
10668 		printf (", ");
10669 	    }
10670 	  if ((flag & 0x04) != 0)
10671 	    {
10672 	      printf ("operands_table");
10673 	      if ((flag & 0xF8) !=  0)
10674 		printf (", ");
10675 	    }
10676 	  if ((flag & 0xF8) != 0)
10677 	    printf ("unknown");
10678 	  printf (")");
10679 	}
10680       printf ("\n");
10681 
10682       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
10683       printf (_(" Offset length:      %" PRIu8 "\n"), offset_len);
10684       Dwarf_Off line_offset = -1;
10685       if (flag & 0x02)
10686 	{
10687 	  if (offset_len == 8)
10688 	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
10689 	  else
10690 	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
10691 	  printf (_(" .debug_line offset: 0x%" PRIx64 "\n"),
10692 		  line_offset);
10693 	}
10694 
10695       struct mac_culist *cu = NULL;
10696       if (line_offset != (Dwarf_Off) -1)
10697 	{
10698 	  cu = culist;
10699 	  while (cu != NULL && line_offset != cu->offset)
10700 	    cu = cu->next;
10701 	}
10702 
10703       Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
10704 							       ? cu->die.cu
10705 							       : NULL));
10706 
10707       const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
10708       memset (vendor, 0, sizeof vendor);
10709       if (flag & 0x04)
10710 	{
10711 	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
10712 	  // of arguments, for each argument 1 byte form code.
10713 	  if (readp + 1 > readendp)
10714 	    goto invalid_data;
10715 	  unsigned int tlen = *readp++;
10716 	  printf (_("  extension opcode table, %" PRIu8 " items:\n"),
10717 		  tlen);
10718 	  for (unsigned int i = 0; i < tlen; i++)
10719 	    {
10720 	      if (readp + 1 > readendp)
10721 		goto invalid_data;
10722 	      unsigned int opcode = *readp++;
10723 	      printf (_("    [%" PRIx8 "]"), opcode);
10724 	      if (opcode < DW_MACRO_lo_user
10725 		  || opcode > DW_MACRO_hi_user)
10726 		goto invalid_data;
10727 	      // Record the start of description for this vendor opcode.
10728 	      // uleb128 nr args, 1 byte per arg form.
10729 	      vendor[opcode - DW_MACRO_lo_user] = readp;
10730 	      if (readp + 1 > readendp)
10731 		goto invalid_data;
10732 	      unsigned int args = *readp++;
10733 	      if (args > 0)
10734 		{
10735 		  printf (_(" %" PRIu8 " arguments:"), args);
10736 		  while (args > 0)
10737 		    {
10738 		      if (readp + 1 > readendp)
10739 			goto invalid_data;
10740 		      unsigned int form = *readp++;
10741 		      printf (" %s", dwarf_form_name (form));
10742 		      if (! libdw_valid_user_form (form))
10743 			goto invalid_data;
10744 		      args--;
10745 		      if (args > 0)
10746 			putchar_unlocked (',');
10747 		    }
10748 		}
10749 	      else
10750 		printf (_(" no arguments."));
10751 	      putchar_unlocked ('\n');
10752 	    }
10753 	}
10754       putchar_unlocked ('\n');
10755 
10756       int level = 1;
10757       if (readp + 1 > readendp)
10758 	goto invalid_data;
10759       unsigned int opcode = *readp++;
10760       while (opcode != 0)
10761 	{
10762 	  unsigned int u128;
10763 	  unsigned int u128_2;
10764 	  const unsigned char *endp;
10765 	  uint64_t off;
10766 
10767           switch (opcode)
10768             {
10769             case DW_MACRO_start_file:
10770 	      get_uleb128 (u128, readp, readendp);
10771 	      if (readp >= readendp)
10772 		goto invalid_data;
10773 	      get_uleb128 (u128_2, readp, readendp);
10774 
10775 	      /* Find the CU DIE that matches this line offset.  */
10776 	      const char *fname = "???";
10777 	      if (cu != NULL)
10778 		{
10779 		  if (cu->files == NULL
10780 		      && dwarf_getsrcfiles (&cu->die, &cu->files,
10781 					    NULL) != 0)
10782 		    cu->files = (Dwarf_Files *) -1l;
10783 
10784 		  if (cu->files != (Dwarf_Files *) -1l)
10785 		    fname = (dwarf_filesrc (cu->files, u128_2,
10786 					    NULL, NULL) ?: "???");
10787 		}
10788 	      printf ("%*sstart_file %u, [%u] %s\n",
10789 		      level, "", u128, u128_2, fname);
10790 	      ++level;
10791 	      break;
10792 
10793 	    case DW_MACRO_end_file:
10794 	      --level;
10795 	      printf ("%*send_file\n", level, "");
10796 	      break;
10797 
10798 	    case DW_MACRO_define:
10799 	      get_uleb128 (u128, readp, readendp);
10800 	      endp = memchr (readp, '\0', readendp - readp);
10801 	      if (endp == NULL)
10802 		goto invalid_data;
10803 	      printf ("%*s#define %s, line %u\n",
10804 		      level, "", readp, u128);
10805 	      readp = endp + 1;
10806 	      break;
10807 
10808 	    case DW_MACRO_undef:
10809 	      get_uleb128 (u128, readp, readendp);
10810 	      endp = memchr (readp, '\0', readendp - readp);
10811 	      if (endp == NULL)
10812 		goto invalid_data;
10813 	      printf ("%*s#undef %s, line %u\n",
10814 		      level, "", readp, u128);
10815 	      readp = endp + 1;
10816 	      break;
10817 
10818 	    case DW_MACRO_define_strp:
10819 	      get_uleb128 (u128, readp, readendp);
10820 	      if (readp + offset_len > readendp)
10821 		goto invalid_data;
10822 	      if (offset_len == 8)
10823 		off = read_8ubyte_unaligned_inc (dbg, readp);
10824 	      else
10825 		off = read_4ubyte_unaligned_inc (dbg, readp);
10826 	      printf ("%*s#define %s, line %u (indirect)\n",
10827 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10828 	      break;
10829 
10830 	    case DW_MACRO_undef_strp:
10831 	      get_uleb128 (u128, readp, readendp);
10832 	      if (readp + offset_len > readendp)
10833 		goto invalid_data;
10834 	      if (offset_len == 8)
10835 		off = read_8ubyte_unaligned_inc (dbg, readp);
10836 	      else
10837 		off = read_4ubyte_unaligned_inc (dbg, readp);
10838 	      printf ("%*s#undef %s, line %u (indirect)\n",
10839 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
10840 	      break;
10841 
10842 	    case DW_MACRO_import:
10843 	      if (readp + offset_len > readendp)
10844 		goto invalid_data;
10845 	      if (offset_len == 8)
10846 		off = read_8ubyte_unaligned_inc (dbg, readp);
10847 	      else
10848 		off = read_4ubyte_unaligned_inc (dbg, readp);
10849 	      printf ("%*s#include offset 0x%" PRIx64 "\n",
10850 		      level, "", off);
10851 	      break;
10852 
10853 	    case DW_MACRO_define_sup:
10854 	      get_uleb128 (u128, readp, readendp);
10855 	      if (readp + offset_len > readendp)
10856 		goto invalid_data;
10857 	      printf ("%*s#define ", level, "");
10858 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10859 					readp, readendp, offset_len,
10860 					str_offsets_base);
10861 	      printf (", line %u (sup)\n", u128);
10862 	      break;
10863 
10864 	    case DW_MACRO_undef_sup:
10865 	      get_uleb128 (u128, readp, readendp);
10866 	      if (readp + offset_len > readendp)
10867 		goto invalid_data;
10868 	      printf ("%*s#undef ", level, "");
10869 	      readp =  print_form_data (dbg, DW_FORM_strp_sup,
10870 					readp, readendp, offset_len,
10871 					str_offsets_base);
10872 	      printf (", line %u (sup)\n", u128);
10873 	      break;
10874 
10875 	    case DW_MACRO_import_sup:
10876 	      if (readp + offset_len > readendp)
10877 		goto invalid_data;
10878 	      if (offset_len == 8)
10879 		off = read_8ubyte_unaligned_inc (dbg, readp);
10880 	      else
10881 		off = read_4ubyte_unaligned_inc (dbg, readp);
10882 	      // XXX Needs support for reading from supplementary object file.
10883 	      printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10884 		      level, "", off);
10885 	      break;
10886 
10887 	    case DW_MACRO_define_strx:
10888 	      get_uleb128 (u128, readp, readendp);
10889 	      if (readp + offset_len > readendp)
10890 		goto invalid_data;
10891 	      printf ("%*s#define ", level, "");
10892 	      readp =  print_form_data (dbg, DW_FORM_strx,
10893 					readp, readendp, offset_len,
10894 					str_offsets_base);
10895 	      printf (", line %u (strx)\n", u128);
10896 	      break;
10897 
10898 	    case DW_MACRO_undef_strx:
10899 	      get_uleb128 (u128, readp, readendp);
10900 	      if (readp + offset_len > readendp)
10901 		goto invalid_data;
10902 	      printf ("%*s#undef ", level, "");
10903 	      readp =  print_form_data (dbg, DW_FORM_strx,
10904 					readp, readendp, offset_len,
10905 					str_offsets_base);
10906 	      printf (", line %u (strx)\n", u128);
10907 	      break;
10908 
10909 	    default:
10910 	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10911 	      if (opcode < DW_MACRO_lo_user
10912 		  || opcode > DW_MACRO_lo_user
10913 		  || vendor[opcode - DW_MACRO_lo_user] == NULL)
10914 		goto invalid_data;
10915 
10916 	      const unsigned char *op_desc;
10917 	      op_desc = vendor[opcode - DW_MACRO_lo_user];
10918 
10919 	      // Just skip the arguments, we cannot really interpret them,
10920 	      // but print as much as we can.
10921 	      unsigned int args = *op_desc++;
10922 	      while (args > 0 && readp < readendp)
10923 		{
10924 		  unsigned int form = *op_desc++;
10925 		  readp = print_form_data (dbg, form, readp, readendp,
10926 					   offset_len, str_offsets_base);
10927 		  args--;
10928 		  if (args > 0)
10929 		    printf (", ");
10930 		}
10931 	      putchar_unlocked ('\n');
10932 	    }
10933 
10934 	  if (readp + 1 > readendp)
10935 	    goto invalid_data;
10936 	  opcode = *readp++;
10937 	  if (opcode == 0)
10938 	    putchar_unlocked ('\n');
10939 	}
10940     }
10941 }
10942 
10943 
10944 /* Callback for printing global names.  */
10945 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10946 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10947 		void *arg)
10948 {
10949   int *np = (int *) arg;
10950 
10951   printf (_(" [%5d] DIE offset: %6" PRId64
10952 		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10953 	  (*np)++, global->die_offset, global->cu_offset, global->name);
10954 
10955   return 0;
10956 }
10957 
10958 
10959 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
10960 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10961 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10962 			      Ebl *ebl,
10963 			      GElf_Ehdr *ehdr __attribute__ ((unused)),
10964 			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10965 {
10966   /* Check section actually exists.  */
10967   if (get_debug_elf_data (dbg, ebl, IDX_debug_pubnames, scn) == NULL)
10968       return;
10969 
10970   printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10971 	  elf_ndxscn (scn), section_name (ebl, shdr),
10972 	  (uint64_t) shdr->sh_offset);
10973 
10974   int n = 0;
10975   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10976 }
10977 
10978 /* Print the content of the DWARF string section '.debug_str'
10979    or 'debug_line_str'.  */
10980 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10981 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10982 			 Ebl *ebl,
10983 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
10984 			 Elf_Scn *scn, GElf_Shdr *shdr,
10985 			 Dwarf *dbg __attribute__ ((unused)))
10986 {
10987   const char *name = section_name (ebl, shdr);
10988   int idx = ((name != NULL && strstr (name, "debug_line_str") != NULL)
10989 	     ? IDX_debug_line_str : IDX_debug_str);
10990   Elf_Data *data = get_debug_elf_data (dbg, ebl, idx, scn);
10991   if (data == NULL)
10992     return;
10993 
10994   const size_t sh_size = data->d_size;
10995 
10996   /* Compute floor(log16(shdr->sh_size)).  */
10997   GElf_Addr tmp = sh_size;
10998   int digits = 1;
10999   while (tmp >= 16)
11000     {
11001       ++digits;
11002       tmp >>= 4;
11003     }
11004   digits = MAX (4, digits);
11005 
11006   printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
11007 		   " %*s  String\n"),
11008 	  elf_ndxscn (scn),
11009 	  section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
11010 	  /* TRANS: the debugstr| prefix makes the string unique.  */
11011 	  digits + 2, sgettext ("debugstr|Offset"));
11012 
11013   Dwarf_Off offset = 0;
11014   while (offset < sh_size)
11015     {
11016       size_t len;
11017       const char *str = (const char *) data->d_buf + offset;
11018       const char *endp = memchr (str, '\0', sh_size - offset);
11019       if (unlikely (endp == NULL))
11020 	{
11021 	  printf (_(" *** error, missing string terminator\n"));
11022 	  break;
11023 	}
11024 
11025       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
11026       len = endp - str;
11027       offset += len + 1;
11028     }
11029 }
11030 
11031 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11032 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
11033 				 Ebl *ebl,
11034 				 GElf_Ehdr *ehdr __attribute__ ((unused)),
11035 				 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11036 {
11037   Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_str_offsets, scn);
11038   if (data == NULL)
11039     return;
11040 
11041   printf (_("\
11042 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
11043 	  elf_ndxscn (scn), section_name (ebl, shdr),
11044 	  (uint64_t) shdr->sh_offset);
11045 
11046   if (shdr->sh_size == 0)
11047     return;
11048 
11049   size_t idx = 0;
11050   sort_listptr (&known_stroffbases, "str_offsets");
11051 
11052   const unsigned char *start = (const unsigned char *) data->d_buf;
11053   const unsigned char *readp = start;
11054   const unsigned char *readendp = ((const unsigned char *) data->d_buf
11055 				   + data->d_size);
11056 
11057   while (readp < readendp)
11058     {
11059       /* Most string offset tables will have a header.  For split
11060 	 dwarf unit GNU DebugFission didn't add one.  But they were
11061 	 also only defined for split units (main or skeleton units
11062 	 didn't have indirect strings).  So if we don't have a
11063 	 DW_AT_str_offsets_base at all and this is offset zero, then
11064 	 just start printing offsets immediately, if this is a .dwo
11065 	 section.  */
11066       Dwarf_Off off = (Dwarf_Off) (readp
11067 				   - (const unsigned char *) data->d_buf);
11068 
11069       printf ("Table at offset %" PRIx64 " ", off);
11070 
11071       struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
11072       const unsigned char *next_unitp = readendp;
11073       uint8_t offset_size;
11074       bool has_header;
11075       if (listptr == NULL)
11076 	{
11077 	  /* This can happen for .dwo files.  There is only an header
11078 	     in the case this is a version 5 split DWARF file.  */
11079 	  Dwarf_CU *cu;
11080 	  uint8_t unit_type;
11081 	  if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
11082 			       NULL, NULL) != 0)
11083 	    {
11084 	      error (0, 0, "Warning: Cannot find any DWARF unit.");
11085 	      /* Just guess some values.  */
11086 	      has_header = false;
11087 	      offset_size = 4;
11088 	    }
11089 	  else if (off == 0
11090 		   && (unit_type == DW_UT_split_type
11091 		       || unit_type == DW_UT_split_compile))
11092 	    {
11093 	      has_header = cu->version > 4;
11094 	      offset_size = cu->offset_size;
11095 	    }
11096 	  else
11097 	    {
11098 	      error (0, 0,
11099 		     "Warning: No CU references .debug_str_offsets after %"
11100 		     PRIx64, off);
11101 	      has_header = cu->version > 4;
11102 	      offset_size = cu->offset_size;
11103 	    }
11104 	  printf ("\n");
11105 	}
11106       else
11107 	{
11108 	  /* This must be DWARF5, since GNU DebugFission didn't define
11109 	     DW_AT_str_offsets_base.  */
11110 	  has_header = true;
11111 
11112 	  Dwarf_Die cudie;
11113 	  if (dwarf_cu_die (listptr->cu, &cudie,
11114 			    NULL, NULL, NULL, NULL,
11115 			    NULL, NULL) == NULL)
11116 	    printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
11117 	  else
11118 	    printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
11119 	}
11120 
11121       if (has_header)
11122 	{
11123 	  uint64_t unit_length;
11124 	  uint16_t version;
11125 	  uint16_t padding;
11126 
11127 	  unit_length = read_4ubyte_unaligned_inc (dbg, readp);
11128 	  if (unlikely (unit_length == 0xffffffff))
11129 	    {
11130 	      if (unlikely (readp > readendp - 8))
11131 		{
11132 		invalid_data:
11133 		  error (0, 0, "Invalid data");
11134 		  return;
11135 		}
11136 	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
11137 	      offset_size = 8;
11138 	    }
11139 	  else
11140 	    offset_size = 4;
11141 
11142 	  printf ("\n");
11143 	  printf (_(" Length:        %8" PRIu64 "\n"),
11144 		  unit_length);
11145 	  printf (_(" Offset size:   %8" PRIu8 "\n"),
11146 		  offset_size);
11147 
11148 	  /* We need at least 2-bytes (version) + 2-bytes (padding) =
11149 	     4 bytes to complete the header.  And this unit cannot go
11150 	     beyond the section data.  */
11151 	  if (readp > readendp - 4
11152 	      || unit_length < 4
11153 	      || unit_length > (uint64_t) (readendp - readp))
11154 	    goto invalid_data;
11155 
11156 	  next_unitp = readp + unit_length;
11157 
11158 	  version = read_2ubyte_unaligned_inc (dbg, readp);
11159 	  printf (_(" DWARF version: %8" PRIu16 "\n"), version);
11160 
11161 	  if (version != 5)
11162 	    {
11163 	      error (0, 0, _("Unknown version"));
11164 	      goto next_unit;
11165 	    }
11166 
11167 	  padding = read_2ubyte_unaligned_inc (dbg, readp);
11168 	  printf (_(" Padding:       %8" PRIx16 "\n"), padding);
11169 
11170 	  if (listptr != NULL
11171 	      && listptr->offset != (Dwarf_Off) (readp - start))
11172 	    {
11173 	      error (0, 0, "String offsets index doesn't start after header");
11174 	      goto next_unit;
11175 	    }
11176 
11177 	  printf ("\n");
11178 	}
11179 
11180       int digits = 1;
11181       size_t offsets = (next_unitp - readp) / offset_size;
11182       while (offsets >= 10)
11183 	{
11184 	  ++digits;
11185 	  offsets /= 10;
11186 	}
11187 
11188       unsigned int uidx = 0;
11189       size_t index_offset =  readp - (const unsigned char *) data->d_buf;
11190       printf (" Offsets start at 0x%zx:\n", index_offset);
11191       while (readp <= next_unitp - offset_size)
11192 	{
11193 	  Dwarf_Word offset;
11194 	  if (offset_size == 4)
11195 	    offset = read_4ubyte_unaligned_inc (dbg, readp);
11196 	  else
11197 	    offset = read_8ubyte_unaligned_inc (dbg, readp);
11198 	  const char *str = dwarf_getstring (dbg, offset, NULL);
11199 	  printf (" [%*u] [%*" PRIx64 "]  \"%s\"\n",
11200 		  digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
11201 	}
11202       printf ("\n");
11203 
11204       if (readp != next_unitp)
11205 	error (0, 0, "extra %zd bytes at end of unit",
11206 	       (size_t) (next_unitp - readp));
11207 
11208     next_unit:
11209       readp = next_unitp;
11210     }
11211 }
11212 
11213 
11214 /* Print the content of the call frame search table section
11215    '.eh_frame_hdr'.  */
11216 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11217 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
11218 			       Ebl *ebl __attribute__ ((unused)),
11219 			       GElf_Ehdr *ehdr __attribute__ ((unused)),
11220 			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11221 {
11222   printf (_("\
11223 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
11224 	  elf_ndxscn (scn));
11225 
11226   Elf_Data *data = elf_rawdata (scn, NULL);
11227 
11228   if (unlikely (data == NULL))
11229     {
11230       error (0, 0, _("cannot get %s content: %s"),
11231 	     ".eh_frame_hdr", elf_errmsg (-1));
11232       return;
11233     }
11234 
11235   const unsigned char *readp = data->d_buf;
11236   const unsigned char *const dataend = ((unsigned char *) data->d_buf
11237 					+ data->d_size);
11238 
11239   if (unlikely (readp + 4 > dataend))
11240     {
11241     invalid_data:
11242       error (0, 0, _("invalid data"));
11243       return;
11244     }
11245 
11246   unsigned int version = *readp++;
11247   unsigned int eh_frame_ptr_enc = *readp++;
11248   unsigned int fde_count_enc = *readp++;
11249   unsigned int table_enc = *readp++;
11250 
11251   printf (" version:          %u\n"
11252 	  " eh_frame_ptr_enc: %#x ",
11253 	  version, eh_frame_ptr_enc);
11254   print_encoding_base ("", eh_frame_ptr_enc);
11255   printf (" fde_count_enc:    %#x ", fde_count_enc);
11256   print_encoding_base ("", fde_count_enc);
11257   printf (" table_enc:        %#x ", table_enc);
11258   print_encoding_base ("", table_enc);
11259 
11260   uint64_t eh_frame_ptr = 0;
11261   if (eh_frame_ptr_enc != DW_EH_PE_omit)
11262     {
11263       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
11264 			    dbg);
11265       if (unlikely (readp == NULL))
11266 	goto invalid_data;
11267 
11268       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
11269       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
11270 	printf (" (offset: %#" PRIx64 ")",
11271 		/* +4 because of the 4 byte header of the section.  */
11272 		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
11273 
11274       putchar_unlocked ('\n');
11275     }
11276 
11277   uint64_t fde_count = 0;
11278   if (fde_count_enc != DW_EH_PE_omit)
11279     {
11280       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
11281       if (unlikely (readp == NULL))
11282 	goto invalid_data;
11283 
11284       printf (" fde_count:        %" PRIu64 "\n", fde_count);
11285     }
11286 
11287   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
11288     return;
11289 
11290   puts (" Table:");
11291 
11292   /* Optimize for the most common case.  */
11293   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
11294     while (fde_count > 0 && readp + 8 <= dataend)
11295       {
11296 	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
11297 	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
11298 				   + (int64_t) initial_location);
11299 	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
11300 	// XXX Possibly print symbol name or section offset for initial_offset
11301 	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
11302 		" fde=[%6" PRIx64 "]\n",
11303 		initial_location, initial_offset,
11304 		address, address - (eh_frame_ptr + 4));
11305       }
11306   else
11307     while (0 && readp < dataend)
11308       {
11309 
11310       }
11311 }
11312 
11313 
11314 /* Print the content of the exception handling table section
11315    '.eh_frame_hdr'.  */
11316 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11317 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
11318 			     Ebl *ebl __attribute__ ((unused)),
11319 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
11320 			     Elf_Scn *scn,
11321 			     GElf_Shdr *shdr __attribute__ ((unused)),
11322 			     Dwarf *dbg __attribute__ ((unused)))
11323 {
11324   printf (_("\
11325 \nException handling table section [%2zu] '.gcc_except_table':\n"),
11326 	  elf_ndxscn (scn));
11327 
11328   Elf_Data *data = elf_rawdata (scn, NULL);
11329 
11330   if (unlikely (data == NULL))
11331     {
11332       error (0, 0, _("cannot get %s content: %s"),
11333 	     ".gcc_except_table", elf_errmsg (-1));
11334       return;
11335     }
11336 
11337   const unsigned char *readp = data->d_buf;
11338   const unsigned char *const dataend = readp + data->d_size;
11339 
11340   if (unlikely (readp + 1 > dataend))
11341     {
11342     invalid_data:
11343       error (0, 0, _("invalid data"));
11344       return;
11345     }
11346   unsigned int lpstart_encoding = *readp++;
11347   printf (_(" LPStart encoding:    %#x "), lpstart_encoding);
11348   print_encoding_base ("", lpstart_encoding);
11349   if (lpstart_encoding != DW_EH_PE_omit)
11350     {
11351       uint64_t lpstart;
11352       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
11353       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
11354     }
11355 
11356   if (unlikely (readp + 1 > dataend))
11357     goto invalid_data;
11358   unsigned int ttype_encoding = *readp++;
11359   printf (_(" TType encoding:      %#x "), ttype_encoding);
11360   print_encoding_base ("", ttype_encoding);
11361   const unsigned char *ttype_base = NULL;
11362   if (ttype_encoding != DW_EH_PE_omit)
11363     {
11364       unsigned int ttype_base_offset;
11365       if (readp >= dataend)
11366 	goto invalid_data;
11367       get_uleb128 (ttype_base_offset, readp, dataend);
11368       printf (" TType base offset:   %#x\n", ttype_base_offset);
11369       if ((size_t) (dataend - readp) > ttype_base_offset)
11370         ttype_base = readp + ttype_base_offset;
11371     }
11372 
11373   if (unlikely (readp + 1 > dataend))
11374     goto invalid_data;
11375   unsigned int call_site_encoding = *readp++;
11376   printf (_(" Call site encoding:  %#x "), call_site_encoding);
11377   print_encoding_base ("", call_site_encoding);
11378   unsigned int call_site_table_len;
11379   if (readp >= dataend)
11380     goto invalid_data;
11381   get_uleb128 (call_site_table_len, readp, dataend);
11382 
11383   const unsigned char *const action_table = readp + call_site_table_len;
11384   if (unlikely (action_table > dataend))
11385     goto invalid_data;
11386   unsigned int u = 0;
11387   unsigned int max_action = 0;
11388   while (readp < action_table)
11389     {
11390       if (u == 0)
11391 	puts (_("\n Call site table:"));
11392 
11393       uint64_t call_site_start;
11394       readp = read_encoded (call_site_encoding, readp, dataend,
11395 			    &call_site_start, dbg);
11396       uint64_t call_site_length;
11397       readp = read_encoded (call_site_encoding, readp, dataend,
11398 			    &call_site_length, dbg);
11399       uint64_t landing_pad;
11400       readp = read_encoded (call_site_encoding, readp, dataend,
11401 			    &landing_pad, dbg);
11402       unsigned int action;
11403       if (readp >= dataend)
11404 	goto invalid_data;
11405       get_uleb128 (action, readp, dataend);
11406       max_action = MAX (action, max_action);
11407       printf (_(" [%4u] Call site start:   %#" PRIx64 "\n"
11408 		       "        Call site length:  %" PRIu64 "\n"
11409 		       "        Landing pad:       %#" PRIx64 "\n"
11410 		       "        Action:            %u\n"),
11411 	      u++, call_site_start, call_site_length, landing_pad, action);
11412     }
11413   if (readp != action_table)
11414     goto invalid_data;
11415 
11416   unsigned int max_ar_filter = 0;
11417   if (max_action > 0)
11418     {
11419       puts ("\n Action table:");
11420 
11421       size_t maxdata = (size_t) (dataend - action_table);
11422       if (max_action > maxdata || maxdata - max_action < 1)
11423 	{
11424 	invalid_action_table:
11425 	  fputs (_("   <INVALID DATA>\n"), stdout);
11426 	  return;
11427 	}
11428 
11429       const unsigned char *const action_table_end
11430 	= action_table + max_action + 1;
11431 
11432       u = 0;
11433       do
11434 	{
11435 	  int ar_filter;
11436 	  get_sleb128 (ar_filter, readp, action_table_end);
11437 	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
11438 	    max_ar_filter = ar_filter;
11439 	  int ar_disp;
11440 	  if (readp >= action_table_end)
11441 	    goto invalid_action_table;
11442 	  get_sleb128 (ar_disp, readp, action_table_end);
11443 
11444 	  printf (" [%4u] ar_filter:  % d\n"
11445 		  "        ar_disp:    % -5d",
11446 		  u, ar_filter, ar_disp);
11447 	  if (abs (ar_disp) & 1)
11448 	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
11449 	  else if (ar_disp != 0)
11450 	    puts (" -> ???");
11451 	  else
11452 	    putchar_unlocked ('\n');
11453 	  ++u;
11454 	}
11455       while (readp < action_table_end);
11456     }
11457 
11458   if (max_ar_filter > 0 && ttype_base != NULL)
11459     {
11460       unsigned char dsize;
11461       puts ("\n TType table:");
11462 
11463       // XXX Not *4, size of encoding;
11464       switch (ttype_encoding & 7)
11465 	{
11466 	case DW_EH_PE_udata2:
11467 	case DW_EH_PE_sdata2:
11468 	  dsize = 2;
11469 	  break;
11470 	case DW_EH_PE_udata4:
11471 	case DW_EH_PE_sdata4:
11472 	  dsize = 4;
11473 	  break;
11474 	case DW_EH_PE_udata8:
11475 	case DW_EH_PE_sdata8:
11476 	  dsize = 8;
11477 	  break;
11478 	default:
11479 	  dsize = 0;
11480 	  error (1, 0, _("invalid TType encoding"));
11481 	}
11482 
11483       if (max_ar_filter
11484 	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
11485 	goto invalid_data;
11486 
11487       readp = ttype_base - max_ar_filter * dsize;
11488       do
11489 	{
11490 	  uint64_t ttype;
11491 	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
11492 				dbg);
11493 	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
11494 	}
11495       while (readp < ttype_base);
11496     }
11497 }
11498 
11499 /* Print the content of the '.gdb_index' section.
11500    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
11501 */
11502 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11503 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
11504 			 GElf_Ehdr *ehdr __attribute__ ((unused)),
11505 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11506 {
11507   printf (_("\nGDB section [%2zu] '%s' at offset %#" PRIx64
11508 		   " contains %" PRId64 " bytes :\n"),
11509 	  elf_ndxscn (scn), section_name (ebl, shdr),
11510 	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
11511 
11512   Elf_Data *data = elf_rawdata (scn, NULL);
11513 
11514   if (unlikely (data == NULL))
11515     {
11516       error (0, 0, _("cannot get %s content: %s"),
11517 	     ".gdb_index", elf_errmsg (-1));
11518       return;
11519     }
11520 
11521   // .gdb_index is always in little endian.
11522   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
11523   dbg = &dummy_dbg;
11524 
11525   const unsigned char *readp = data->d_buf;
11526   const unsigned char *const dataend = readp + data->d_size;
11527 
11528   if (unlikely (readp + 4 > dataend))
11529     {
11530     invalid_data:
11531       error (0, 0, _("invalid data"));
11532       return;
11533     }
11534 
11535   int32_t vers = read_4ubyte_unaligned (dbg, readp);
11536   printf (_(" Version:         %" PRId32 "\n"), vers);
11537 
11538   // The only difference between version 4 and version 5 is the
11539   // hash used for generating the table.  Version 6 contains symbols
11540   // for inlined functions, older versions didn't.  Version 7 adds
11541   // symbol kinds.  Version 8 just indicates that it correctly includes
11542   // TUs for symbols.  Version 9 adds shortcut table for information
11543   // regarding the main function.
11544   if (vers < 4 || vers > 9)
11545     {
11546       printf (_("  unknown version, cannot parse section\n"));
11547       return;
11548     }
11549 
11550   readp += 4;
11551   if (unlikely (readp + 4 > dataend))
11552     goto invalid_data;
11553 
11554   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
11555   printf (_(" CU offset:       %#" PRIx32 "\n"), cu_off);
11556 
11557   readp += 4;
11558   if (unlikely (readp + 4 > dataend))
11559     goto invalid_data;
11560 
11561   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
11562   printf (_(" TU offset:       %#" PRIx32 "\n"), tu_off);
11563 
11564   readp += 4;
11565   if (unlikely (readp + 4 > dataend))
11566     goto invalid_data;
11567 
11568   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
11569   printf (_(" address offset:  %#" PRIx32 "\n"), addr_off);
11570 
11571   readp += 4;
11572   if (unlikely (readp + 4 > dataend))
11573     goto invalid_data;
11574 
11575   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
11576   printf (_(" symbol offset:   %#" PRIx32 "\n"), sym_off);
11577 
11578   readp += 4;
11579   if (unlikely (readp + 4 > dataend))
11580     goto invalid_data;
11581 
11582   uint32_t shortcut_off = 0;
11583   if (vers >= 9)
11584     {
11585       shortcut_off = read_4ubyte_unaligned (dbg, readp);
11586       printf (_(" shortcut offset: %#" PRIx32 "\n"), shortcut_off);
11587 
11588       readp += 4;
11589       if (unlikely (readp + 4 > dataend))
11590 	goto invalid_data;
11591     }
11592 
11593   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
11594   printf (_(" constant offset: %#" PRIx32 "\n"), const_off);
11595 
11596   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
11597 		< const_off))
11598     goto invalid_data;
11599 
11600   readp = data->d_buf + cu_off;
11601 
11602   const unsigned char *nextp = data->d_buf + tu_off;
11603   if (tu_off >= data->d_size)
11604     goto invalid_data;
11605 
11606   size_t cu_nr = (nextp - readp) / 16;
11607 
11608   printf (_("\n CU list at offset %#" PRIx32
11609 		   " contains %zu entries:\n"),
11610 	  cu_off, cu_nr);
11611 
11612   size_t n = 0;
11613   while (dataend - readp >= 16 && n < cu_nr)
11614     {
11615       uint64_t off = read_8ubyte_unaligned (dbg, readp);
11616       readp += 8;
11617 
11618       uint64_t len = read_8ubyte_unaligned (dbg, readp);
11619       readp += 8;
11620 
11621       printf (" [%4zu] start: %0#8" PRIx64
11622 	      ", length: %5" PRIu64 "\n", n, off, len);
11623       n++;
11624     }
11625 
11626   readp = data->d_buf + tu_off;
11627   nextp = data->d_buf + addr_off;
11628   if (addr_off >= data->d_size)
11629     goto invalid_data;
11630 
11631   size_t tu_nr = (nextp - readp) / 24;
11632 
11633   printf (_("\n TU list at offset %#" PRIx32
11634 		   " contains %zu entries:\n"),
11635 	  tu_off, tu_nr);
11636 
11637   n = 0;
11638   while (dataend - readp >= 24 && n < tu_nr)
11639     {
11640       uint64_t off = read_8ubyte_unaligned (dbg, readp);
11641       readp += 8;
11642 
11643       uint64_t type = read_8ubyte_unaligned (dbg, readp);
11644       readp += 8;
11645 
11646       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
11647       readp += 8;
11648 
11649       printf (" [%4zu] CU offset: %5" PRId64
11650 	      ", type offset: %5" PRId64
11651 	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
11652       n++;
11653     }
11654 
11655   readp = data->d_buf + addr_off;
11656   nextp = data->d_buf + sym_off;
11657   if (sym_off >= data->d_size)
11658     goto invalid_data;
11659 
11660   size_t addr_nr = (nextp - readp) / 20;
11661 
11662   printf (_("\n Address list at offset %#" PRIx32
11663 		   " contains %zu entries:\n"),
11664 	  addr_off, addr_nr);
11665 
11666   n = 0;
11667   while (dataend - readp >= 20 && n < addr_nr)
11668     {
11669       uint64_t low = read_8ubyte_unaligned (dbg, readp);
11670       readp += 8;
11671 
11672       uint64_t high = read_8ubyte_unaligned (dbg, readp);
11673       readp += 8;
11674 
11675       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
11676       readp += 4;
11677 
11678       printf (" [%4zu] ", n);
11679       print_dwarf_addr (dwflmod, 8, low, low);
11680       printf ("..");
11681       print_dwarf_addr (dwflmod, 8, high - 1, high);
11682       printf (", CU index: %5" PRId32 "\n", idx);
11683       n++;
11684     }
11685 
11686   const unsigned char *const_start = data->d_buf + const_off;
11687   if (const_off >= data->d_size)
11688     goto invalid_data;
11689 
11690   const unsigned char *shortcut_start = NULL;
11691   if (vers >= 9)
11692     {
11693       if (shortcut_off >= data->d_size)
11694 	goto invalid_data;
11695 
11696       shortcut_start = data->d_buf + shortcut_off;
11697       nextp = shortcut_start;
11698     }
11699   else
11700     nextp = const_start;
11701 
11702   readp = data->d_buf + sym_off;
11703   size_t sym_nr = (nextp - readp) / 8;
11704 
11705   printf (_("\n Symbol table at offset %#" PRIx32
11706 		   " contains %zu slots:\n"),
11707 	  addr_off, sym_nr);
11708 
11709   n = 0;
11710   while (dataend - readp >= 8 && n < sym_nr)
11711     {
11712       uint32_t name = read_4ubyte_unaligned (dbg, readp);
11713       readp += 4;
11714 
11715       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
11716       readp += 4;
11717 
11718       if (name != 0 || vector != 0)
11719 	{
11720 	  const unsigned char *sym = const_start + name;
11721 	  if (unlikely ((size_t) (dataend - const_start) < name
11722 			|| memchr (sym, '\0', dataend - sym) == NULL))
11723 	    goto invalid_data;
11724 
11725 	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
11726 
11727 	  const unsigned char *readcus = const_start + vector;
11728 	  if (unlikely ((size_t) (dataend - const_start) < vector))
11729 	    goto invalid_data;
11730 	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
11731 	  while (cus--)
11732 	    {
11733 	      uint32_t cu_kind, cu, kind;
11734 	      bool is_static;
11735 	      readcus += 4;
11736 	      if (unlikely (readcus + 4 > dataend))
11737 		goto invalid_data;
11738 	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
11739 	      cu = cu_kind & ((1 << 24) - 1);
11740 	      kind = (cu_kind >> 28) & 7;
11741 	      is_static = cu_kind & (1U << 31);
11742 	      if (cu > cu_nr - 1)
11743 		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
11744 	      else
11745 		printf ("%" PRId32, cu);
11746 	      if (kind != 0)
11747 		{
11748 		  printf (" (");
11749 		  switch (kind)
11750 		    {
11751 		    case 1:
11752 		      printf ("type");
11753 		      break;
11754 		    case 2:
11755 		      printf ("var");
11756 		      break;
11757 		    case 3:
11758 		      printf ("func");
11759 		      break;
11760 		    case 4:
11761 		      printf ("other");
11762 		      break;
11763 		    default:
11764 		      printf ("unknown-0x%" PRIx32, kind);
11765 		      break;
11766 		    }
11767 		  printf (":%c)", (is_static ? 'S' : 'G'));
11768 		}
11769 	      if (cus > 0)
11770 		printf (", ");
11771 	    }
11772 	  printf ("\n");
11773 	}
11774       n++;
11775     }
11776 
11777   if (vers < 9)
11778     return;
11779 
11780   if (unlikely (shortcut_start == NULL))
11781     goto invalid_data;
11782 
11783   readp = shortcut_start;
11784   nextp = const_start;
11785   size_t shortcut_nr = (nextp - readp) / 4;
11786 
11787   if (unlikely (shortcut_nr != 2))
11788     goto invalid_data;
11789 
11790   printf (_("\nShortcut table at offset %#" PRIx32 " contains %zu slots:\n"),
11791 	  shortcut_off, shortcut_nr);
11792 
11793   uint32_t lang = read_4ubyte_unaligned (dbg, readp);
11794   readp += 4;
11795 
11796   /* Include the hex number of LANG in the output if the language
11797      is unknown.  */
11798   const char *lang_str = dwarf_lang_string (lang);
11799   lang_str = string_or_unknown (lang_str, lang, DW_LANG_lo_user,
11800 				DW_LANG_hi_user, true);
11801 
11802   printf (_("Language of main: %s\n"), lang_str);
11803   printf (_("Name of main: "));
11804 
11805   if (lang != 0)
11806     {
11807       uint32_t name = read_4ubyte_unaligned (dbg, readp);
11808       readp += 4;
11809       const unsigned char *sym = const_start + name;
11810 
11811       if (unlikely ((size_t) (dataend - const_start) < name
11812 		    || memchr (sym, '\0', dataend - sym) == NULL))
11813 	goto invalid_data;
11814 
11815       printf ("%s\n", sym);
11816     }
11817   else
11818     printf ("<unknown>\n");
11819 }
11820 
11821 /* Returns true and sets split DWARF CU id if there is a split compile
11822    unit in the given Dwarf, and no non-split units are found (before it).  */
11823 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11824 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11825 {
11826   Dwarf_CU *cu = NULL;
11827   while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11828     {
11829       uint8_t unit_type;
11830       if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11831 			 id, NULL, NULL) != 0)
11832 	return false;
11833 
11834       if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11835 	return false;
11836 
11837       /* We really only care about the split compile unit, the types
11838 	 should be fine and self sufficient.  Also they don't have an
11839 	 id that we can match with a skeleton unit.  */
11840       if (unit_type == DW_UT_split_compile)
11841 	{
11842 	  *split_cu = cu;
11843 	  return true;
11844 	}
11845     }
11846 
11847   return false;
11848 }
11849 
11850 /* Check that there is one and only one Dwfl_Module, return in arg.  */
11851 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11852 getone_dwflmod (Dwfl_Module *dwflmod,
11853 	       void **userdata __attribute__ ((unused)),
11854 	       const char *name __attribute__ ((unused)),
11855 	       Dwarf_Addr base __attribute__ ((unused)),
11856 	       void *arg)
11857 {
11858   Dwfl_Module **m = (Dwfl_Module **) arg;
11859   if (*m != NULL)
11860     return DWARF_CB_ABORT;
11861   *m = dwflmod;
11862   return DWARF_CB_OK;
11863 }
11864 
11865 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11866 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11867 {
11868   /* Used for skeleton file, if necessary for split DWARF.  */
11869   Dwfl *skel_dwfl = NULL;
11870   Dwfl_Module *skel_mod = NULL;
11871   char *skel_name = NULL;
11872   Dwarf *split_dbg = NULL;
11873   Dwarf_CU *split_cu = NULL;
11874 
11875   /* Before we start the real work get a debug context descriptor.  */
11876   Dwarf_Addr dwbias;
11877   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11878   Dwarf dummy_dbg =
11879     {
11880       .elf = ebl->elf,
11881       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11882     };
11883   if (dbg == NULL)
11884     {
11885       if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
11886 	error (0, 0, _("cannot get debug context descriptor: %s"),
11887 	       dwfl_errmsg (-1));
11888       dbg = &dummy_dbg;
11889     }
11890   else
11891     {
11892       /* If we are asked about a split dwarf (.dwo) file, use the user
11893 	 provided, or find the corresponding skeleton file. If we got
11894 	 a skeleton file, replace the given dwflmod and dbg, with one
11895 	 derived from the skeleton file to provide enough context.  */
11896       uint64_t split_id;
11897       if (is_split_dwarf (dbg, &split_id, &split_cu))
11898 	{
11899 	  if (dwarf_skeleton != NULL)
11900 	    skel_name = strdup (dwarf_skeleton);
11901 	  else
11902 	    {
11903 	      /* Replace file.dwo with file.o and see if that matches. */
11904 	      const char *fname;
11905 	      dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11906 				&fname, NULL);
11907 	      if (fname != NULL)
11908 		{
11909 		  size_t flen = strlen (fname);
11910 		  if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11911 		    {
11912 		      skel_name = strdup (fname);
11913 		      if (skel_name != NULL)
11914 			{
11915 			  skel_name[flen - 3] = 'o';
11916 			  skel_name[flen - 2] = '\0';
11917 			}
11918 		    }
11919 		}
11920 	    }
11921 
11922 	  if (skel_name != NULL)
11923 	    {
11924 	      int skel_fd = open (skel_name, O_RDONLY);
11925 	      if (skel_fd == -1)
11926 		fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11927 			 " '%s'\n", skel_name);
11928 	      else
11929 		skel_dwfl = create_dwfl (skel_fd, skel_name);
11930 
11931 	      if (skel_dwfl != NULL)
11932 		{
11933 		  if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11934 				       &skel_mod, 0) != 0)
11935 		    {
11936 		      fprintf (stderr, "Warning: Bad DWARF skeleton,"
11937 			       " multiple modules '%s'\n", skel_name);
11938 		      dwfl_end (skel_dwfl);
11939 		      skel_mod = NULL;
11940 		    }
11941 		}
11942 	      else if (skel_fd != -1)
11943 		fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11944 			 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11945 
11946 	      if (skel_mod != NULL)
11947 		{
11948 		  Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11949 		  if (skel_dbg != NULL)
11950 		    {
11951 		      /* First check the skeleton CU DIE, only fetch
11952 			 the split DIE if we know the id matches to
11953 			 not unnecessary search for any split DIEs we
11954 			 don't need. */
11955 		      Dwarf_CU *cu = NULL;
11956 		      while (dwarf_get_units (skel_dbg, cu, &cu,
11957 					      NULL, NULL, NULL, NULL) == 0)
11958 			{
11959 			  uint8_t unit_type;
11960 			  uint64_t skel_id;
11961 			  if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11962 					     &skel_id, NULL, NULL) == 0
11963 			      && unit_type == DW_UT_skeleton
11964 			      && split_id == skel_id)
11965 			    {
11966 			      Dwarf_Die subdie;
11967 			      if (dwarf_cu_info (cu, NULL, NULL, NULL,
11968 						 &subdie,
11969 						 NULL, NULL, NULL) == 0
11970 				  && dwarf_tag (&subdie) != DW_TAG_invalid)
11971 				{
11972 				  split_dbg = dwarf_cu_getdwarf (subdie.cu);
11973 				  if (split_dbg == NULL)
11974 				    fprintf (stderr,
11975 					     "Warning: Couldn't get split_dbg:"
11976 					     " %s\n", dwarf_errmsg (-1));
11977 				  break;
11978 				}
11979 			      else
11980 				{
11981 				  /* Everything matches up, but not
11982 				     according to libdw. Which means
11983 				     the user knew better.  So...
11984 				     Terrible hack... We can never
11985 				     destroy the underlying dwfl
11986 				     because it would free the wrong
11987 				     Dwarfs... So we leak memory...*/
11988 				  if (cu->split == NULL
11989 				      && dwarf_skeleton != NULL)
11990 				    {
11991 				      do_not_close_dwfl = true;
11992 				      __libdw_link_skel_split (cu, split_cu);
11993 				      split_dbg = dwarf_cu_getdwarf (split_cu);
11994 				      break;
11995 				    }
11996 				  else
11997 				    fprintf (stderr, "Warning: Couldn't get"
11998 					     " skeleton subdie: %s\n",
11999 					     dwarf_errmsg (-1));
12000 				}
12001 			    }
12002 			}
12003 		      if (split_dbg == NULL)
12004 			fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
12005 		    }
12006 		  else
12007 		    fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
12008 			     " %s\n", dwfl_errmsg (-1));
12009 		}
12010 	    }
12011 
12012 	  if (split_dbg != NULL)
12013 	    {
12014 	      dbg = split_dbg;
12015 	      dwflmod = skel_mod;
12016 	    }
12017 	  else if (skel_name == NULL)
12018 	    fprintf (stderr,
12019 		     "Warning: split DWARF file, but no skeleton found.\n");
12020 	}
12021       else if (dwarf_skeleton != NULL)
12022 	fprintf (stderr, "Warning: DWARF skeleton given,"
12023 		 " but not a split DWARF file\n");
12024     }
12025 
12026   /* Get the section header string table index.  */
12027   size_t shstrndx;
12028   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12029     error_exit (0, _("cannot get section header string table index"));
12030 
12031   /* If the .debug_info section is listed as implicitly required then
12032      we must make sure to handle it before handling any other debug
12033      section.  Various other sections depend on the CU DIEs being
12034      scanned (silently) first.  */
12035   bool implicit_info = (implicit_debug_sections & section_info) != 0;
12036   bool explicit_info = (print_debug_sections & section_info) != 0;
12037   if (implicit_info)
12038     {
12039       Elf_Scn *scn = NULL;
12040       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12041 	{
12042 	  GElf_Shdr shdr_mem;
12043 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12044 
12045 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
12046 	    {
12047 	      const char *name = elf_strptr (ebl->elf, shstrndx,
12048 					     shdr->sh_name);
12049 	      if (name == NULL)
12050 		continue;
12051 
12052 	      if (strcmp (name, ".debug_info") == 0
12053 		  || strcmp (name, ".debug_info.dwo") == 0
12054 		  || strcmp (name, ".zdebug_info") == 0
12055 		  || strcmp (name, ".zdebug_info.dwo") == 0
12056 		  || strcmp (name, ".gnu.debuglto_.debug_info") == 0)
12057 		{
12058 		  print_debug_info_section (dwflmod, ebl, ehdr,
12059 					    scn, shdr, dbg);
12060 		  break;
12061 		}
12062 	    }
12063 	}
12064       print_debug_sections &= ~section_info;
12065       implicit_debug_sections &= ~section_info;
12066     }
12067 
12068   /* Look through all the sections for the debugging sections to print.  */
12069   Elf_Scn *scn = NULL;
12070   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12071     {
12072       GElf_Shdr shdr_mem;
12073       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12074 
12075       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
12076 	{
12077 	  static const struct
12078 	  {
12079 	    const char *name;
12080 	    enum section_e bitmask;
12081 	    void (*fp) (Dwfl_Module *, Ebl *,
12082 			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
12083 	  } debug_sections[] =
12084 	    {
12085 #define NEW_SECTION(name) \
12086 	      { ".debug_" #name, section_##name, print_debug_##name##_section }
12087 	      NEW_SECTION (abbrev),
12088 	      NEW_SECTION (addr),
12089 	      NEW_SECTION (aranges),
12090 	      NEW_SECTION (frame),
12091 	      NEW_SECTION (info),
12092 	      NEW_SECTION (types),
12093 	      NEW_SECTION (line),
12094 	      NEW_SECTION (loc),
12095 	      /* loclists is loc for DWARF5.  */
12096 	      { ".debug_loclists", section_loc,
12097 		print_debug_loclists_section },
12098 	      NEW_SECTION (pubnames),
12099 	      NEW_SECTION (str),
12100 	      /* A DWARF5 specialised debug string section.  */
12101 	      { ".debug_line_str", section_str,
12102 		print_debug_str_section },
12103 	      /* DWARF5 string offsets table.  */
12104 	      { ".debug_str_offsets", section_str,
12105 		print_debug_str_offsets_section },
12106 	      NEW_SECTION (macinfo),
12107 	      NEW_SECTION (macro),
12108 	      NEW_SECTION (ranges),
12109 	      /* rnglists is ranges for DWARF5.  */
12110 	      { ".debug_rnglists", section_ranges,
12111 		print_debug_rnglists_section },
12112 	      { ".eh_frame", section_frame | section_exception,
12113 		print_debug_frame_section },
12114 	      { ".eh_frame_hdr", section_frame | section_exception,
12115 		print_debug_frame_hdr_section },
12116 	      { ".gcc_except_table", section_frame | section_exception,
12117 		print_debug_exception_table },
12118 	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
12119 	    };
12120 	  const int ndebug_sections = (sizeof (debug_sections)
12121 				       / sizeof (debug_sections[0]));
12122 	  const char *name = elf_strptr (ebl->elf, shstrndx,
12123 					 shdr->sh_name);
12124 	  if (name == NULL)
12125 	    continue;
12126 
12127 	  int n;
12128 	  for (n = 0; n < ndebug_sections; ++n)
12129 	    {
12130 	      size_t dbglen = strlen (debug_sections[n].name);
12131 	      size_t scnlen = strlen (name);
12132 	      if ((strncmp (name, debug_sections[n].name, dbglen) == 0
12133 		   && (dbglen == scnlen
12134 		       || (scnlen == dbglen + 4
12135 			   && strstr (name, ".dwo") == name + dbglen)))
12136 		  || (name[0] == '.' && name[1] == 'z'
12137 		      && debug_sections[n].name[1] == 'd'
12138 		      && strncmp (&name[2], &debug_sections[n].name[1],
12139 				  dbglen - 1) == 0
12140 		      && (scnlen == dbglen + 1
12141 			  || (scnlen == dbglen + 5
12142 			      && strstr (name, ".dwo") == name + dbglen + 1)))
12143 		  || (scnlen > 14 /* .gnu.debuglto_ prefix. */
12144 		      && startswith (name, ".gnu.debuglto_")
12145 		      && strcmp (&name[14], debug_sections[n].name) == 0)
12146 )
12147 		{
12148 		  if ((print_debug_sections | implicit_debug_sections)
12149 		      & debug_sections[n].bitmask)
12150 		    debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
12151 		  break;
12152 		}
12153 	    }
12154 	}
12155     }
12156 
12157   dwfl_end (skel_dwfl);
12158   free (skel_name);
12159 
12160   /* Turn implicit and/or explicit back on in case we go over another file.  */
12161   if (implicit_info)
12162     implicit_debug_sections |= section_info;
12163   if (explicit_info)
12164     print_debug_sections |= section_info;
12165 
12166   reset_listptr (&known_locsptr);
12167   reset_listptr (&known_loclistsptr);
12168   reset_listptr (&known_rangelistptr);
12169   reset_listptr (&known_rnglistptr);
12170   reset_listptr (&known_addrbases);
12171   reset_listptr (&known_stroffbases);
12172 }
12173 
12174 
12175 #define ITEM_INDENT		4
12176 #define WRAP_COLUMN		75
12177 
12178 /* Print "NAME: FORMAT", wrapping when output text would make the line
12179    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
12180    but this function is also used for registers which should be printed
12181    aligned.  Fortunately registers output uses fixed fields width (such
12182    as %11d) for the alignment.
12183 
12184    Line breaks should not depend on the particular values although that
12185    may happen in some cases of the core items.  */
12186 
12187 static unsigned int
12188 __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,...)12189 print_core_item (unsigned int colno, char sep, unsigned int wrap,
12190 		 size_t name_width, const char *name, const char *format, ...)
12191 {
12192   size_t len = strlen (name);
12193   if (name_width < len)
12194     name_width = len;
12195 
12196   char *out;
12197   va_list ap;
12198   va_start (ap, format);
12199   int out_len = vasprintf (&out, format, ap);
12200   va_end (ap);
12201   if (out_len == -1)
12202     error_exit (0, _("memory exhausted"));
12203 
12204   size_t n = name_width + sizeof ": " - 1 + out_len;
12205 
12206   if (colno == 0)
12207     {
12208       printf ("%*s", ITEM_INDENT, "");
12209       colno = ITEM_INDENT + n;
12210     }
12211   else if (colno + 2 + n < wrap)
12212     {
12213       printf ("%c ", sep);
12214       colno += 2 + n;
12215     }
12216   else
12217     {
12218       printf ("\n%*s", ITEM_INDENT, "");
12219       colno = ITEM_INDENT + n;
12220     }
12221 
12222   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
12223 
12224   free (out);
12225 
12226   return colno;
12227 }
12228 
12229 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)12230 convert (Elf *core, Elf_Type type, uint_fast16_t count,
12231 	 void *value, const void *data, size_t size)
12232 {
12233   Elf_Data valuedata =
12234     {
12235       .d_type = type,
12236       .d_buf = value,
12237       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
12238       .d_version = EV_CURRENT,
12239     };
12240   Elf_Data indata =
12241     {
12242       .d_type = type,
12243       .d_buf = (void *) data,
12244       .d_size = valuedata.d_size,
12245       .d_version = EV_CURRENT,
12246     };
12247 
12248   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
12249 		 ? elf32_xlatetom : elf64_xlatetom)
12250     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
12251   if (d == NULL)
12252     error_exit (0, _("cannot convert core note data: %s"),
12253 		elf_errmsg (-1));
12254 
12255   return data + indata.d_size;
12256 }
12257 
12258 typedef uint8_t GElf_Byte;
12259 
12260 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)12261 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
12262 		  unsigned int colno, size_t *repeated_size)
12263 {
12264   uint_fast16_t count = item->count ?: 1;
12265   /* Ebl_Core_Item count is always a small number.
12266      Make sure the backend didn't put in some large bogus value.  */
12267   assert (count < 128);
12268 
12269 #define TYPES								      \
12270   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
12271   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
12272   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
12273   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
12274   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
12275   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
12276 
12277 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
12278   typedef union { TYPES; } value_t;
12279   void *data = alloca (count * sizeof (value_t));
12280 #undef DO_TYPE
12281 
12282 #define DO_TYPE(NAME, Name, hex, dec) \
12283     GElf_##Name *value_##Name __attribute__((unused)) = data
12284   TYPES;
12285 #undef DO_TYPE
12286 
12287   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
12288   size_t convsize = size;
12289   if (repeated_size != NULL)
12290     {
12291       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
12292 	{
12293 	  data = alloca (*repeated_size);
12294 	  count *= *repeated_size / size;
12295 	  convsize = count * size;
12296 	  *repeated_size -= convsize;
12297 	}
12298       else if (item->count != 0 || item->format != '\n')
12299 	*repeated_size -= size;
12300     }
12301 
12302   convert (core, item->type, count, data, desc + item->offset, convsize);
12303 
12304   Elf_Type type = item->type;
12305   if (type == ELF_T_ADDR)
12306     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
12307 
12308   switch (item->format)
12309     {
12310     case 'd':
12311       assert (count == 1);
12312       switch (type)
12313 	{
12314 #define DO_TYPE(NAME, Name, hex, dec)					      \
12315 	  case ELF_T_##NAME:						      \
12316 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
12317 				     0, item->name, dec, value_##Name[0]); \
12318 	    break
12319 	  TYPES;
12320 #undef DO_TYPE
12321 	default:
12322 	  abort ();
12323 	}
12324       break;
12325 
12326     case 'x':
12327       assert (count == 1);
12328       switch (type)
12329 	{
12330 #define DO_TYPE(NAME, Name, hex, dec)					      \
12331 	  case ELF_T_##NAME:						      \
12332 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
12333 				     0, item->name, hex, value_##Name[0]);      \
12334 	    break
12335 	  TYPES;
12336 #undef DO_TYPE
12337 	default:
12338 	  abort ();
12339 	}
12340       break;
12341 
12342     case 'b':
12343     case 'B':
12344       assert (size % sizeof (unsigned int) == 0);
12345       unsigned int nbits = count * size * 8;
12346       unsigned int pop = 0;
12347       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
12348 	pop += __builtin_popcount (*i);
12349       bool negate = pop > nbits / 2;
12350       const unsigned int bias = item->format == 'b';
12351 
12352       {
12353 	char printed[(negate ? nbits - pop : pop) * 16 + 1];
12354 	char *p = printed;
12355 	*p = '\0';
12356 
12357 	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
12358 	  {
12359 	    assert (size == sizeof (unsigned int) * 2);
12360 	    for (unsigned int *i = data;
12361 		 (void *) i < data + count * size; i += 2)
12362 	      {
12363 		unsigned int w = i[1];
12364 		i[1] = i[0];
12365 		i[0] = w;
12366 	      }
12367 	  }
12368 
12369 	unsigned int lastbit = 0;
12370 	unsigned int run = 0;
12371 	for (const unsigned int *i = data;
12372 	     (void *) i < data + count * size; ++i)
12373 	  {
12374 	    unsigned int bit = ((void *) i - data) * 8;
12375 	    unsigned int w = negate ? ~*i : *i;
12376 	    while (w != 0)
12377 	      {
12378 		/* Note that a right shift equal to (or greater than)
12379 		   the number of bits of w is undefined behaviour.  In
12380 		   particular when the least significant bit is bit 32
12381 		   (w = 0x8000000) then w >>= n is undefined.  So
12382 		   explicitly handle that case separately.  */
12383 		unsigned int n = ffs (w);
12384 		if (n < sizeof (w) * 8)
12385 		  w >>= n;
12386 		else
12387 		  w = 0;
12388 		bit += n;
12389 
12390 		if (lastbit != 0 && lastbit + 1 == bit)
12391 		  ++run;
12392 		else
12393 		  {
12394 		    if (lastbit == 0)
12395 		      p += sprintf (p, "%u", bit - bias);
12396 		    else if (run == 0)
12397 		      p += sprintf (p, ",%u", bit - bias);
12398 		    else
12399 		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
12400 		    run = 0;
12401 		  }
12402 
12403 		lastbit = bit;
12404 	      }
12405 	  }
12406 	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
12407 	  p += sprintf (p, "-%u", lastbit - bias);
12408 
12409 	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12410 				 negate ? "~<%s>" : "<%s>", printed);
12411       }
12412       break;
12413 
12414     case 'T':
12415     case (char) ('T'|0x80):
12416       assert (count == 2);
12417       Dwarf_Word sec;
12418       Dwarf_Word usec;
12419       switch (type)
12420 	{
12421 #define DO_TYPE(NAME, Name, hex, dec)					      \
12422 	  case ELF_T_##NAME:						      \
12423 	    sec = value_##Name[0];					      \
12424 	    usec = value_##Name[1];					      \
12425 	    break
12426 	  TYPES;
12427 #undef DO_TYPE
12428 	default:
12429 	  abort ();
12430 	}
12431       if (unlikely (item->format == (char) ('T'|0x80)))
12432 	{
12433 	  /* This is a hack for an ill-considered 64-bit ABI where
12434 	     tv_usec is actually a 32-bit field with 32 bits of padding
12435 	     rounding out struct timeval.  We've already converted it as
12436 	     a 64-bit field.  For little-endian, this just means the
12437 	     high half is the padding; it's presumably zero, but should
12438 	     be ignored anyway.  For big-endian, it means the 32-bit
12439 	     field went into the high half of USEC.  */
12440 	  GElf_Ehdr ehdr_mem;
12441 	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
12442 	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
12443 	    usec >>= 32;
12444 	  else
12445 	    usec &= UINT32_MAX;
12446 	}
12447       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12448 			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
12449       break;
12450 
12451     case 'c':
12452       assert (count == 1);
12453       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12454 			       "%c", value_Byte[0]);
12455       break;
12456 
12457     case 's':
12458       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12459 			       "%.*s", (int) count, value_Byte);
12460       break;
12461 
12462     case '\n':
12463       /* This is a list of strings separated by '\n'.  */
12464       assert (item->count == 0);
12465       assert (repeated_size != NULL);
12466       assert (item->name == NULL);
12467       if (unlikely (item->offset >= *repeated_size))
12468 	break;
12469 
12470       const char *s = desc + item->offset;
12471       size = *repeated_size - item->offset;
12472       *repeated_size = 0;
12473       while (size > 0)
12474 	{
12475 	  const char *eol = memchr (s, '\n', size);
12476 	  int len = size;
12477 	  if (eol != NULL)
12478 	    len = eol - s;
12479 	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
12480 	  if (eol == NULL)
12481 	    break;
12482 	  size -= eol + 1 - s;
12483 	  s = eol + 1;
12484 	}
12485 
12486       colno = WRAP_COLUMN;
12487       break;
12488 
12489     case 'h':
12490       break;
12491 
12492     default:
12493       error (0, 0, "XXX not handling format '%c' for %s",
12494 	     item->format, item->name);
12495       break;
12496     }
12497 
12498 #undef TYPES
12499 
12500   return colno;
12501 }
12502 
12503 
12504 /* Sort items by group, and by layout offset within each group.  */
12505 static int
compare_core_items(const void * a,const void * b)12506 compare_core_items (const void *a, const void *b)
12507 {
12508   const Ebl_Core_Item *const *p1 = a;
12509   const Ebl_Core_Item *const *p2 = b;
12510   const Ebl_Core_Item *item1 = *p1;
12511   const Ebl_Core_Item *item2 = *p2;
12512 
12513   return ((item1->group == item2->group ? 0
12514 	   : strcmp (item1->group, item2->group))
12515 	  ?: (int) item1->offset - (int) item2->offset);
12516 }
12517 
12518 /* Sort item groups by layout offset of the first item in the group.  */
12519 static int
compare_core_item_groups(const void * a,const void * b)12520 compare_core_item_groups (const void *a, const void *b)
12521 {
12522   const Ebl_Core_Item *const *const *p1 = a;
12523   const Ebl_Core_Item *const *const *p2 = b;
12524   const Ebl_Core_Item *const *group1 = *p1;
12525   const Ebl_Core_Item *const *group2 = *p2;
12526   const Ebl_Core_Item *item1 = *group1;
12527   const Ebl_Core_Item *item2 = *group2;
12528 
12529   return (int) item1->offset - (int) item2->offset;
12530 }
12531 
12532 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)12533 handle_core_items (Elf *core, const void *desc, size_t descsz,
12534 		   const Ebl_Core_Item *items, size_t nitems)
12535 {
12536   if (nitems == 0)
12537     return 0;
12538   unsigned int colno = 0;
12539 
12540   /* FORMAT '\n' makes sense to be present only as a single item as it
12541      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
12542      if present as a single item but they can be also processed with other
12543      items below.  */
12544   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
12545 		      || items[0].format == 'B'))
12546     {
12547       assert (items[0].offset == 0);
12548       size_t size = descsz;
12549       colno = handle_core_item (core, items, desc, colno, &size);
12550       /* If SIZE is not zero here there is some remaining data.  But we do not
12551 	 know how to process it anyway.  */
12552       return colno;
12553     }
12554   for (size_t i = 0; i < nitems; ++i)
12555     assert (items[i].format != '\n');
12556 
12557   /* Sort to collect the groups together.  */
12558   const Ebl_Core_Item *sorted_items[nitems];
12559   for (size_t i = 0; i < nitems; ++i)
12560     sorted_items[i] = &items[i];
12561   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
12562 
12563   /* Collect the unique groups and sort them.  */
12564   const Ebl_Core_Item **groups[nitems];
12565   groups[0] = &sorted_items[0];
12566   size_t ngroups = 1;
12567   for (size_t i = 1; i < nitems; ++i)
12568     if (sorted_items[i]->group != sorted_items[i - 1]->group
12569 	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
12570       groups[ngroups++] = &sorted_items[i];
12571   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
12572 
12573   /* Write out all the groups.  */
12574   const void *last = desc;
12575   do
12576     {
12577       for (size_t i = 0; i < ngroups; ++i)
12578 	{
12579 	  for (const Ebl_Core_Item **item = groups[i];
12580 	       (item < &sorted_items[nitems]
12581 		&& ((*item)->group == groups[i][0]->group
12582 		    || !strcmp ((*item)->group, groups[i][0]->group)));
12583 	       ++item)
12584 	    colno = handle_core_item (core, *item, desc, colno, NULL);
12585 
12586 	  /* Force a line break at the end of the group.  */
12587 	  colno = WRAP_COLUMN;
12588 	}
12589 
12590       if (descsz == 0)
12591 	break;
12592 
12593       /* This set of items consumed a certain amount of the note's data.
12594 	 If there is more data there, we have another unit of the same size.
12595 	 Loop to print that out too.  */
12596       const Ebl_Core_Item *item = &items[nitems - 1];
12597       size_t eltsz = item->offset + gelf_fsize (core, item->type,
12598 						item->count ?: 1, EV_CURRENT);
12599 
12600       int reps = -1;
12601       do
12602 	{
12603 	  ++reps;
12604 	  desc += eltsz;
12605 	  descsz -= eltsz;
12606 	}
12607       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
12608 
12609       if (reps == 1)
12610 	{
12611 	  /* For just one repeat, print it unabridged twice.  */
12612 	  desc -= eltsz;
12613 	  descsz += eltsz;
12614 	}
12615       else if (reps > 1)
12616 	printf (_("\n%*s... <repeats %u more times> ..."),
12617 		ITEM_INDENT, "", reps);
12618 
12619       last = desc;
12620     }
12621   while (descsz > 0);
12622 
12623   return colno;
12624 }
12625 
12626 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)12627 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
12628 		      const Ebl_Register_Location *regloc, const void *desc,
12629 		      unsigned int colno)
12630 {
12631   if (regloc->bits % 8 != 0)
12632     {
12633       error (0, 0, "Warning: Cannot handle register with %" PRIu8 "bits\n",
12634 	     regloc->bits);
12635       return colno;
12636     }
12637 
12638   desc += regloc->offset;
12639 
12640   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
12641     {
12642       char name[REGNAMESZ];
12643       int bits;
12644       int type;
12645       register_info (ebl, reg, regloc, name, &bits, &type);
12646 
12647 #define TYPES								      \
12648       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
12649       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
12650       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
12651       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
12652 
12653 #define BITS(bits, xtype, sfmt, ufmt)				\
12654       uint##bits##_t b##bits; int##bits##_t b##bits##s
12655       union { TYPES; uint64_t b128[2]; } value;
12656 #undef	BITS
12657 
12658       switch (type)
12659 	{
12660 	case DW_ATE_unsigned:
12661 	case DW_ATE_signed:
12662 	case DW_ATE_address:
12663 	  switch (bits)
12664 	    {
12665 #define BITS(bits, xtype, sfmt, ufmt)					      \
12666 	    case bits:							      \
12667 	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
12668 	      if (type == DW_ATE_signed)				      \
12669 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
12670 					 maxregname, name,		      \
12671 					 sfmt, value.b##bits##s);	      \
12672 	      else							      \
12673 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
12674 					 maxregname, name,		      \
12675 					 ufmt, value.b##bits);		      \
12676 	      break
12677 
12678 	    TYPES;
12679 
12680 	    case 128:
12681 	      assert (type == DW_ATE_unsigned);
12682 	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
12683 	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
12684 	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
12685 				       maxregname, name,
12686 				       "0x%.16" PRIx64 "%.16" PRIx64,
12687 				       value.b128[!be], value.b128[be]);
12688 	      break;
12689 
12690 	    default:
12691 	      abort ();
12692 #undef	BITS
12693 	    }
12694 	  break;
12695 
12696 	default:
12697 	  /* Print each byte in hex, the whole thing in native byte order.  */
12698 	  assert (bits % 8 == 0);
12699 	  const uint8_t *bytes = desc;
12700 	  desc += bits / 8;
12701 	  char hex[bits / 4 + 1];
12702 	  hex[bits / 4] = '\0';
12703 	  int incr = 1;
12704 	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
12705 	    {
12706 	      bytes += bits / 8 - 1;
12707 	      incr = -1;
12708 	    }
12709 	  size_t idx = 0;
12710 	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
12711 	    {
12712 	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
12713 	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
12714 	    }
12715 	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
12716 				   maxregname, name, "0x%s", hex);
12717 	  break;
12718 	}
12719       desc += regloc->pad;
12720 
12721 #undef TYPES
12722     }
12723 
12724   return colno;
12725 }
12726 
12727 
12728 struct register_info
12729 {
12730   const Ebl_Register_Location *regloc;
12731   const char *set;
12732   char name[REGNAMESZ];
12733   int regno;
12734   int bits;
12735   int type;
12736 };
12737 
12738 static int
register_bitpos(const struct register_info * r)12739 register_bitpos (const struct register_info *r)
12740 {
12741   return (r->regloc->offset * 8
12742 	  + ((r->regno - r->regloc->regno)
12743 	     * (r->regloc->bits + r->regloc->pad * 8)));
12744 }
12745 
12746 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)12747 compare_sets_by_info (const struct register_info *r1,
12748 		      const struct register_info *r2)
12749 {
12750   return ((int) r2->bits - (int) r1->bits
12751 	  ?: register_bitpos (r1) - register_bitpos (r2));
12752 }
12753 
12754 /* Sort registers by set, and by size and layout offset within each set.  */
12755 static int
compare_registers(const void * a,const void * b)12756 compare_registers (const void *a, const void *b)
12757 {
12758   const struct register_info *r1 = a;
12759   const struct register_info *r2 = b;
12760 
12761   /* Unused elements sort last.  */
12762   if (r1->regloc == NULL)
12763     return r2->regloc == NULL ? 0 : 1;
12764   if (r2->regloc == NULL)
12765     return -1;
12766 
12767   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
12768 	  ?: compare_sets_by_info (r1, r2));
12769 }
12770 
12771 /* Sort register sets by layout offset of the first register in the set.  */
12772 static int
compare_register_sets(const void * a,const void * b)12773 compare_register_sets (const void *a, const void *b)
12774 {
12775   const struct register_info *const *p1 = a;
12776   const struct register_info *const *p2 = b;
12777   return compare_sets_by_info (*p1, *p2);
12778 }
12779 
12780 static inline bool
same_set(const struct register_info * a,const struct register_info * b,const struct register_info * regs,size_t maxnreg)12781 same_set (const struct register_info *a,
12782 	  const struct register_info *b,
12783 	  const struct register_info *regs,
12784 	  size_t maxnreg)
12785 {
12786   return (a < &regs[maxnreg] && a->regloc != NULL
12787 	  && b < &regs[maxnreg] && b->regloc != NULL
12788 	  && a->bits == b->bits
12789 	  && (a->set == b->set || !strcmp (a->set, b->set)));
12790 }
12791 
12792 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)12793 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
12794 		       const Ebl_Register_Location *reglocs, size_t nregloc)
12795 {
12796   if (nregloc == 0)
12797     return 0;
12798 
12799   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12800   if (maxnreg <= 0)
12801     {
12802       for (size_t i = 0; i < nregloc; ++i)
12803 	if (maxnreg < reglocs[i].regno + reglocs[i].count)
12804 	  maxnreg = reglocs[i].regno + reglocs[i].count;
12805       assert (maxnreg > 0);
12806     }
12807 
12808   struct register_info regs[maxnreg];
12809   memset (regs, 0, sizeof regs);
12810 
12811   /* Sort to collect the sets together.  */
12812   int maxreg = 0;
12813   for (size_t i = 0; i < nregloc; ++i)
12814     for (int reg = reglocs[i].regno;
12815 	 reg < reglocs[i].regno + reglocs[i].count;
12816 	 ++reg)
12817       {
12818 	assert (reg < maxnreg);
12819 	if (reg > maxreg)
12820 	  maxreg = reg;
12821 	struct register_info *info = &regs[reg];
12822 	info->regloc = &reglocs[i];
12823 	info->regno = reg;
12824 	info->set = register_info (ebl, reg, &reglocs[i],
12825 				   info->name, &info->bits, &info->type);
12826       }
12827   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12828 
12829   /* Collect the unique sets and sort them.  */
12830   struct register_info *sets[maxreg + 1];
12831   sets[0] = &regs[0];
12832   size_t nsets = 1;
12833   for (int i = 1; i <= maxreg; ++i)
12834     if (regs[i].regloc != NULL
12835 	&& !same_set (&regs[i], &regs[i - 1], regs, maxnreg))
12836       sets[nsets++] = &regs[i];
12837   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12838 
12839   /* Write out all the sets.  */
12840   unsigned int colno = 0;
12841   for (size_t i = 0; i < nsets; ++i)
12842     {
12843       /* Find the longest name of a register in this set.  */
12844       size_t maxname = 0;
12845       const struct register_info *end;
12846       for (end = sets[i]; same_set (sets[i], end, regs, maxnreg); ++end)
12847 	{
12848 	  size_t len = strlen (end->name);
12849 	  if (len > maxname)
12850 	    maxname = len;
12851 	}
12852 
12853       for (const struct register_info *reg = sets[i];
12854 	   reg < end;
12855 	   reg += reg->regloc->count ?: 1)
12856 	colno = handle_core_register (ebl, core, maxname,
12857 				      reg->regloc, desc, colno);
12858 
12859       /* Force a line break at the end of the group.  */
12860       colno = WRAP_COLUMN;
12861     }
12862 
12863   return colno;
12864 }
12865 
12866 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12867 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12868 {
12869   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12870   if (data == NULL)
12871   elf_error:
12872     error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12873 
12874   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12875   for (size_t i = 0; i < nauxv; ++i)
12876     {
12877       GElf_auxv_t av_mem;
12878       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12879       if (av == NULL)
12880 	goto elf_error;
12881 
12882       const char *name;
12883       const char *fmt;
12884       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12885 	{
12886 	  /* Unknown type.  */
12887 	  if (av->a_un.a_val == 0)
12888 	    printf ("    %" PRIu64 "\n", av->a_type);
12889 	  else
12890 	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
12891 		    av->a_type, av->a_un.a_val);
12892 	}
12893       else
12894 	switch (fmt[0])
12895 	  {
12896 	  case '\0':		/* Normally zero.  */
12897 	    if (av->a_un.a_val == 0)
12898 	      {
12899 		printf ("    %s\n", name);
12900 		break;
12901 	      }
12902 	    FALLTHROUGH;
12903 	  case 'x':		/* hex */
12904 	  case 'p':		/* address */
12905 	  case 's':		/* address of string */
12906 	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12907 	    break;
12908 	  case 'u':
12909 	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
12910 	    break;
12911 	  case 'd':
12912 	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
12913 	    break;
12914 
12915 	  case 'b':
12916 	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
12917 	    GElf_Xword bit = 1;
12918 	    const char *pfx = "<";
12919 	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12920 	      {
12921 		if (av->a_un.a_val & bit)
12922 		  {
12923 		    printf ("%s%s", pfx, p);
12924 		    pfx = " ";
12925 		  }
12926 		bit <<= 1;
12927 	      }
12928 	    printf (">\n");
12929 	    break;
12930 
12931 	  default:
12932 	    abort ();
12933 	  }
12934     }
12935 }
12936 
12937 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12938 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12939 {
12940   return ptr < end && (size_t) (end - ptr) >= sz;
12941 }
12942 
12943 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12944 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12945 	      int *retp)
12946 {
12947   if (! buf_has_data (*ptrp, end, 4))
12948     return false;
12949 
12950   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12951   return true;
12952 }
12953 
12954 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12955 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12956 		uint64_t *retp)
12957 {
12958   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12959   if (! buf_has_data (*ptrp, end, sz))
12960     return false;
12961 
12962   union
12963   {
12964     uint64_t u64;
12965     uint32_t u32;
12966   } u;
12967 
12968   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12969 
12970   if (sz == 4)
12971     *retp = u.u32;
12972   else
12973     *retp = u.u64;
12974   return true;
12975 }
12976 
12977 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12978 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12979 {
12980   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12981   if (data == NULL)
12982     error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12983 
12984   unsigned char const *ptr = data->d_buf;
12985   unsigned char const *const end = data->d_buf + data->d_size;
12986 
12987   /* Siginfo head is three ints: signal number, error number, origin
12988      code.  */
12989   int si_signo, si_errno, si_code;
12990   if (! buf_read_int (core, &ptr, end, &si_signo)
12991       || ! buf_read_int (core, &ptr, end, &si_errno)
12992       || ! buf_read_int (core, &ptr, end, &si_code))
12993     {
12994     fail:
12995       printf ("    Not enough data in NT_SIGINFO note.\n");
12996       return;
12997     }
12998 
12999   /* Next is a pointer-aligned union of structures.  On 64-bit
13000      machines, that implies a word of padding.  */
13001   if (gelf_getclass (core) == ELFCLASS64)
13002     ptr += 4;
13003 
13004   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
13005 	  si_signo, si_errno, si_code);
13006 
13007   if (si_code > 0)
13008     switch (si_signo)
13009       {
13010       case CORE_SIGILL:
13011       case CORE_SIGFPE:
13012       case CORE_SIGSEGV:
13013       case CORE_SIGBUS:
13014 	{
13015 	  uint64_t addr;
13016 	  if (! buf_read_ulong (core, &ptr, end, &addr))
13017 	    goto fail;
13018 	  printf ("    fault address: %#" PRIx64 "\n", addr);
13019 	  break;
13020 	}
13021       default:
13022 	;
13023       }
13024   else if (si_code == CORE_SI_USER)
13025     {
13026       int pid, uid;
13027       if (! buf_read_int (core, &ptr, end, &pid)
13028 	  || ! buf_read_int (core, &ptr, end, &uid))
13029 	goto fail;
13030       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
13031     }
13032 }
13033 
13034 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)13035 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
13036 {
13037   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
13038   if (data == NULL)
13039     error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
13040 
13041   unsigned char const *ptr = data->d_buf;
13042   unsigned char const *const end = data->d_buf + data->d_size;
13043 
13044   uint64_t count, page_size;
13045   if (! buf_read_ulong (core, &ptr, end, &count)
13046       || ! buf_read_ulong (core, &ptr, end, &page_size))
13047     {
13048     fail:
13049       printf ("    Not enough data in NT_FILE note.\n");
13050       return;
13051     }
13052 
13053   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
13054   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
13055   if (count > maxcount)
13056     goto fail;
13057 
13058   /* Where file names are stored.  */
13059   unsigned char const *const fstart = ptr + 3 * count * addrsize;
13060   char const *fptr = (char *) fstart;
13061 
13062   printf ("    %" PRId64 " files:\n", count);
13063   for (uint64_t i = 0; i < count; ++i)
13064     {
13065       uint64_t mstart, mend, moffset;
13066       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
13067 	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
13068 	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
13069 	goto fail;
13070 
13071       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
13072       if (fnext == NULL)
13073 	goto fail;
13074 
13075       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
13076 		       " %08" PRIx64 " %" PRId64,
13077 		       mstart, mend, moffset * page_size, mend - mstart);
13078       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
13079 
13080       fptr = fnext + 1;
13081     }
13082 }
13083 
13084 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)13085 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
13086 		  const char *name, const void *desc)
13087 {
13088   GElf_Word regs_offset;
13089   size_t nregloc;
13090   const Ebl_Register_Location *reglocs;
13091   size_t nitems;
13092   const Ebl_Core_Item *items;
13093 
13094   if (! ebl_core_note (ebl, nhdr, name, desc,
13095 		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
13096     return;
13097 
13098   /* Pass 0 for DESCSZ when there are registers in the note,
13099      so that the ITEMS array does not describe the whole thing.
13100      For non-register notes, the actual descsz might be a multiple
13101      of the unit size, not just exactly the unit size.  */
13102   unsigned int colno = handle_core_items (ebl->elf, desc,
13103 					  nregloc == 0 ? nhdr->n_descsz : 0,
13104 					  items, nitems);
13105   if (colno != 0)
13106     putchar_unlocked ('\n');
13107 
13108   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
13109 				 reglocs, nregloc);
13110   if (colno != 0)
13111     putchar_unlocked ('\n');
13112 }
13113 
13114 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)13115 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
13116 		   GElf_Off start, Elf_Data *data)
13117 {
13118   fputs_unlocked (_("  Owner          Data size  Type\n"), stdout);
13119 
13120   if (data == NULL)
13121     goto bad_note;
13122 
13123   size_t offset = 0;
13124   GElf_Nhdr nhdr;
13125   size_t name_offset;
13126   size_t desc_offset;
13127   while (offset < data->d_size
13128 	 && (offset = gelf_getnote (data, offset,
13129 				    &nhdr, &name_offset, &desc_offset)) > 0)
13130     {
13131       const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
13132       const char *desc = data->d_buf + desc_offset;
13133 
13134       /* GNU Build Attributes are weird, they store most of their data
13135 	 into the owner name field.  Extract just the owner name
13136 	 prefix here, then use the rest later as data.  */
13137       bool is_gnu_build_attr
13138 	= startswith (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX);
13139       const char *print_name = (is_gnu_build_attr
13140 				? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
13141       size_t print_namesz = (is_gnu_build_attr
13142 			     ? strlen (print_name) : nhdr.n_namesz);
13143 
13144       char buf[100];
13145       char buf2[100];
13146       printf (_("  %-13.*s  %9" PRId32 "  %s\n"),
13147 	      (int) print_namesz, print_name, nhdr.n_descsz,
13148 	      ehdr->e_type == ET_CORE
13149 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
13150 					 buf, sizeof (buf))
13151 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
13152 					   nhdr.n_descsz,
13153 					   buf2, sizeof (buf2)));
13154 
13155       /* Filter out invalid entries.  */
13156       if (memchr (name, '\0', nhdr.n_namesz) != NULL
13157 	  /* XXX For now help broken Linux kernels.  */
13158 	  || 1)
13159 	{
13160 	  if (ehdr->e_type == ET_CORE)
13161 	    {
13162 	      if (nhdr.n_type == NT_AUXV
13163 		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
13164 		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
13165 		  && !memcmp (name, "CORE", 4))
13166 		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
13167 				  start + desc_offset);
13168 	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
13169 		switch (nhdr.n_type)
13170 		  {
13171 		  case NT_SIGINFO:
13172 		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
13173 					 start + desc_offset);
13174 		    break;
13175 
13176 		  case NT_FILE:
13177 		    handle_file_note (ebl->elf, nhdr.n_descsz,
13178 				      start + desc_offset);
13179 		    break;
13180 
13181 		  default:
13182 		    handle_core_note (ebl, &nhdr, name, desc);
13183 		  }
13184 	      else
13185 		handle_core_note (ebl, &nhdr, name, desc);
13186 	    }
13187 	  else
13188 	    ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
13189 			     nhdr.n_descsz, desc);
13190 	}
13191     }
13192 
13193   if (offset == data->d_size)
13194     return;
13195 
13196  bad_note:
13197   error (0, 0,
13198 	 _("cannot get content of note: %s"),
13199 	 data != NULL ? "garbage data" : elf_errmsg (-1));
13200 }
13201 
13202 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)13203 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
13204 {
13205   /* If we have section headers, just look for SHT_NOTE sections.
13206      In a debuginfo file, the program headers are not reliable.  */
13207   if (shnum != 0)
13208     {
13209       /* Get the section header string table index.  */
13210       size_t shstrndx;
13211       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
13212 	error_exit (0, _("cannot get section header string table index"));
13213 
13214       Elf_Scn *scn = NULL;
13215       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
13216 	{
13217 	  GElf_Shdr shdr_mem;
13218 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
13219 
13220 	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
13221 	    /* Not what we are looking for.  */
13222 	    continue;
13223 
13224 	  if (notes_section != NULL)
13225 	    {
13226 	      char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
13227 	      if (sname == NULL || strcmp (sname, notes_section) != 0)
13228 		continue;
13229 	    }
13230 
13231 	  printf (_("\
13232 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
13233 		  elf_ndxscn (scn),
13234 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
13235 		  shdr->sh_size, shdr->sh_offset);
13236 
13237 	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
13238 			     elf_getdata (scn, NULL));
13239 	}
13240       return;
13241     }
13242 
13243   /* We have to look through the program header to find the note
13244      sections.  There can be more than one.  */
13245   for (size_t cnt = 0; cnt < phnum; ++cnt)
13246     {
13247       GElf_Phdr mem;
13248       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
13249 
13250       if (phdr == NULL || phdr->p_type != PT_NOTE)
13251 	/* Not what we are looking for.  */
13252 	continue;
13253 
13254       printf (_("\
13255 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
13256 	      phdr->p_filesz, phdr->p_offset);
13257 
13258       handle_notes_data (ebl, ehdr, phdr->p_offset,
13259 			 elf_getdata_rawchunk (ebl->elf,
13260 					       phdr->p_offset, phdr->p_filesz,
13261 					       (phdr->p_align == 8
13262 						? ELF_T_NHDR8 : ELF_T_NHDR)));
13263     }
13264 }
13265 
13266 
13267 static void
hex_dump(const uint8_t * data,size_t len)13268 hex_dump (const uint8_t *data, size_t len)
13269 {
13270   size_t pos = 0;
13271   while (pos < len)
13272     {
13273       printf ("  0x%08zx ", pos);
13274 
13275       const size_t chunk = MIN (len - pos, 16);
13276 
13277       for (size_t i = 0; i < chunk; ++i)
13278 	if (i % 4 == 3)
13279 	  printf ("%02x ", data[pos + i]);
13280 	else
13281 	  printf ("%02x", data[pos + i]);
13282 
13283       if (chunk < 16)
13284 	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
13285 
13286       for (size_t i = 0; i < chunk; ++i)
13287 	{
13288 	  unsigned char b = data[pos + i];
13289 	  printf ("%c", isprint (b) ? b : '.');
13290 	}
13291 
13292       putchar ('\n');
13293       pos += chunk;
13294     }
13295 }
13296 
13297 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)13298 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
13299 {
13300   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
13301     printf (_("\nSection [%zu] '%s' has no data to dump.\n"),
13302 	    elf_ndxscn (scn), name);
13303   else
13304     {
13305       if (print_decompress)
13306 	{
13307 	  /* We try to decompress the section, but keep the old shdr around
13308 	     so we can show both the original shdr size and the uncompressed
13309 	     data size.   */
13310 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
13311 	    {
13312 	      if (elf_compress (scn, 0, 0) < 0)
13313 		printf ("WARNING: %s [%zd]\n",
13314 			_("Couldn't uncompress section"),
13315 			elf_ndxscn (scn));
13316 	    }
13317 	  else if (startswith (name, ".zdebug"))
13318 	    {
13319 	      if (elf_compress_gnu (scn, 0, 0) < 0)
13320 		printf ("WARNING: %s [%zd]\n",
13321 			_("Couldn't uncompress section"),
13322 			elf_ndxscn (scn));
13323 	    }
13324 	}
13325 
13326       Elf_Data *data = elf_rawdata (scn, NULL);
13327       if (data == NULL)
13328 	error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
13329 	       elf_ndxscn (scn), name, elf_errmsg (-1));
13330       else
13331 	{
13332 	  if (data->d_size == shdr->sh_size)
13333 	    printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
13334 			     " bytes at offset %#0" PRIx64 ":\n"),
13335 		    elf_ndxscn (scn), name,
13336 		    shdr->sh_size, shdr->sh_offset);
13337 	  else
13338 	    printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
13339 			     " bytes (%zd uncompressed) at offset %#0"
13340 			     PRIx64 ":\n"),
13341 		    elf_ndxscn (scn), name,
13342 		    shdr->sh_size, data->d_size, shdr->sh_offset);
13343 	  hex_dump (data->d_buf, data->d_size);
13344 	}
13345     }
13346 }
13347 
13348 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)13349 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
13350 {
13351   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
13352     printf (_("\nSection [%zu] '%s' has no strings to dump.\n"),
13353 	    elf_ndxscn (scn), name);
13354   else
13355     {
13356       if (print_decompress)
13357 	{
13358 	  /* We try to decompress the section, but keep the old shdr around
13359 	     so we can show both the original shdr size and the uncompressed
13360 	     data size.  */
13361 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
13362 	    {
13363 	      if (elf_compress (scn, 0, 0) < 0)
13364 		printf ("WARNING: %s [%zd]\n",
13365 			_("Couldn't uncompress section"),
13366 			elf_ndxscn (scn));
13367 	    }
13368 	  else if (startswith (name, ".zdebug"))
13369 	    {
13370 	      if (elf_compress_gnu (scn, 0, 0) < 0)
13371 		printf ("WARNING: %s [%zd]\n",
13372 			_("Couldn't uncompress section"),
13373 			elf_ndxscn (scn));
13374 	    }
13375 	}
13376 
13377       Elf_Data *data = elf_rawdata (scn, NULL);
13378       if (data == NULL)
13379 	error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
13380 	       elf_ndxscn (scn), name, elf_errmsg (-1));
13381       else
13382 	{
13383 	  if (data->d_size == shdr->sh_size)
13384 	    printf (_("\nString section [%zu] '%s' contains %" PRIu64
13385 			     " bytes at offset %#0" PRIx64 ":\n"),
13386 		    elf_ndxscn (scn), name,
13387 		    shdr->sh_size, shdr->sh_offset);
13388 	  else
13389 	    printf (_("\nString section [%zu] '%s' contains %" PRIu64
13390 			     " bytes (%zd uncompressed) at offset %#0"
13391 			     PRIx64 ":\n"),
13392 		    elf_ndxscn (scn), name,
13393 		    shdr->sh_size, data->d_size, shdr->sh_offset);
13394 
13395 	  const char *start = data->d_buf;
13396 	  const char *const limit = start + data->d_size;
13397 	  do
13398 	    {
13399 	      const char *end = memchr (start, '\0', limit - start);
13400 	      const size_t pos = start - (const char *) data->d_buf;
13401 	      if (unlikely (end == NULL))
13402 		{
13403 		  printf ("  [%6zx]- %.*s\n",
13404 			  pos, (int) (limit - start), start);
13405 		  break;
13406 		}
13407 	      printf ("  [%6zx]  %s\n", pos, start);
13408 	      start = end + 1;
13409 	    } while (start < limit);
13410 	}
13411     }
13412 }
13413 
13414 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))13415 for_each_section_argument (Elf *elf, const struct section_argument *list,
13416 			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
13417 					 const char *name))
13418 {
13419   /* Get the section header string table index.  */
13420   size_t shstrndx;
13421   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
13422     error_exit (0, _("cannot get section header string table index"));
13423 
13424   for (const struct section_argument *a = list; a != NULL; a = a->next)
13425     {
13426       Elf_Scn *scn;
13427       GElf_Shdr shdr_mem;
13428       const char *name = NULL;
13429 
13430       char *endp = NULL;
13431       unsigned long int shndx = strtoul (a->arg, &endp, 0);
13432       if (endp != a->arg && *endp == '\0')
13433 	{
13434 	  scn = elf_getscn (elf, shndx);
13435 	  if (scn == NULL)
13436 	    {
13437 	      error (0, 0, _("\nsection [%lu] does not exist"), shndx);
13438 	      continue;
13439 	    }
13440 
13441 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
13442 	    error_exit (0, _("cannot get section header: %s"),
13443 			elf_errmsg (-1));
13444 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
13445 	  (*dump) (scn, &shdr_mem, name);
13446 	}
13447       else
13448 	{
13449 	  /* Need to look up the section by name.  */
13450 	  scn = NULL;
13451 	  bool found = false;
13452 	  while ((scn = elf_nextscn (elf, scn)) != NULL)
13453 	    {
13454 	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
13455 		continue;
13456 	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
13457 	      if (name == NULL)
13458 		continue;
13459 	      if (!strcmp (name, a->arg))
13460 		{
13461 		  found = true;
13462 		  (*dump) (scn, &shdr_mem, name);
13463 		}
13464 	    }
13465 
13466 	  if (unlikely (!found) && !a->implicit)
13467 	    error (0, 0, _("\nsection '%s' does not exist"), a->arg);
13468 	}
13469     }
13470 }
13471 
13472 static void
dump_data(Ebl * ebl)13473 dump_data (Ebl *ebl)
13474 {
13475   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
13476 }
13477 
13478 static void
dump_strings(Ebl * ebl)13479 dump_strings (Ebl *ebl)
13480 {
13481   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
13482 }
13483 
13484 static void
print_strings(Ebl * ebl)13485 print_strings (Ebl *ebl)
13486 {
13487   /* Get the section header string table index.  */
13488   size_t shstrndx;
13489   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
13490     error_exit (0, _("cannot get section header string table index"));
13491 
13492   Elf_Scn *scn;
13493   GElf_Shdr shdr_mem;
13494   const char *name;
13495   scn = NULL;
13496   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
13497     {
13498       if (gelf_getshdr (scn, &shdr_mem) == NULL)
13499 	continue;
13500 
13501       if (shdr_mem.sh_type != SHT_PROGBITS
13502 	  || !(shdr_mem.sh_flags & SHF_STRINGS))
13503 	continue;
13504 
13505       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
13506       if (name == NULL)
13507 	continue;
13508 
13509       print_string_section (scn, &shdr_mem, name);
13510     }
13511 }
13512 
13513 static void
dump_archive_index(Elf * elf,const char * fname)13514 dump_archive_index (Elf *elf, const char *fname)
13515 {
13516   size_t narsym;
13517   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
13518   if (arsym == NULL)
13519     {
13520       int result = elf_errno ();
13521       if (unlikely (result != ELF_E_NO_INDEX))
13522 	error_exit (0, _("cannot get symbol index of archive '%s': %s"),
13523 		    fname, elf_errmsg (result));
13524       else
13525 	printf (_("\nArchive '%s' has no symbol index\n"), fname);
13526       return;
13527     }
13528 
13529   printf (_("\nIndex of archive '%s' has %zu entries:\n"),
13530 	  fname, narsym);
13531 
13532   size_t as_off = 0;
13533   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
13534     {
13535       if (s->as_off != as_off)
13536 	{
13537 	  as_off = s->as_off;
13538 
13539 	  Elf *subelf = NULL;
13540 	  if (unlikely (elf_rand (elf, as_off) == 0)
13541 	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
13542 			   == NULL))
13543 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
13544 	    while (1)
13545 #endif
13546 	      error_exit (0,
13547 			  _("cannot extract member at offset %zu in '%s': %s"),
13548 			  as_off, fname, elf_errmsg (-1));
13549 
13550 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
13551 
13552 	  printf (_("Archive member '%s' contains:\n"), h->ar_name);
13553 
13554 	  elf_end (subelf);
13555 	}
13556 
13557       printf ("\t%s\n", s->as_name);
13558     }
13559 }
13560 
13561 #include "debugpred.h"
13562