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