• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Print information from ELF file in human-readable form.
2    Copyright (C) 1999-2015 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
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 <error.h>
29 #include <fcntl.h>
30 #include <gelf.h>
31 #include <inttypes.h>
32 #include <langinfo.h>
33 #include <libdw.h>
34 #include <libdwfl.h>
35 #include <libintl.h>
36 #include <locale.h>
37 #include <stdarg.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42 #include <unistd.h>
43 #include <sys/param.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46 
47 #include <system.h>
48 #include "../libelf/libelfP.h"
49 #include "../libelf/common.h"
50 #include "../libebl/libeblP.h"
51 #include "../libdwelf/libdwelf.h"
52 #include "../libdw/libdwP.h"
53 #include "../libdwfl/libdwflP.h"
54 #include "../libdw/memory-access.h"
55 
56 #include "../libdw/known-dwarf.h"
57 
58 
59 /* Name and version of program.  */
60 static void print_version (FILE *stream, struct argp_state *state);
61 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
62 
63 /* Bug report address.  */
64 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
65 
66 /* argp key value for --elf-section, non-ascii.  */
67 #define ELF_INPUT_SECTION 256
68 
69 /* Definitions of arguments for argp functions.  */
70 static const struct argp_option options[] =
71 {
72   { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
73   { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
74     N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
75        "input data"), 0 },
76   { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
77   { "all", 'a', NULL, 0,
78     N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
79   { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
80   { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
81   { "histogram", 'I', NULL, 0,
82     N_("Display histogram of bucket list lengths"), 0 },
83   { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
84   { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
85   { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
86   { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
87   { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
88   { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
89   { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
90   { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
91   { "arch-specific", 'A', NULL, 0,
92     N_("Display architecture specific information, if any"), 0 },
93   { "exception", 'e', NULL, 0,
94     N_("Display sections for exception handling"), 0 },
95 
96   { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
97   { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
98     N_("Display DWARF section content.  SECTION can be one of abbrev, "
99        "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
100        "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
101   { "hex-dump", 'x', "SECTION", 0,
102     N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
103   { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
104     N_("Print string contents of sections"), 0 },
105   { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
106   { "archive-index", 'c', NULL, 0,
107     N_("Display the symbol index of an archive"), 0 },
108 
109   { NULL, 0, NULL, 0, N_("Output control:"), 0 },
110   { "numeric-addresses", 'N', NULL, 0,
111     N_("Do not find symbol names for addresses in DWARF data"), 0 },
112   { "unresolved-address-offsets", 'U', NULL, 0,
113     N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
114   { "wide", 'W', NULL, 0,
115     N_("Ignored for compatibility (lines always wide)"), 0 },
116   { "decompress", 'z', NULL, 0,
117     N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
118   { NULL, 0, NULL, 0, NULL, 0 }
119 };
120 
121 /* Short description of program.  */
122 static const char doc[] = N_("\
123 Print information from ELF file in human-readable form.");
124 
125 /* Strings for arguments in help texts.  */
126 static const char args_doc[] = N_("FILE...");
127 
128 /* Prototype for option handler.  */
129 static error_t parse_opt (int key, char *arg, struct argp_state *state);
130 
131 /* Data structure to communicate with argp functions.  */
132 static struct argp argp =
133 {
134   options, parse_opt, args_doc, doc, NULL, NULL, NULL
135 };
136 
137 /* If non-null, the section from which we should read to (compressed) ELF.  */
138 static const char *elf_input_section = NULL;
139 
140 /* Flags set by the option controlling the output.  */
141 
142 /* True if dynamic segment should be printed.  */
143 static bool print_dynamic_table;
144 
145 /* True if the file header should be printed.  */
146 static bool print_file_header;
147 
148 /* True if the program headers should be printed.  */
149 static bool print_program_header;
150 
151 /* True if relocations should be printed.  */
152 static bool print_relocations;
153 
154 /* True if the section headers should be printed.  */
155 static bool print_section_header;
156 
157 /* True if the symbol table should be printed.  */
158 static bool print_symbol_table;
159 
160 /* True if the version information should be printed.  */
161 static bool print_version_info;
162 
163 /* True if section groups should be printed.  */
164 static bool print_section_groups;
165 
166 /* True if bucket list length histogram should be printed.  */
167 static bool print_histogram;
168 
169 /* True if the architecture specific data should be printed.  */
170 static bool print_arch;
171 
172 /* True if note section content should be printed.  */
173 static bool print_notes;
174 
175 /* True if SHF_STRINGS section content should be printed.  */
176 static bool print_string_sections;
177 
178 /* True if archive index should be printed.  */
179 static bool print_archive_index;
180 
181 /* True if any of the control options except print_archive_index is set.  */
182 static bool any_control_option;
183 
184 /* True if we should print addresses from DWARF in symbolic form.  */
185 static bool print_address_names = true;
186 
187 /* True if we should print raw values instead of relativized addresses.  */
188 static bool print_unresolved_addresses = false;
189 
190 /* True if we should print the .debug_aranges section using libdw.  */
191 static bool decodedaranges = false;
192 
193 /* True if we should print the .debug_aranges section using libdw.  */
194 static bool decodedline = false;
195 
196 /* True if we want to show more information about compressed sections.  */
197 static bool print_decompress = false;
198 
199 /* Select printing of debugging sections.  */
200 static enum section_e
201 {
202   section_abbrev = 1,		/* .debug_abbrev  */
203   section_aranges = 2,		/* .debug_aranges  */
204   section_frame = 4,		/* .debug_frame or .eh_frame & al.  */
205   section_info = 8,		/* .debug_info, .debug_types  */
206   section_types = section_info,
207   section_line = 16,		/* .debug_line  */
208   section_loc = 32,		/* .debug_loc  */
209   section_pubnames = 64,	/* .debug_pubnames  */
210   section_str = 128,		/* .debug_str  */
211   section_macinfo = 256,	/* .debug_macinfo  */
212   section_ranges = 512, 	/* .debug_ranges  */
213   section_exception = 1024,	/* .eh_frame & al.  */
214   section_gdb_index = 2048,	/* .gdb_index  */
215   section_macro = 4096,		/* .debug_macro  */
216   section_all = (section_abbrev | section_aranges | section_frame
217 		 | section_info | section_line | section_loc
218 		 | section_pubnames | section_str | section_macinfo
219 		 | section_ranges | section_exception | section_gdb_index
220 		 | section_macro)
221 } print_debug_sections, implicit_debug_sections;
222 
223 /* Select hex dumping of sections.  */
224 static struct section_argument *dump_data_sections;
225 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
226 
227 /* Select string dumping of sections.  */
228 static struct section_argument *string_sections;
229 static struct section_argument **string_sections_tail = &string_sections;
230 
231 struct section_argument
232 {
233   struct section_argument *next;
234   const char *arg;
235   bool implicit;
236 };
237 
238 /* Numbers of sections and program headers in the file.  */
239 static size_t shnum;
240 static size_t phnum;
241 
242 
243 /* Declarations of local functions.  */
244 static void process_file (int fd, const char *fname, bool only_one);
245 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
246 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
247 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
248 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
249 static void print_scngrp (Ebl *ebl);
250 static void print_dynamic (Ebl *ebl);
251 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
252 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
253 			       GElf_Shdr *shdr);
254 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
255 				GElf_Shdr *shdr);
256 static void print_symtab (Ebl *ebl, int type);
257 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
258 static void print_verinfo (Ebl *ebl);
259 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
260 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
261 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
262 			   GElf_Shdr *shdr);
263 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
264 static void handle_hash (Ebl *ebl);
265 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
266 static void print_liblist (Ebl *ebl);
267 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
268 static void dump_data (Ebl *ebl);
269 static void dump_strings (Ebl *ebl);
270 static void print_strings (Ebl *ebl);
271 static void dump_archive_index (Elf *, const char *);
272 
273 
274 int
main(int argc,char * argv[])275 main (int argc, char *argv[])
276 {
277   /* Set locale.  */
278   setlocale (LC_ALL, "");
279 
280   /* Initialize the message catalog.  */
281   textdomain (PACKAGE_TARNAME);
282 
283   /* Parse and process arguments.  */
284   int remaining;
285   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
286 
287   /* Before we start tell the ELF library which version we are using.  */
288   elf_version (EV_CURRENT);
289 
290   /* Now process all the files given at the command line.  */
291   bool only_one = remaining + 1 == argc;
292   do
293     {
294       /* Open the file.  */
295       int fd = open (argv[remaining], O_RDONLY);
296       if (fd == -1)
297 	{
298 	  error (0, errno, gettext ("cannot open input file"));
299 	  continue;
300 	}
301 
302       process_file (fd, argv[remaining], only_one);
303 
304       close (fd);
305     }
306   while (++remaining < argc);
307 
308   return error_message_count != 0;
309 }
310 
311 
312 /* Handle program arguments.  */
313 static error_t
parse_opt(int key,char * arg,struct argp_state * state)314 parse_opt (int key, char *arg,
315 	   struct argp_state *state __attribute__ ((unused)))
316 {
317   void add_dump_section (const char *name, bool implicit)
318   {
319     struct section_argument *a = xmalloc (sizeof *a);
320     a->arg = name;
321     a->next = NULL;
322     a->implicit = implicit;
323     struct section_argument ***tailp
324       = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
325     **tailp = a;
326     *tailp = &a->next;
327   }
328 
329   switch (key)
330     {
331     case 'a':
332       print_file_header = true;
333       print_program_header = true;
334       print_relocations = true;
335       print_section_header = true;
336       print_symbol_table = true;
337       print_version_info = true;
338       print_dynamic_table = true;
339       print_section_groups = true;
340       print_histogram = true;
341       print_arch = true;
342       print_notes = true;
343       implicit_debug_sections |= section_exception;
344       add_dump_section (".strtab", true);
345       add_dump_section (".dynstr", true);
346       add_dump_section (".comment", true);
347       any_control_option = true;
348       break;
349     case 'A':
350       print_arch = true;
351       any_control_option = true;
352       break;
353     case 'd':
354       print_dynamic_table = true;
355       any_control_option = true;
356       break;
357     case 'e':
358       print_debug_sections |= section_exception;
359       any_control_option = true;
360       break;
361     case 'g':
362       print_section_groups = true;
363       any_control_option = true;
364       break;
365     case 'h':
366       print_file_header = true;
367       any_control_option = true;
368       break;
369     case 'I':
370       print_histogram = true;
371       any_control_option = true;
372       break;
373     case 'l':
374       print_program_header = true;
375       any_control_option = true;
376       break;
377     case 'n':
378       print_notes = true;
379       any_control_option = true;
380       break;
381     case 'r':
382       print_relocations = true;
383       any_control_option = true;
384      break;
385     case 'S':
386       print_section_header = true;
387       any_control_option = true;
388       break;
389     case 's':
390       print_symbol_table = true;
391       any_control_option = true;
392       break;
393     case 'V':
394       print_version_info = true;
395       any_control_option = true;
396       break;
397     case 'c':
398       print_archive_index = true;
399       break;
400     case 'w':
401       if (arg == NULL)
402 	print_debug_sections = section_all;
403       else if (strcmp (arg, "abbrev") == 0)
404 	print_debug_sections |= section_abbrev;
405       else if (strcmp (arg, "aranges") == 0)
406 	print_debug_sections |= section_aranges;
407       else if (strcmp (arg, "decodedaranges") == 0)
408 	{
409 	  print_debug_sections |= section_aranges;
410 	  decodedaranges = true;
411 	}
412       else if (strcmp (arg, "ranges") == 0)
413 	{
414 	  print_debug_sections |= section_ranges;
415 	  implicit_debug_sections |= section_info;
416 	}
417       else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
418 	print_debug_sections |= section_frame;
419       else if (strcmp (arg, "info") == 0)
420 	print_debug_sections |= section_info;
421       else if (strcmp (arg, "loc") == 0)
422 	{
423 	  print_debug_sections |= section_loc;
424 	  implicit_debug_sections |= section_info;
425 	}
426       else if (strcmp (arg, "line") == 0)
427 	print_debug_sections |= section_line;
428       else if (strcmp (arg, "decodedline") == 0)
429 	{
430 	  print_debug_sections |= section_line;
431 	  decodedline = true;
432 	}
433       else if (strcmp (arg, "pubnames") == 0)
434 	print_debug_sections |= section_pubnames;
435       else if (strcmp (arg, "str") == 0)
436 	print_debug_sections |= section_str;
437       else if (strcmp (arg, "macinfo") == 0)
438 	print_debug_sections |= section_macinfo;
439       else if (strcmp (arg, "macro") == 0)
440 	print_debug_sections |= section_macro;
441       else if (strcmp (arg, "exception") == 0)
442 	print_debug_sections |= section_exception;
443       else if (strcmp (arg, "gdb_index") == 0)
444 	print_debug_sections |= section_gdb_index;
445       else
446 	{
447 	  fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
448 		   arg);
449 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
450 		     program_invocation_short_name);
451 	  exit (1);
452 	}
453       any_control_option = true;
454       break;
455     case 'p':
456       any_control_option = true;
457       if (arg == NULL)
458 	{
459 	  print_string_sections = true;
460 	  break;
461 	}
462       /* Fall through.  */
463     case 'x':
464       add_dump_section (arg, false);
465       any_control_option = true;
466       break;
467     case 'N':
468       print_address_names = false;
469       break;
470     case 'U':
471       print_unresolved_addresses = true;
472       break;
473     case ARGP_KEY_NO_ARGS:
474       fputs (gettext ("Missing file name.\n"), stderr);
475       goto do_argp_help;
476     case ARGP_KEY_FINI:
477       if (! any_control_option && ! print_archive_index)
478 	{
479 	  fputs (gettext ("No operation specified.\n"), stderr);
480 	do_argp_help:
481 	  argp_help (&argp, stderr, ARGP_HELP_SEE,
482 		     program_invocation_short_name);
483 	  exit (EXIT_FAILURE);
484 	}
485       break;
486     case 'W':			/* Ignored.  */
487       break;
488     case 'z':
489       print_decompress = true;
490       break;
491     case ELF_INPUT_SECTION:
492       if (arg == NULL)
493 	elf_input_section = ".gnu_debugdata";
494       else
495 	elf_input_section = arg;
496       break;
497     default:
498       return ARGP_ERR_UNKNOWN;
499     }
500   return 0;
501 }
502 
503 
504 /* Print the version information.  */
505 static void
print_version(FILE * stream,struct argp_state * state)506 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
507 {
508   fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
509   fprintf (stream, gettext ("\
510 Copyright (C) %s Red Hat, Inc.\n\
511 This is free software; see the source for copying conditions.  There is NO\n\
512 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
513 "), "2012");
514   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
515 }
516 
517 
518 /* Create a file descriptor to read the data from the
519    elf_input_section given a file descriptor to an ELF file.  */
520 static int
open_input_section(int fd)521 open_input_section (int fd)
522 {
523   size_t shnums;
524   size_t cnt;
525   size_t shstrndx;
526   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
527   if (elf == NULL)
528     {
529       error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
530 	     elf_errmsg (-1));
531       return -1;
532     }
533 
534   if (elf_getshdrnum (elf, &shnums) < 0)
535     {
536       error (0, 0, gettext ("cannot determine number of sections: %s"),
537 	     elf_errmsg (-1));
538     open_error:
539       elf_end (elf);
540       return -1;
541     }
542 
543   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
544     {
545       error (0, 0, gettext ("cannot get section header string table index"));
546       goto open_error;
547     }
548 
549   for (cnt = 0; cnt < shnums; ++cnt)
550     {
551       Elf_Scn *scn = elf_getscn (elf, cnt);
552       if (scn == NULL)
553 	{
554 	  error (0, 0, gettext ("cannot get section: %s"),
555 		 elf_errmsg (-1));
556 	  goto open_error;
557 	}
558 
559       GElf_Shdr shdr_mem;
560       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
561       if (unlikely (shdr == NULL))
562 	{
563 	  error (0, 0, gettext ("cannot get section header: %s"),
564 		 elf_errmsg (-1));
565 	  goto open_error;
566 	}
567 
568       const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
569       if (sname == NULL)
570 	{
571 	  error (0, 0, gettext ("cannot get section name"));
572 	  goto open_error;
573 	}
574 
575       if (strcmp (sname, elf_input_section) == 0)
576 	{
577 	  Elf_Data *data = elf_rawdata (scn, NULL);
578 	  if (data == NULL)
579 	    {
580 	      error (0, 0, gettext ("cannot get %s content: %s"),
581 		     sname, elf_errmsg (-1));
582 	      goto open_error;
583 	    }
584 
585 	  /* Create (and immediately unlink) a temporary file to store
586 	     section data in to create a file descriptor for it.  */
587 	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
588 	  static const char suffix[] = "/readelfXXXXXX";
589 	  int tmplen = strlen (tmpdir) + sizeof (suffix);
590 	  char *tempname = alloca (tmplen);
591 	  sprintf (tempname, "%s%s", tmpdir, suffix);
592 
593 	  int sfd = mkstemp (tempname);
594 	  if (sfd == -1)
595 	    {
596 	      error (0, 0, gettext ("cannot create temp file '%s'"),
597 		     tempname);
598 	      goto open_error;
599 	    }
600 	  unlink (tempname);
601 
602 	  ssize_t size = data->d_size;
603 	  if (write_retry (sfd, data->d_buf, size) != size)
604 	    {
605 	      error (0, 0, gettext ("cannot write section data"));
606 	      goto open_error;
607 	    }
608 
609 	  if (elf_end (elf) != 0)
610 	    {
611 	      error (0, 0, gettext ("error while closing Elf descriptor: %s"),
612 		     elf_errmsg (-1));
613 	      return -1;
614 	    }
615 
616 	  if (lseek (sfd, 0, SEEK_SET) == -1)
617 	    {
618 	      error (0, 0, gettext ("error while rewinding file descriptor"));
619 	      return -1;
620 	    }
621 
622 	  return sfd;
623 	}
624     }
625 
626   /* Named section not found.  */
627   if (elf_end (elf) != 0)
628     error (0, 0, gettext ("error while closing Elf descriptor: %s"),
629 	   elf_errmsg (-1));
630   return -1;
631 }
632 
633 /* Check if the file is an archive, and if so dump its index.  */
634 static void
check_archive_index(int fd,const char * fname,bool only_one)635 check_archive_index (int fd, const char *fname, bool only_one)
636 {
637   /* Create an `Elf' descriptor.  */
638   Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
639   if (elf == NULL)
640     error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
641 	   elf_errmsg (-1));
642   else
643     {
644       if (elf_kind (elf) == ELF_K_AR)
645 	{
646 	  if (!only_one)
647 	    printf ("\n%s:\n\n", fname);
648 	  dump_archive_index (elf, fname);
649 	}
650       else
651 	error (0, 0,
652 	       gettext ("'%s' is not an archive, cannot print archive index"),
653 	       fname);
654 
655       /* Now we can close the descriptor.  */
656       if (elf_end (elf) != 0)
657 	error (0, 0, gettext ("error while closing Elf descriptor: %s"),
658 	       elf_errmsg (-1));
659     }
660 }
661 
662 /* Trivial callback used for checking if we opened an archive.  */
663 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)664 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
665 	       void **userdata __attribute__ ((unused)),
666 	       const char *name __attribute__ ((unused)),
667 	       Dwarf_Addr base __attribute__ ((unused)),
668 	       void *arg)
669 {
670   if (*(bool *) arg)
671     return DWARF_CB_ABORT;
672   *(bool *) arg = true;
673   return DWARF_CB_OK;
674 }
675 
676 struct process_dwflmod_args
677 {
678   int fd;
679   bool only_one;
680 };
681 
682 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)683 process_dwflmod (Dwfl_Module *dwflmod,
684 		 void **userdata __attribute__ ((unused)),
685 		 const char *name __attribute__ ((unused)),
686 		 Dwarf_Addr base __attribute__ ((unused)),
687 		 void *arg)
688 {
689   const struct process_dwflmod_args *a = arg;
690 
691   /* Print the file name.  */
692   if (!a->only_one)
693     {
694       const char *fname;
695       dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
696 
697       printf ("\n%s:\n\n", fname);
698     }
699 
700   process_elf_file (dwflmod, a->fd);
701 
702   return DWARF_CB_OK;
703 }
704 
705 /* Stub libdwfl callback, only the ELF handle already open is ever used.
706    Only used for finding the alternate debug file if the Dwarf comes from
707    the main file.  We are not interested in separate debuginfo.  */
708 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)709 find_no_debuginfo (Dwfl_Module *mod,
710 		   void **userdata,
711 		   const char *modname,
712 		   Dwarf_Addr base,
713 		   const char *file_name,
714 		   const char *debuglink_file,
715 		   GElf_Word debuglink_crc,
716 		   char **debuginfo_file_name)
717 {
718   Dwarf_Addr dwbias;
719   dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
720 
721   /* We are only interested if the Dwarf has been setup on the main
722      elf file but is only missing the alternate debug link.  If dwbias
723      hasn't even been setup, this is searching for separate debuginfo
724      for the main elf.  We don't care in that case.  */
725   if (dwbias == (Dwarf_Addr) -1)
726     return -1;
727 
728   return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
729 				       file_name, debuglink_file,
730 				       debuglink_crc, debuginfo_file_name);
731 }
732 
733 /* Process one input file.  */
734 static void
process_file(int fd,const char * fname,bool only_one)735 process_file (int fd, const char *fname, bool only_one)
736 {
737   if (print_archive_index)
738     check_archive_index (fd, fname, only_one);
739 
740   if (!any_control_option)
741     return;
742 
743   if (elf_input_section != NULL)
744     {
745       /* Replace fname and fd with section content. */
746       char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
747       sprintf (fnname, "%s:%s", fname, elf_input_section);
748       fd = open_input_section (fd);
749       if (fd == -1)
750         {
751           error (0, 0, gettext ("No such section '%s' in '%s'"),
752 		 elf_input_section, fname);
753           return;
754         }
755       fname = fnname;
756     }
757 
758   /* Duplicate an fd for dwfl_report_offline to swallow.  */
759   int dwfl_fd = dup (fd);
760   if (unlikely (dwfl_fd < 0))
761     error (EXIT_FAILURE, errno, "dup");
762 
763   /* Use libdwfl in a trivial way to open the libdw handle for us.
764      This takes care of applying relocations to DWARF data in ET_REL files.  */
765   static const Dwfl_Callbacks callbacks =
766     {
767       .section_address = dwfl_offline_section_address,
768       .find_debuginfo = find_no_debuginfo
769     };
770   Dwfl *dwfl = dwfl_begin (&callbacks);
771   if (likely (dwfl != NULL))
772     /* Let 0 be the logical address of the file (or first in archive).  */
773     dwfl->offline_next_address = 0;
774   if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
775     {
776       struct stat st;
777       if (fstat (dwfl_fd, &st) != 0)
778 	error (0, errno, gettext ("cannot stat input file"));
779       else if (unlikely (st.st_size == 0))
780 	error (0, 0, gettext ("input file is empty"));
781       else
782 	error (0, 0, gettext ("failed reading '%s': %s"),
783 	       fname, dwfl_errmsg (-1));
784       close (dwfl_fd);		/* Consumed on success, not on failure.  */
785     }
786   else
787     {
788       dwfl_report_end (dwfl, NULL, NULL);
789 
790       if (only_one)
791 	{
792 	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
793 	  bool seen = false;
794 	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
795 	}
796 
797       /* Process the one or more modules gleaned from this file.  */
798       struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
799       dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
800     }
801   dwfl_end (dwfl);
802 
803   /* Need to close the replaced fd if we created it.  Caller takes
804      care of original.  */
805   if (elf_input_section != NULL)
806     close (fd);
807 }
808 
809 /* Check whether there are any compressed sections in the ELF file.  */
810 static bool
elf_contains_chdrs(Elf * elf)811 elf_contains_chdrs (Elf *elf)
812 {
813   Elf_Scn *scn = NULL;
814   while ((scn = elf_nextscn (elf, scn)) != NULL)
815     {
816       GElf_Shdr shdr_mem;
817       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
818       if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
819 	return true;
820     }
821   return false;
822 }
823 
824 /* Process one ELF file.  */
825 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)826 process_elf_file (Dwfl_Module *dwflmod, int fd)
827 {
828   GElf_Addr dwflbias;
829   Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
830 
831   GElf_Ehdr ehdr_mem;
832   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
833 
834   if (ehdr == NULL)
835     {
836     elf_error:
837       error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
838       return;
839     }
840 
841   Ebl *ebl = ebl_openbackend (elf);
842   if (unlikely (ebl == NULL))
843     {
844     ebl_error:
845       error (0, errno, gettext ("cannot create EBL handle"));
846       return;
847     }
848 
849   /* Determine the number of sections.  */
850   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
851     error (EXIT_FAILURE, 0,
852 	   gettext ("cannot determine number of sections: %s"),
853 	   elf_errmsg (-1));
854 
855   /* Determine the number of phdrs.  */
856   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
857     error (EXIT_FAILURE, 0,
858 	   gettext ("cannot determine number of program headers: %s"),
859 	   elf_errmsg (-1));
860 
861   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
862      may have applied relocation to some sections.  If there are any
863      compressed sections, any pass (or libdw/libdwfl) might have
864      uncompressed them.  So we need to get a fresh Elf handle on the
865      file to display those.  */
866   bool print_unchanged = ((print_section_header
867 			   || print_relocations
868 			   || dump_data_sections != NULL
869 			   || print_notes)
870 			  && (ehdr->e_type == ET_REL
871 			      || elf_contains_chdrs (ebl->elf)));
872 
873   Elf *pure_elf = NULL;
874   Ebl *pure_ebl = ebl;
875   if (print_unchanged)
876     {
877       /* Read the file afresh.  */
878       off_t aroff = elf_getaroff (elf);
879       pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
880       if (aroff > 0)
881 	{
882 	  /* Archive member.  */
883 	  (void) elf_rand (pure_elf, aroff);
884 	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
885 	  elf_end (pure_elf);
886 	  pure_elf = armem;
887 	}
888       if (pure_elf == NULL)
889 	goto elf_error;
890       pure_ebl = ebl_openbackend (pure_elf);
891       if (pure_ebl == NULL)
892 	goto ebl_error;
893     }
894 
895   if (print_file_header)
896     print_ehdr (ebl, ehdr);
897   if (print_section_header)
898     print_shdr (pure_ebl, ehdr);
899   if (print_program_header)
900     print_phdr (ebl, ehdr);
901   if (print_section_groups)
902     print_scngrp (ebl);
903   if (print_dynamic_table)
904     print_dynamic (ebl);
905   if (print_relocations)
906     print_relocs (pure_ebl, ehdr);
907   if (print_histogram)
908     handle_hash (ebl);
909   if (print_symbol_table)
910     print_symtab (ebl, SHT_DYNSYM);
911   if (print_version_info)
912     print_verinfo (ebl);
913   if (print_symbol_table)
914     print_symtab (ebl, SHT_SYMTAB);
915   if (print_arch)
916     print_liblist (ebl);
917   if (print_arch)
918     print_attributes (ebl, ehdr);
919   if (dump_data_sections != NULL)
920     dump_data (pure_ebl);
921   if (string_sections != NULL)
922     dump_strings (ebl);
923   if ((print_debug_sections | implicit_debug_sections) != 0)
924     print_debug (dwflmod, ebl, ehdr);
925   if (print_notes)
926     handle_notes (pure_ebl, ehdr);
927   if (print_string_sections)
928     print_strings (ebl);
929 
930   ebl_closebackend (ebl);
931 
932   if (pure_ebl != ebl)
933     {
934       ebl_closebackend (pure_ebl);
935       elf_end (pure_elf);
936     }
937 }
938 
939 
940 /* Print file type.  */
941 static void
print_file_type(unsigned short int e_type)942 print_file_type (unsigned short int e_type)
943 {
944   if (likely (e_type <= ET_CORE))
945     {
946       static const char *const knowntypes[] =
947       {
948 	N_("NONE (None)"),
949 	N_("REL (Relocatable file)"),
950 	N_("EXEC (Executable file)"),
951 	N_("DYN (Shared object file)"),
952 	N_("CORE (Core file)")
953       };
954       puts (gettext (knowntypes[e_type]));
955     }
956   else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
957     printf (gettext ("OS Specific: (%x)\n"),  e_type);
958   else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
959     printf (gettext ("Processor Specific: (%x)\n"),  e_type);
960   else
961     puts ("???");
962 }
963 
964 
965 /* Print ELF header.  */
966 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)967 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
968 {
969   fputs_unlocked (gettext ("ELF Header:\n  Magic:  "), stdout);
970   for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
971     printf (" %02hhx", ehdr->e_ident[cnt]);
972 
973   printf (gettext ("\n  Class:                             %s\n"),
974 	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
975 	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
976 	  : "\?\?\?");
977 
978   printf (gettext ("  Data:                              %s\n"),
979 	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
980 	  ? "2's complement, little endian"
981 	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
982 	  ? "2's complement, big endian" : "\?\?\?");
983 
984   printf (gettext ("  Ident Version:                     %hhd %s\n"),
985 	  ehdr->e_ident[EI_VERSION],
986 	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
987 	  : "(\?\?\?)");
988 
989   char buf[512];
990   printf (gettext ("  OS/ABI:                            %s\n"),
991 	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
992 
993   printf (gettext ("  ABI Version:                       %hhd\n"),
994 	  ehdr->e_ident[EI_ABIVERSION]);
995 
996   fputs_unlocked (gettext ("  Type:                              "), stdout);
997   print_file_type (ehdr->e_type);
998 
999   printf (gettext ("  Machine:                           %s\n"), ebl->name);
1000 
1001   printf (gettext ("  Version:                           %d %s\n"),
1002 	  ehdr->e_version,
1003 	  ehdr->e_version  == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1004 
1005   printf (gettext ("  Entry point address:               %#" PRIx64 "\n"),
1006 	  ehdr->e_entry);
1007 
1008   printf (gettext ("  Start of program headers:          %" PRId64 " %s\n"),
1009 	  ehdr->e_phoff, gettext ("(bytes into file)"));
1010 
1011   printf (gettext ("  Start of section headers:          %" PRId64 " %s\n"),
1012 	  ehdr->e_shoff, gettext ("(bytes into file)"));
1013 
1014   printf (gettext ("  Flags:                             %s\n"),
1015 	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1016 
1017   printf (gettext ("  Size of this header:               %" PRId16 " %s\n"),
1018 	  ehdr->e_ehsize, gettext ("(bytes)"));
1019 
1020   printf (gettext ("  Size of program header entries:    %" PRId16 " %s\n"),
1021 	  ehdr->e_phentsize, gettext ("(bytes)"));
1022 
1023   printf (gettext ("  Number of program headers entries: %" PRId16),
1024 	  ehdr->e_phnum);
1025   if (ehdr->e_phnum == PN_XNUM)
1026     {
1027       GElf_Shdr shdr_mem;
1028       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1029       if (shdr != NULL)
1030 	printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1031 		(uint32_t) shdr->sh_info);
1032       else
1033 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
1034     }
1035   fputc_unlocked ('\n', stdout);
1036 
1037   printf (gettext ("  Size of section header entries:    %" PRId16 " %s\n"),
1038 	  ehdr->e_shentsize, gettext ("(bytes)"));
1039 
1040   printf (gettext ("  Number of section headers entries: %" PRId16),
1041 	  ehdr->e_shnum);
1042   if (ehdr->e_shnum == 0)
1043     {
1044       GElf_Shdr shdr_mem;
1045       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1046       if (shdr != NULL)
1047 	printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1048 		(uint32_t) shdr->sh_size);
1049       else
1050 	fputs_unlocked (gettext (" ([0] not available)"), stdout);
1051     }
1052   fputc_unlocked ('\n', stdout);
1053 
1054   if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1055     {
1056       GElf_Shdr shdr_mem;
1057       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1058       if (shdr != NULL)
1059 	/* We managed to get the zeroth section.  */
1060 	snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1061 		  (uint32_t) shdr->sh_link);
1062       else
1063 	{
1064 	  strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1065 	  buf[sizeof (buf) - 1] = '\0';
1066 	}
1067 
1068       printf (gettext ("  Section header string table index: XINDEX%s\n\n"),
1069 	      buf);
1070     }
1071   else
1072     printf (gettext ("  Section header string table index: %" PRId16 "\n\n"),
1073 	    ehdr->e_shstrndx);
1074 }
1075 
1076 
1077 static const char *
get_visibility_type(int value)1078 get_visibility_type (int value)
1079 {
1080   switch (value)
1081     {
1082     case STV_DEFAULT:
1083       return "DEFAULT";
1084     case STV_INTERNAL:
1085       return "INTERNAL";
1086     case STV_HIDDEN:
1087       return "HIDDEN";
1088     case STV_PROTECTED:
1089       return "PROTECTED";
1090     default:
1091       return "???";
1092     }
1093 }
1094 
1095 static const char *
elf_ch_type_name(unsigned int code)1096 elf_ch_type_name (unsigned int code)
1097 {
1098   if (code == 0)
1099     return "NONE";
1100 
1101   if (code == ELFCOMPRESS_ZLIB)
1102     return "ZLIB";
1103 
1104   return "UNKNOWN";
1105 }
1106 
1107 /* Print the section headers.  */
1108 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1109 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1110 {
1111   size_t cnt;
1112   size_t shstrndx;
1113 
1114   if (! print_file_header)
1115     printf (gettext ("\
1116 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1117 \n"),
1118 	    ehdr->e_shnum, ehdr->e_shoff);
1119 
1120   /* Get the section header string table index.  */
1121   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1122     error (EXIT_FAILURE, 0,
1123 	   gettext ("cannot get section header string table index"));
1124 
1125   puts (gettext ("Section Headers:"));
1126 
1127   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1128     puts (gettext ("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
1129   else
1130     puts (gettext ("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
1131 
1132   if (print_decompress)
1133     {
1134       if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1135 	puts (gettext ("     [Compression  Size   Al]"));
1136       else
1137 	puts (gettext ("     [Compression  Size     Al]"));
1138     }
1139 
1140   for (cnt = 0; cnt < shnum; ++cnt)
1141     {
1142       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1143 
1144       if (unlikely (scn == NULL))
1145 	error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1146 	       elf_errmsg (-1));
1147 
1148       /* Get the section header.  */
1149       GElf_Shdr shdr_mem;
1150       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1151       if (unlikely (shdr == NULL))
1152 	error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1153 	       elf_errmsg (-1));
1154 
1155       char flagbuf[20];
1156       char *cp = flagbuf;
1157       if (shdr->sh_flags & SHF_WRITE)
1158 	*cp++ = 'W';
1159       if (shdr->sh_flags & SHF_ALLOC)
1160 	*cp++ = 'A';
1161       if (shdr->sh_flags & SHF_EXECINSTR)
1162 	*cp++ = 'X';
1163       if (shdr->sh_flags & SHF_MERGE)
1164 	*cp++ = 'M';
1165       if (shdr->sh_flags & SHF_STRINGS)
1166 	*cp++ = 'S';
1167       if (shdr->sh_flags & SHF_INFO_LINK)
1168 	*cp++ = 'I';
1169       if (shdr->sh_flags & SHF_LINK_ORDER)
1170 	*cp++ = 'L';
1171       if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1172 	*cp++ = 'N';
1173       if (shdr->sh_flags & SHF_GROUP)
1174 	*cp++ = 'G';
1175       if (shdr->sh_flags & SHF_TLS)
1176 	*cp++ = 'T';
1177       if (shdr->sh_flags & SHF_COMPRESSED)
1178 	*cp++ = 'C';
1179       if (shdr->sh_flags & SHF_ORDERED)
1180 	*cp++ = 'O';
1181       if (shdr->sh_flags & SHF_EXCLUDE)
1182 	*cp++ = 'E';
1183       *cp = '\0';
1184 
1185       const char *sname;
1186       char buf[128];
1187       sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1188       printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1189 	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1190 	      " %2" PRId64 "\n",
1191 	      cnt, sname,
1192 	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1193 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1194 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1195 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1196 	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1197 	      shdr->sh_addralign);
1198 
1199       if (print_decompress)
1200 	{
1201 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1202 	    {
1203 	      GElf_Chdr chdr;
1204 	      if (gelf_getchdr (scn, &chdr) != NULL)
1205 		printf ("     [ELF %s (%" PRId32 ") %0*" PRIx64
1206 			" %2" PRId64 "]\n",
1207 			elf_ch_type_name (chdr.ch_type),
1208 			chdr.ch_type,
1209 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1210 			chdr.ch_size, chdr.ch_addralign);
1211 	      else
1212 		error (0, 0,
1213 		       gettext ("bad compression header for section %zd: %s"),
1214 		       elf_ndxscn (scn), elf_errmsg (-1));
1215 	    }
1216 	  else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1217 	    {
1218 	      ssize_t size;
1219 	      if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1220 		printf ("     [GNU ZLIB     %0*zx   ]\n",
1221 			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1222 	      else
1223 		error (0, 0,
1224 		       gettext ("bad gnu compressed size for section %zd: %s"),
1225 		       elf_ndxscn (scn), elf_errmsg (-1));
1226 	    }
1227 	}
1228     }
1229 
1230   fputc_unlocked ('\n', stdout);
1231 }
1232 
1233 
1234 /* Print the program header.  */
1235 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1236 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1237 {
1238   if (phnum == 0)
1239     /* No program header, this is OK in relocatable objects.  */
1240     return;
1241 
1242   puts (gettext ("Program Headers:"));
1243   if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1244     puts (gettext ("\
1245   Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
1246   else
1247     puts (gettext ("\
1248   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
1249 
1250   /* Process all program headers.  */
1251   bool has_relro = false;
1252   GElf_Addr relro_from = 0;
1253   GElf_Addr relro_to = 0;
1254   for (size_t cnt = 0; cnt < phnum; ++cnt)
1255     {
1256       char buf[128];
1257       GElf_Phdr mem;
1258       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1259 
1260       /* If for some reason the header cannot be returned show this.  */
1261       if (unlikely (phdr == NULL))
1262 	{
1263 	  puts ("  ???");
1264 	  continue;
1265 	}
1266 
1267       printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1268 	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1269 	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1270 	      phdr->p_offset,
1271 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1272 	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1273 	      phdr->p_filesz,
1274 	      phdr->p_memsz,
1275 	      phdr->p_flags & PF_R ? 'R' : ' ',
1276 	      phdr->p_flags & PF_W ? 'W' : ' ',
1277 	      phdr->p_flags & PF_X ? 'E' : ' ',
1278 	      phdr->p_align);
1279 
1280       if (phdr->p_type == PT_INTERP)
1281 	{
1282 	  /* If we are sure the file offset is valid then we can show
1283 	     the user the name of the interpreter.  We check whether
1284 	     there is a section at the file offset.  Normally there
1285 	     would be a section called ".interp".  But in separate
1286 	     .debug files it is a NOBITS section (and so doesn't match
1287 	     with gelf_offscn).  Which probably means the offset is
1288 	     not valid another reason could be because the ELF file
1289 	     just doesn't contain any section headers, in that case
1290 	     just play it safe and don't display anything.  */
1291 
1292 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1293 	  GElf_Shdr shdr_mem;
1294 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1295 
1296 	  size_t maxsize;
1297 	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
1298 
1299 	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1300 	      && filedata != NULL && phdr->p_offset < maxsize
1301 	      && phdr->p_filesz <= maxsize - phdr->p_offset
1302 	      && memchr (filedata + phdr->p_offset, '\0',
1303 			 phdr->p_filesz) != NULL)
1304 	    printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1305 		    filedata + phdr->p_offset);
1306 	}
1307       else if (phdr->p_type == PT_GNU_RELRO)
1308 	{
1309 	  has_relro = true;
1310 	  relro_from = phdr->p_vaddr;
1311 	  relro_to = relro_from + phdr->p_memsz;
1312 	}
1313     }
1314 
1315   if (ehdr->e_shnum == 0)
1316     /* No sections in the file.  Punt.  */
1317     return;
1318 
1319   /* Get the section header string table index.  */
1320   size_t shstrndx;
1321   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1322     error (EXIT_FAILURE, 0,
1323 	   gettext ("cannot get section header string table index"));
1324 
1325   puts (gettext ("\n Section to Segment mapping:\n  Segment Sections..."));
1326 
1327   for (size_t cnt = 0; cnt < phnum; ++cnt)
1328     {
1329       /* Print the segment number.  */
1330       printf ("   %2.2zu     ", cnt);
1331 
1332       GElf_Phdr phdr_mem;
1333       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1334       /* This must not happen.  */
1335       if (unlikely (phdr == NULL))
1336 	error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1337 	       elf_errmsg (-1));
1338 
1339       /* Iterate over the sections.  */
1340       bool in_relro = false;
1341       bool in_ro = false;
1342       for (size_t inner = 1; inner < shnum; ++inner)
1343 	{
1344 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1345 	  /* This should not happen.  */
1346 	  if (unlikely (scn == NULL))
1347 	    error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1348 		   elf_errmsg (-1));
1349 
1350 	  /* Get the section header.  */
1351 	  GElf_Shdr shdr_mem;
1352 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1353 	  if (unlikely (shdr == NULL))
1354 	    error (EXIT_FAILURE, 0,
1355 		   gettext ("cannot get section header: %s"),
1356 		   elf_errmsg (-1));
1357 
1358 	  if (shdr->sh_size > 0
1359 	      /* Compare allocated sections by VMA, unallocated
1360 		 sections by file offset.  */
1361 	      && (shdr->sh_flags & SHF_ALLOC
1362 		  ? (shdr->sh_addr >= phdr->p_vaddr
1363 		     && (shdr->sh_addr + shdr->sh_size
1364 			 <= phdr->p_vaddr + phdr->p_memsz))
1365 		  : (shdr->sh_offset >= phdr->p_offset
1366 		     && (shdr->sh_offset + shdr->sh_size
1367 			 <= phdr->p_offset + phdr->p_filesz))))
1368 	    {
1369 	      if (has_relro && !in_relro
1370 		  && shdr->sh_addr >= relro_from
1371 		  && shdr->sh_addr + shdr->sh_size <= relro_to)
1372 		{
1373 		  fputs_unlocked (" [RELRO:", stdout);
1374 		  in_relro = true;
1375 		}
1376 	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1377 		{
1378 		  fputs_unlocked ("]", stdout);
1379 		  in_relro =  false;
1380 		}
1381 	      else if (has_relro && in_relro
1382 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1383 		fputs_unlocked ("] <RELRO:", stdout);
1384 	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1385 		{
1386 		  if (!in_ro)
1387 		    {
1388 		      fputs_unlocked (" [RO:", stdout);
1389 		      in_ro = true;
1390 		    }
1391 		}
1392 	      else
1393 		{
1394 		  /* Determine the segment this section is part of.  */
1395 		  size_t cnt2;
1396 		  GElf_Phdr phdr2_mem;
1397 		  GElf_Phdr *phdr2 = NULL;
1398 		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1399 		    {
1400 		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1401 
1402 		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1403 			  && shdr->sh_addr >= phdr2->p_vaddr
1404 			  && (shdr->sh_addr + shdr->sh_size
1405 			      <= phdr2->p_vaddr + phdr2->p_memsz))
1406 			break;
1407 		    }
1408 
1409 		  if (cnt2 < phnum)
1410 		    {
1411 		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1412 			{
1413 			  fputs_unlocked (" [RO:", stdout);
1414 			  in_ro = true;
1415 			}
1416 		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1417 			{
1418 			  fputs_unlocked ("]", stdout);
1419 			  in_ro = false;
1420 			}
1421 		    }
1422 		}
1423 
1424 	      printf (" %s",
1425 		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1426 
1427 	      /* Signal that this sectin is only partially covered.  */
1428 	      if (has_relro && in_relro
1429 		       && shdr->sh_addr + shdr->sh_size > relro_to)
1430 		{
1431 		  fputs_unlocked (">", stdout);
1432 		  in_relro =  false;
1433 		}
1434 	    }
1435 	}
1436       if (in_relro || in_ro)
1437 	fputs_unlocked ("]", stdout);
1438 
1439       /* Finish the line.  */
1440       fputc_unlocked ('\n', stdout);
1441     }
1442 }
1443 
1444 
1445 static const char *
section_name(Ebl * ebl,GElf_Ehdr * ehdr,GElf_Shdr * shdr)1446 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1447 {
1448   return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1449 }
1450 
1451 
1452 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1453 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1454 {
1455   /* Get the data of the section.  */
1456   Elf_Data *data = elf_getdata (scn, NULL);
1457 
1458   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1459   GElf_Shdr symshdr_mem;
1460   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1461   Elf_Data *symdata = elf_getdata (symscn, NULL);
1462 
1463   if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1464       || symdata == NULL)
1465     return;
1466 
1467   /* Get the section header string table index.  */
1468   size_t shstrndx;
1469   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1470     error (EXIT_FAILURE, 0,
1471 	   gettext ("cannot get section header string table index"));
1472 
1473   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1474 
1475   GElf_Sym sym_mem;
1476   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1477 
1478   printf ((grpref[0] & GRP_COMDAT)
1479 	  ? ngettext ("\
1480 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1481 		      "\
1482 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1483 		      data->d_size / sizeof (Elf32_Word) - 1)
1484 	  : ngettext ("\
1485 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1486 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1487 		      data->d_size / sizeof (Elf32_Word) - 1),
1488 	  elf_ndxscn (scn),
1489 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1490 	  (sym == NULL ? NULL
1491 	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1492 	  ?: gettext ("<INVALID SYMBOL>"),
1493 	  data->d_size / sizeof (Elf32_Word) - 1);
1494 
1495   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1496     {
1497       GElf_Shdr grpshdr_mem;
1498       GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1499 					 &grpshdr_mem);
1500 
1501       const char *str;
1502       printf ("  [%2u] %s\n",
1503 	      grpref[cnt],
1504 	      grpshdr != NULL
1505 	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1506 	      ? str : gettext ("<INVALID SECTION>"));
1507     }
1508 }
1509 
1510 
1511 static void
print_scngrp(Ebl * ebl)1512 print_scngrp (Ebl *ebl)
1513 {
1514   /* Find all relocation sections and handle them.  */
1515   Elf_Scn *scn = NULL;
1516 
1517   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1518     {
1519        /* Handle the section if it is a symbol table.  */
1520       GElf_Shdr shdr_mem;
1521       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1522 
1523       if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1524 	{
1525 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1526 	    {
1527 	      if (elf_compress (scn, 0, 0) < 0)
1528 		printf ("WARNING: %s [%zd]\n",
1529 			gettext ("Couldn't uncompress section"),
1530 			elf_ndxscn (scn));
1531 	      shdr = gelf_getshdr (scn, &shdr_mem);
1532 	    }
1533 	  handle_scngrp (ebl, scn, shdr);
1534 	}
1535     }
1536 }
1537 
1538 
1539 static const struct flags
1540 {
1541   int mask;
1542   const char *str;
1543 } dt_flags[] =
1544   {
1545     { DF_ORIGIN, "ORIGIN" },
1546     { DF_SYMBOLIC, "SYMBOLIC" },
1547     { DF_TEXTREL, "TEXTREL" },
1548     { DF_BIND_NOW, "BIND_NOW" },
1549     { DF_STATIC_TLS, "STATIC_TLS" }
1550   };
1551 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1552 
1553 static const struct flags dt_flags_1[] =
1554   {
1555     { DF_1_NOW, "NOW" },
1556     { DF_1_GLOBAL, "GLOBAL" },
1557     { DF_1_GROUP, "GROUP" },
1558     { DF_1_NODELETE, "NODELETE" },
1559     { DF_1_LOADFLTR, "LOADFLTR" },
1560     { DF_1_INITFIRST, "INITFIRST" },
1561     { DF_1_NOOPEN, "NOOPEN" },
1562     { DF_1_ORIGIN, "ORIGIN" },
1563     { DF_1_DIRECT, "DIRECT" },
1564     { DF_1_TRANS, "TRANS" },
1565     { DF_1_INTERPOSE, "INTERPOSE" },
1566     { DF_1_NODEFLIB, "NODEFLIB" },
1567     { DF_1_NODUMP, "NODUMP" },
1568     { DF_1_CONFALT, "CONFALT" },
1569     { DF_1_ENDFILTEE, "ENDFILTEE" },
1570     { DF_1_DISPRELDNE, "DISPRELDNE" },
1571     { DF_1_DISPRELPND, "DISPRELPND" },
1572   };
1573 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1574 
1575 static const struct flags dt_feature_1[] =
1576   {
1577     { DTF_1_PARINIT, "PARINIT" },
1578     { DTF_1_CONFEXP, "CONFEXP" }
1579   };
1580 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1581 				  / sizeof (dt_feature_1[0]));
1582 
1583 static const struct flags dt_posflag_1[] =
1584   {
1585     { DF_P1_LAZYLOAD, "LAZYLOAD" },
1586     { DF_P1_GROUPPERM, "GROUPPERM" }
1587   };
1588 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1589 				  / sizeof (dt_posflag_1[0]));
1590 
1591 
1592 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1593 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1594 		int nflags)
1595 {
1596   bool first = true;
1597   int cnt;
1598 
1599   for (cnt = 0; cnt < nflags; ++cnt)
1600     if (d_val & flags[cnt].mask)
1601       {
1602 	if (!first)
1603 	  putchar_unlocked (' ');
1604 	fputs_unlocked (flags[cnt].str, stdout);
1605 	d_val &= ~flags[cnt].mask;
1606 	first = false;
1607       }
1608 
1609   if (d_val != 0)
1610     {
1611       if (!first)
1612 	putchar_unlocked (' ');
1613       printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1614     }
1615 
1616   putchar_unlocked ('\n');
1617 }
1618 
1619 
1620 static void
print_dt_flags(int class,GElf_Xword d_val)1621 print_dt_flags (int class, GElf_Xword d_val)
1622 {
1623   print_flags (class, d_val, dt_flags, ndt_flags);
1624 }
1625 
1626 
1627 static void
print_dt_flags_1(int class,GElf_Xword d_val)1628 print_dt_flags_1 (int class, GElf_Xword d_val)
1629 {
1630   print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1631 }
1632 
1633 
1634 static void
print_dt_feature_1(int class,GElf_Xword d_val)1635 print_dt_feature_1 (int class, GElf_Xword d_val)
1636 {
1637   print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1638 }
1639 
1640 
1641 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1642 print_dt_posflag_1 (int class, GElf_Xword d_val)
1643 {
1644   print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1645 }
1646 
1647 
1648 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1649 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1650 {
1651   int class = gelf_getclass (ebl->elf);
1652   GElf_Shdr glink_mem;
1653   GElf_Shdr *glink;
1654   Elf_Data *data;
1655   size_t cnt;
1656   size_t shstrndx;
1657   size_t sh_entsize;
1658 
1659   /* Get the data of the section.  */
1660   data = elf_getdata (scn, NULL);
1661   if (data == NULL)
1662     return;
1663 
1664   /* Get the section header string table index.  */
1665   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1666     error (EXIT_FAILURE, 0,
1667 	   gettext ("cannot get section header string table index"));
1668 
1669   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1670 
1671   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1672   if (glink == NULL)
1673     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1674 	   elf_ndxscn (scn));
1675 
1676   printf (ngettext ("\
1677 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1678 		    "\
1679 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
1680 		    shdr->sh_size / sh_entsize),
1681 	  (unsigned long int) (shdr->sh_size / sh_entsize),
1682 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1683 	  shdr->sh_offset,
1684 	  (int) shdr->sh_link,
1685 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1686   fputs_unlocked (gettext ("  Type              Value\n"), stdout);
1687 
1688   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1689     {
1690       GElf_Dyn dynmem;
1691       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1692       if (dyn == NULL)
1693 	break;
1694 
1695       char buf[64];
1696       printf ("  %-17s ",
1697 	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1698 
1699       switch (dyn->d_tag)
1700 	{
1701 	case DT_NULL:
1702 	case DT_DEBUG:
1703 	case DT_BIND_NOW:
1704 	case DT_TEXTREL:
1705 	  /* No further output.  */
1706 	  fputc_unlocked ('\n', stdout);
1707 	  break;
1708 
1709 	case DT_NEEDED:
1710 	  printf (gettext ("Shared library: [%s]\n"),
1711 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1712 	  break;
1713 
1714 	case DT_SONAME:
1715 	  printf (gettext ("Library soname: [%s]\n"),
1716 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1717 	  break;
1718 
1719 	case DT_RPATH:
1720 	  printf (gettext ("Library rpath: [%s]\n"),
1721 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1722 	  break;
1723 
1724 	case DT_RUNPATH:
1725 	  printf (gettext ("Library runpath: [%s]\n"),
1726 		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1727 	  break;
1728 
1729 	case DT_PLTRELSZ:
1730 	case DT_RELASZ:
1731 	case DT_STRSZ:
1732 	case DT_RELSZ:
1733 	case DT_RELAENT:
1734 	case DT_SYMENT:
1735 	case DT_RELENT:
1736 	case DT_PLTPADSZ:
1737 	case DT_MOVEENT:
1738 	case DT_MOVESZ:
1739 	case DT_INIT_ARRAYSZ:
1740 	case DT_FINI_ARRAYSZ:
1741 	case DT_SYMINSZ:
1742 	case DT_SYMINENT:
1743 	case DT_GNU_CONFLICTSZ:
1744 	case DT_GNU_LIBLISTSZ:
1745 	  printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1746 	  break;
1747 
1748 	case DT_VERDEFNUM:
1749 	case DT_VERNEEDNUM:
1750 	case DT_RELACOUNT:
1751 	case DT_RELCOUNT:
1752 	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
1753 	  break;
1754 
1755 	case DT_PLTREL:;
1756 	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1757 						      NULL, 0);
1758 	  puts (tagname ?: "???");
1759 	  break;
1760 
1761 	case DT_FLAGS:
1762 	  print_dt_flags (class, dyn->d_un.d_val);
1763 	  break;
1764 
1765 	case DT_FLAGS_1:
1766 	  print_dt_flags_1 (class, dyn->d_un.d_val);
1767 	  break;
1768 
1769 	case DT_FEATURE_1:
1770 	  print_dt_feature_1 (class, dyn->d_un.d_val);
1771 	  break;
1772 
1773 	case DT_POSFLAG_1:
1774 	  print_dt_posflag_1 (class, dyn->d_un.d_val);
1775 	  break;
1776 
1777 	default:
1778 	  printf ("%#0*" PRIx64 "\n",
1779 		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1780 	  break;
1781 	}
1782     }
1783 }
1784 
1785 
1786 /* Print the dynamic segment.  */
1787 static void
print_dynamic(Ebl * ebl)1788 print_dynamic (Ebl *ebl)
1789 {
1790   for (size_t i = 0; i < phnum; ++i)
1791     {
1792       GElf_Phdr phdr_mem;
1793       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1794 
1795       if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1796 	{
1797 	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1798 	  GElf_Shdr shdr_mem;
1799 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1800 	  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1801 	    handle_dynamic (ebl, scn, shdr);
1802 	  break;
1803 	}
1804     }
1805 }
1806 
1807 
1808 /* Print relocations.  */
1809 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1810 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1811 {
1812   /* Find all relocation sections and handle them.  */
1813   Elf_Scn *scn = NULL;
1814 
1815   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1816     {
1817        /* Handle the section if it is a symbol table.  */
1818       GElf_Shdr shdr_mem;
1819       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1820 
1821       if (likely (shdr != NULL))
1822 	{
1823 	  if (shdr->sh_type == SHT_REL)
1824 	    handle_relocs_rel (ebl, ehdr, scn, shdr);
1825 	  else if (shdr->sh_type == SHT_RELA)
1826 	    handle_relocs_rela (ebl, ehdr, scn, shdr);
1827 	}
1828     }
1829 }
1830 
1831 
1832 /* Handle a relocation section.  */
1833 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1834 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1835 {
1836   int class = gelf_getclass (ebl->elf);
1837   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1838   int nentries = shdr->sh_size / sh_entsize;
1839 
1840   /* Get the data of the section.  */
1841   Elf_Data *data = elf_getdata (scn, NULL);
1842   if (data == NULL)
1843     return;
1844 
1845   /* Get the symbol table information.  */
1846   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1847   GElf_Shdr symshdr_mem;
1848   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1849   Elf_Data *symdata = elf_getdata (symscn, NULL);
1850 
1851   /* Get the section header of the section the relocations are for.  */
1852   GElf_Shdr destshdr_mem;
1853   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1854 				      &destshdr_mem);
1855 
1856   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1857     {
1858       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1859 	      shdr->sh_offset);
1860       return;
1861     }
1862 
1863   /* Search for the optional extended section index table.  */
1864   Elf_Data *xndxdata = NULL;
1865   int xndxscnidx = elf_scnshndx (scn);
1866   if (unlikely (xndxscnidx > 0))
1867     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1868 
1869   /* Get the section header string table index.  */
1870   size_t shstrndx;
1871   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1872     error (EXIT_FAILURE, 0,
1873 	   gettext ("cannot get section header string table index"));
1874 
1875   if (shdr->sh_info != 0)
1876     printf (ngettext ("\
1877 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1878 		    "\
1879 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1880 		      nentries),
1881 	    elf_ndxscn (scn),
1882 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1883 	    (unsigned int) shdr->sh_info,
1884 	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1885 	    shdr->sh_offset,
1886 	    nentries);
1887   else
1888     /* The .rel.dyn section does not refer to a specific section but
1889        instead of section index zero.  Do not try to print a section
1890        name.  */
1891     printf (ngettext ("\
1892 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1893 		    "\
1894 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1895 		      nentries),
1896 	    (unsigned int) elf_ndxscn (scn),
1897 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1898 	    shdr->sh_offset,
1899 	    nentries);
1900   fputs_unlocked (class == ELFCLASS32
1901 		  ? gettext ("\
1902   Offset      Type                 Value       Name\n")
1903 		  : gettext ("\
1904   Offset              Type                 Value               Name\n"),
1905 	 stdout);
1906 
1907   int is_statically_linked = 0;
1908   for (int cnt = 0; cnt < nentries; ++cnt)
1909     {
1910       GElf_Rel relmem;
1911       GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1912       if (likely (rel != NULL))
1913 	{
1914 	  char buf[128];
1915 	  GElf_Sym symmem;
1916 	  Elf32_Word xndx;
1917 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1918 					    GELF_R_SYM (rel->r_info),
1919 					    &symmem, &xndx);
1920 	  if (unlikely (sym == NULL))
1921 	    {
1922 	      /* As a special case we have to handle relocations in static
1923 		 executables.  This only happens for IRELATIVE relocations
1924 		 (so far).  There is no symbol table.  */
1925 	      if (is_statically_linked == 0)
1926 		{
1927 		  /* Find the program header and look for a PT_INTERP entry. */
1928 		  is_statically_linked = -1;
1929 		  if (ehdr->e_type == ET_EXEC)
1930 		    {
1931 		      is_statically_linked = 1;
1932 
1933 		      for (size_t inner = 0; inner < phnum; ++inner)
1934 			{
1935 			  GElf_Phdr phdr_mem;
1936 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1937 							  &phdr_mem);
1938 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
1939 			    {
1940 			      is_statically_linked = -1;
1941 			      break;
1942 			    }
1943 			}
1944 		    }
1945 		}
1946 
1947 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
1948 		printf ("\
1949   %#0*" PRIx64 "  %-20s %*s  %s\n",
1950 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1951 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1952 			/* Avoid the leading R_ which isn't carrying any
1953 			   information.  */
1954 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1955 					       buf, sizeof (buf)) + 2
1956 			: gettext ("<INVALID RELOC>"),
1957 			class == ELFCLASS32 ? 10 : 18, "",
1958 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1959 	      else
1960 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
1961 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1962 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1963 			/* Avoid the leading R_ which isn't carrying any
1964 			   information.  */
1965 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1966 					       buf, sizeof (buf)) + 2
1967 			: gettext ("<INVALID RELOC>"),
1968 			gettext ("INVALID SYMBOL"),
1969 			(long int) GELF_R_SYM (rel->r_info));
1970 	    }
1971 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1972 	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
1973 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1974 		    likely (ebl_reloc_type_check (ebl,
1975 						  GELF_R_TYPE (rel->r_info)))
1976 		    /* Avoid the leading R_ which isn't carrying any
1977 		       information.  */
1978 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1979 					   buf, sizeof (buf)) + 2
1980 		    : gettext ("<INVALID RELOC>"),
1981 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
1982 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1983 	  else
1984 	    {
1985 	      /* This is a relocation against a STT_SECTION symbol.  */
1986 	      GElf_Shdr secshdr_mem;
1987 	      GElf_Shdr *secshdr;
1988 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
1989 						  sym->st_shndx == SHN_XINDEX
1990 						  ? xndx : sym->st_shndx),
1991 				      &secshdr_mem);
1992 
1993 	      if (unlikely (secshdr == NULL))
1994 		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
1995 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1996 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1997 			/* Avoid the leading R_ which isn't carrying any
1998 			   information.  */
1999 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2000 					       buf, sizeof (buf)) + 2
2001 			: gettext ("<INVALID RELOC>"),
2002 			gettext ("INVALID SECTION"),
2003 			(long int) (sym->st_shndx == SHN_XINDEX
2004 				    ? xndx : sym->st_shndx));
2005 	      else
2006 		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
2007 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2008 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2009 			/* Avoid the leading R_ which isn't carrying any
2010 			   information.  */
2011 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2012 					       buf, sizeof (buf)) + 2
2013 			: gettext ("<INVALID RELOC>"),
2014 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2015 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2016 	    }
2017 	}
2018     }
2019 }
2020 
2021 
2022 /* Handle a relocation section.  */
2023 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2024 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2025 {
2026   int class = gelf_getclass (ebl->elf);
2027   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2028   int nentries = shdr->sh_size / sh_entsize;
2029 
2030   /* Get the data of the section.  */
2031   Elf_Data *data = elf_getdata (scn, NULL);
2032   if (data == NULL)
2033     return;
2034 
2035   /* Get the symbol table information.  */
2036   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2037   GElf_Shdr symshdr_mem;
2038   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2039   Elf_Data *symdata = elf_getdata (symscn, NULL);
2040 
2041   /* Get the section header of the section the relocations are for.  */
2042   GElf_Shdr destshdr_mem;
2043   GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2044 				      &destshdr_mem);
2045 
2046   if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2047     {
2048       printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2049 	      shdr->sh_offset);
2050       return;
2051     }
2052 
2053   /* Search for the optional extended section index table.  */
2054   Elf_Data *xndxdata = NULL;
2055   int xndxscnidx = elf_scnshndx (scn);
2056   if (unlikely (xndxscnidx > 0))
2057     xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2058 
2059   /* Get the section header string table index.  */
2060   size_t shstrndx;
2061   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2062     error (EXIT_FAILURE, 0,
2063 	   gettext ("cannot get section header string table index"));
2064 
2065   if (shdr->sh_info != 0)
2066     printf (ngettext ("\
2067 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2068 		    "\
2069 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2070 		    nentries),
2071 	  elf_ndxscn (scn),
2072 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2073 	  (unsigned int) shdr->sh_info,
2074 	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2075 	  shdr->sh_offset,
2076 	  nentries);
2077   else
2078     /* The .rela.dyn section does not refer to a specific section but
2079        instead of section index zero.  Do not try to print a section
2080        name.  */
2081     printf (ngettext ("\
2082 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2083 		    "\
2084 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2085 		      nentries),
2086 	    (unsigned int) elf_ndxscn (scn),
2087 	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2088 	    shdr->sh_offset,
2089 	    nentries);
2090   fputs_unlocked (class == ELFCLASS32
2091 		  ? gettext ("\
2092   Offset      Type            Value       Addend Name\n")
2093 		  : gettext ("\
2094   Offset              Type            Value               Addend Name\n"),
2095 		  stdout);
2096 
2097   int is_statically_linked = 0;
2098   for (int cnt = 0; cnt < nentries; ++cnt)
2099     {
2100       GElf_Rela relmem;
2101       GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2102       if (likely (rel != NULL))
2103 	{
2104 	  char buf[64];
2105 	  GElf_Sym symmem;
2106 	  Elf32_Word xndx;
2107 	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2108 					    GELF_R_SYM (rel->r_info),
2109 					    &symmem, &xndx);
2110 
2111 	  if (unlikely (sym == NULL))
2112 	    {
2113 	      /* As a special case we have to handle relocations in static
2114 		 executables.  This only happens for IRELATIVE relocations
2115 		 (so far).  There is no symbol table.  */
2116 	      if (is_statically_linked == 0)
2117 		{
2118 		  /* Find the program header and look for a PT_INTERP entry. */
2119 		  is_statically_linked = -1;
2120 		  if (ehdr->e_type == ET_EXEC)
2121 		    {
2122 		      is_statically_linked = 1;
2123 
2124 		      for (size_t inner = 0; inner < phnum; ++inner)
2125 			{
2126 			  GElf_Phdr phdr_mem;
2127 			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2128 							  &phdr_mem);
2129 			  if (phdr != NULL && phdr->p_type == PT_INTERP)
2130 			    {
2131 			      is_statically_linked = -1;
2132 			      break;
2133 			    }
2134 			}
2135 		    }
2136 		}
2137 
2138 	      if (is_statically_linked > 0 && shdr->sh_link == 0)
2139 		printf ("\
2140   %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
2141 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2142 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2143 			/* Avoid the leading R_ which isn't carrying any
2144 			   information.  */
2145 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2146 					       buf, sizeof (buf)) + 2
2147 			: gettext ("<INVALID RELOC>"),
2148 			class == ELFCLASS32 ? 10 : 18, "",
2149 			rel->r_addend,
2150 			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2151 	      else
2152 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2153 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2154 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2155 			/* Avoid the leading R_ which isn't carrying any
2156 			   information.  */
2157 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2158 					       buf, sizeof (buf)) + 2
2159 			: gettext ("<INVALID RELOC>"),
2160 			gettext ("INVALID SYMBOL"),
2161 			(long int) GELF_R_SYM (rel->r_info));
2162 	    }
2163 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2164 	    printf ("\
2165   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2166 		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2167 		    likely (ebl_reloc_type_check (ebl,
2168 						  GELF_R_TYPE (rel->r_info)))
2169 		    /* Avoid the leading R_ which isn't carrying any
2170 		       information.  */
2171 		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2172 					   buf, sizeof (buf)) + 2
2173 		    : gettext ("<INVALID RELOC>"),
2174 		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
2175 		    rel->r_addend,
2176 		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2177 	  else
2178 	    {
2179 	      /* This is a relocation against a STT_SECTION symbol.  */
2180 	      GElf_Shdr secshdr_mem;
2181 	      GElf_Shdr *secshdr;
2182 	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2183 						  sym->st_shndx == SHN_XINDEX
2184 						  ? xndx : sym->st_shndx),
2185 				      &secshdr_mem);
2186 
2187 	      if (unlikely (secshdr == NULL))
2188 		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
2189 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2190 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2191 			/* Avoid the leading R_ which isn't carrying any
2192 			   information.  */
2193 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2194 					       buf, sizeof (buf)) + 2
2195 			: gettext ("<INVALID RELOC>"),
2196 			gettext ("INVALID SECTION"),
2197 			(long int) (sym->st_shndx == SHN_XINDEX
2198 				    ? xndx : sym->st_shndx));
2199 	      else
2200 		printf ("\
2201   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
2202 			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2203 			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2204 			/* Avoid the leading R_ which isn't carrying any
2205 			   information.  */
2206 			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2207 					       buf, sizeof (buf)) + 2
2208 			: gettext ("<INVALID RELOC>"),
2209 			class == ELFCLASS32 ? 10 : 18, sym->st_value,
2210 			rel->r_addend,
2211 			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2212 	    }
2213 	}
2214     }
2215 }
2216 
2217 
2218 /* Print the program header.  */
2219 static void
print_symtab(Ebl * ebl,int type)2220 print_symtab (Ebl *ebl, int type)
2221 {
2222   /* Find the symbol table(s).  For this we have to search through the
2223      section table.  */
2224   Elf_Scn *scn = NULL;
2225 
2226   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2227     {
2228       /* Handle the section if it is a symbol table.  */
2229       GElf_Shdr shdr_mem;
2230       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2231 
2232       if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2233 	{
2234 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2235 	    {
2236 	      if (elf_compress (scn, 0, 0) < 0)
2237 		printf ("WARNING: %s [%zd]\n",
2238 			gettext ("Couldn't uncompress section"),
2239 			elf_ndxscn (scn));
2240 	      shdr = gelf_getshdr (scn, &shdr_mem);
2241 	    }
2242 	  handle_symtab (ebl, scn, shdr);
2243 	}
2244     }
2245 }
2246 
2247 
2248 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2249 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2250 {
2251   Elf_Data *versym_data = NULL;
2252   Elf_Data *verneed_data = NULL;
2253   Elf_Data *verdef_data = NULL;
2254   Elf_Data *xndx_data = NULL;
2255   int class = gelf_getclass (ebl->elf);
2256   Elf32_Word verneed_stridx = 0;
2257   Elf32_Word verdef_stridx = 0;
2258 
2259   /* Get the data of the section.  */
2260   Elf_Data *data = elf_getdata (scn, NULL);
2261   if (data == NULL)
2262     return;
2263 
2264   /* Find out whether we have other sections we might need.  */
2265   Elf_Scn *runscn = NULL;
2266   while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2267     {
2268       GElf_Shdr runshdr_mem;
2269       GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2270 
2271       if (likely (runshdr != NULL))
2272 	{
2273 	  if (runshdr->sh_type == SHT_GNU_versym
2274 	      && runshdr->sh_link == elf_ndxscn (scn))
2275 	    /* Bingo, found the version information.  Now get the data.  */
2276 	    versym_data = elf_getdata (runscn, NULL);
2277 	  else if (runshdr->sh_type == SHT_GNU_verneed)
2278 	    {
2279 	      /* This is the information about the needed versions.  */
2280 	      verneed_data = elf_getdata (runscn, NULL);
2281 	      verneed_stridx = runshdr->sh_link;
2282 	    }
2283 	  else if (runshdr->sh_type == SHT_GNU_verdef)
2284 	    {
2285 	      /* This is the information about the defined versions.  */
2286 	      verdef_data = elf_getdata (runscn, NULL);
2287 	      verdef_stridx = runshdr->sh_link;
2288 	    }
2289 	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2290 	      && runshdr->sh_link == elf_ndxscn (scn))
2291 	    /* Extended section index.  */
2292 	    xndx_data = elf_getdata (runscn, NULL);
2293 	}
2294     }
2295 
2296   /* Get the section header string table index.  */
2297   size_t shstrndx;
2298   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2299     error (EXIT_FAILURE, 0,
2300 	   gettext ("cannot get section header string table index"));
2301 
2302   GElf_Shdr glink_mem;
2303   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2304 				   &glink_mem);
2305   if (glink == NULL)
2306     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2307 	   elf_ndxscn (scn));
2308 
2309   /* Now we can compute the number of entries in the section.  */
2310   unsigned int nsyms = data->d_size / (class == ELFCLASS32
2311 				       ? sizeof (Elf32_Sym)
2312 				       : sizeof (Elf64_Sym));
2313 
2314   printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2315 		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
2316 		    nsyms),
2317 	  (unsigned int) elf_ndxscn (scn),
2318 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2319   printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
2320 		    " %lu local symbols  String table: [%2u] '%s'\n",
2321 		    shdr->sh_info),
2322 	  (unsigned long int) shdr->sh_info,
2323 	  (unsigned int) shdr->sh_link,
2324 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2325 
2326   fputs_unlocked (class == ELFCLASS32
2327 		  ? gettext ("\
2328   Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
2329 		  : gettext ("\
2330   Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
2331 		  stdout);
2332 
2333   for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2334     {
2335       char typebuf[64];
2336       char bindbuf[64];
2337       char scnbuf[64];
2338       Elf32_Word xndx;
2339       GElf_Sym sym_mem;
2340       GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2341 
2342       if (unlikely (sym == NULL))
2343 	continue;
2344 
2345       /* Determine the real section index.  */
2346       if (likely (sym->st_shndx != SHN_XINDEX))
2347 	xndx = sym->st_shndx;
2348 
2349       printf (gettext ("\
2350 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2351 	      cnt,
2352 	      class == ELFCLASS32 ? 8 : 16,
2353 	      sym->st_value,
2354 	      sym->st_size,
2355 	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2356 				    typebuf, sizeof (typebuf)),
2357 	      ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2358 				       bindbuf, sizeof (bindbuf)),
2359 	      get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2360 	      ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2361 				sizeof (scnbuf), NULL, shnum),
2362 	      elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2363 
2364       if (versym_data != NULL)
2365 	{
2366 	  /* Get the version information.  */
2367 	  GElf_Versym versym_mem;
2368 	  GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2369 
2370 	  if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2371 	    {
2372 	      bool is_nobits = false;
2373 	      bool check_def = xndx != SHN_UNDEF;
2374 
2375 	      if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2376 		{
2377 		  GElf_Shdr symshdr_mem;
2378 		  GElf_Shdr *symshdr =
2379 		    gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2380 
2381 		  is_nobits = (symshdr != NULL
2382 			       && symshdr->sh_type == SHT_NOBITS);
2383 		}
2384 
2385 	      if (is_nobits || ! check_def)
2386 		{
2387 		  /* We must test both.  */
2388 		  GElf_Vernaux vernaux_mem;
2389 		  GElf_Vernaux *vernaux = NULL;
2390 		  size_t vn_offset = 0;
2391 
2392 		  GElf_Verneed verneed_mem;
2393 		  GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2394 							   &verneed_mem);
2395 		  while (verneed != NULL)
2396 		    {
2397 		      size_t vna_offset = vn_offset;
2398 
2399 		      vernaux = gelf_getvernaux (verneed_data,
2400 						 vna_offset += verneed->vn_aux,
2401 						 &vernaux_mem);
2402 		      while (vernaux != NULL
2403 			     && vernaux->vna_other != *versym
2404 			     && vernaux->vna_next != 0)
2405 			{
2406 			  /* Update the offset.  */
2407 			  vna_offset += vernaux->vna_next;
2408 
2409 			  vernaux = (vernaux->vna_next == 0
2410 				     ? NULL
2411 				     : gelf_getvernaux (verneed_data,
2412 							vna_offset,
2413 							&vernaux_mem));
2414 			}
2415 
2416 		      /* Check whether we found the version.  */
2417 		      if (vernaux != NULL && vernaux->vna_other == *versym)
2418 			/* Found it.  */
2419 			break;
2420 
2421 		      vn_offset += verneed->vn_next;
2422 		      verneed = (verneed->vn_next == 0
2423 				 ? NULL
2424 				 : gelf_getverneed (verneed_data, vn_offset,
2425 						    &verneed_mem));
2426 		    }
2427 
2428 		  if (vernaux != NULL && vernaux->vna_other == *versym)
2429 		    {
2430 		      printf ("@%s (%u)",
2431 			      elf_strptr (ebl->elf, verneed_stridx,
2432 					  vernaux->vna_name),
2433 			      (unsigned int) vernaux->vna_other);
2434 		      check_def = 0;
2435 		    }
2436 		  else if (unlikely (! is_nobits))
2437 		    error (0, 0, gettext ("bad dynamic symbol"));
2438 		  else
2439 		    check_def = 1;
2440 		}
2441 
2442 	      if (check_def && *versym != 0x8001)
2443 		{
2444 		  /* We must test both.  */
2445 		  size_t vd_offset = 0;
2446 
2447 		  GElf_Verdef verdef_mem;
2448 		  GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2449 							&verdef_mem);
2450 		  while (verdef != NULL)
2451 		    {
2452 		      if (verdef->vd_ndx == (*versym & 0x7fff))
2453 			/* Found the definition.  */
2454 			break;
2455 
2456 		      vd_offset += verdef->vd_next;
2457 		      verdef = (verdef->vd_next == 0
2458 				? NULL
2459 				: gelf_getverdef (verdef_data, vd_offset,
2460 						  &verdef_mem));
2461 		    }
2462 
2463 		  if (verdef != NULL)
2464 		    {
2465 		      GElf_Verdaux verdaux_mem;
2466 		      GElf_Verdaux *verdaux
2467 			= gelf_getverdaux (verdef_data,
2468 					   vd_offset + verdef->vd_aux,
2469 					   &verdaux_mem);
2470 
2471 		      if (verdaux != NULL)
2472 			printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2473 				elf_strptr (ebl->elf, verdef_stridx,
2474 					    verdaux->vda_name));
2475 		    }
2476 		}
2477 	    }
2478 	}
2479 
2480       putchar_unlocked ('\n');
2481     }
2482 }
2483 
2484 
2485 /* Print version information.  */
2486 static void
print_verinfo(Ebl * ebl)2487 print_verinfo (Ebl *ebl)
2488 {
2489   /* Find the version information sections.  For this we have to
2490      search through the section table.  */
2491   Elf_Scn *scn = NULL;
2492 
2493   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2494     {
2495       /* Handle the section if it is part of the versioning handling.  */
2496       GElf_Shdr shdr_mem;
2497       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2498 
2499       if (likely (shdr != NULL))
2500 	{
2501 	  if (shdr->sh_type == SHT_GNU_verneed)
2502 	    handle_verneed (ebl, scn, shdr);
2503 	  else if (shdr->sh_type == SHT_GNU_verdef)
2504 	    handle_verdef (ebl, scn, shdr);
2505 	  else if (shdr->sh_type == SHT_GNU_versym)
2506 	    handle_versym (ebl, scn, shdr);
2507 	}
2508     }
2509 }
2510 
2511 
2512 static const char *
get_ver_flags(unsigned int flags)2513 get_ver_flags (unsigned int flags)
2514 {
2515   static char buf[32];
2516   char *endp;
2517 
2518   if (flags == 0)
2519     return gettext ("none");
2520 
2521   if (flags & VER_FLG_BASE)
2522     endp = stpcpy (buf, "BASE ");
2523   else
2524     endp = buf;
2525 
2526   if (flags & VER_FLG_WEAK)
2527     {
2528       if (endp != buf)
2529 	endp = stpcpy (endp, "| ");
2530 
2531       endp = stpcpy (endp, "WEAK ");
2532     }
2533 
2534   if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2535     {
2536       strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2537       buf[sizeof (buf) - 1] = '\0';
2538     }
2539 
2540   return buf;
2541 }
2542 
2543 
2544 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2545 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2546 {
2547   int class = gelf_getclass (ebl->elf);
2548 
2549   /* Get the data of the section.  */
2550   Elf_Data *data = elf_getdata (scn, NULL);
2551   if (data == NULL)
2552     return;
2553 
2554   /* Get the section header string table index.  */
2555   size_t shstrndx;
2556   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2557     error (EXIT_FAILURE, 0,
2558 	   gettext ("cannot get section header string table index"));
2559 
2560   GElf_Shdr glink_mem;
2561   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2562 				   &glink_mem);
2563   if (glink == NULL)
2564     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2565 	   elf_ndxscn (scn));
2566 
2567   printf (ngettext ("\
2568 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2569 		    "\
2570 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2571 		    shdr->sh_info),
2572 	  (unsigned int) elf_ndxscn (scn),
2573 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2574 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2575 	  shdr->sh_offset,
2576 	  (unsigned int) shdr->sh_link,
2577 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2578 
2579   unsigned int offset = 0;
2580   for (int cnt = shdr->sh_info; --cnt >= 0; )
2581     {
2582       /* Get the data at the next offset.  */
2583       GElf_Verneed needmem;
2584       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2585       if (unlikely (need == NULL))
2586 	break;
2587 
2588       printf (gettext ("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
2589 	      offset, (unsigned short int) need->vn_version,
2590 	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2591 	      (unsigned short int) need->vn_cnt);
2592 
2593       unsigned int auxoffset = offset + need->vn_aux;
2594       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2595 	{
2596 	  GElf_Vernaux auxmem;
2597 	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2598 	  if (unlikely (aux == NULL))
2599 	    break;
2600 
2601 	  printf (gettext ("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
2602 		  auxoffset,
2603 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2604 		  get_ver_flags (aux->vna_flags),
2605 		  (unsigned short int) aux->vna_other);
2606 
2607 	  if (aux->vna_next == 0)
2608 	    break;
2609 
2610 	  auxoffset += aux->vna_next;
2611 	}
2612 
2613       /* Find the next offset.  */
2614       if (need->vn_next == 0)
2615 	break;
2616 
2617       offset += need->vn_next;
2618     }
2619 }
2620 
2621 
2622 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2623 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2624 {
2625   /* Get the data of the section.  */
2626   Elf_Data *data = elf_getdata (scn, NULL);
2627   if (data == NULL)
2628     return;
2629 
2630   /* Get the section header string table index.  */
2631   size_t shstrndx;
2632   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2633     error (EXIT_FAILURE, 0,
2634 	   gettext ("cannot get section header string table index"));
2635 
2636   GElf_Shdr glink_mem;
2637   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2638 				   &glink_mem);
2639   if (glink == NULL)
2640     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2641 	   elf_ndxscn (scn));
2642 
2643   int class = gelf_getclass (ebl->elf);
2644   printf (ngettext ("\
2645 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2646 		    "\
2647 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
2648 		    shdr->sh_info),
2649 	  (unsigned int) elf_ndxscn (scn),
2650 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2651 	  shdr->sh_info,
2652 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2653 	  shdr->sh_offset,
2654 	  (unsigned int) shdr->sh_link,
2655 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2656 
2657   unsigned int offset = 0;
2658   for (int cnt = shdr->sh_info; --cnt >= 0; )
2659     {
2660       /* Get the data at the next offset.  */
2661       GElf_Verdef defmem;
2662       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2663       if (unlikely (def == NULL))
2664 	break;
2665 
2666       unsigned int auxoffset = offset + def->vd_aux;
2667       GElf_Verdaux auxmem;
2668       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2669       if (unlikely (aux == NULL))
2670 	break;
2671 
2672       printf (gettext ("\
2673   %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
2674 	      offset, def->vd_version,
2675 	      get_ver_flags (def->vd_flags),
2676 	      def->vd_ndx,
2677 	      def->vd_cnt,
2678 	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2679 
2680       auxoffset += aux->vda_next;
2681       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2682 	{
2683 	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
2684 	  if (unlikely (aux == NULL))
2685 	    break;
2686 
2687 	  printf (gettext ("  %#06x: Parent %d: %s\n"),
2688 		  auxoffset, cnt2,
2689 		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2690 
2691 	  if (aux->vda_next == 0)
2692 	    break;
2693 
2694 	  auxoffset += aux->vda_next;
2695 	}
2696 
2697       /* Find the next offset.  */
2698       if (def->vd_next == 0)
2699 	break;
2700       offset += def->vd_next;
2701     }
2702 }
2703 
2704 
2705 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2706 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2707 {
2708   int class = gelf_getclass (ebl->elf);
2709   const char **vername;
2710   const char **filename;
2711 
2712   /* Get the data of the section.  */
2713   Elf_Data *data = elf_getdata (scn, NULL);
2714   if (data == NULL)
2715     return;
2716 
2717   /* Get the section header string table index.  */
2718   size_t shstrndx;
2719   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2720     error (EXIT_FAILURE, 0,
2721 	   gettext ("cannot get section header string table index"));
2722 
2723   /* We have to find the version definition section and extract the
2724      version names.  */
2725   Elf_Scn *defscn = NULL;
2726   Elf_Scn *needscn = NULL;
2727 
2728   Elf_Scn *verscn = NULL;
2729   while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2730     {
2731       GElf_Shdr vershdr_mem;
2732       GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2733 
2734       if (likely (vershdr != NULL))
2735 	{
2736 	  if (vershdr->sh_type == SHT_GNU_verdef)
2737 	    defscn = verscn;
2738 	  else if (vershdr->sh_type == SHT_GNU_verneed)
2739 	    needscn = verscn;
2740 	}
2741     }
2742 
2743   size_t nvername;
2744   if (defscn != NULL || needscn != NULL)
2745     {
2746       /* We have a version information (better should have).  Now get
2747 	 the version names.  First find the maximum version number.  */
2748       nvername = 0;
2749       if (defscn != NULL)
2750 	{
2751 	  /* Run through the version definitions and find the highest
2752 	     index.  */
2753 	  unsigned int offset = 0;
2754 	  Elf_Data *defdata;
2755 	  GElf_Shdr defshdrmem;
2756 	  GElf_Shdr *defshdr;
2757 
2758 	  defdata = elf_getdata (defscn, NULL);
2759 	  if (unlikely (defdata == NULL))
2760 	    return;
2761 
2762 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
2763 	  if (unlikely (defshdr == NULL))
2764 	    return;
2765 
2766 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2767 	    {
2768 	      GElf_Verdef defmem;
2769 	      GElf_Verdef *def;
2770 
2771 	      /* Get the data at the next offset.  */
2772 	      def = gelf_getverdef (defdata, offset, &defmem);
2773 	      if (unlikely (def == NULL))
2774 		break;
2775 
2776 	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2777 
2778 	      if (def->vd_next == 0)
2779 		break;
2780 	      offset += def->vd_next;
2781 	    }
2782 	}
2783       if (needscn != NULL)
2784 	{
2785 	  unsigned int offset = 0;
2786 	  Elf_Data *needdata;
2787 	  GElf_Shdr needshdrmem;
2788 	  GElf_Shdr *needshdr;
2789 
2790 	  needdata = elf_getdata (needscn, NULL);
2791 	  if (unlikely (needdata == NULL))
2792 	    return;
2793 
2794 	  needshdr = gelf_getshdr (needscn, &needshdrmem);
2795 	  if (unlikely (needshdr == NULL))
2796 	    return;
2797 
2798 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2799 	    {
2800 	      GElf_Verneed needmem;
2801 	      GElf_Verneed *need;
2802 	      unsigned int auxoffset;
2803 	      int cnt2;
2804 
2805 	      /* Get the data at the next offset.  */
2806 	      need = gelf_getverneed (needdata, offset, &needmem);
2807 	      if (unlikely (need == NULL))
2808 		break;
2809 
2810 	      /* Run through the auxiliary entries.  */
2811 	      auxoffset = offset + need->vn_aux;
2812 	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2813 		{
2814 		  GElf_Vernaux auxmem;
2815 		  GElf_Vernaux *aux;
2816 
2817 		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2818 		  if (unlikely (aux == NULL))
2819 		    break;
2820 
2821 		  nvername = MAX (nvername,
2822 				  (size_t) (aux->vna_other & 0x7fff));
2823 
2824 		  if (aux->vna_next == 0)
2825 		    break;
2826 		  auxoffset += aux->vna_next;
2827 		}
2828 
2829 	      if (need->vn_next == 0)
2830 		break;
2831 	      offset += need->vn_next;
2832 	    }
2833 	}
2834 
2835       /* This is the number of versions we know about.  */
2836       ++nvername;
2837 
2838       /* Allocate the array.  */
2839       vername = (const char **) alloca (nvername * sizeof (const char *));
2840       memset(vername, 0, nvername * sizeof (const char *));
2841       filename = (const char **) alloca (nvername * sizeof (const char *));
2842       memset(filename, 0, nvername * sizeof (const char *));
2843 
2844       /* Run through the data structures again and collect the strings.  */
2845       if (defscn != NULL)
2846 	{
2847 	  /* Run through the version definitions and find the highest
2848 	     index.  */
2849 	  unsigned int offset = 0;
2850 	  Elf_Data *defdata;
2851 	  GElf_Shdr defshdrmem;
2852 	  GElf_Shdr *defshdr;
2853 
2854 	  defdata = elf_getdata (defscn, NULL);
2855 	  if (unlikely (defdata == NULL))
2856 	    return;
2857 
2858 	  defshdr = gelf_getshdr (defscn, &defshdrmem);
2859 	  if (unlikely (defshdr == NULL))
2860 	    return;
2861 
2862 	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2863 	    {
2864 
2865 	      /* Get the data at the next offset.  */
2866 	      GElf_Verdef defmem;
2867 	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2868 	      if (unlikely (def == NULL))
2869 		break;
2870 
2871 	      GElf_Verdaux auxmem;
2872 	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
2873 						   offset + def->vd_aux,
2874 						   &auxmem);
2875 	      if (unlikely (aux == NULL))
2876 		break;
2877 
2878 	      vername[def->vd_ndx & 0x7fff]
2879 		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2880 	      filename[def->vd_ndx & 0x7fff] = NULL;
2881 
2882 	      if (def->vd_next == 0)
2883 		break;
2884 	      offset += def->vd_next;
2885 	    }
2886 	}
2887       if (needscn != NULL)
2888 	{
2889 	  unsigned int offset = 0;
2890 
2891 	  Elf_Data *needdata = elf_getdata (needscn, NULL);
2892 	  GElf_Shdr needshdrmem;
2893 	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2894 	  if (unlikely (needdata == NULL || needshdr == NULL))
2895 	    return;
2896 
2897 	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2898 	    {
2899 	      /* Get the data at the next offset.  */
2900 	      GElf_Verneed needmem;
2901 	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
2902 						    &needmem);
2903 	      if (unlikely (need == NULL))
2904 		break;
2905 
2906 	      /* Run through the auxiliary entries.  */
2907 	      unsigned int auxoffset = offset + need->vn_aux;
2908 	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2909 		{
2910 		  GElf_Vernaux auxmem;
2911 		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2912 						       &auxmem);
2913 		  if (unlikely (aux == NULL))
2914 		    break;
2915 
2916 		  vername[aux->vna_other & 0x7fff]
2917 		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2918 		  filename[aux->vna_other & 0x7fff]
2919 		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2920 
2921 		  if (aux->vna_next == 0)
2922 		    break;
2923 		  auxoffset += aux->vna_next;
2924 		}
2925 
2926 	      if (need->vn_next == 0)
2927 		break;
2928 	      offset += need->vn_next;
2929 	    }
2930 	}
2931     }
2932   else
2933     {
2934       vername = NULL;
2935       nvername = 1;
2936       filename = NULL;
2937     }
2938 
2939   GElf_Shdr glink_mem;
2940   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2941 				   &glink_mem);
2942   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2943   if (glink == NULL)
2944     error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2945 	   elf_ndxscn (scn));
2946 
2947   /* Print the header.  */
2948   printf (ngettext ("\
2949 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
2950 		    "\
2951 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
2952 		    shdr->sh_size / sh_entsize),
2953 	  (unsigned int) elf_ndxscn (scn),
2954 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2955 	  (int) (shdr->sh_size / sh_entsize),
2956 	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2957 	  shdr->sh_offset,
2958 	  (unsigned int) shdr->sh_link,
2959 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2960 
2961   /* Now we can finally look at the actual contents of this section.  */
2962   for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2963     {
2964       if (cnt % 2 == 0)
2965 	printf ("\n %4d:", cnt);
2966 
2967       GElf_Versym symmem;
2968       GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2969       if (sym == NULL)
2970 	break;
2971 
2972       switch (*sym)
2973 	{
2974 	  ssize_t n;
2975 	case 0:
2976 	  fputs_unlocked (gettext ("   0 *local*                     "),
2977 			  stdout);
2978 	  break;
2979 
2980 	case 1:
2981 	  fputs_unlocked (gettext ("   1 *global*                    "),
2982 			  stdout);
2983 	  break;
2984 
2985 	default:
2986 	  n = printf ("%4d%c%s",
2987 		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2988 		      (vername != NULL
2989 		       && (unsigned int) (*sym & 0x7fff) < nvername)
2990 		      ? vername[*sym & 0x7fff] : "???");
2991 	  if ((unsigned int) (*sym & 0x7fff) < nvername
2992 	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
2993 	    n += printf ("(%s)", filename[*sym & 0x7fff]);
2994 	  printf ("%*s", MAX (0, 33 - (int) n), " ");
2995 	  break;
2996 	}
2997     }
2998   putchar_unlocked ('\n');
2999 }
3000 
3001 
3002 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)3003 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3004 		 uint_fast32_t maxlength, Elf32_Word nbucket,
3005 		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3006 {
3007   uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3008 
3009   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3010     ++counts[lengths[cnt]];
3011 
3012   GElf_Shdr glink_mem;
3013   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3014 					       shdr->sh_link),
3015 				   &glink_mem);
3016   if (glink == NULL)
3017     {
3018       error (0, 0, gettext ("invalid sh_link value in section %zu"),
3019 	     elf_ndxscn (scn));
3020       return;
3021     }
3022 
3023   printf (ngettext ("\
3024 \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",
3025 		    "\
3026 \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",
3027 		    nbucket),
3028 	  (unsigned int) elf_ndxscn (scn),
3029 	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3030 	  (int) nbucket,
3031 	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3032 	  shdr->sh_addr,
3033 	  shdr->sh_offset,
3034 	  (unsigned int) shdr->sh_link,
3035 	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3036 
3037   if (extrastr != NULL)
3038     fputs (extrastr, stdout);
3039 
3040   if (likely (nbucket > 0))
3041     {
3042       uint64_t success = 0;
3043 
3044       /* xgettext:no-c-format */
3045       fputs_unlocked (gettext ("\
3046  Length  Number  % of total  Coverage\n"), stdout);
3047       printf (gettext ("      0  %6" PRIu32 "      %5.1f%%\n"),
3048 	      counts[0], (counts[0] * 100.0) / nbucket);
3049 
3050       uint64_t nzero_counts = 0;
3051       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3052 	{
3053 	  nzero_counts += counts[cnt] * cnt;
3054 	  printf (gettext ("\
3055 %7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
3056 		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3057 		  (nzero_counts * 100.0) / nsyms);
3058 	}
3059 
3060       Elf32_Word acc = 0;
3061       for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3062 	{
3063 	  acc += cnt;
3064 	  success += counts[cnt] * acc;
3065 	}
3066 
3067       printf (gettext ("\
3068  Average number of tests:   successful lookup: %f\n\
3069 			  unsuccessful lookup: %f\n"),
3070 	      (double) success / (double) nzero_counts,
3071 	      (double) nzero_counts / (double) nbucket);
3072     }
3073 
3074   free (counts);
3075 }
3076 
3077 
3078 /* This function handles the traditional System V-style hash table format.  */
3079 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3080 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3081 {
3082   Elf_Data *data = elf_getdata (scn, NULL);
3083   if (unlikely (data == NULL))
3084     {
3085       error (0, 0, gettext ("cannot get data for section %d: %s"),
3086 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3087       return;
3088     }
3089 
3090   if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3091     {
3092     invalid_data:
3093       error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3094 	     (int) elf_ndxscn (scn));
3095       return;
3096     }
3097 
3098   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3099   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3100 
3101   uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3102   if (used_buf > data->d_size)
3103     goto invalid_data;
3104 
3105   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3106   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3107 
3108   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3109 
3110   uint_fast32_t maxlength = 0;
3111   uint_fast32_t nsyms = 0;
3112   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3113     {
3114       Elf32_Word inner = bucket[cnt];
3115       while (inner > 0 && inner < nchain)
3116 	{
3117 	  ++nsyms;
3118 	  if (maxlength < ++lengths[cnt])
3119 	    ++maxlength;
3120 
3121 	  inner = chain[inner];
3122 	}
3123     }
3124 
3125   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3126 		   lengths, NULL);
3127 
3128   free (lengths);
3129 }
3130 
3131 
3132 /* This function handles the incorrect, System V-style hash table
3133    format some 64-bit architectures use.  */
3134 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3135 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3136 {
3137   Elf_Data *data = elf_getdata (scn, NULL);
3138   if (unlikely (data == NULL))
3139     {
3140       error (0, 0, gettext ("cannot get data for section %d: %s"),
3141 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3142       return;
3143     }
3144 
3145   if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3146     {
3147     invalid_data:
3148       error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3149 	     (int) elf_ndxscn (scn));
3150       return;
3151     }
3152 
3153   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3154   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3155 
3156   uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3157   if (maxwords < 2
3158       || maxwords - 2 < nbucket
3159       || maxwords - 2 - nbucket < nchain)
3160     goto invalid_data;
3161 
3162   Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3163   Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3164 
3165   uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3166 
3167   uint_fast32_t maxlength = 0;
3168   uint_fast32_t nsyms = 0;
3169   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3170     {
3171       Elf64_Xword inner = bucket[cnt];
3172       while (inner > 0 && inner < nchain)
3173 	{
3174 	  ++nsyms;
3175 	  if (maxlength < ++lengths[cnt])
3176 	    ++maxlength;
3177 
3178 	  inner = chain[inner];
3179 	}
3180     }
3181 
3182   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3183 		   lengths, NULL);
3184 
3185   free (lengths);
3186 }
3187 
3188 
3189 /* This function handles the GNU-style hash table format.  */
3190 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3191 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3192 {
3193   uint32_t *lengths = NULL;
3194   Elf_Data *data = elf_getdata (scn, NULL);
3195   if (unlikely (data == NULL))
3196     {
3197       error (0, 0, gettext ("cannot get data for section %d: %s"),
3198 	     (int) elf_ndxscn (scn), elf_errmsg (-1));
3199       return;
3200     }
3201 
3202   if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3203     {
3204     invalid_data:
3205       free (lengths);
3206       error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3207 	     (int) elf_ndxscn (scn));
3208       return;
3209     }
3210 
3211   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3212   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3213 
3214   /* Next comes the size of the bitmap.  It's measured in words for
3215      the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
3216      64 bit archs.  There is always a bloom filter present, so zero is
3217      an invalid value.  */
3218   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3219   if (gelf_getclass (ebl->elf) == ELFCLASS64)
3220     bitmask_words *= 2;
3221 
3222   if (bitmask_words == 0)
3223     goto invalid_data;
3224 
3225   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3226 
3227   /* Is there still room for the sym chain?
3228      Use uint64_t calculation to prevent 32bit overlow.  */
3229   uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3230   uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3231   if (used_buf > data->d_size)
3232     goto invalid_data;
3233 
3234   lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3235 
3236   Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3237   Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3238   Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3239 						    + nbucket];
3240 
3241   /* Compute distribution of chain lengths.  */
3242   uint_fast32_t maxlength = 0;
3243   uint_fast32_t nsyms = 0;
3244   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3245     if (bucket[cnt] != 0)
3246       {
3247 	Elf32_Word inner = bucket[cnt] - symbias;
3248 	do
3249 	  {
3250 	    ++nsyms;
3251 	    if (maxlength < ++lengths[cnt])
3252 	      ++maxlength;
3253 	    if (inner > max_nsyms)
3254 	      goto invalid_data;
3255 	  }
3256 	while ((chain[inner++] & 1) == 0);
3257       }
3258 
3259   /* Count bits in bitmask.  */
3260   uint_fast32_t nbits = 0;
3261   for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3262     {
3263       uint_fast32_t word = bitmask[cnt];
3264 
3265       word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3266       word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3267       word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3268       word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3269       nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3270     }
3271 
3272   char *str;
3273   if (unlikely (asprintf (&str, gettext ("\
3274  Symbol Bias: %u\n\
3275  Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
3276 			  (unsigned int) symbias,
3277 			  bitmask_words * sizeof (Elf32_Word),
3278 			  ((nbits * 100 + 50)
3279 			   / (uint_fast32_t) (bitmask_words
3280 					      * sizeof (Elf32_Word) * 8)),
3281 			  (unsigned int) shift) == -1))
3282     error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3283 
3284   print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3285 		   lengths, str);
3286 
3287   free (str);
3288   free (lengths);
3289 }
3290 
3291 
3292 /* Find the symbol table(s).  For this we have to search through the
3293    section table.  */
3294 static void
handle_hash(Ebl * ebl)3295 handle_hash (Ebl *ebl)
3296 {
3297   /* Get the section header string table index.  */
3298   size_t shstrndx;
3299   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3300     error (EXIT_FAILURE, 0,
3301 	   gettext ("cannot get section header string table index"));
3302 
3303   Elf_Scn *scn = NULL;
3304   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3305     {
3306       /* Handle the section if it is a symbol table.  */
3307       GElf_Shdr shdr_mem;
3308       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3309 
3310       if (likely (shdr != NULL))
3311 	{
3312 	  if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3313 	      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3314 	    {
3315 	      if (elf_compress (scn, 0, 0) < 0)
3316 		printf ("WARNING: %s [%zd]\n",
3317 			gettext ("Couldn't uncompress section"),
3318 			elf_ndxscn (scn));
3319 	      shdr = gelf_getshdr (scn, &shdr_mem);
3320 	    }
3321 
3322 	  if (shdr->sh_type == SHT_HASH)
3323 	    {
3324 	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3325 		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3326 	      else
3327 		handle_sysv_hash (ebl, scn, shdr, shstrndx);
3328 	    }
3329 	  else if (shdr->sh_type == SHT_GNU_HASH)
3330 	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
3331 	}
3332     }
3333 }
3334 
3335 
3336 static void
print_liblist(Ebl * ebl)3337 print_liblist (Ebl *ebl)
3338 {
3339   /* Find the library list sections.  For this we have to search
3340      through the section table.  */
3341   Elf_Scn *scn = NULL;
3342 
3343   /* Get the section header string table index.  */
3344   size_t shstrndx;
3345   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3346     error (EXIT_FAILURE, 0,
3347 	   gettext ("cannot get section header string table index"));
3348 
3349   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3350     {
3351       GElf_Shdr shdr_mem;
3352       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3353 
3354       if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3355 	{
3356 	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3357 	  int nentries = shdr->sh_size / sh_entsize;
3358 	  printf (ngettext ("\
3359 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3360 			    "\
3361 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3362 			    nentries),
3363 		  elf_ndxscn (scn),
3364 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3365 		  shdr->sh_offset,
3366 		  nentries);
3367 
3368 	  Elf_Data *data = elf_getdata (scn, NULL);
3369 	  if (data == NULL)
3370 	    return;
3371 
3372 	  puts (gettext ("\
3373        Library                       Time Stamp          Checksum Version Flags"));
3374 
3375 	  for (int cnt = 0; cnt < nentries; ++cnt)
3376 	    {
3377 	      GElf_Lib lib_mem;
3378 	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3379 	      if (unlikely (lib == NULL))
3380 		continue;
3381 
3382 	      time_t t = (time_t) lib->l_time_stamp;
3383 	      struct tm *tm = gmtime (&t);
3384 	      if (unlikely (tm == NULL))
3385 		continue;
3386 
3387 	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3388 		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3389 		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3390 		      tm->tm_hour, tm->tm_min, tm->tm_sec,
3391 		      (unsigned int) lib->l_checksum,
3392 		      (unsigned int) lib->l_version,
3393 		      (unsigned int) lib->l_flags);
3394 	    }
3395 	}
3396     }
3397 }
3398 
3399 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3400 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3401 {
3402   /* Find the object attributes sections.  For this we have to search
3403      through the section table.  */
3404   Elf_Scn *scn = NULL;
3405 
3406   /* Get the section header string table index.  */
3407   size_t shstrndx;
3408   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3409     error (EXIT_FAILURE, 0,
3410 	   gettext ("cannot get section header string table index"));
3411 
3412   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3413     {
3414       GElf_Shdr shdr_mem;
3415       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3416 
3417       if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3418 			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3419 			       || ehdr->e_machine != EM_ARM)))
3420 	continue;
3421 
3422       printf (gettext ("\
3423 \nObject attributes section [%2zu] '%s' of %" PRIu64
3424 		       " bytes at offset %#0" PRIx64 ":\n"),
3425 	      elf_ndxscn (scn),
3426 	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3427 	      shdr->sh_size, shdr->sh_offset);
3428 
3429       Elf_Data *data = elf_rawdata (scn, NULL);
3430       if (unlikely (data == NULL || data->d_size == 0))
3431 	return;
3432 
3433       const unsigned char *p = data->d_buf;
3434 
3435       /* There is only one 'version', A.  */
3436       if (unlikely (*p++ != 'A'))
3437 	return;
3438 
3439       fputs_unlocked (gettext ("  Owner          Size\n"), stdout);
3440 
3441       inline size_t left (void)
3442       {
3443 	return (const unsigned char *) data->d_buf + data->d_size - p;
3444       }
3445 
3446       /* Loop over the sections.  */
3447       while (left () >= 4)
3448 	{
3449 	  /* Section length.  */
3450 	  uint32_t len;
3451 	  memcpy (&len, p, sizeof len);
3452 
3453 	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3454 	    CONVERT (len);
3455 
3456 	  if (unlikely (len > left ()))
3457 	    break;
3458 
3459 	  /* Section vendor name.  */
3460 	  const unsigned char *name = p + sizeof len;
3461 	  p += len;
3462 
3463 	  unsigned const char *q = memchr (name, '\0', len);
3464 	  if (unlikely (q == NULL))
3465 	    break;
3466 	  ++q;
3467 
3468 	  printf (gettext ("  %-13s  %4" PRIu32 "\n"), name, len);
3469 
3470 	  bool gnu_vendor = (q - name == sizeof "gnu"
3471 			     && !memcmp (name, "gnu", sizeof "gnu"));
3472 
3473 	  /* Loop over subsections.  */
3474 	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3475 	      || gnu_vendor)
3476 	    while (q < p)
3477 	      {
3478 		const unsigned char *const sub = q;
3479 
3480 		unsigned int subsection_tag;
3481 		get_uleb128 (subsection_tag, q, p);
3482 		if (unlikely (q >= p))
3483 		  break;
3484 
3485 		uint32_t subsection_len;
3486 		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3487 		  break;
3488 
3489 		memcpy (&subsection_len, q, sizeof subsection_len);
3490 
3491 		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3492 		  CONVERT (subsection_len);
3493 
3494 		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
3495 		if (unlikely (subsection_len == 0
3496 			      || subsection_len >= (uint32_t) PTRDIFF_MAX
3497 			      || p - sub < (ptrdiff_t) subsection_len))
3498 		  break;
3499 
3500 		const unsigned char *r = q + sizeof subsection_len;
3501 		q = sub + subsection_len;
3502 
3503 		switch (subsection_tag)
3504 		  {
3505 		  default:
3506 		    /* Unknown subsection, print and skip.  */
3507 		    printf (gettext ("    %-4u %12" PRIu32 "\n"),
3508 			    subsection_tag, subsection_len);
3509 		    break;
3510 
3511 		  case 1:	/* Tag_File */
3512 		    printf (gettext ("    File: %11" PRIu32 "\n"),
3513 			    subsection_len);
3514 
3515 		    while (r < q)
3516 		      {
3517 			unsigned int tag;
3518 			get_uleb128 (tag, r, q);
3519 			if (unlikely (r >= q))
3520 			  break;
3521 
3522 			/* GNU style tags have either a uleb128 value,
3523 			   when lowest bit is not set, or a string
3524 			   when the lowest bit is set.
3525 			   "compatibility" (32) is special.  It has
3526 			   both a string and a uleb128 value.  For
3527 			   non-gnu we assume 6 till 31 only take ints.
3528 			   XXX see arm backend, do we need a separate
3529 			   hook?  */
3530 			uint64_t value = 0;
3531 			const char *string = NULL;
3532 			if (tag == 32 || (tag & 1) == 0
3533 			    || (! gnu_vendor && (tag > 5 && tag < 32)))
3534 			  {
3535 			    get_uleb128 (value, r, q);
3536 			    if (r > q)
3537 			      break;
3538 			  }
3539 			if (tag == 32
3540 			    || ((tag & 1) != 0
3541 				&& (gnu_vendor
3542 				    || (! gnu_vendor && tag > 32)))
3543 			    || (! gnu_vendor && tag > 3 && tag < 6))
3544 			  {
3545 			    string = (const char *) r;
3546 			    r = memchr (r, '\0', q - r);
3547 			    if (r == NULL)
3548 			      break;
3549 			    ++r;
3550 			  }
3551 
3552 			const char *tag_name = NULL;
3553 			const char *value_name = NULL;
3554 			ebl_check_object_attribute (ebl, (const char *) name,
3555 						    tag, value,
3556 						    &tag_name, &value_name);
3557 
3558 			if (tag_name != NULL)
3559 			  {
3560 			    if (tag == 32)
3561 			      printf (gettext ("      %s: %" PRId64 ", %s\n"),
3562 				      tag_name, value, string);
3563 			    else if (string == NULL && value_name == NULL)
3564 			      printf (gettext ("      %s: %" PRId64 "\n"),
3565 				      tag_name, value);
3566 			    else
3567 			      printf (gettext ("      %s: %s\n"),
3568 				      tag_name, string ?: value_name);
3569 			  }
3570 			else
3571 			  {
3572 			    /* For "gnu" vendor 32 "compatibility" has
3573 			       already been handled above.  */
3574 			    assert (tag != 32
3575 				    || strcmp ((const char *) name, "gnu"));
3576 			    if (string == NULL)
3577 			      printf (gettext ("      %u: %" PRId64 "\n"),
3578 				      tag, value);
3579 			    else
3580 			      printf (gettext ("      %u: %s\n"),
3581 				      tag, string);
3582 			  }
3583 		      }
3584 		  }
3585 	      }
3586 	}
3587     }
3588 }
3589 
3590 
3591 static char *
format_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3592 format_dwarf_addr (Dwfl_Module *dwflmod,
3593 		   int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3594 {
3595   /* See if there is a name we can give for this address.  */
3596   GElf_Sym sym;
3597   GElf_Off off = 0;
3598   const char *name = (print_address_names && ! print_unresolved_addresses)
3599     ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3600     : NULL;
3601 
3602   const char *scn;
3603   if (print_unresolved_addresses)
3604     {
3605       address = raw;
3606       scn = NULL;
3607     }
3608   else
3609     {
3610       /* Relativize the address.  */
3611       int n = dwfl_module_relocations (dwflmod);
3612       int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3613 
3614       /* In an ET_REL file there is a section name to refer to.  */
3615       scn = (i < 0 ? NULL
3616 	     : dwfl_module_relocation_info (dwflmod, i, NULL));
3617     }
3618 
3619   char *result;
3620   if ((name != NULL
3621        ? (off != 0
3622 	  ? (scn != NULL
3623 	     ? (address_size == 0
3624 		? asprintf (&result,
3625 			    gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3626 			    scn, address, name, off)
3627 		: asprintf (&result,
3628 			    gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3629 			    scn, 2 + address_size * 2, address,
3630 			    name, off))
3631 	     : (address_size == 0
3632 		? asprintf (&result,
3633 			    gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3634 			    address, name, off)
3635 		: asprintf (&result,
3636 			    gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3637 			    2 + address_size * 2, address,
3638 			    name, off)))
3639 	  : (scn != NULL
3640 	     ? (address_size == 0
3641 		? asprintf (&result,
3642 			    gettext ("%s+%#" PRIx64 " <%s>"),
3643 			    scn, address, name)
3644 		: asprintf (&result,
3645 			    gettext ("%s+%#0*" PRIx64 " <%s>"),
3646 			    scn, 2 + address_size * 2, address, name))
3647 	     : (address_size == 0
3648 		? asprintf (&result,
3649 			    gettext ("%#" PRIx64 " <%s>"),
3650 			    address, name)
3651 		: asprintf (&result,
3652 			    gettext ("%#0*" PRIx64 " <%s>"),
3653 			    2 + address_size * 2, address, name))))
3654        : (scn != NULL
3655 	  ? (address_size == 0
3656 	     ? asprintf (&result,
3657 			 gettext ("%s+%#" PRIx64),
3658 			 scn, address)
3659 	     : asprintf (&result,
3660 			 gettext ("%s+%#0*" PRIx64),
3661 			 scn, 2 + address_size * 2, address))
3662 	  : (address_size == 0
3663 	     ? asprintf (&result,
3664 			 "%#" PRIx64,
3665 			 address)
3666 	     : asprintf (&result,
3667 			 "%#0*" PRIx64,
3668 			 2 + address_size * 2, address)))) < 0)
3669     error (EXIT_FAILURE, 0, _("memory exhausted"));
3670 
3671   return result;
3672 }
3673 
3674 static const char *
dwarf_tag_string(unsigned int tag)3675 dwarf_tag_string (unsigned int tag)
3676 {
3677   switch (tag)
3678     {
3679 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3680       DWARF_ALL_KNOWN_DW_TAG
3681 #undef DWARF_ONE_KNOWN_DW_TAG
3682     default:
3683       return NULL;
3684     }
3685 }
3686 
3687 
3688 static const char *
dwarf_attr_string(unsigned int attrnum)3689 dwarf_attr_string (unsigned int attrnum)
3690 {
3691   switch (attrnum)
3692     {
3693 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3694       DWARF_ALL_KNOWN_DW_AT
3695 #undef DWARF_ONE_KNOWN_DW_AT
3696     default:
3697       return NULL;
3698     }
3699 }
3700 
3701 
3702 static const char *
dwarf_form_string(unsigned int form)3703 dwarf_form_string (unsigned int form)
3704 {
3705   switch (form)
3706     {
3707 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3708       DWARF_ALL_KNOWN_DW_FORM
3709 #undef DWARF_ONE_KNOWN_DW_FORM
3710     default:
3711       return NULL;
3712     }
3713 }
3714 
3715 
3716 static const char *
dwarf_lang_string(unsigned int lang)3717 dwarf_lang_string (unsigned int lang)
3718 {
3719   switch (lang)
3720     {
3721 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3722       DWARF_ALL_KNOWN_DW_LANG
3723 #undef DWARF_ONE_KNOWN_DW_LANG
3724     default:
3725       return NULL;
3726     }
3727 }
3728 
3729 
3730 static const char *
dwarf_inline_string(unsigned int code)3731 dwarf_inline_string (unsigned int code)
3732 {
3733   static const char *const known[] =
3734     {
3735 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3736       DWARF_ALL_KNOWN_DW_INL
3737 #undef DWARF_ONE_KNOWN_DW_INL
3738     };
3739 
3740   if (likely (code < sizeof (known) / sizeof (known[0])))
3741     return known[code];
3742 
3743   return NULL;
3744 }
3745 
3746 
3747 static const char *
dwarf_encoding_string(unsigned int code)3748 dwarf_encoding_string (unsigned int code)
3749 {
3750   static const char *const known[] =
3751     {
3752 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3753       DWARF_ALL_KNOWN_DW_ATE
3754 #undef DWARF_ONE_KNOWN_DW_ATE
3755     };
3756 
3757   if (likely (code < sizeof (known) / sizeof (known[0])))
3758     return known[code];
3759 
3760   return NULL;
3761 }
3762 
3763 
3764 static const char *
dwarf_access_string(unsigned int code)3765 dwarf_access_string (unsigned int code)
3766 {
3767   static const char *const known[] =
3768     {
3769 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3770       DWARF_ALL_KNOWN_DW_ACCESS
3771 #undef DWARF_ONE_KNOWN_DW_ACCESS
3772     };
3773 
3774   if (likely (code < sizeof (known) / sizeof (known[0])))
3775     return known[code];
3776 
3777   return NULL;
3778 }
3779 
3780 
3781 static const char *
dwarf_visibility_string(unsigned int code)3782 dwarf_visibility_string (unsigned int code)
3783 {
3784   static const char *const known[] =
3785     {
3786 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3787       DWARF_ALL_KNOWN_DW_VIS
3788 #undef DWARF_ONE_KNOWN_DW_VIS
3789     };
3790 
3791   if (likely (code < sizeof (known) / sizeof (known[0])))
3792     return known[code];
3793 
3794   return NULL;
3795 }
3796 
3797 
3798 static const char *
dwarf_virtuality_string(unsigned int code)3799 dwarf_virtuality_string (unsigned int code)
3800 {
3801   static const char *const known[] =
3802     {
3803 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3804       DWARF_ALL_KNOWN_DW_VIRTUALITY
3805 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3806     };
3807 
3808   if (likely (code < sizeof (known) / sizeof (known[0])))
3809     return known[code];
3810 
3811   return NULL;
3812 }
3813 
3814 
3815 static const char *
dwarf_identifier_case_string(unsigned int code)3816 dwarf_identifier_case_string (unsigned int code)
3817 {
3818   static const char *const known[] =
3819     {
3820 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3821       DWARF_ALL_KNOWN_DW_ID
3822 #undef DWARF_ONE_KNOWN_DW_ID
3823     };
3824 
3825   if (likely (code < sizeof (known) / sizeof (known[0])))
3826     return known[code];
3827 
3828   return NULL;
3829 }
3830 
3831 
3832 static const char *
dwarf_calling_convention_string(unsigned int code)3833 dwarf_calling_convention_string (unsigned int code)
3834 {
3835   static const char *const known[] =
3836     {
3837 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3838       DWARF_ALL_KNOWN_DW_CC
3839 #undef DWARF_ONE_KNOWN_DW_CC
3840     };
3841 
3842   if (likely (code < sizeof (known) / sizeof (known[0])))
3843     return known[code];
3844 
3845   return NULL;
3846 }
3847 
3848 
3849 static const char *
dwarf_ordering_string(unsigned int code)3850 dwarf_ordering_string (unsigned int code)
3851 {
3852   static const char *const known[] =
3853     {
3854 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3855       DWARF_ALL_KNOWN_DW_ORD
3856 #undef DWARF_ONE_KNOWN_DW_ORD
3857     };
3858 
3859   if (likely (code < sizeof (known) / sizeof (known[0])))
3860     return known[code];
3861 
3862   return NULL;
3863 }
3864 
3865 
3866 static const char *
dwarf_discr_list_string(unsigned int code)3867 dwarf_discr_list_string (unsigned int code)
3868 {
3869   static const char *const known[] =
3870     {
3871 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3872       DWARF_ALL_KNOWN_DW_DSC
3873 #undef DWARF_ONE_KNOWN_DW_DSC
3874     };
3875 
3876   if (likely (code < sizeof (known) / sizeof (known[0])))
3877     return known[code];
3878 
3879   return NULL;
3880 }
3881 
3882 
3883 static const char *
dwarf_locexpr_opcode_string(unsigned int code)3884 dwarf_locexpr_opcode_string (unsigned int code)
3885 {
3886   static const char *const known[] =
3887     {
3888       /* Normally we can't affort building huge table of 64K entries,
3889 	 most of them zero, just because there are a couple defined
3890 	 values at the far end.  In case of opcodes, it's OK.  */
3891 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3892       DWARF_ALL_KNOWN_DW_OP
3893 #undef DWARF_ONE_KNOWN_DW_OP
3894     };
3895 
3896   if (likely (code < sizeof (known) / sizeof (known[0])))
3897     return known[code];
3898 
3899   return NULL;
3900 }
3901 
3902 
3903 /* Used by all dwarf_foo_name functions.  */
3904 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)3905 string_or_unknown (const char *known, unsigned int code,
3906                    unsigned int lo_user, unsigned int hi_user,
3907 		   bool print_unknown_num)
3908 {
3909   static char unknown_buf[20];
3910 
3911   if (likely (known != NULL))
3912     return known;
3913 
3914   if (lo_user != 0 && code >= lo_user && code <= hi_user)
3915     {
3916       snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3917 		code - lo_user);
3918       return unknown_buf;
3919     }
3920 
3921   if (print_unknown_num)
3922     {
3923       snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3924       return unknown_buf;
3925     }
3926 
3927   return "???";
3928 }
3929 
3930 
3931 static const char *
dwarf_tag_name(unsigned int tag)3932 dwarf_tag_name (unsigned int tag)
3933 {
3934   const char *ret = dwarf_tag_string (tag);
3935   return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3936 }
3937 
3938 static const char *
dwarf_attr_name(unsigned int attr)3939 dwarf_attr_name (unsigned int attr)
3940 {
3941   const char *ret = dwarf_attr_string (attr);
3942   return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3943 }
3944 
3945 
3946 static const char *
dwarf_form_name(unsigned int form)3947 dwarf_form_name (unsigned int form)
3948 {
3949   const char *ret = dwarf_form_string (form);
3950   return string_or_unknown (ret, form, 0, 0, true);
3951 }
3952 
3953 
3954 static const char *
dwarf_lang_name(unsigned int lang)3955 dwarf_lang_name (unsigned int lang)
3956 {
3957   const char *ret = dwarf_lang_string (lang);
3958   return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3959 }
3960 
3961 
3962 static const char *
dwarf_inline_name(unsigned int code)3963 dwarf_inline_name (unsigned int code)
3964 {
3965   const char *ret = dwarf_inline_string (code);
3966   return string_or_unknown (ret, code, 0, 0, false);
3967 }
3968 
3969 
3970 static const char *
dwarf_encoding_name(unsigned int code)3971 dwarf_encoding_name (unsigned int code)
3972 {
3973   const char *ret = dwarf_encoding_string (code);
3974   return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3975 }
3976 
3977 
3978 static const char *
dwarf_access_name(unsigned int code)3979 dwarf_access_name (unsigned int code)
3980 {
3981   const char *ret = dwarf_access_string (code);
3982   return string_or_unknown (ret, code, 0, 0, false);
3983 }
3984 
3985 
3986 static const char *
dwarf_visibility_name(unsigned int code)3987 dwarf_visibility_name (unsigned int code)
3988 {
3989   const char *ret = dwarf_visibility_string (code);
3990   return string_or_unknown (ret, code, 0, 0, false);
3991 }
3992 
3993 
3994 static const char *
dwarf_virtuality_name(unsigned int code)3995 dwarf_virtuality_name (unsigned int code)
3996 {
3997   const char *ret = dwarf_virtuality_string (code);
3998   return string_or_unknown (ret, code, 0, 0, false);
3999 }
4000 
4001 
4002 static const char *
dwarf_identifier_case_name(unsigned int code)4003 dwarf_identifier_case_name (unsigned int code)
4004 {
4005   const char *ret = dwarf_identifier_case_string (code);
4006   return string_or_unknown (ret, code, 0, 0, false);
4007 }
4008 
4009 
4010 static const char *
dwarf_calling_convention_name(unsigned int code)4011 dwarf_calling_convention_name (unsigned int code)
4012 {
4013   const char *ret = dwarf_calling_convention_string (code);
4014   return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4015 }
4016 
4017 
4018 static const char *
dwarf_ordering_name(unsigned int code)4019 dwarf_ordering_name (unsigned int code)
4020 {
4021   const char *ret = dwarf_ordering_string (code);
4022   return string_or_unknown (ret, code, 0, 0, false);
4023 }
4024 
4025 
4026 static const char *
dwarf_discr_list_name(unsigned int code)4027 dwarf_discr_list_name (unsigned int code)
4028 {
4029   const char *ret = dwarf_discr_list_string (code);
4030   return string_or_unknown (ret, code, 0, 0, false);
4031 }
4032 
4033 
4034 static void
print_block(size_t n,const void * block)4035 print_block (size_t n, const void *block)
4036 {
4037   if (n == 0)
4038     puts (_("empty block"));
4039   else
4040     {
4041       printf (_("%zu byte block:"), n);
4042       const unsigned char *data = block;
4043       do
4044 	printf (" %02x", *data++);
4045       while (--n > 0);
4046       putchar ('\n');
4047     }
4048 }
4049 
4050 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)4051 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4052 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4053 	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4054 {
4055   const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4056 
4057   if (len == 0)
4058     {
4059       printf ("%*s(empty)\n", indent, "");
4060       return;
4061     }
4062 
4063 #define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
4064 #define CONSUME(n)	NEED (n); else len -= (n)
4065 
4066   Dwarf_Word offset = 0;
4067   while (len-- > 0)
4068     {
4069       uint_fast8_t op = *data++;
4070 
4071       const char *op_name = dwarf_locexpr_opcode_string (op);
4072       if (unlikely (op_name == NULL))
4073 	{
4074 	  static char buf[20];
4075 	  if (op >= DW_OP_lo_user)
4076 	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4077 	  else
4078 	    snprintf (buf, sizeof buf, "??? (%#x)", op);
4079 	  op_name = buf;
4080 	}
4081 
4082       switch (op)
4083 	{
4084 	case DW_OP_addr:;
4085 	  /* Address operand.  */
4086 	  Dwarf_Word addr;
4087 	  NEED (addrsize);
4088 	  if (addrsize == 4)
4089 	    addr = read_4ubyte_unaligned (dbg, data);
4090 	  else if (addrsize == 8)
4091 	    addr = read_8ubyte_unaligned (dbg, data);
4092 	  else
4093 	    goto invalid;
4094 	  data += addrsize;
4095 	  CONSUME (addrsize);
4096 
4097 	  char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
4098 	  printf ("%*s[%4" PRIuMAX "] %s %s\n",
4099 		  indent, "", (uintmax_t) offset, op_name, a);
4100 	  free (a);
4101 
4102 	  offset += 1 + addrsize;
4103 	  break;
4104 
4105 	case DW_OP_call_ref:
4106 	  /* Offset operand.  */
4107 	  if (ref_size != 4 && ref_size != 8)
4108 	    goto invalid; /* Cannot be used in CFA.  */
4109 	  NEED (ref_size);
4110 	  if (ref_size == 4)
4111 	    addr = read_4ubyte_unaligned (dbg, data);
4112 	  else
4113 	    addr = read_8ubyte_unaligned (dbg, data);
4114 	  data += ref_size;
4115 	  CONSUME (ref_size);
4116 
4117 	  printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4118 		  indent, "", (uintmax_t) offset,
4119 		  op_name, (uintmax_t) addr);
4120 	  offset += 1 + ref_size;
4121 	  break;
4122 
4123 	case DW_OP_deref_size:
4124 	case DW_OP_xderef_size:
4125 	case DW_OP_pick:
4126 	case DW_OP_const1u:
4127 	  // XXX value might be modified by relocation
4128 	  NEED (1);
4129 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4130 		  indent, "", (uintmax_t) offset,
4131 		  op_name, *((uint8_t *) data));
4132 	  ++data;
4133 	  --len;
4134 	  offset += 2;
4135 	  break;
4136 
4137 	case DW_OP_const2u:
4138 	  NEED (2);
4139 	  // XXX value might be modified by relocation
4140 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4141 		  indent, "", (uintmax_t) offset,
4142 		  op_name, read_2ubyte_unaligned (dbg, data));
4143 	  CONSUME (2);
4144 	  data += 2;
4145 	  offset += 3;
4146 	  break;
4147 
4148 	case DW_OP_const4u:
4149 	  NEED (4);
4150 	  // XXX value might be modified by relocation
4151 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4152 		  indent, "", (uintmax_t) offset,
4153 		  op_name, read_4ubyte_unaligned (dbg, data));
4154 	  CONSUME (4);
4155 	  data += 4;
4156 	  offset += 5;
4157 	  break;
4158 
4159 	case DW_OP_const8u:
4160 	  NEED (8);
4161 	  // XXX value might be modified by relocation
4162 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4163 		  indent, "", (uintmax_t) offset,
4164 		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4165 	  CONSUME (8);
4166 	  data += 8;
4167 	  offset += 9;
4168 	  break;
4169 
4170 	case DW_OP_const1s:
4171 	  NEED (1);
4172 	  // XXX value might be modified by relocation
4173 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4174 		  indent, "", (uintmax_t) offset,
4175 		  op_name, *((int8_t *) data));
4176 	  ++data;
4177 	  --len;
4178 	  offset += 2;
4179 	  break;
4180 
4181 	case DW_OP_const2s:
4182 	  NEED (2);
4183 	  // XXX value might be modified by relocation
4184 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4185 		  indent, "", (uintmax_t) offset,
4186 		  op_name, read_2sbyte_unaligned (dbg, data));
4187 	  CONSUME (2);
4188 	  data += 2;
4189 	  offset += 3;
4190 	  break;
4191 
4192 	case DW_OP_const4s:
4193 	  NEED (4);
4194 	  // XXX value might be modified by relocation
4195 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4196 		  indent, "", (uintmax_t) offset,
4197 		  op_name, read_4sbyte_unaligned (dbg, data));
4198 	  CONSUME (4);
4199 	  data += 4;
4200 	  offset += 5;
4201 	  break;
4202 
4203 	case DW_OP_const8s:
4204 	  NEED (8);
4205 	  // XXX value might be modified by relocation
4206 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4207 		  indent, "", (uintmax_t) offset,
4208 		  op_name, read_8sbyte_unaligned (dbg, data));
4209 	  CONSUME (8);
4210 	  data += 8;
4211 	  offset += 9;
4212 	  break;
4213 
4214 	case DW_OP_piece:
4215 	case DW_OP_regx:
4216 	case DW_OP_plus_uconst:
4217 	case DW_OP_constu:;
4218 	  const unsigned char *start = data;
4219 	  uint64_t uleb;
4220 	  NEED (1);
4221 	  get_uleb128 (uleb, data, data + len);
4222 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4223 		  indent, "", (uintmax_t) offset, op_name, uleb);
4224 	  CONSUME (data - start);
4225 	  offset += 1 + (data - start);
4226 	  break;
4227 
4228 	case DW_OP_bit_piece:
4229 	  start = data;
4230 	  uint64_t uleb2;
4231 	  NEED (1);
4232 	  get_uleb128 (uleb, data, data + len);
4233 	  NEED (1);
4234 	  get_uleb128 (uleb2, data, data + len);
4235 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4236 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4237 	  CONSUME (data - start);
4238 	  offset += 1 + (data - start);
4239 	  break;
4240 
4241 	case DW_OP_fbreg:
4242 	case DW_OP_breg0 ... DW_OP_breg31:
4243 	case DW_OP_consts:
4244 	  start = data;
4245 	  int64_t sleb;
4246 	  NEED (1);
4247 	  get_sleb128 (sleb, data, data + len);
4248 	  printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4249 		  indent, "", (uintmax_t) offset, op_name, sleb);
4250 	  CONSUME (data - start);
4251 	  offset += 1 + (data - start);
4252 	  break;
4253 
4254 	case DW_OP_bregx:
4255 	  start = data;
4256 	  NEED (1);
4257 	  get_uleb128 (uleb, data, data + len);
4258 	  NEED (1);
4259 	  get_sleb128 (sleb, data, data + len);
4260 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4261 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4262 	  CONSUME (data - start);
4263 	  offset += 1 + (data - start);
4264 	  break;
4265 
4266 	case DW_OP_call2:
4267 	  NEED (2);
4268 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4269 		  indent, "", (uintmax_t) offset, op_name,
4270 		  read_2ubyte_unaligned (dbg, data));
4271 	  CONSUME (2);
4272 	  offset += 3;
4273 	  break;
4274 
4275 	case DW_OP_call4:
4276 	  NEED (4);
4277 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4278 		  indent, "", (uintmax_t) offset, op_name,
4279 		  read_4ubyte_unaligned (dbg, data));
4280 	  CONSUME (4);
4281 	  offset += 5;
4282 	  break;
4283 
4284 	case DW_OP_skip:
4285 	case DW_OP_bra:
4286 	  NEED (2);
4287 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4288 		  indent, "", (uintmax_t) offset, op_name,
4289 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4290 	  CONSUME (2);
4291 	  data += 2;
4292 	  offset += 3;
4293 	  break;
4294 
4295 	case DW_OP_implicit_value:
4296 	  start = data;
4297 	  NEED (1);
4298 	  get_uleb128 (uleb, data, data + len);
4299 	  printf ("%*s[%4" PRIuMAX "] %s: ",
4300 		  indent, "", (uintmax_t) offset, op_name);
4301 	  NEED (uleb);
4302 	  print_block (uleb, data);
4303 	  data += uleb;
4304 	  CONSUME (data - start);
4305 	  offset += 1 + (data - start);
4306 	  break;
4307 
4308 	case DW_OP_GNU_implicit_pointer:
4309 	  /* DIE offset operand.  */
4310 	  start = data;
4311 	  NEED (ref_size);
4312 	  if (ref_size != 4 && ref_size != 8)
4313 	    goto invalid; /* Cannot be used in CFA.  */
4314 	  if (ref_size == 4)
4315 	    addr = read_4ubyte_unaligned (dbg, data);
4316 	  else
4317 	    addr = read_8ubyte_unaligned (dbg, data);
4318 	  data += ref_size;
4319 	  /* Byte offset operand.  */
4320 	  NEED (1);
4321 	  get_sleb128 (sleb, data, data + len);
4322 
4323 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4324 		  indent, "", (intmax_t) offset,
4325 		  op_name, (uintmax_t) addr, sleb);
4326 	  CONSUME (data - start);
4327 	  offset += 1 + (data - start);
4328 	  break;
4329 
4330 	case DW_OP_GNU_entry_value:
4331 	  /* Size plus expression block.  */
4332 	  start = data;
4333 	  NEED (1);
4334 	  get_uleb128 (uleb, data, data + len);
4335 	  printf ("%*s[%4" PRIuMAX "] %s:\n",
4336 		  indent, "", (uintmax_t) offset, op_name);
4337 	  NEED (uleb);
4338 	  print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4339 		     addrsize, offset_size, cu, uleb, data);
4340 	  data += uleb;
4341 	  CONSUME (data - start);
4342 	  offset += 1 + (data - start);
4343 	  break;
4344 
4345 	case DW_OP_GNU_const_type:
4346 	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4347 	     unsigned size plus block.  */
4348 	  start = data;
4349 	  NEED (1);
4350 	  get_uleb128 (uleb, data, data + len);
4351 	  if (! print_unresolved_addresses && cu != NULL)
4352 	    uleb += cu->start;
4353 	  NEED (1);
4354 	  uint8_t usize = *(uint8_t *) data++;
4355 	  NEED (usize);
4356 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4357 		  indent, "", (uintmax_t) offset, op_name, uleb);
4358 	  print_block (usize, data);
4359 	  data += usize;
4360 	  CONSUME (data - start);
4361 	  offset += 1 + (data - start);
4362 	  break;
4363 
4364 	case DW_OP_GNU_regval_type:
4365 	  /* uleb128 register number, uleb128 CU relative
4366 	     DW_TAG_base_type DIE offset.  */
4367 	  start = data;
4368 	  NEED (1);
4369 	  get_uleb128 (uleb, data, data + len);
4370 	  NEED (1);
4371 	  get_uleb128 (uleb2, data, data + len);
4372 	  if (! print_unresolved_addresses && cu != NULL)
4373 	    uleb2 += cu->start;
4374 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4375 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4376 	  CONSUME (data - start);
4377 	  offset += 1 + (data - start);
4378 	  break;
4379 
4380 	case DW_OP_GNU_deref_type:
4381 	  /* 1-byte unsigned size of value, uleb128 CU relative
4382 	     DW_TAG_base_type DIE offset.  */
4383 	  start = data;
4384 	  NEED (1);
4385 	  usize = *(uint8_t *) data++;
4386 	  NEED (1);
4387 	  get_uleb128 (uleb, data, data + len);
4388 	  if (! print_unresolved_addresses && cu != NULL)
4389 	    uleb += cu->start;
4390 	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4391 		  indent, "", (uintmax_t) offset,
4392 		  op_name, usize, uleb);
4393 	  CONSUME (data - start);
4394 	  offset += 1 + (data - start);
4395 	  break;
4396 
4397 	case DW_OP_GNU_convert:
4398 	case DW_OP_GNU_reinterpret:
4399 	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4400 	     for conversion to untyped.  */
4401 	  start = data;
4402 	  NEED (1);
4403 	  get_uleb128 (uleb, data, data + len);
4404 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4405 	    uleb += cu->start;
4406 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4407 		  indent, "", (uintmax_t) offset, op_name, uleb);
4408 	  CONSUME (data - start);
4409 	  offset += 1 + (data - start);
4410 	  break;
4411 
4412 	case DW_OP_GNU_parameter_ref:
4413 	  /* 4 byte CU relative reference to the abstract optimized away
4414 	     DW_TAG_formal_parameter.  */
4415 	  NEED (4);
4416 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4417 	  if (! print_unresolved_addresses && cu != NULL)
4418 	    param_off += cu->start;
4419 	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4420 		  indent, "", (uintmax_t) offset, op_name, param_off);
4421 	  CONSUME (4);
4422 	  data += 4;
4423 	  offset += 5;
4424 	  break;
4425 
4426 	default:
4427 	  /* No Operand.  */
4428 	  printf ("%*s[%4" PRIuMAX "] %s\n",
4429 		  indent, "", (uintmax_t) offset, op_name);
4430 	  ++offset;
4431 	  break;
4432 	}
4433 
4434       indent = indentrest;
4435       continue;
4436 
4437     invalid:
4438       printf (gettext ("%*s[%4" PRIuMAX "] %s  <TRUNCATED>\n"),
4439 	      indent, "", (uintmax_t) offset, op_name);
4440       break;
4441     }
4442 }
4443 
4444 
4445 struct listptr
4446 {
4447   Dwarf_Off offset:(64 - 3);
4448   bool addr64:1;
4449   bool dwarf64:1;
4450   bool warned:1;
4451   struct Dwarf_CU *cu;
4452 };
4453 
4454 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
4455 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
4456 
4457 static Dwarf_Addr
listptr_base(struct listptr * p)4458 listptr_base (struct listptr *p)
4459 {
4460   Dwarf_Addr base;
4461   Dwarf_Die cu = CUDIE (p->cu);
4462   /* Find the base address of the compilation unit.  It will normally
4463      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
4464      address could be overridden by DW_AT_entry_pc.  It's been
4465      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4466      compilation units with discontinuous ranges.  */
4467   if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4468     {
4469       Dwarf_Attribute attr_mem;
4470       if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4471 			  &base) != 0)
4472 	base = 0;
4473     }
4474   return base;
4475 }
4476 
4477 static int
compare_listptr(const void * a,const void * b,void * arg)4478 compare_listptr (const void *a, const void *b, void *arg)
4479 {
4480   const char *name = arg;
4481   struct listptr *p1 = (void *) a;
4482   struct listptr *p2 = (void *) b;
4483 
4484   if (p1->offset < p2->offset)
4485     return -1;
4486   if (p1->offset > p2->offset)
4487     return 1;
4488 
4489   if (!p1->warned && !p2->warned)
4490     {
4491       if (p1->addr64 != p2->addr64)
4492 	{
4493 	  p1->warned = p2->warned = true;
4494 	  error (0, 0,
4495 		 gettext ("%s %#" PRIx64 " used with different address sizes"),
4496 		 name, (uint64_t) p1->offset);
4497 	}
4498       if (p1->dwarf64 != p2->dwarf64)
4499 	{
4500 	  p1->warned = p2->warned = true;
4501 	  error (0, 0,
4502 		 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4503 		 name, (uint64_t) p1->offset);
4504 	}
4505       if (listptr_base (p1) != listptr_base (p2))
4506 	{
4507 	  p1->warned = p2->warned = true;
4508 	  error (0, 0,
4509 		 gettext ("%s %#" PRIx64 " used with different base addresses"),
4510 		 name, (uint64_t) p1->offset);
4511 	}
4512     }
4513 
4514   return 0;
4515 }
4516 
4517 struct listptr_table
4518 {
4519   size_t n;
4520   size_t alloc;
4521   struct listptr *table;
4522 };
4523 
4524 static struct listptr_table known_loclistptr;
4525 static struct listptr_table known_rangelistptr;
4526 
4527 static void
reset_listptr(struct listptr_table * table)4528 reset_listptr (struct listptr_table *table)
4529 {
4530   free (table->table);
4531   table->table = NULL;
4532   table->n = table->alloc = 0;
4533 }
4534 
4535 /* Returns false if offset doesn't fit.  See struct listptr.  */
4536 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)4537 notice_listptr (enum section_e section, struct listptr_table *table,
4538 		uint_fast8_t address_size, uint_fast8_t offset_size,
4539 		struct Dwarf_CU *cu, Dwarf_Off offset)
4540 {
4541   if (print_debug_sections & section)
4542     {
4543       if (table->n == table->alloc)
4544 	{
4545 	  if (table->alloc == 0)
4546 	    table->alloc = 128;
4547 	  else
4548 	    table->alloc *= 2;
4549 	  table->table = xrealloc (table->table,
4550 				   table->alloc * sizeof table->table[0]);
4551 	}
4552 
4553       struct listptr *p = &table->table[table->n++];
4554 
4555       *p = (struct listptr)
4556 	{
4557 	  .addr64 = address_size == 8,
4558 	  .dwarf64 = offset_size == 8,
4559 	  .offset = offset,
4560 	  .cu = cu
4561 	};
4562 
4563       if (p->offset != offset)
4564 	{
4565 	  table->n--;
4566 	  return false;
4567 	}
4568     }
4569   return true;
4570 }
4571 
4572 static void
sort_listptr(struct listptr_table * table,const char * name)4573 sort_listptr (struct listptr_table *table, const char *name)
4574 {
4575   if (table->n > 0)
4576     qsort_r (table->table, table->n, sizeof table->table[0],
4577 	     &compare_listptr, (void *) name);
4578 }
4579 
4580 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)4581 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4582 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4583 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4584 		   unsigned char **readp, unsigned char *endp)
4585 {
4586   if (table->n == 0)
4587     return false;
4588 
4589   while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4590     ++*idxp;
4591 
4592   struct listptr *p = &table->table[*idxp];
4593 
4594   if (*idxp == table->n
4595       || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4596     {
4597       *readp = endp;
4598       printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
4599 	      offset);
4600       return true;
4601     }
4602 
4603   if (p->offset != (Dwarf_Off) offset)
4604     {
4605       *readp += p->offset - offset;
4606       printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4607 	      offset, (Dwarf_Off) p->offset - offset);
4608       return true;
4609     }
4610 
4611   if (address_sizep != NULL)
4612     *address_sizep = listptr_address_size (p);
4613   if (offset_sizep != NULL)
4614     *offset_sizep = listptr_offset_size (p);
4615   if (base != NULL)
4616     *base = listptr_base (p);
4617   if (cu != NULL)
4618     *cu = p->cu;
4619 
4620   return false;
4621 }
4622 
4623 
4624 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4625 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4626 			    Ebl *ebl, GElf_Ehdr *ehdr,
4627 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4628 {
4629   const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4630 			  dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4631 
4632   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4633 		   " [ Code]\n"),
4634 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4635 	  (uint64_t) shdr->sh_offset);
4636 
4637   Dwarf_Off offset = 0;
4638   while (offset < sh_size)
4639     {
4640       printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4641 	      offset);
4642 
4643       while (1)
4644 	{
4645 	  size_t length;
4646 	  Dwarf_Abbrev abbrev;
4647 
4648 	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4649 	  if (res != 0)
4650 	    {
4651 	      if (unlikely (res < 0))
4652 		{
4653 		  printf (gettext ("\
4654  *** error while reading abbreviation: %s\n"),
4655 			  dwarf_errmsg (-1));
4656 		  return;
4657 		}
4658 
4659 	      /* This is the NUL byte at the end of the section.  */
4660 	      ++offset;
4661 	      break;
4662 	    }
4663 
4664 	  /* We know these calls can never fail.  */
4665 	  unsigned int code = dwarf_getabbrevcode (&abbrev);
4666 	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
4667 	  int has_children = dwarf_abbrevhaschildren (&abbrev);
4668 
4669 	  printf (gettext (" [%5u] offset: %" PRId64
4670 			   ", children: %s, tag: %s\n"),
4671 		  code, (int64_t) offset,
4672 		  has_children ? gettext ("yes") : gettext ("no"),
4673 		  dwarf_tag_name (tag));
4674 
4675 	  size_t cnt = 0;
4676 	  unsigned int name;
4677 	  unsigned int form;
4678 	  Dwarf_Off enoffset;
4679 	  while (dwarf_getabbrevattr (&abbrev, cnt,
4680 				      &name, &form, &enoffset) == 0)
4681 	    {
4682 	      printf ("          attr: %s, form: %s, offset: %#" PRIx64 "\n",
4683 		      dwarf_attr_name (name), dwarf_form_name (form),
4684 		      (uint64_t) enoffset);
4685 
4686 	      ++cnt;
4687 	    }
4688 
4689 	  offset += length;
4690 	}
4691     }
4692 }
4693 
4694 
4695 /* Print content of DWARF .debug_aranges section.  We fortunately do
4696    not have to know a bit about the structure of the section, libdwarf
4697    takes care of it.  */
4698 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4699 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4700 			       GElf_Shdr *shdr, Dwarf *dbg)
4701 {
4702   Dwarf_Aranges *aranges;
4703   size_t cnt;
4704   if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4705     {
4706       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4707 	     dwarf_errmsg (-1));
4708       return;
4709     }
4710 
4711   GElf_Shdr glink_mem;
4712   GElf_Shdr *glink;
4713   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4714   if (glink == NULL)
4715     {
4716       error (0, 0, gettext ("invalid sh_link value in section %zu"),
4717 	     elf_ndxscn (scn));
4718       return;
4719     }
4720 
4721   printf (ngettext ("\
4722 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4723 		    "\
4724 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4725 		    cnt),
4726 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4727 	  (uint64_t) shdr->sh_offset, cnt);
4728 
4729   /* Compute floor(log16(cnt)).  */
4730   size_t tmp = cnt;
4731   int digits = 1;
4732   while (tmp >= 16)
4733     {
4734       ++digits;
4735       tmp >>= 4;
4736     }
4737 
4738   for (size_t n = 0; n < cnt; ++n)
4739     {
4740       Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4741       if (unlikely (runp == NULL))
4742 	{
4743 	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4744 	  return;
4745 	}
4746 
4747       Dwarf_Addr start;
4748       Dwarf_Word length;
4749       Dwarf_Off offset;
4750 
4751       if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4752 	printf (gettext (" [%*zu] ???\n"), digits, n);
4753       else
4754 	printf (gettext (" [%*zu] start: %0#*" PRIx64
4755 			 ", length: %5" PRIu64 ", CU DIE offset: %6"
4756 			 PRId64 "\n"),
4757 		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4758 		(uint64_t) start, (uint64_t) length, (int64_t) offset);
4759     }
4760 }
4761 
4762 
4763 /* Print content of DWARF .debug_aranges section.  */
4764 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4765 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4766 			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4767 			     GElf_Shdr *shdr, Dwarf *dbg)
4768 {
4769   if (decodedaranges)
4770     {
4771       print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4772       return;
4773     }
4774 
4775   Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4776 
4777   if (unlikely (data == NULL))
4778     {
4779       error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4780 	     elf_errmsg (-1));
4781       return;
4782     }
4783 
4784   printf (gettext ("\
4785 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4786 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4787 	  (uint64_t) shdr->sh_offset);
4788 
4789   const unsigned char *readp = data->d_buf;
4790   const unsigned char *readendp = readp + data->d_size;
4791 
4792   while (readp < readendp)
4793     {
4794       const unsigned char *hdrstart = readp;
4795       size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4796 
4797       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
4798       if (readp + 4 > readendp)
4799 	{
4800 	invalid_data:
4801 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4802 		 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4803 	  return;
4804 	}
4805 
4806       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4807       unsigned int length_bytes = 4;
4808       if (length == DWARF3_LENGTH_64_BIT)
4809 	{
4810 	  if (readp + 8 > readendp)
4811 	    goto invalid_data;
4812 	  length = read_8ubyte_unaligned_inc (dbg, readp);
4813 	  length_bytes = 8;
4814 	}
4815 
4816       const unsigned char *nexthdr = readp + length;
4817       printf (gettext ("\n Length:        %6" PRIu64 "\n"),
4818 	      (uint64_t) length);
4819 
4820       if (unlikely (length > (size_t) (readendp - readp)))
4821 	goto invalid_data;
4822 
4823       if (length == 0)
4824 	continue;
4825 
4826       if (readp + 2 > readendp)
4827 	goto invalid_data;
4828       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4829       printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4830 	      version);
4831       if (version != 2)
4832 	{
4833 	  error (0, 0, gettext ("unsupported aranges version"));
4834 	  goto next_table;
4835 	}
4836 
4837       Dwarf_Word offset;
4838       if (readp + length_bytes > readendp)
4839 	goto invalid_data;
4840       if (length_bytes == 8)
4841 	offset = read_8ubyte_unaligned_inc (dbg, readp);
4842       else
4843 	offset = read_4ubyte_unaligned_inc (dbg, readp);
4844       printf (gettext (" CU offset:     %6" PRIx64 "\n"),
4845 	      (uint64_t) offset);
4846 
4847       if (readp + 1 > readendp)
4848 	goto invalid_data;
4849       unsigned int address_size = *readp++;
4850       printf (gettext (" Address size:  %6" PRIu64 "\n"),
4851 	      (uint64_t) address_size);
4852       if (address_size != 4 && address_size != 8)
4853 	{
4854 	  error (0, 0, gettext ("unsupported address size"));
4855 	  goto next_table;
4856 	}
4857 
4858       unsigned int segment_size = *readp++;
4859       printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
4860 	      (uint64_t) segment_size);
4861       if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4862 	{
4863 	  error (0, 0, gettext ("unsupported segment size"));
4864 	  goto next_table;
4865 	}
4866 
4867       /* Round the address to the next multiple of 2*address_size.  */
4868       readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4869 		% (2 * address_size));
4870 
4871       while (readp < nexthdr)
4872 	{
4873 	  Dwarf_Word range_address;
4874 	  Dwarf_Word range_length;
4875 	  Dwarf_Word segment = 0;
4876 	  if (readp + 2 * address_size + segment_size > readendp)
4877 	    goto invalid_data;
4878 	  if (address_size == 4)
4879 	    {
4880 	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
4881 	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
4882 	    }
4883 	  else
4884 	    {
4885 	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
4886 	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
4887 	    }
4888 
4889 	  if (segment_size == 4)
4890 	    segment = read_4ubyte_unaligned_inc (dbg, readp);
4891 	  else if (segment_size == 8)
4892 	    segment = read_8ubyte_unaligned_inc (dbg, readp);
4893 
4894 	  if (range_address == 0 && range_length == 0 && segment == 0)
4895 	    break;
4896 
4897 	  char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4898 				       range_address);
4899 	  char *e = format_dwarf_addr (dwflmod, address_size,
4900 				       range_address + range_length - 1,
4901 				       range_length);
4902 	  if (segment_size != 0)
4903 	    printf (gettext ("   %s..%s (%" PRIx64 ")\n"), b, e,
4904 		    (uint64_t) segment);
4905 	  else
4906 	    printf (gettext ("   %s..%s\n"), b, e);
4907 	  free (b);
4908 	  free (e);
4909 	}
4910 
4911     next_table:
4912       if (readp != nexthdr)
4913 	{
4914 	  size_t padding = nexthdr - readp;
4915 	  printf (gettext ("   %zu padding bytes\n"), padding);
4916 	  readp = nexthdr;
4917 	}
4918     }
4919 }
4920 
4921 
4922 /* Print content of DWARF .debug_ranges section.  */
4923 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4924 print_debug_ranges_section (Dwfl_Module *dwflmod,
4925 			    Ebl *ebl, GElf_Ehdr *ehdr,
4926 			    Elf_Scn *scn, GElf_Shdr *shdr,
4927 			    Dwarf *dbg)
4928 {
4929   Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4930 
4931   if (unlikely (data == NULL))
4932     {
4933       error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4934 	     elf_errmsg (-1));
4935       return;
4936     }
4937 
4938   printf (gettext ("\
4939 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4940 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4941 	  (uint64_t) shdr->sh_offset);
4942 
4943   sort_listptr (&known_rangelistptr, "rangelistptr");
4944   size_t listptr_idx = 0;
4945 
4946   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4947 
4948   bool first = true;
4949   Dwarf_Addr base = 0;
4950   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4951   unsigned char *readp = data->d_buf;
4952   while (readp < endp)
4953     {
4954       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4955 
4956       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4957 				      &address_size, NULL, &base, NULL,
4958 				      offset, &readp, endp))
4959 	continue;
4960 
4961       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4962 	{
4963 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
4964 	  break;
4965 	}
4966 
4967       Dwarf_Addr begin;
4968       Dwarf_Addr end;
4969       if (address_size == 8)
4970 	{
4971 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
4972 	  end = read_8ubyte_unaligned_inc (dbg, readp);
4973 	}
4974       else
4975 	{
4976 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
4977 	  end = read_4ubyte_unaligned_inc (dbg, readp);
4978 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
4979 	    begin = (Dwarf_Addr) -1l;
4980 	}
4981 
4982       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
4983 	{
4984 	  char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4985 	  printf (gettext (" [%6tx]  base address %s\n"), offset, b);
4986 	  free (b);
4987 	  base = end;
4988 	}
4989       else if (begin == 0 && end == 0) /* End of list entry.  */
4990 	{
4991 	  if (first)
4992 	    printf (gettext (" [%6tx]  empty list\n"), offset);
4993 	  first = true;
4994 	}
4995       else
4996 	{
4997 	  char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4998 				       begin);
4999 	  char *e = format_dwarf_addr (dwflmod, address_size, base + end,
5000 				       end);
5001 	  /* We have an address range entry.  */
5002 	  if (first)		/* First address range entry in a list.  */
5003 	    printf (gettext (" [%6tx]  %s..%s\n"), offset, b, e);
5004 	  else
5005 	    printf (gettext ("           %s..%s\n"), b, e);
5006 	  free (b);
5007 	  free (e);
5008 
5009 	  first = false;
5010 	}
5011     }
5012 }
5013 
5014 #define REGNAMESZ 16
5015 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)5016 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
5017 	       char name[REGNAMESZ], int *bits, int *type)
5018 {
5019   const char *set;
5020   const char *pfx;
5021   int ignore;
5022   ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
5023 				 bits ?: &ignore, type ?: &ignore);
5024   if (n <= 0)
5025     {
5026       if (loc != NULL)
5027 	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
5028       else
5029 	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
5030       if (bits != NULL)
5031 	*bits = loc != NULL ? loc->bits : 0;
5032       if (type != NULL)
5033 	*type = DW_ATE_unsigned;
5034       set = "??? unrecognized";
5035     }
5036   else
5037     {
5038       if (bits != NULL && *bits <= 0)
5039 	*bits = loc != NULL ? loc->bits : 0;
5040       if (type != NULL && *type == DW_ATE_void)
5041 	*type = DW_ATE_unsigned;
5042 
5043     }
5044   return set;
5045 }
5046 
5047 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,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)5048 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
5049 		   Dwarf_Word vma_base, unsigned int code_align,
5050 		   int data_align,
5051 		   unsigned int version, unsigned int ptr_size,
5052 		   Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
5053 {
5054   char regnamebuf[REGNAMESZ];
5055   const char *regname (unsigned int regno)
5056   {
5057     register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
5058     return regnamebuf;
5059   }
5060 
5061   puts ("\n   Program:");
5062   Dwarf_Word pc = vma_base;
5063   while (readp < endp)
5064     {
5065       unsigned int opcode = *readp++;
5066 
5067       if (opcode < DW_CFA_advance_loc)
5068 	/* Extended opcode.  */
5069 	switch (opcode)
5070 	  {
5071 	    uint64_t op1;
5072 	    int64_t sop1;
5073 	    uint64_t op2;
5074 	    int64_t sop2;
5075 
5076 	  case DW_CFA_nop:
5077 	    puts ("     nop");
5078 	    break;
5079 	  case DW_CFA_set_loc:
5080 	    if ((uint64_t) (endp - readp) < 1)
5081 	      goto invalid;
5082 	    get_uleb128 (op1, readp, endp);
5083 	    op1 += vma_base;
5084 	    printf ("     set_loc %" PRIu64 "\n", op1 * code_align);
5085 	    break;
5086 	  case DW_CFA_advance_loc1:
5087 	    if ((uint64_t) (endp - readp) < 1)
5088 	      goto invalid;
5089 	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
5090 		    *readp, pc += *readp * code_align);
5091 	    ++readp;
5092 	    break;
5093 	  case DW_CFA_advance_loc2:
5094 	    if ((uint64_t) (endp - readp) < 2)
5095 	      goto invalid;
5096 	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
5097 	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
5098 		    op1, pc += op1 * code_align);
5099 	    break;
5100 	  case DW_CFA_advance_loc4:
5101 	    if ((uint64_t) (endp - readp) < 4)
5102 	      goto invalid;
5103 	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
5104 	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
5105 		    op1, pc += op1 * code_align);
5106 	    break;
5107 	  case DW_CFA_offset_extended:
5108 	    if ((uint64_t) (endp - readp) < 1)
5109 	      goto invalid;
5110 	    get_uleb128 (op1, readp, endp);
5111 	    if ((uint64_t) (endp - readp) < 1)
5112 	      goto invalid;
5113 	    get_uleb128 (op2, readp, endp);
5114 	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5115 		    "\n",
5116 		    op1, regname (op1), op2 * data_align);
5117 	    break;
5118 	  case DW_CFA_restore_extended:
5119 	    if ((uint64_t) (endp - readp) < 1)
5120 	      goto invalid;
5121 	    get_uleb128 (op1, readp, endp);
5122 	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
5123 		    op1, regname (op1));
5124 	    break;
5125 	  case DW_CFA_undefined:
5126 	    if ((uint64_t) (endp - readp) < 1)
5127 	      goto invalid;
5128 	    get_uleb128 (op1, readp, endp);
5129 	    printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5130 	    break;
5131 	  case DW_CFA_same_value:
5132 	    if ((uint64_t) (endp - readp) < 1)
5133 	      goto invalid;
5134 	    get_uleb128 (op1, readp, endp);
5135 	    printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5136 	    break;
5137 	  case DW_CFA_register:
5138 	    if ((uint64_t) (endp - readp) < 1)
5139 	      goto invalid;
5140 	    get_uleb128 (op1, readp, endp);
5141 	    if ((uint64_t) (endp - readp) < 1)
5142 	      goto invalid;
5143 	    get_uleb128 (op2, readp, endp);
5144 	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5145 		    op1, regname (op1), op2, regname (op2));
5146 	    break;
5147 	  case DW_CFA_remember_state:
5148 	    puts ("     remember_state");
5149 	    break;
5150 	  case DW_CFA_restore_state:
5151 	    puts ("     restore_state");
5152 	    break;
5153 	  case DW_CFA_def_cfa:
5154 	    if ((uint64_t) (endp - readp) < 1)
5155 	      goto invalid;
5156 	    get_uleb128 (op1, readp, endp);
5157 	    if ((uint64_t) (endp - readp) < 1)
5158 	      goto invalid;
5159 	    get_uleb128 (op2, readp, endp);
5160 	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5161 		    op1, regname (op1), op2);
5162 	    break;
5163 	  case DW_CFA_def_cfa_register:
5164 	    if ((uint64_t) (endp - readp) < 1)
5165 	      goto invalid;
5166 	    get_uleb128 (op1, readp, endp);
5167 	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
5168 		    op1, regname (op1));
5169 	    break;
5170 	  case DW_CFA_def_cfa_offset:
5171 	    if ((uint64_t) (endp - readp) < 1)
5172 	      goto invalid;
5173 	    get_uleb128 (op1, readp, endp);
5174 	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
5175 	    break;
5176 	  case DW_CFA_def_cfa_expression:
5177 	    if ((uint64_t) (endp - readp) < 1)
5178 	      goto invalid;
5179 	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
5180 	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
5181 	    if ((uint64_t) (endp - readp) < op1)
5182 	      {
5183 	    invalid:
5184 	        fputs (gettext ("         <INVALID DATA>\n"), stdout);
5185 		return;
5186 	      }
5187 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5188 		       op1, readp);
5189 	    readp += op1;
5190 	    break;
5191 	  case DW_CFA_expression:
5192 	    if ((uint64_t) (endp - readp) < 1)
5193 	      goto invalid;
5194 	    get_uleb128 (op1, readp, endp);
5195 	    if ((uint64_t) (endp - readp) < 1)
5196 	      goto invalid;
5197 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
5198 	    printf ("     expression r%" PRIu64 " (%s) \n",
5199 		    op1, regname (op1));
5200 	    if ((uint64_t) (endp - readp) < op2)
5201 	      goto invalid;
5202 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5203 		       op2, readp);
5204 	    readp += op2;
5205 	    break;
5206 	  case DW_CFA_offset_extended_sf:
5207 	    if ((uint64_t) (endp - readp) < 1)
5208 	      goto invalid;
5209 	    get_uleb128 (op1, readp, endp);
5210 	    if ((uint64_t) (endp - readp) < 1)
5211 	      goto invalid;
5212 	    get_sleb128 (sop2, readp, endp);
5213 	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5214 		    PRId64 "\n",
5215 		    op1, regname (op1), sop2 * data_align);
5216 	    break;
5217 	  case DW_CFA_def_cfa_sf:
5218 	    if ((uint64_t) (endp - readp) < 1)
5219 	      goto invalid;
5220 	    get_uleb128 (op1, readp, endp);
5221 	    if ((uint64_t) (endp - readp) < 1)
5222 	      goto invalid;
5223 	    get_sleb128 (sop2, readp, endp);
5224 	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5225 		    op1, regname (op1), sop2 * data_align);
5226 	    break;
5227 	  case DW_CFA_def_cfa_offset_sf:
5228 	    if ((uint64_t) (endp - readp) < 1)
5229 	      goto invalid;
5230 	    get_sleb128 (sop1, readp, endp);
5231 	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5232 	    break;
5233 	  case DW_CFA_val_offset:
5234 	    if ((uint64_t) (endp - readp) < 1)
5235 	      goto invalid;
5236 	    get_uleb128 (op1, readp, endp);
5237 	    if ((uint64_t) (endp - readp) < 1)
5238 	      goto invalid;
5239 	    get_uleb128 (op2, readp, endp);
5240 	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5241 		    op1, op2 * data_align);
5242 	    break;
5243 	  case DW_CFA_val_offset_sf:
5244 	    if ((uint64_t) (endp - readp) < 1)
5245 	      goto invalid;
5246 	    get_uleb128 (op1, readp, endp);
5247 	    if ((uint64_t) (endp - readp) < 1)
5248 	      goto invalid;
5249 	    get_sleb128 (sop2, readp, endp);
5250 	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5251 		    op1, sop2 * data_align);
5252 	    break;
5253 	  case DW_CFA_val_expression:
5254 	    if ((uint64_t) (endp - readp) < 1)
5255 	      goto invalid;
5256 	    get_uleb128 (op1, readp, endp);
5257 	    if ((uint64_t) (endp - readp) < 1)
5258 	      goto invalid;
5259 	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
5260 	    printf ("     val_expression r%" PRIu64 " (%s)\n",
5261 		    op1, regname (op1));
5262 	    if ((uint64_t) (endp - readp) < op2)
5263 	      goto invalid;
5264 	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5265 		       NULL, op2, readp);
5266 	    readp += op2;
5267 	    break;
5268 	  case DW_CFA_MIPS_advance_loc8:
5269 	    if ((uint64_t) (endp - readp) < 8)
5270 	      goto invalid;
5271 	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
5272 	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5273 		    op1, pc += op1 * code_align);
5274 	    break;
5275 	  case DW_CFA_GNU_window_save:
5276 	    puts ("     GNU_window_save");
5277 	    break;
5278 	  case DW_CFA_GNU_args_size:
5279 	    if ((uint64_t) (endp - readp) < 1)
5280 	      goto invalid;
5281 	    get_uleb128 (op1, readp, endp);
5282 	    printf ("     args_size %" PRIu64 "\n", op1);
5283 	    break;
5284 	  default:
5285 	    printf ("     ??? (%u)\n", opcode);
5286 	    break;
5287 	  }
5288       else if (opcode < DW_CFA_offset)
5289 	printf ("     advance_loc %u to %#" PRIx64 "\n",
5290 		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5291       else if (opcode < DW_CFA_restore)
5292 	{
5293 	  uint64_t offset;
5294 	  if ((uint64_t) (endp - readp) < 1)
5295 	    goto invalid;
5296 	  get_uleb128 (offset, readp, endp);
5297 	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
5298 		  opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5299 	}
5300       else
5301 	printf ("     restore r%u (%s)\n",
5302 		opcode & 0x3f, regname (opcode & 0x3f));
5303     }
5304 }
5305 
5306 
5307 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)5308 encoded_ptr_size (int encoding, unsigned int ptr_size)
5309 {
5310   switch (encoding & 7)
5311     {
5312     case DW_EH_PE_udata4:
5313       return 4;
5314     case DW_EH_PE_udata8:
5315       return 8;
5316     case 0:
5317       return ptr_size;
5318     }
5319 
5320   fprintf (stderr, "Unsupported pointer encoding: %#x, "
5321 	   "assuming pointer size of %d.\n", encoding, ptr_size);
5322   return ptr_size;
5323 }
5324 
5325 
5326 static unsigned int
print_encoding(unsigned int val)5327 print_encoding (unsigned int val)
5328 {
5329   switch (val & 0xf)
5330     {
5331     case DW_EH_PE_absptr:
5332       fputs ("absptr", stdout);
5333       break;
5334     case DW_EH_PE_uleb128:
5335       fputs ("uleb128", stdout);
5336       break;
5337     case DW_EH_PE_udata2:
5338       fputs ("udata2", stdout);
5339       break;
5340     case DW_EH_PE_udata4:
5341       fputs ("udata4", stdout);
5342       break;
5343     case DW_EH_PE_udata8:
5344       fputs ("udata8", stdout);
5345       break;
5346     case DW_EH_PE_sleb128:
5347       fputs ("sleb128", stdout);
5348       break;
5349     case DW_EH_PE_sdata2:
5350       fputs ("sdata2", stdout);
5351       break;
5352     case DW_EH_PE_sdata4:
5353       fputs ("sdata4", stdout);
5354       break;
5355     case DW_EH_PE_sdata8:
5356       fputs ("sdata8", stdout);
5357       break;
5358     default:
5359       /* We did not use any of the bits after all.  */
5360       return val;
5361     }
5362 
5363   return val & ~0xf;
5364 }
5365 
5366 
5367 static unsigned int
print_relinfo(unsigned int val)5368 print_relinfo (unsigned int val)
5369 {
5370   switch (val & 0x70)
5371     {
5372     case DW_EH_PE_pcrel:
5373       fputs ("pcrel", stdout);
5374       break;
5375     case DW_EH_PE_textrel:
5376       fputs ("textrel", stdout);
5377       break;
5378     case DW_EH_PE_datarel:
5379       fputs ("datarel", stdout);
5380       break;
5381     case DW_EH_PE_funcrel:
5382       fputs ("funcrel", stdout);
5383       break;
5384     case DW_EH_PE_aligned:
5385       fputs ("aligned", stdout);
5386       break;
5387     default:
5388       return val;
5389     }
5390 
5391   return val & ~0x70;
5392 }
5393 
5394 
5395 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)5396 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5397 {
5398   printf ("(%s", pfx);
5399 
5400   if (fde_encoding == DW_EH_PE_omit)
5401     puts ("omit)");
5402   else
5403     {
5404       unsigned int w = fde_encoding;
5405 
5406       w = print_encoding (w);
5407 
5408       if (w & 0x70)
5409 	{
5410 	  if (w != fde_encoding)
5411 	    fputc_unlocked (' ', stdout);
5412 
5413 	  w = print_relinfo (w);
5414 	}
5415 
5416       if (w != 0)
5417 	printf ("%s%x", w != fde_encoding ? " " : "", w);
5418 
5419       puts (")");
5420     }
5421 }
5422 
5423 
5424 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)5425 read_encoded (unsigned int encoding, const unsigned char *readp,
5426 	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5427 {
5428   if ((encoding & 0xf) == DW_EH_PE_absptr)
5429     encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5430       ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5431 
5432   switch (encoding & 0xf)
5433     {
5434     case DW_EH_PE_uleb128:
5435       get_uleb128 (*res, readp, endp);
5436       break;
5437     case DW_EH_PE_sleb128:
5438       get_sleb128 (*res, readp, endp);
5439       break;
5440     case DW_EH_PE_udata2:
5441       if (readp + 2 > endp)
5442 	goto invalid;
5443       *res = read_2ubyte_unaligned_inc (dbg, readp);
5444       break;
5445     case DW_EH_PE_udata4:
5446       if (readp + 4 > endp)
5447 	goto invalid;
5448       *res = read_4ubyte_unaligned_inc (dbg, readp);
5449       break;
5450     case DW_EH_PE_udata8:
5451       if (readp + 8 > endp)
5452 	goto invalid;
5453       *res = read_8ubyte_unaligned_inc (dbg, readp);
5454       break;
5455     case DW_EH_PE_sdata2:
5456       if (readp + 2 > endp)
5457 	goto invalid;
5458       *res = read_2sbyte_unaligned_inc (dbg, readp);
5459       break;
5460     case DW_EH_PE_sdata4:
5461       if (readp + 4 > endp)
5462 	goto invalid;
5463       *res = read_4sbyte_unaligned_inc (dbg, readp);
5464       break;
5465     case DW_EH_PE_sdata8:
5466       if (readp + 8 > endp)
5467 	goto invalid;
5468       *res = read_8sbyte_unaligned_inc (dbg, readp);
5469       break;
5470     default:
5471     invalid:
5472       error (1, 0,
5473 	     gettext ("invalid encoding"));
5474     }
5475 
5476   return readp;
5477 }
5478 
5479 
5480 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5481 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5482 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5483 {
5484   size_t shstrndx;
5485   /* We know this call will succeed since it did in the caller.  */
5486   (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5487   const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5488 
5489   /* Needed if we find PC-relative addresses.  */
5490   GElf_Addr bias;
5491   if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5492     {
5493       error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5494       return;
5495     }
5496 
5497   bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5498   Elf_Data *data = (is_eh_frame
5499 		    ? elf_rawdata (scn, NULL)
5500 		    : dbg->sectiondata[IDX_debug_frame]);
5501 
5502   if (unlikely (data == NULL))
5503     {
5504       error (0, 0, gettext ("cannot get %s content: %s"),
5505 	     scnname, elf_errmsg (-1));
5506       return;
5507     }
5508 
5509   if (is_eh_frame)
5510     printf (gettext ("\
5511 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5512 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5513   else
5514     printf (gettext ("\
5515 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5516 	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5517 
5518   struct cieinfo
5519   {
5520     ptrdiff_t cie_offset;
5521     const char *augmentation;
5522     unsigned int code_alignment_factor;
5523     unsigned int data_alignment_factor;
5524     uint8_t address_size;
5525     uint8_t fde_encoding;
5526     uint8_t lsda_encoding;
5527     struct cieinfo *next;
5528   } *cies = NULL;
5529 
5530   const unsigned char *readp = data->d_buf;
5531   const unsigned char *const dataend = ((unsigned char *) data->d_buf
5532 					+ data->d_size);
5533   while (readp < dataend)
5534     {
5535       if (unlikely (readp + 4 > dataend))
5536 	{
5537 	invalid_data:
5538 	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5539 		     elf_ndxscn (scn), scnname);
5540 	      return;
5541 	}
5542 
5543       /* At the beginning there must be a CIE.  There can be multiple,
5544 	 hence we test tis in a loop.  */
5545       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5546 
5547       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5548       unsigned int length = 4;
5549       if (unlikely (unit_length == 0xffffffff))
5550 	{
5551 	  if (unlikely (readp + 8 > dataend))
5552 	    goto invalid_data;
5553 
5554 	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5555 	  length = 8;
5556 	}
5557 
5558       if (unlikely (unit_length == 0))
5559 	{
5560 	  printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5561 	  continue;
5562 	}
5563 
5564       Dwarf_Word maxsize = dataend - readp;
5565       if (unlikely (unit_length > maxsize))
5566 	goto invalid_data;
5567 
5568       unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5569 
5570       ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5571       const unsigned char *const cieend = readp + unit_length;
5572       if (unlikely (cieend > dataend || readp + 8 > dataend))
5573 	goto invalid_data;
5574 
5575       Dwarf_Off cie_id;
5576       if (length == 4)
5577 	{
5578 	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5579 	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5580 	    cie_id = DW_CIE_ID_64;
5581 	}
5582       else
5583 	cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5584 
5585       uint_fast8_t version = 2;
5586       unsigned int code_alignment_factor;
5587       int data_alignment_factor;
5588       unsigned int fde_encoding = 0;
5589       unsigned int lsda_encoding = 0;
5590       Dwarf_Word initial_location = 0;
5591       Dwarf_Word vma_base = 0;
5592 
5593       if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5594 	{
5595 	  version = *readp++;
5596 	  const char *const augmentation = (const char *) readp;
5597 	  readp = memchr (readp, '\0', cieend - readp);
5598 	  if (unlikely (readp == NULL))
5599 	    goto invalid_data;
5600 	  ++readp;
5601 
5602 	  uint_fast8_t segment_size = 0;
5603 	  if (version >= 4)
5604 	    {
5605 	      if (cieend - readp < 5)
5606 		goto invalid_data;
5607 	      ptr_size = *readp++;
5608 	      segment_size = *readp++;
5609 	    }
5610 
5611 	  if (cieend - readp < 1)
5612 	    goto invalid_data;
5613 	  get_uleb128 (code_alignment_factor, readp, cieend);
5614 	  if (cieend - readp < 1)
5615 	    goto invalid_data;
5616 	  get_sleb128 (data_alignment_factor, readp, cieend);
5617 
5618 	  /* In some variant for unwind data there is another field.  */
5619 	  if (strcmp (augmentation, "eh") == 0)
5620 	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5621 
5622 	  unsigned int return_address_register;
5623 	  if (cieend - readp < 1)
5624 	    goto invalid_data;
5625 	  if (unlikely (version == 1))
5626 	    return_address_register = *readp++;
5627 	  else
5628 	    get_uleb128 (return_address_register, readp, cieend);
5629 
5630 	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5631 		  "   CIE_id:                   %" PRIu64 "\n"
5632 		  "   version:                  %u\n"
5633 		  "   augmentation:             \"%s\"\n",
5634 		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
5635 		  version, augmentation);
5636 	  if (version >= 4)
5637 	    printf ("   address_size:             %u\n"
5638 		    "   segment_size:             %u\n",
5639 		    ptr_size, segment_size);
5640 	  printf ("   code_alignment_factor:    %u\n"
5641 		  "   data_alignment_factor:    %d\n"
5642 		  "   return_address_register:  %u\n",
5643 		  code_alignment_factor,
5644 		  data_alignment_factor, return_address_register);
5645 
5646 	  if (augmentation[0] == 'z')
5647 	    {
5648 	      unsigned int augmentationlen;
5649 	      get_uleb128 (augmentationlen, readp, cieend);
5650 
5651 	      if (augmentationlen > (size_t) (cieend - readp))
5652 		{
5653 		  error (0, 0, gettext ("invalid augmentation length"));
5654 		  readp = cieend;
5655 		  continue;
5656 		}
5657 
5658 	      const char *hdr = "Augmentation data:";
5659 	      const char *cp = augmentation + 1;
5660 	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5661 		{
5662 		  printf ("   %-26s%#x ", hdr, *readp);
5663 		  hdr = "";
5664 
5665 		  if (*cp == 'R')
5666 		    {
5667 		      fde_encoding = *readp++;
5668 		      print_encoding_base (gettext ("FDE address encoding: "),
5669 					   fde_encoding);
5670 		    }
5671 		  else if (*cp == 'L')
5672 		    {
5673 		      lsda_encoding = *readp++;
5674 		      print_encoding_base (gettext ("LSDA pointer encoding: "),
5675 					   lsda_encoding);
5676 		    }
5677 		  else if (*cp == 'P')
5678 		    {
5679 		      /* Personality.  This field usually has a relocation
5680 			 attached pointing to __gcc_personality_v0.  */
5681 		      const unsigned char *startp = readp;
5682 		      unsigned int encoding = *readp++;
5683 		      uint64_t val = 0;
5684 		      readp = read_encoded (encoding, readp,
5685 					    readp - 1 + augmentationlen,
5686 					    &val, dbg);
5687 
5688 		      while (++startp < readp)
5689 			printf ("%#x ", *startp);
5690 
5691 		      putchar ('(');
5692 		      print_encoding (encoding);
5693 		      putchar (' ');
5694 		      switch (encoding & 0xf)
5695 			{
5696 			case DW_EH_PE_sleb128:
5697 			case DW_EH_PE_sdata2:
5698 			case DW_EH_PE_sdata4:
5699 			  printf ("%" PRId64 ")\n", val);
5700 			  break;
5701 			default:
5702 			  printf ("%#" PRIx64 ")\n", val);
5703 			  break;
5704 			}
5705 		    }
5706 		  else
5707 		    printf ("(%x)\n", *readp++);
5708 
5709 		  ++cp;
5710 		}
5711 	    }
5712 
5713 	  if (likely (ptr_size == 4 || ptr_size == 8))
5714 	    {
5715 	      struct cieinfo *newp = alloca (sizeof (*newp));
5716 	      newp->cie_offset = offset;
5717 	      newp->augmentation = augmentation;
5718 	      newp->fde_encoding = fde_encoding;
5719 	      newp->lsda_encoding = lsda_encoding;
5720 	      newp->address_size = ptr_size;
5721 	      newp->code_alignment_factor = code_alignment_factor;
5722 	      newp->data_alignment_factor = data_alignment_factor;
5723 	      newp->next = cies;
5724 	      cies = newp;
5725 	    }
5726 	}
5727       else
5728 	{
5729 	  struct cieinfo *cie = cies;
5730 	  while (cie != NULL)
5731 	    if (is_eh_frame
5732 		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
5733 		: cie_id == (Dwarf_Off) cie->cie_offset)
5734 	      break;
5735 	    else
5736 	      cie = cie->next;
5737 	  if (unlikely (cie == NULL))
5738 	    {
5739 	      puts ("invalid CIE reference in FDE");
5740 	      return;
5741 	    }
5742 
5743 	  /* Initialize from CIE data.  */
5744 	  fde_encoding = cie->fde_encoding;
5745 	  lsda_encoding = cie->lsda_encoding;
5746 	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5747 	  code_alignment_factor = cie->code_alignment_factor;
5748 	  data_alignment_factor = cie->data_alignment_factor;
5749 
5750 	  const unsigned char *base = readp;
5751 	  // XXX There are sometimes relocations for this value
5752 	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5753 	  Dwarf_Word address_range
5754 	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
5755 
5756 	  /* pcrel for an FDE address is relative to the runtime
5757 	     address of the start_address field itself.  Sign extend
5758 	     if necessary to make sure the calculation is done on the
5759 	     full 64 bit address even when initial_location only holds
5760 	     the lower 32 bits.  */
5761 	  Dwarf_Addr pc_start = initial_location;
5762 	  if (ptr_size == 4)
5763 	    pc_start = (uint64_t) (int32_t) pc_start;
5764 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5765 	    pc_start += ((uint64_t) shdr->sh_addr
5766 			 + (base - (const unsigned char *) data->d_buf)
5767 			 - bias);
5768 
5769 	  char *a = format_dwarf_addr (dwflmod, cie->address_size,
5770 				       pc_start, initial_location);
5771 	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5772 		  "   CIE_pointer:              %" PRIu64 "\n"
5773 		  "   initial_location:         %s",
5774 		  offset, (uint64_t) unit_length,
5775 		  cie->cie_offset, (uint64_t) cie_id, a);
5776 	  free (a);
5777 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5778 	    {
5779 	      vma_base = (((uint64_t) shdr->sh_offset
5780 			   + (base - (const unsigned char *) data->d_buf)
5781 			   + (uint64_t) initial_location)
5782 			  & (ptr_size == 4
5783 			     ? UINT64_C (0xffffffff)
5784 			     : UINT64_C (0xffffffffffffffff)));
5785 	      printf (gettext (" (offset: %#" PRIx64 ")"),
5786 		      (uint64_t) vma_base);
5787 	    }
5788 
5789 	  printf ("\n   address_range:            %#" PRIx64,
5790 		  (uint64_t) address_range);
5791 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5792 	    printf (gettext (" (end offset: %#" PRIx64 ")"),
5793 		    ((uint64_t) vma_base + (uint64_t) address_range)
5794 		    & (ptr_size == 4
5795 		       ? UINT64_C (0xffffffff)
5796 		       : UINT64_C (0xffffffffffffffff)));
5797 	  putchar ('\n');
5798 
5799 	  if (cie->augmentation[0] == 'z')
5800 	    {
5801 	      unsigned int augmentationlen;
5802 	      if (cieend - readp < 1)
5803 		goto invalid_data;
5804 	      get_uleb128 (augmentationlen, readp, cieend);
5805 
5806 	      if (augmentationlen > (size_t) (cieend - readp))
5807 		{
5808 		  error (0, 0, gettext ("invalid augmentation length"));
5809 		  readp = cieend;
5810 		  continue;
5811 		}
5812 
5813 	      if (augmentationlen > 0)
5814 		{
5815 		  const char *hdr = "Augmentation data:";
5816 		  const char *cp = cie->augmentation + 1;
5817 		  unsigned int u = 0;
5818 		  while (*cp != '\0'
5819 			 && cp < cie->augmentation + augmentationlen + 1)
5820 		    {
5821 		      if (*cp == 'L')
5822 			{
5823 			  uint64_t lsda_pointer;
5824 			  const unsigned char *p
5825 			    = read_encoded (lsda_encoding, &readp[u],
5826 					    &readp[augmentationlen],
5827 					    &lsda_pointer, dbg);
5828 			  u = p - readp;
5829 			  printf (gettext ("\
5830    %-26sLSDA pointer: %#" PRIx64 "\n"),
5831 				  hdr, lsda_pointer);
5832 			  hdr = "";
5833 			}
5834 		      ++cp;
5835 		    }
5836 
5837 		  while (u < augmentationlen)
5838 		    {
5839 		      printf ("   %-26s%#x\n", hdr, readp[u++]);
5840 		      hdr = "";
5841 		    }
5842 		}
5843 
5844 	      readp += augmentationlen;
5845 	    }
5846 	}
5847 
5848       /* Handle the initialization instructions.  */
5849       if (ptr_size != 4 && ptr_size !=8)
5850 	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5851       else
5852 	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5853 			   data_alignment_factor, version, ptr_size,
5854 			   dwflmod, ebl, dbg);
5855       readp = cieend;
5856     }
5857 }
5858 
5859 
5860 struct attrcb_args
5861 {
5862   Dwfl_Module *dwflmod;
5863   Dwarf *dbg;
5864   Dwarf_Die *die;
5865   int level;
5866   bool silent;
5867   unsigned int version;
5868   unsigned int addrsize;
5869   unsigned int offset_size;
5870   struct Dwarf_CU *cu;
5871 };
5872 
5873 
5874 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)5875 attr_callback (Dwarf_Attribute *attrp, void *arg)
5876 {
5877   struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5878   const int level = cbargs->level;
5879 
5880   unsigned int attr = dwarf_whatattr (attrp);
5881   if (unlikely (attr == 0))
5882     {
5883       if (!cbargs->silent)
5884 	error (0, 0, gettext ("cannot get attribute code: %s"),
5885 	       dwarf_errmsg (-1));
5886       return DWARF_CB_ABORT;
5887     }
5888 
5889   unsigned int form = dwarf_whatform (attrp);
5890   if (unlikely (form == 0))
5891     {
5892       if (!cbargs->silent)
5893 	error (0, 0, gettext ("cannot get attribute form: %s"),
5894 	       dwarf_errmsg (-1));
5895       return DWARF_CB_ABORT;
5896     }
5897 
5898   switch (form)
5899     {
5900     case DW_FORM_addr:
5901       if (!cbargs->silent)
5902 	{
5903 	  Dwarf_Addr addr;
5904 	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5905 	    {
5906 	    attrval_out:
5907 	      if (!cbargs->silent)
5908 		error (0, 0, gettext ("cannot get attribute value: %s"),
5909 		       dwarf_errmsg (-1));
5910 	      return DWARF_CB_ABORT;
5911 	    }
5912 	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5913 				       addr, addr);
5914 	  printf ("           %*s%-20s (%s) %s\n",
5915 		  (int) (level * 2), "", dwarf_attr_name (attr),
5916 		  dwarf_form_name (form), a);
5917 	  free (a);
5918 	}
5919       break;
5920 
5921     case DW_FORM_indirect:
5922     case DW_FORM_strp:
5923     case DW_FORM_string:
5924     case DW_FORM_GNU_strp_alt:
5925       if (cbargs->silent)
5926 	break;
5927       const char *str = dwarf_formstring (attrp);
5928       if (unlikely (str == NULL))
5929 	goto attrval_out;
5930       printf ("           %*s%-20s (%s) \"%s\"\n",
5931 	      (int) (level * 2), "", dwarf_attr_name (attr),
5932 	      dwarf_form_name (form), str);
5933       break;
5934 
5935     case DW_FORM_ref_addr:
5936     case DW_FORM_ref_udata:
5937     case DW_FORM_ref8:
5938     case DW_FORM_ref4:
5939     case DW_FORM_ref2:
5940     case DW_FORM_ref1:
5941     case DW_FORM_GNU_ref_alt:
5942       if (cbargs->silent)
5943 	break;
5944       Dwarf_Die ref;
5945       if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5946 	goto attrval_out;
5947 
5948       printf ("           %*s%-20s (%s) [%6" PRIxMAX "]\n",
5949 	      (int) (level * 2), "", dwarf_attr_name (attr),
5950 	      dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5951       break;
5952 
5953     case DW_FORM_ref_sig8:
5954       if (cbargs->silent)
5955 	break;
5956       printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
5957 	      (int) (level * 2), "", dwarf_attr_name (attr),
5958 	      dwarf_form_name (form),
5959 	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5960       break;
5961 
5962     case DW_FORM_sec_offset:
5963     case DW_FORM_udata:
5964     case DW_FORM_sdata:
5965     case DW_FORM_data8:
5966     case DW_FORM_data4:
5967     case DW_FORM_data2:
5968     case DW_FORM_data1:;
5969       Dwarf_Word num;
5970       if (unlikely (dwarf_formudata (attrp, &num) != 0))
5971 	goto attrval_out;
5972 
5973       const char *valuestr = NULL;
5974       switch (attr)
5975 	{
5976 	  /* This case can take either a constant or a loclistptr.  */
5977 	case DW_AT_data_member_location:
5978 	  if (form != DW_FORM_sec_offset
5979 	      && (cbargs->version >= 4
5980 		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5981 	    {
5982 	      if (!cbargs->silent)
5983 		printf ("           %*s%-20s (%s) %" PRIxMAX "\n",
5984 			(int) (level * 2), "", dwarf_attr_name (attr),
5985 			dwarf_form_name (form), (uintmax_t) num);
5986 	      return DWARF_CB_OK;
5987 	    }
5988 	  /* else fallthrough */
5989 
5990 	/* These cases always take a loclistptr and no constant. */
5991 	case DW_AT_location:
5992 	case DW_AT_data_location:
5993 	case DW_AT_vtable_elem_location:
5994 	case DW_AT_string_length:
5995 	case DW_AT_use_location:
5996 	case DW_AT_frame_base:
5997 	case DW_AT_return_addr:
5998 	case DW_AT_static_link:
5999 	case DW_AT_GNU_call_site_value:
6000 	case DW_AT_GNU_call_site_data_value:
6001 	case DW_AT_GNU_call_site_target:
6002 	case DW_AT_GNU_call_site_target_clobbered:
6003 	  {
6004 	    bool nlpt = notice_listptr (section_loc, &known_loclistptr,
6005 					cbargs->addrsize, cbargs->offset_size,
6006 					cbargs->cu, num);
6007 	    if (!cbargs->silent)
6008 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
6009 		      (int) (level * 2), "", dwarf_attr_name (attr),
6010 		      dwarf_form_name (form), (uintmax_t) num,
6011 		      nlpt ? "" : " <WARNING offset too big>");
6012 	  }
6013 	  return DWARF_CB_OK;
6014 
6015 	case DW_AT_ranges:
6016 	  {
6017 	    bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
6018 					cbargs->addrsize, cbargs->offset_size,
6019 					cbargs->cu, num);
6020 	    if (!cbargs->silent)
6021 	      printf ("           %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
6022 		      (int) (level * 2), "", dwarf_attr_name (attr),
6023 		      dwarf_form_name (form), (uintmax_t) num,
6024 		      nlpt ? "" : " <WARNING offset too big>");
6025 	  }
6026 	  return DWARF_CB_OK;
6027 
6028 	case DW_AT_language:
6029 	  valuestr = dwarf_lang_name (num);
6030 	  break;
6031 	case DW_AT_encoding:
6032 	  valuestr = dwarf_encoding_name (num);
6033 	  break;
6034 	case DW_AT_accessibility:
6035 	  valuestr = dwarf_access_name (num);
6036 	  break;
6037 	case DW_AT_visibility:
6038 	  valuestr = dwarf_visibility_name (num);
6039 	  break;
6040 	case DW_AT_virtuality:
6041 	  valuestr = dwarf_virtuality_name (num);
6042 	  break;
6043 	case DW_AT_identifier_case:
6044 	  valuestr = dwarf_identifier_case_name (num);
6045 	  break;
6046 	case DW_AT_calling_convention:
6047 	  valuestr = dwarf_calling_convention_name (num);
6048 	  break;
6049 	case DW_AT_inline:
6050 	  valuestr = dwarf_inline_name (num);
6051 	  break;
6052 	case DW_AT_ordering:
6053 	  valuestr = dwarf_ordering_name (num);
6054 	  break;
6055 	case DW_AT_discr_list:
6056 	  valuestr = dwarf_discr_list_name (num);
6057 	  break;
6058 	default:
6059 	  /* Nothing.  */
6060 	  break;
6061 	}
6062 
6063       if (cbargs->silent)
6064 	break;
6065 
6066       /* When highpc is in constant form it is relative to lowpc.
6067 	 In that case also show the address.  */
6068       Dwarf_Addr highpc;
6069       if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
6070 	{
6071 	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
6072 				       highpc, highpc);
6073 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (%s)\n",
6074 		  (int) (level * 2), "", dwarf_attr_name (attr),
6075 		  dwarf_form_name (form), (uintmax_t) num, a);
6076 	  free (a);
6077 	}
6078       else
6079 	{
6080 	  Dwarf_Sword snum = 0;
6081 	  if (form == DW_FORM_sdata)
6082 	    if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
6083 	      goto attrval_out;
6084 
6085 	  if (valuestr == NULL)
6086 	    {
6087 	      printf ("           %*s%-20s (%s)",
6088 		      (int) (level * 2), "", dwarf_attr_name (attr),
6089 		      dwarf_form_name (form));
6090 	      if (form == DW_FORM_sdata)
6091 		printf (" %" PRIdMAX "\n", (intmax_t) snum);
6092 	      else
6093 		printf (" %" PRIuMAX "\n", (uintmax_t) num);
6094 	    }
6095 	  else
6096 	    {
6097 	      printf ("           %*s%-20s (%s) %s",
6098 		      (int) (level * 2), "", dwarf_attr_name (attr),
6099 		      dwarf_form_name (form), valuestr);
6100 	      if (form == DW_FORM_sdata)
6101 		printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
6102 	      else
6103 		printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6104 	    }
6105 	}
6106       break;
6107 
6108     case DW_FORM_flag:
6109       if (cbargs->silent)
6110 	break;
6111       bool flag;
6112       if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6113 	goto attrval_out;
6114 
6115       printf ("           %*s%-20s (%s) %s\n",
6116 	      (int) (level * 2), "", dwarf_attr_name (attr),
6117 	      dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
6118       break;
6119 
6120     case DW_FORM_flag_present:
6121       if (cbargs->silent)
6122 	break;
6123       printf ("           %*s%-20s (%s) %s\n",
6124 	      (int) (level * 2), "", dwarf_attr_name (attr),
6125 	      dwarf_form_name (form), nl_langinfo (YESSTR));
6126       break;
6127 
6128     case DW_FORM_exprloc:
6129     case DW_FORM_block4:
6130     case DW_FORM_block2:
6131     case DW_FORM_block1:
6132     case DW_FORM_block:
6133       if (cbargs->silent)
6134 	break;
6135       Dwarf_Block block;
6136       if (unlikely (dwarf_formblock (attrp, &block) != 0))
6137 	goto attrval_out;
6138 
6139       printf ("           %*s%-20s (%s) ",
6140 	      (int) (level * 2), "", dwarf_attr_name (attr),
6141 	      dwarf_form_name (form));
6142 
6143       switch (attr)
6144 	{
6145 	default:
6146 	  if (form != DW_FORM_exprloc)
6147 	    {
6148 	      print_block (block.length, block.data);
6149 	      break;
6150 	    }
6151 	  /* Fall through.  */
6152 
6153 	case DW_AT_location:
6154 	case DW_AT_data_location:
6155 	case DW_AT_data_member_location:
6156 	case DW_AT_vtable_elem_location:
6157 	case DW_AT_string_length:
6158 	case DW_AT_use_location:
6159 	case DW_AT_frame_base:
6160 	case DW_AT_return_addr:
6161 	case DW_AT_static_link:
6162 	case DW_AT_allocated:
6163 	case DW_AT_associated:
6164 	case DW_AT_bit_size:
6165 	case DW_AT_bit_offset:
6166 	case DW_AT_bit_stride:
6167 	case DW_AT_byte_size:
6168 	case DW_AT_byte_stride:
6169 	case DW_AT_count:
6170 	case DW_AT_lower_bound:
6171 	case DW_AT_upper_bound:
6172 	case DW_AT_GNU_call_site_value:
6173 	case DW_AT_GNU_call_site_data_value:
6174 	case DW_AT_GNU_call_site_target:
6175 	case DW_AT_GNU_call_site_target_clobbered:
6176 	  putchar ('\n');
6177 	  print_ops (cbargs->dwflmod, cbargs->dbg,
6178 		     12 + level * 2, 12 + level * 2,
6179 		     cbargs->version, cbargs->addrsize, cbargs->offset_size,
6180 		     attrp->cu, block.length, block.data);
6181 	  break;
6182 	}
6183       break;
6184 
6185     default:
6186       if (cbargs->silent)
6187 	break;
6188       printf ("           %*s%-20s (form: %#x) ???\n",
6189 	      (int) (level * 2), "", dwarf_attr_name (attr),
6190 	      (int) form);
6191       break;
6192     }
6193 
6194   return DWARF_CB_OK;
6195 }
6196 
6197 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)6198 print_debug_units (Dwfl_Module *dwflmod,
6199 		   Ebl *ebl, GElf_Ehdr *ehdr,
6200 		   Elf_Scn *scn, GElf_Shdr *shdr,
6201 		   Dwarf *dbg, bool debug_types)
6202 {
6203   const bool silent = !(print_debug_sections & section_info);
6204   const char *secname = section_name (ebl, ehdr, shdr);
6205 
6206   if (!silent)
6207     printf (gettext ("\
6208 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6209 	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6210 
6211   /* If the section is empty we don't have to do anything.  */
6212   if (!silent && shdr->sh_size == 0)
6213     return;
6214 
6215   int maxdies = 20;
6216   Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6217 
6218   Dwarf_Off offset = 0;
6219 
6220   /* New compilation unit.  */
6221   size_t cuhl;
6222   Dwarf_Half version;
6223   Dwarf_Off abbroffset;
6224   uint8_t addrsize;
6225   uint8_t offsize;
6226   Dwarf_Off nextcu;
6227   uint64_t typesig;
6228   Dwarf_Off typeoff;
6229  next_cu:
6230   if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6231 		       &abbroffset, &addrsize, &offsize,
6232 		       debug_types ? &typesig : NULL,
6233 		       debug_types ? &typeoff : NULL) != 0)
6234     goto do_return;
6235 
6236   if (!silent)
6237     {
6238       if (debug_types)
6239 	printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6240 			 " Version: %" PRIu16 ", Abbreviation section offset: %"
6241 			 PRIu64 ", Address size: %" PRIu8
6242 			 ", Offset size: %" PRIu8
6243 			 "\n Type signature: %#" PRIx64
6244 			 ", Type offset: %#" PRIx64 "\n"),
6245 		(uint64_t) offset, version, abbroffset, addrsize, offsize,
6246 		typesig, (uint64_t) typeoff);
6247       else
6248 	printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6249 			 " Version: %" PRIu16 ", Abbreviation section offset: %"
6250 			 PRIu64 ", Address size: %" PRIu8
6251 			 ", Offset size: %" PRIu8 "\n"),
6252 		(uint64_t) offset, version, abbroffset, addrsize, offsize);
6253     }
6254 
6255   struct attrcb_args args =
6256     {
6257       .dwflmod = dwflmod,
6258       .dbg = dbg,
6259       .silent = silent,
6260       .version = version,
6261       .addrsize = addrsize,
6262       .offset_size = offsize
6263     };
6264 
6265   offset += cuhl;
6266 
6267   int level = 0;
6268 
6269   if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6270 		(dbg, offset, &dies[level]) == NULL))
6271     {
6272       if (!silent)
6273 	error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6274 			      " in section '%s': %s"),
6275 	       (uint64_t) offset, secname, dwarf_errmsg (-1));
6276       goto do_return;
6277     }
6278 
6279   args.cu = dies[0].cu;
6280 
6281   do
6282     {
6283       offset = dwarf_dieoffset (&dies[level]);
6284       if (unlikely (offset == ~0ul))
6285 	{
6286 	  if (!silent)
6287 	    error (0, 0, gettext ("cannot get DIE offset: %s"),
6288 		   dwarf_errmsg (-1));
6289 	  goto do_return;
6290 	}
6291 
6292       int tag = dwarf_tag (&dies[level]);
6293       if (unlikely (tag == DW_TAG_invalid))
6294 	{
6295 	  if (!silent)
6296 	    error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6297 				  " in section '%s': %s"),
6298 		   (uint64_t) offset, secname, dwarf_errmsg (-1));
6299 	  goto do_return;
6300 	}
6301 
6302       if (!silent)
6303 	printf (" [%6" PRIx64 "]  %*s%s\n",
6304 		(uint64_t) offset, (int) (level * 2), "",
6305 		dwarf_tag_name (tag));
6306 
6307       /* Print the attribute values.  */
6308       args.level = level;
6309       args.die = &dies[level];
6310       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6311 
6312       /* Make room for the next level's DIE.  */
6313       if (level + 1 == maxdies)
6314 	dies = (Dwarf_Die *) xrealloc (dies,
6315 				       (maxdies += 10)
6316 				       * sizeof (Dwarf_Die));
6317 
6318       int res = dwarf_child (&dies[level], &dies[level + 1]);
6319       if (res > 0)
6320 	{
6321 	  while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6322 	    if (level-- == 0)
6323 	      break;
6324 
6325 	  if (unlikely (res == -1))
6326 	    {
6327 	      if (!silent)
6328 		error (0, 0, gettext ("cannot get next DIE: %s\n"),
6329 		       dwarf_errmsg (-1));
6330 	      goto do_return;
6331 	    }
6332 	}
6333       else if (unlikely (res < 0))
6334 	{
6335 	  if (!silent)
6336 	    error (0, 0, gettext ("cannot get next DIE: %s"),
6337 		   dwarf_errmsg (-1));
6338 	  goto do_return;
6339 	}
6340       else
6341 	++level;
6342     }
6343   while (level >= 0);
6344 
6345   offset = nextcu;
6346   if (offset != 0)
6347      goto next_cu;
6348 
6349  do_return:
6350   free (dies);
6351 }
6352 
6353 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6354 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6355 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6356 {
6357   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6358 }
6359 
6360 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6361 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6362 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6363 {
6364   print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6365 }
6366 
6367 
6368 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6369 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6370 			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6371 {
6372   printf (gettext ("\
6373 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6374 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6375 	  (uint64_t) shdr->sh_offset);
6376 
6377   size_t address_size
6378     = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6379 
6380   Dwarf_Off cuoffset;
6381   Dwarf_Off ncuoffset = 0;
6382   size_t hsize;
6383   while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6384 		       NULL, NULL, NULL) == 0)
6385     {
6386       Dwarf_Die cudie;
6387       if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6388 	continue;
6389 
6390       size_t nlines;
6391       Dwarf_Lines *lines;
6392       if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6393 	continue;
6394 
6395       printf (" CU [%" PRIx64 "] %s\n",
6396 	      dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6397       printf ("  line:col SBPE* disc isa op address"
6398 	      " (Statement Block Prologue Epilogue *End)\n");
6399       const char *last_file = "";
6400       for (size_t n = 0; n < nlines; n++)
6401 	{
6402 	  Dwarf_Line *line = dwarf_onesrcline (lines, n);
6403 	  if (line == NULL)
6404 	    {
6405 	      printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6406 	      continue;
6407 	    }
6408 	  Dwarf_Word mtime, length;
6409 	  const char *file = dwarf_linesrc (line, &mtime, &length);
6410 	  if (file == NULL)
6411 	    {
6412 	      printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6413 	      last_file = "";
6414 	    }
6415 	  else if (strcmp (last_file, file) != 0)
6416 	    {
6417 	      printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6418 		      file, mtime, length);
6419 	      last_file = file;
6420 	    }
6421 
6422 	  int lineno, colno;
6423 	  bool statement, endseq, block, prologue_end, epilogue_begin;
6424 	  unsigned int lineop, isa, disc;
6425 	  Dwarf_Addr address;
6426 	  dwarf_lineaddr (line, &address);
6427 	  dwarf_lineno (line, &lineno);
6428 	  dwarf_linecol (line, &colno);
6429 	  dwarf_lineop_index (line, &lineop);
6430 	  dwarf_linebeginstatement (line, &statement);
6431 	  dwarf_lineendsequence (line, &endseq);
6432 	  dwarf_lineblock (line, &block);
6433 	  dwarf_lineprologueend (line, &prologue_end);
6434 	  dwarf_lineepiloguebegin (line, &epilogue_begin);
6435 	  dwarf_lineisa (line, &isa);
6436 	  dwarf_linediscriminator (line, &disc);
6437 
6438 	  /* End sequence is special, it is one byte past.  */
6439 	  char *a = format_dwarf_addr (dwflmod, address_size,
6440 				       address - (endseq ? 1 : 0), address);
6441 	  printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6442 		  lineno, colno,
6443 		  (statement ? 'S' : ' '),
6444 		  (block ? 'B' : ' '),
6445 		  (prologue_end ? 'P' : ' '),
6446 		  (epilogue_begin ? 'E' : ' '),
6447 		  (endseq ? '*' : ' '),
6448 		  disc, isa, lineop, a);
6449 	  free (a);
6450 
6451 	  if (endseq)
6452 	    printf("\n");
6453 	}
6454     }
6455 }
6456 
6457 
6458 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6459 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6460 			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6461 {
6462   if (decodedline)
6463     {
6464       print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6465       return;
6466     }
6467 
6468   printf (gettext ("\
6469 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6470 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6471 	  (uint64_t) shdr->sh_offset);
6472 
6473   if (shdr->sh_size == 0)
6474     return;
6475 
6476   /* There is no functionality in libdw to read the information in the
6477      way it is represented here.  Hardcode the decoder.  */
6478   Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6479   if (unlikely (data == NULL || data->d_buf == NULL))
6480     {
6481       error (0, 0, gettext ("cannot get line data section data: %s"),
6482 	     elf_errmsg (-1));
6483       return;
6484     }
6485 
6486   const unsigned char *linep = (const unsigned char *) data->d_buf;
6487   const unsigned char *lineendp;
6488 
6489   while (linep
6490 	 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6491     {
6492       size_t start_offset = linep - (const unsigned char *) data->d_buf;
6493 
6494       printf (gettext ("\nTable at offset %zu:\n"), start_offset);
6495 
6496       if (unlikely (linep + 4 > lineendp))
6497 	goto invalid_data;
6498       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6499       unsigned int length = 4;
6500       if (unlikely (unit_length == 0xffffffff))
6501 	{
6502 	  if (unlikely (linep + 8 > lineendp))
6503 	    {
6504 	    invalid_data:
6505 	      error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6506 		     elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6507 	      return;
6508 	    }
6509 	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6510 	  length = 8;
6511 	}
6512 
6513       /* Check whether we have enough room in the section.  */
6514       if (unlikely (unit_length > (size_t) (lineendp - linep)
6515 	  || unit_length < 2 + length + 5 * 1))
6516 	goto invalid_data;
6517       lineendp = linep + unit_length;
6518 
6519       /* The next element of the header is the version identifier.  */
6520       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6521 
6522       /* Next comes the header length.  */
6523       Dwarf_Word header_length;
6524       if (length == 4)
6525 	header_length = read_4ubyte_unaligned_inc (dbg, linep);
6526       else
6527 	header_length = read_8ubyte_unaligned_inc (dbg, linep);
6528       //const unsigned char *header_start = linep;
6529 
6530       /* Next the minimum instruction length.  */
6531       uint_fast8_t minimum_instr_len = *linep++;
6532 
6533       /* Next the maximum operations per instruction, in version 4 format.  */
6534       uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6535 
6536 	/* Then the flag determining the default value of the is_stmt
6537 	   register.  */
6538       uint_fast8_t default_is_stmt = *linep++;
6539 
6540       /* Now the line base.  */
6541       int_fast8_t line_base = *((const int_fast8_t *) linep);
6542       ++linep;
6543 
6544       /* And the line range.  */
6545       uint_fast8_t line_range = *linep++;
6546 
6547       /* The opcode base.  */
6548       uint_fast8_t opcode_base = *linep++;
6549 
6550       /* Print what we got so far.  */
6551       printf (gettext ("\n"
6552 		       " Length:                     %" PRIu64 "\n"
6553 		       " DWARF version:              %" PRIuFAST16 "\n"
6554 		       " Prologue length:            %" PRIu64 "\n"
6555 		       " Minimum instruction length: %" PRIuFAST8 "\n"
6556 		       " Maximum operations per instruction: %" PRIuFAST8 "\n"
6557 		       " Initial value if '%s': %" PRIuFAST8 "\n"
6558 		       " Line base:                  %" PRIdFAST8 "\n"
6559 		       " Line range:                 %" PRIuFAST8 "\n"
6560 		       " Opcode base:                %" PRIuFAST8 "\n"
6561 		       "\n"
6562 		       "Opcodes:\n"),
6563 	      (uint64_t) unit_length, version, (uint64_t) header_length,
6564 	      minimum_instr_len, max_ops_per_instr,
6565 	      "is_stmt", default_is_stmt, line_base,
6566 	      line_range, opcode_base);
6567 
6568       if (unlikely (linep + opcode_base - 1 >= lineendp))
6569 	{
6570 	invalid_unit:
6571 	  error (0, 0,
6572 		 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6573 		 linep - (const unsigned char *) data->d_buf,
6574 		 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6575 	  linep = lineendp;
6576 	  continue;
6577 	}
6578       int opcode_base_l10 = 1;
6579       unsigned int tmp = opcode_base;
6580       while (tmp > 10)
6581 	{
6582 	  tmp /= 10;
6583 	  ++opcode_base_l10;
6584 	}
6585       const uint8_t *standard_opcode_lengths = linep - 1;
6586       for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6587 	printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
6588 			  "  [%*" PRIuFAST8 "]  %hhu arguments\n",
6589 			  (int) linep[cnt - 1]),
6590 		opcode_base_l10, cnt, linep[cnt - 1]);
6591       linep += opcode_base - 1;
6592       if (unlikely (linep >= lineendp))
6593 	goto invalid_unit;
6594 
6595       puts (gettext ("\nDirectory table:"));
6596       while (*linep != 0)
6597 	{
6598 	  unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6599 	  if (unlikely (endp == NULL))
6600 	    goto invalid_unit;
6601 
6602 	  printf (" %s\n", (char *) linep);
6603 
6604 	  linep = endp + 1;
6605 	}
6606       /* Skip the final NUL byte.  */
6607       ++linep;
6608 
6609       if (unlikely (linep >= lineendp))
6610 	goto invalid_unit;
6611       puts (gettext ("\nFile name table:\n"
6612 		     " Entry Dir   Time      Size      Name"));
6613       for (unsigned int cnt = 1; *linep != 0; ++cnt)
6614 	{
6615 	  /* First comes the file name.  */
6616 	  char *fname = (char *) linep;
6617 	  unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6618 	  if (unlikely (endp == NULL))
6619 	    goto invalid_unit;
6620 	  linep = endp + 1;
6621 
6622 	  /* Then the index.  */
6623 	  unsigned int diridx;
6624 	  if (lineendp - linep < 1)
6625 	    goto invalid_unit;
6626 	  get_uleb128 (diridx, linep, lineendp);
6627 
6628 	  /* Next comes the modification time.  */
6629 	  unsigned int mtime;
6630 	  if (lineendp - linep < 1)
6631 	    goto invalid_unit;
6632 	  get_uleb128 (mtime, linep, lineendp);
6633 
6634 	  /* Finally the length of the file.  */
6635 	  unsigned int fsize;
6636 	  if (lineendp - linep < 1)
6637 	    goto invalid_unit;
6638 	  get_uleb128 (fsize, linep, lineendp);
6639 
6640 	  printf (" %-5u %-5u %-9u %-9u %s\n",
6641 		  cnt, diridx, mtime, fsize, fname);
6642 	}
6643       /* Skip the final NUL byte.  */
6644       ++linep;
6645 
6646       puts (gettext ("\nLine number statements:"));
6647       Dwarf_Word address = 0;
6648       unsigned int op_index = 0;
6649       size_t line = 1;
6650       uint_fast8_t is_stmt = default_is_stmt;
6651 
6652       /* Default address value, in case we do not find the CU.  */
6653       size_t address_size
6654 	= elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6655 
6656       /* Determine the CU this block is for.  */
6657       Dwarf_Off cuoffset;
6658       Dwarf_Off ncuoffset = 0;
6659       size_t hsize;
6660       while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6661 			   NULL, NULL, NULL) == 0)
6662 	{
6663 	  Dwarf_Die cudie;
6664 	  if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6665 	    continue;
6666 	  Dwarf_Attribute stmt_list;
6667 	  if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6668 	    continue;
6669 	  Dwarf_Word lineoff;
6670 	  if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6671 	    continue;
6672 	  if (lineoff == start_offset)
6673 	    {
6674 	      /* Found the CU.  */
6675 	      address_size = cudie.cu->address_size;
6676 	      break;
6677 	    }
6678 	}
6679 
6680       /* Apply the "operation advance" from a special opcode
6681 	 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
6682       unsigned int op_addr_advance;
6683       bool show_op_index;
6684       inline void advance_pc (unsigned int op_advance)
6685       {
6686 	op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6687 					       / max_ops_per_instr);
6688 	address += op_advance;
6689 	show_op_index = (op_index > 0 ||
6690 			 (op_index + op_advance) % max_ops_per_instr > 0);
6691 	op_index = (op_index + op_advance) % max_ops_per_instr;
6692       }
6693 
6694       if (max_ops_per_instr == 0)
6695 	{
6696 	  error (0, 0,
6697 		 gettext ("invalid maximum operations per instruction is zero"));
6698 	  linep = lineendp;
6699 	  continue;
6700 	}
6701 
6702       while (linep < lineendp)
6703 	{
6704 	  size_t offset = linep - (const unsigned char *) data->d_buf;
6705 	  unsigned int u128;
6706 	  int s128;
6707 
6708 	  /* Read the opcode.  */
6709 	  unsigned int opcode = *linep++;
6710 
6711 	  printf (" [%6" PRIx64 "]", (uint64_t)offset);
6712 	  /* Is this a special opcode?  */
6713 	  if (likely (opcode >= opcode_base))
6714 	    {
6715 	      if (unlikely (line_range == 0))
6716 		goto invalid_unit;
6717 
6718 	      /* Yes.  Handling this is quite easy since the opcode value
6719 		 is computed with
6720 
6721 		 opcode = (desired line increment - line_base)
6722 			   + (line_range * address advance) + opcode_base
6723 	      */
6724 	      int line_increment = (line_base
6725 				    + (opcode - opcode_base) % line_range);
6726 
6727 	      /* Perform the increments.  */
6728 	      line += line_increment;
6729 	      advance_pc ((opcode - opcode_base) / line_range);
6730 
6731 	      char *a = format_dwarf_addr (dwflmod, 0, address, address);
6732 	      if (show_op_index)
6733 		printf (gettext ("\
6734  special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6735 			opcode, op_addr_advance, a, op_index,
6736 			line_increment, line);
6737 	      else
6738 		printf (gettext ("\
6739  special opcode %u: address+%u = %s, line%+d = %zu\n"),
6740 			opcode, op_addr_advance, a, line_increment, line);
6741 	      free (a);
6742 	    }
6743 	  else if (opcode == 0)
6744 	    {
6745 	      /* This an extended opcode.  */
6746 	      if (unlikely (linep + 2 > lineendp))
6747 		goto invalid_unit;
6748 
6749 	      /* The length.  */
6750 	      unsigned int len = *linep++;
6751 
6752 	      if (unlikely (linep + len > lineendp))
6753 		goto invalid_unit;
6754 
6755 	      /* The sub-opcode.  */
6756 	      opcode = *linep++;
6757 
6758 	      printf (gettext (" extended opcode %u: "), opcode);
6759 
6760 	      switch (opcode)
6761 		{
6762 		case DW_LNE_end_sequence:
6763 		  puts (gettext (" end of sequence"));
6764 
6765 		  /* Reset the registers we care about.  */
6766 		  address = 0;
6767 		  op_index = 0;
6768 		  line = 1;
6769 		  is_stmt = default_is_stmt;
6770 		  break;
6771 
6772 		case DW_LNE_set_address:
6773 		  op_index = 0;
6774 		  if (unlikely ((size_t) (lineendp - linep) < address_size))
6775 		    goto invalid_unit;
6776 		  if (address_size == 4)
6777 		    address = read_4ubyte_unaligned_inc (dbg, linep);
6778 		  else
6779 		    address = read_8ubyte_unaligned_inc (dbg, linep);
6780 		  {
6781 		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
6782 		    printf (gettext (" set address to %s\n"), a);
6783 		    free (a);
6784 		  }
6785 		  break;
6786 
6787 		case DW_LNE_define_file:
6788 		  {
6789 		    char *fname = (char *) linep;
6790 		    unsigned char *endp = memchr (linep, '\0',
6791 						  lineendp - linep);
6792 		    if (unlikely (endp == NULL))
6793 		      goto invalid_unit;
6794 		    linep = endp + 1;
6795 
6796 		    unsigned int diridx;
6797 		    if (lineendp - linep < 1)
6798 		      goto invalid_unit;
6799 		    get_uleb128 (diridx, linep, lineendp);
6800 		    Dwarf_Word mtime;
6801 		    if (lineendp - linep < 1)
6802 		      goto invalid_unit;
6803 		    get_uleb128 (mtime, linep, lineendp);
6804 		    Dwarf_Word filelength;
6805 		    if (lineendp - linep < 1)
6806 		      goto invalid_unit;
6807 		    get_uleb128 (filelength, linep, lineendp);
6808 
6809 		    printf (gettext ("\
6810  define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6811 			    diridx, (uint64_t) mtime, (uint64_t) filelength,
6812 			    fname);
6813 		  }
6814 		  break;
6815 
6816 		case DW_LNE_set_discriminator:
6817 		  /* Takes one ULEB128 parameter, the discriminator.  */
6818 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
6819 		    goto invalid_unit;
6820 
6821 		  get_uleb128 (u128, linep, lineendp);
6822 		  printf (gettext (" set discriminator to %u\n"), u128);
6823 		  break;
6824 
6825 		default:
6826 		  /* Unknown, ignore it.  */
6827 		  puts (gettext (" unknown opcode"));
6828 		  linep += len - 1;
6829 		  break;
6830 		}
6831 	    }
6832 	  else if (opcode <= DW_LNS_set_isa)
6833 	    {
6834 	      /* This is a known standard opcode.  */
6835 	      switch (opcode)
6836 		{
6837 		case DW_LNS_copy:
6838 		  /* Takes no argument.  */
6839 		  puts (gettext (" copy"));
6840 		  break;
6841 
6842 		case DW_LNS_advance_pc:
6843 		  /* Takes one uleb128 parameter which is added to the
6844 		     address.  */
6845 		  get_uleb128 (u128, linep, lineendp);
6846 		  advance_pc (u128);
6847 		  {
6848 		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
6849 		    if (show_op_index)
6850 		      printf (gettext ("\
6851  advance address by %u to %s, op_index to %u\n"),
6852 			      op_addr_advance, a, op_index);
6853 		    else
6854 		      printf (gettext (" advance address by %u to %s\n"),
6855 			      op_addr_advance, a);
6856 		    free (a);
6857 		  }
6858 		  break;
6859 
6860 		case DW_LNS_advance_line:
6861 		  /* Takes one sleb128 parameter which is added to the
6862 		     line.  */
6863 		  get_sleb128 (s128, linep, lineendp);
6864 		  line += s128;
6865 		  printf (gettext ("\
6866  advance line by constant %d to %" PRId64 "\n"),
6867 			  s128, (int64_t) line);
6868 		  break;
6869 
6870 		case DW_LNS_set_file:
6871 		  /* Takes one uleb128 parameter which is stored in file.  */
6872 		  get_uleb128 (u128, linep, lineendp);
6873 		  printf (gettext (" set file to %" PRIu64 "\n"),
6874 			  (uint64_t) u128);
6875 		  break;
6876 
6877 		case DW_LNS_set_column:
6878 		  /* Takes one uleb128 parameter which is stored in column.  */
6879 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
6880 		    goto invalid_unit;
6881 
6882 		  get_uleb128 (u128, linep, lineendp);
6883 		  printf (gettext (" set column to %" PRIu64 "\n"),
6884 			  (uint64_t) u128);
6885 		  break;
6886 
6887 		case DW_LNS_negate_stmt:
6888 		  /* Takes no argument.  */
6889 		  is_stmt = 1 - is_stmt;
6890 		  printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6891 			  "is_stmt", is_stmt);
6892 		  break;
6893 
6894 		case DW_LNS_set_basic_block:
6895 		  /* Takes no argument.  */
6896 		  puts (gettext (" set basic block flag"));
6897 		  break;
6898 
6899 		case DW_LNS_const_add_pc:
6900 		  /* Takes no argument.  */
6901 
6902 		  if (unlikely (line_range == 0))
6903 		    goto invalid_unit;
6904 
6905 		  advance_pc ((255 - opcode_base) / line_range);
6906 		  {
6907 		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
6908 		    if (show_op_index)
6909 		      printf (gettext ("\
6910  advance address by constant %u to %s, op_index to %u\n"),
6911 			      op_addr_advance, a, op_index);
6912 		    else
6913 		      printf (gettext ("\
6914  advance address by constant %u to %s\n"),
6915 			      op_addr_advance, a);
6916 		    free (a);
6917 		  }
6918 		  break;
6919 
6920 		case DW_LNS_fixed_advance_pc:
6921 		  /* Takes one 16 bit parameter which is added to the
6922 		     address.  */
6923 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
6924 		    goto invalid_unit;
6925 
6926 		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
6927 		  address += u128;
6928 		  op_index = 0;
6929 		  {
6930 		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
6931 		    printf (gettext ("\
6932  advance address by fixed value %u to %s\n"),
6933 			    u128, a);
6934 		    free (a);
6935 		  }
6936 		  break;
6937 
6938 		case DW_LNS_set_prologue_end:
6939 		  /* Takes no argument.  */
6940 		  puts (gettext (" set prologue end flag"));
6941 		  break;
6942 
6943 		case DW_LNS_set_epilogue_begin:
6944 		  /* Takes no argument.  */
6945 		  puts (gettext (" set epilogue begin flag"));
6946 		  break;
6947 
6948 		case DW_LNS_set_isa:
6949 		  /* Takes one uleb128 parameter which is stored in isa.  */
6950 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
6951 		    goto invalid_unit;
6952 
6953 		  get_uleb128 (u128, linep, lineendp);
6954 		  printf (gettext (" set isa to %u\n"), u128);
6955 		  break;
6956 		}
6957 	    }
6958 	  else
6959 	    {
6960 	      /* This is a new opcode the generator but not we know about.
6961 		 Read the parameters associated with it but then discard
6962 		 everything.  Read all the parameters for this opcode.  */
6963 	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6964 				" unknown opcode with %" PRIu8 " parameters:",
6965 				standard_opcode_lengths[opcode]),
6966 		      standard_opcode_lengths[opcode]);
6967 	      for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6968 		{
6969 		  get_uleb128 (u128, linep, lineendp);
6970 		  if (n != standard_opcode_lengths[opcode])
6971 		    putc_unlocked (',', stdout);
6972 		  printf (" %u", u128);
6973 		}
6974 
6975 	      /* Next round, ignore this opcode.  */
6976 	      continue;
6977 	    }
6978 	}
6979     }
6980 
6981   /* There must only be one data block.  */
6982   assert (elf_getdata (scn, data) == NULL);
6983 }
6984 
6985 
6986 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6987 print_debug_loc_section (Dwfl_Module *dwflmod,
6988 			 Ebl *ebl, GElf_Ehdr *ehdr,
6989 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6990 {
6991   Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6992 
6993   if (unlikely (data == NULL))
6994     {
6995       error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6996 	     elf_errmsg (-1));
6997       return;
6998     }
6999 
7000   printf (gettext ("\
7001 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7002 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7003 	  (uint64_t) shdr->sh_offset);
7004 
7005   sort_listptr (&known_loclistptr, "loclistptr");
7006   size_t listptr_idx = 0;
7007 
7008   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7009   uint_fast8_t offset_size = 4;
7010 
7011   bool first = true;
7012   struct Dwarf_CU *cu = NULL;
7013   Dwarf_Addr base = 0;
7014   unsigned char *readp = data->d_buf;
7015   unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
7016   while (readp < endp)
7017     {
7018       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
7019 
7020       if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
7021 				      &address_size, &offset_size, &base,
7022 				      &cu, offset, &readp, endp))
7023 	continue;
7024 
7025       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
7026 	{
7027 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
7028 	  break;
7029 	}
7030 
7031       Dwarf_Addr begin;
7032       Dwarf_Addr end;
7033       if (address_size == 8)
7034 	{
7035 	  begin = read_8ubyte_unaligned_inc (dbg, readp);
7036 	  end = read_8ubyte_unaligned_inc (dbg, readp);
7037 	}
7038       else
7039 	{
7040 	  begin = read_4ubyte_unaligned_inc (dbg, readp);
7041 	  end = read_4ubyte_unaligned_inc (dbg, readp);
7042 	  if (begin == (Dwarf_Addr) (uint32_t) -1)
7043 	    begin = (Dwarf_Addr) -1l;
7044 	}
7045 
7046       if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
7047 	{
7048 	  char *b = format_dwarf_addr (dwflmod, address_size, end, end);
7049 	  printf (gettext (" [%6tx]  base address %s\n"), offset, b);
7050 	  free (b);
7051 	  base = end;
7052 	}
7053       else if (begin == 0 && end == 0) /* End of list entry.  */
7054 	{
7055 	  if (first)
7056 	    printf (gettext (" [%6tx]  empty list\n"), offset);
7057 	  first = true;
7058 	}
7059       else
7060 	{
7061 	  /* We have a location expression entry.  */
7062 	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
7063 
7064 	  char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
7065 				       begin);
7066 	  char *e = format_dwarf_addr (dwflmod, address_size, base + end,
7067 				       end);
7068 
7069 	  if (first)		/* First entry in a list.  */
7070 	    printf (gettext (" [%6tx]  %s..%s"), offset, b, e);
7071 	  else
7072 	    printf (gettext ("           %s..%s"), b, e);
7073 
7074 	  free (b);
7075 	  free (e);
7076 
7077 	  if (endp - readp <= (ptrdiff_t) len)
7078 	    {
7079 	      fputs (gettext ("   <INVALID DATA>\n"), stdout);
7080 	      break;
7081 	    }
7082 
7083 	  print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
7084 		     3 /*XXX*/, address_size, offset_size, cu, len, readp);
7085 
7086 	  first = false;
7087 	  readp += len;
7088 	}
7089     }
7090 }
7091 
7092 struct mac_culist
7093 {
7094   Dwarf_Die die;
7095   Dwarf_Off offset;
7096   Dwarf_Files *files;
7097   struct mac_culist *next;
7098 };
7099 
7100 
7101 static int
mac_compare(const void * p1,const void * p2)7102 mac_compare (const void *p1, const void *p2)
7103 {
7104   struct mac_culist *m1 = (struct mac_culist *) p1;
7105   struct mac_culist *m2 = (struct mac_culist *) p2;
7106 
7107   if (m1->offset < m2->offset)
7108     return -1;
7109   if (m1->offset > m2->offset)
7110     return 1;
7111   return 0;
7112 }
7113 
7114 
7115 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7116 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7117 			     Ebl *ebl, GElf_Ehdr *ehdr,
7118 			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7119 {
7120   printf (gettext ("\
7121 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7122 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7123 	  (uint64_t) shdr->sh_offset);
7124   putc_unlocked ('\n', stdout);
7125 
7126   /* There is no function in libdw to iterate over the raw content of
7127      the section but it is easy enough to do.  */
7128   Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7129   if (unlikely (data == NULL || data->d_buf == NULL))
7130     {
7131       error (0, 0, gettext ("cannot get macro information section data: %s"),
7132 	     elf_errmsg (-1));
7133       return;
7134     }
7135 
7136   /* Get the source file information for all CUs.  */
7137   Dwarf_Off offset;
7138   Dwarf_Off ncu = 0;
7139   size_t hsize;
7140   struct mac_culist *culist = NULL;
7141   size_t nculist = 0;
7142   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7143     {
7144       Dwarf_Die cudie;
7145       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7146 	continue;
7147 
7148       Dwarf_Attribute attr;
7149       if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7150 	continue;
7151 
7152       Dwarf_Word macoff;
7153       if (dwarf_formudata (&attr, &macoff) != 0)
7154 	continue;
7155 
7156       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7157       newp->die = cudie;
7158       newp->offset = macoff;
7159       newp->files = NULL;
7160       newp->next = culist;
7161       culist = newp;
7162       ++nculist;
7163     }
7164 
7165   /* Convert the list into an array for easier consumption.  */
7166   struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7167 							 * sizeof (*cus));
7168   /* Add sentinel.  */
7169   cus[nculist].offset = data->d_size;
7170   cus[nculist].files = (Dwarf_Files *) -1l;
7171   if (nculist > 0)
7172     {
7173       for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7174 	{
7175 	  assert (cnt < nculist);
7176 	  cus[cnt] = *culist;
7177 	  culist = culist->next;
7178 	}
7179 
7180       /* Sort the array according to the offset in the .debug_macinfo
7181 	 section.  Note we keep the sentinel at the end.  */
7182       qsort (cus, nculist, sizeof (*cus), mac_compare);
7183     }
7184 
7185   const unsigned char *readp = (const unsigned char *) data->d_buf;
7186   const unsigned char *readendp = readp + data->d_size;
7187   int level = 1;
7188 
7189   while (readp < readendp)
7190     {
7191       unsigned int opcode = *readp++;
7192       unsigned int u128;
7193       unsigned int u128_2;
7194       const unsigned char *endp;
7195 
7196       switch (opcode)
7197 	{
7198 	case DW_MACINFO_define:
7199 	case DW_MACINFO_undef:
7200 	case DW_MACINFO_vendor_ext:
7201 	  /*  For the first two opcodes the parameters are
7202 		line, string
7203 	      For the latter
7204 		number, string.
7205 	      We can treat these cases together.  */
7206 	  get_uleb128 (u128, readp, readendp);
7207 
7208 	  endp = memchr (readp, '\0', readendp - readp);
7209 	  if (unlikely (endp == NULL))
7210 	    {
7211 	      printf (gettext ("\
7212 %*s*** non-terminated string at end of section"),
7213 		      level, "");
7214 	      return;
7215 	    }
7216 
7217 	  if (opcode == DW_MACINFO_define)
7218 	    printf ("%*s#define %s, line %u\n",
7219 		    level, "", (char *) readp, u128);
7220 	  else if (opcode == DW_MACINFO_undef)
7221 	    printf ("%*s#undef %s, line %u\n",
7222 		    level, "", (char *) readp, u128);
7223 	  else
7224 	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7225 
7226 	  readp = endp + 1;
7227 	  break;
7228 
7229 	case DW_MACINFO_start_file:
7230 	  /* The two parameters are line and file index, in this order.  */
7231 	  get_uleb128 (u128, readp, readendp);
7232 	  if (readendp - readp < 1)
7233 	    {
7234 	      printf (gettext ("\
7235 %*s*** missing DW_MACINFO_start_file argument at end of section"),
7236 		      level, "");
7237 	      return;
7238 	    }
7239 	  get_uleb128 (u128_2, readp, readendp);
7240 
7241 	  /* Find the CU DIE for this file.  */
7242 	  size_t macoff = readp - (const unsigned char *) data->d_buf;
7243 	  const char *fname = "???";
7244 	  if (macoff >= cus[0].offset)
7245 	    {
7246 	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
7247 		++cus;
7248 
7249 	      if (cus[0].files == NULL
7250 		&& dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7251 		cus[0].files = (Dwarf_Files *) -1l;
7252 
7253 	      if (cus[0].files != (Dwarf_Files *) -1l)
7254 		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7255 			 ?: "???");
7256 	    }
7257 
7258 	  printf ("%*sstart_file %u, [%u] %s\n",
7259 		  level, "", u128, u128_2, fname);
7260 	  ++level;
7261 	  break;
7262 
7263 	case DW_MACINFO_end_file:
7264 	  --level;
7265 	  printf ("%*send_file\n", level, "");
7266 	  /* Nothing more to do.  */
7267 	  break;
7268 
7269 	default:
7270 	  // XXX gcc seems to generate files with a trailing zero.
7271 	  if (unlikely (opcode != 0 || readp != readendp))
7272 	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7273 	  break;
7274 	}
7275     }
7276 }
7277 
7278 
7279 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7280 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7281 			   Ebl *ebl, GElf_Ehdr *ehdr,
7282 			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7283 {
7284   printf (gettext ("\
7285 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7286 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7287 	  (uint64_t) shdr->sh_offset);
7288   putc_unlocked ('\n', stdout);
7289 
7290   Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7291   if (unlikely (data == NULL || data->d_buf == NULL))
7292     {
7293       error (0, 0, gettext ("cannot get macro information section data: %s"),
7294 	     elf_errmsg (-1));
7295       return;
7296     }
7297 
7298   /* Get the source file information for all CUs.  Uses same
7299      datastructure as macinfo.  But uses offset field to directly
7300      match .debug_line offset.  And just stored in a list.  */
7301   Dwarf_Off offset;
7302   Dwarf_Off ncu = 0;
7303   size_t hsize;
7304   struct mac_culist *culist = NULL;
7305   size_t nculist = 0;
7306   while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7307     {
7308       Dwarf_Die cudie;
7309       if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7310 	continue;
7311 
7312       Dwarf_Attribute attr;
7313       if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7314 	continue;
7315 
7316       Dwarf_Word lineoff;
7317       if (dwarf_formudata (&attr, &lineoff) != 0)
7318 	continue;
7319 
7320       struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7321       newp->die = cudie;
7322       newp->offset = lineoff;
7323       newp->files = NULL;
7324       newp->next = culist;
7325       culist = newp;
7326       ++nculist;
7327     }
7328 
7329   const unsigned char *readp = (const unsigned char *) data->d_buf;
7330   const unsigned char *readendp = readp + data->d_size;
7331 
7332   while (readp < readendp)
7333     {
7334       printf (gettext (" Offset:             0x%" PRIx64 "\n"),
7335 	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
7336 
7337       // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7338       // optional vendor extension macro entry table.
7339       if (readp + 2 > readendp)
7340 	{
7341 	invalid_data:
7342 	  error (0, 0, gettext ("invalid data"));
7343 	  return;
7344 	}
7345       const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7346       printf (gettext (" Version:            %" PRIu16 "\n"), vers);
7347 
7348       // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
7349       // 5 when it gets standardized.
7350       if (vers != 4)
7351 	{
7352 	  printf (gettext ("  unknown version, cannot parse section\n"));
7353 	  return;
7354 	}
7355 
7356       if (readp + 1 > readendp)
7357 	goto invalid_data;
7358       const unsigned char flag = *readp++;
7359       printf (gettext (" Flag:               0x%" PRIx8 "\n"), flag);
7360 
7361       unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7362       printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
7363       Dwarf_Off line_offset = -1;
7364       if (flag & 0x02)
7365 	{
7366 	  if (offset_len == 8)
7367 	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7368 	  else
7369 	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7370 	  printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7371 		  line_offset);
7372 	}
7373 
7374       const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7375       memset (vendor, 0, sizeof vendor);
7376       if (flag & 0x04)
7377 	{
7378 	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
7379 	  // of arguments, for each argument 1 byte form code.
7380 	  if (readp + 1 > readendp)
7381 	    goto invalid_data;
7382 	  unsigned int tlen = *readp++;
7383 	  printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
7384 		  tlen);
7385 	  for (unsigned int i = 0; i < tlen; i++)
7386 	    {
7387 	      if (readp + 1 > readendp)
7388 		goto invalid_data;
7389 	      unsigned int opcode = *readp++;
7390 	      printf (gettext ("    [%" PRIx8 "]"), opcode);
7391 	      if (opcode < DW_MACRO_GNU_lo_user
7392 		  || opcode > DW_MACRO_GNU_hi_user)
7393 		goto invalid_data;
7394 	      // Record the start of description for this vendor opcode.
7395 	      // uleb128 nr args, 1 byte per arg form.
7396 	      vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7397 	      if (readp + 1 > readendp)
7398 		goto invalid_data;
7399 	      unsigned int args = *readp++;
7400 	      if (args > 0)
7401 		{
7402 		  printf (gettext (" %" PRIu8 " arguments:"), args);
7403 		  while (args > 0)
7404 		    {
7405 		      if (readp + 1 > readendp)
7406 			goto invalid_data;
7407 		      unsigned int form = *readp++;
7408 		      printf (" %s", dwarf_form_string (form));
7409 		      if (form != DW_FORM_data1
7410 			  && form != DW_FORM_data2
7411 			  && form != DW_FORM_data4
7412 			  && form != DW_FORM_data8
7413 			  && form != DW_FORM_sdata
7414 			  && form != DW_FORM_udata
7415 			  && form != DW_FORM_block
7416 			  && form != DW_FORM_block1
7417 			  && form != DW_FORM_block2
7418 			  && form != DW_FORM_block4
7419 			  && form != DW_FORM_flag
7420 			  && form != DW_FORM_string
7421 			  && form != DW_FORM_strp
7422 			  && form != DW_FORM_sec_offset)
7423 			goto invalid_data;
7424 		      args--;
7425 		      if (args > 0)
7426 			putchar_unlocked (',');
7427 		    }
7428 		}
7429 	      else
7430 		printf (gettext (" no arguments."));
7431 	      putchar_unlocked ('\n');
7432 	    }
7433 	}
7434       putchar_unlocked ('\n');
7435 
7436       int level = 1;
7437       if (readp + 1 > readendp)
7438 	goto invalid_data;
7439       unsigned int opcode = *readp++;
7440       while (opcode != 0)
7441 	{
7442 	  unsigned int u128;
7443 	  unsigned int u128_2;
7444 	  const unsigned char *endp;
7445 	  uint64_t off;
7446 
7447           switch (opcode)
7448             {
7449             case DW_MACRO_GNU_start_file:
7450 	      get_uleb128 (u128, readp, readendp);
7451 	      if (readp >= readendp)
7452 		goto invalid_data;
7453 	      get_uleb128 (u128_2, readp, readendp);
7454 
7455 	      /* Find the CU DIE that matches this line offset.  */
7456 	      const char *fname = "???";
7457 	      if (line_offset != (Dwarf_Off) -1)
7458 		{
7459 		  struct mac_culist *cu = culist;
7460 		  while (cu != NULL && line_offset != cu->offset)
7461 		    cu = cu->next;
7462 		  if (cu != NULL)
7463 		    {
7464 		      if (cu->files == NULL
7465 			  && dwarf_getsrcfiles (&cu->die, &cu->files,
7466 						NULL) != 0)
7467 			cu->files = (Dwarf_Files *) -1l;
7468 
7469 		      if (cu->files != (Dwarf_Files *) -1l)
7470 			fname = (dwarf_filesrc (cu->files, u128_2,
7471 						NULL, NULL) ?: "???");
7472 		    }
7473 		}
7474 	      printf ("%*sstart_file %u, [%u] %s\n",
7475 		      level, "", u128, u128_2, fname);
7476 	      ++level;
7477 	      break;
7478 
7479 	    case DW_MACRO_GNU_end_file:
7480 	      --level;
7481 	      printf ("%*send_file\n", level, "");
7482 	      break;
7483 
7484 	    case DW_MACRO_GNU_define:
7485 	      get_uleb128 (u128, readp, readendp);
7486 	      endp = memchr (readp, '\0', readendp - readp);
7487 	      if (endp == NULL)
7488 		goto invalid_data;
7489 	      printf ("%*s#define %s, line %u\n",
7490 		      level, "", readp, u128);
7491 	      readp = endp + 1;
7492 	      break;
7493 
7494 	    case DW_MACRO_GNU_undef:
7495 	      get_uleb128 (u128, readp, readendp);
7496 	      endp = memchr (readp, '\0', readendp - readp);
7497 	      if (endp == NULL)
7498 		goto invalid_data;
7499 	      printf ("%*s#undef %s, line %u\n",
7500 		      level, "", readp, u128);
7501 	      readp = endp + 1;
7502 	      break;
7503 
7504 	    case DW_MACRO_GNU_define_indirect:
7505 	      get_uleb128 (u128, readp, readendp);
7506 	      if (readp + offset_len > readendp)
7507 		goto invalid_data;
7508 	      if (offset_len == 8)
7509 		off = read_8ubyte_unaligned_inc (dbg, readp);
7510 	      else
7511 		off = read_4ubyte_unaligned_inc (dbg, readp);
7512 	      printf ("%*s#define %s, line %u (indirect)\n",
7513 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
7514 	      break;
7515 
7516 	    case DW_MACRO_GNU_undef_indirect:
7517 	      get_uleb128 (u128, readp, readendp);
7518 	      if (readp + offset_len > readendp)
7519 		goto invalid_data;
7520 	      if (offset_len == 8)
7521 		off = read_8ubyte_unaligned_inc (dbg, readp);
7522 	      else
7523 		off = read_4ubyte_unaligned_inc (dbg, readp);
7524 	      printf ("%*s#undef %s, line %u (indirect)\n",
7525 		      level, "", dwarf_getstring (dbg, off, NULL), u128);
7526 	      break;
7527 
7528 	    case DW_MACRO_GNU_transparent_include:
7529 	      if (readp + offset_len > readendp)
7530 		goto invalid_data;
7531 	      if (offset_len == 8)
7532 		off = read_8ubyte_unaligned_inc (dbg, readp);
7533 	      else
7534 		off = read_4ubyte_unaligned_inc (dbg, readp);
7535 	      printf ("%*s#include offset 0x%" PRIx64 "\n",
7536 		      level, "", off);
7537 	      break;
7538 
7539 	    default:
7540 	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7541 	      if (opcode < DW_MACRO_GNU_lo_user
7542 		  || opcode > DW_MACRO_GNU_lo_user
7543 		  || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7544 		goto invalid_data;
7545 
7546 	      const unsigned char *op_desc;
7547 	      op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7548 
7549 	      // Just skip the arguments, we cannot really interpret them,
7550 	      // but print as much as we can.
7551 	      unsigned int args = *op_desc++;
7552 	      while (args > 0)
7553 		{
7554 		  unsigned int form = *op_desc++;
7555 		  Dwarf_Word val;
7556 		  switch (form)
7557 		    {
7558 		    case DW_FORM_data1:
7559 		      if (readp + 1 > readendp)
7560 			goto invalid_data;
7561 		      val = *readp++;
7562 		      printf (" %" PRIx8, (unsigned int) val);
7563 		      break;
7564 
7565 		    case DW_FORM_data2:
7566 		      if (readp + 2 > readendp)
7567 			goto invalid_data;
7568 		      val = read_2ubyte_unaligned_inc (dbg, readp);
7569 		      printf(" %" PRIx16, (unsigned int) val);
7570 		      break;
7571 
7572 		    case DW_FORM_data4:
7573 		      if (readp + 4 > readendp)
7574 			goto invalid_data;
7575 		      val = read_4ubyte_unaligned_inc (dbg, readp);
7576 		      printf (" %" PRIx32, (unsigned int) val);
7577 		      break;
7578 
7579 		    case DW_FORM_data8:
7580 		      if (readp + 8 > readendp)
7581 			goto invalid_data;
7582 		      val = read_8ubyte_unaligned_inc (dbg, readp);
7583 		      printf (" %" PRIx64, val);
7584 		      break;
7585 
7586 		    case DW_FORM_sdata:
7587 		      get_sleb128 (val, readp, readendp);
7588 		      printf (" %" PRIx64, val);
7589 		      break;
7590 
7591 		    case DW_FORM_udata:
7592 		      get_uleb128 (val, readp, readendp);
7593 		      printf (" %" PRIx64, val);
7594 		      break;
7595 
7596 		    case DW_FORM_block:
7597 		      get_uleb128 (val, readp, readendp);
7598 		      printf (" block[%" PRIu64 "]", val);
7599 		      if (readp + val > readendp)
7600 			goto invalid_data;
7601 		      readp += val;
7602 		      break;
7603 
7604 		    case DW_FORM_block1:
7605 		      if (readp + 1 > readendp)
7606 			goto invalid_data;
7607 		      val = *readp++;
7608 		      printf (" block[%" PRIu64 "]", val);
7609 		      if (readp + val > readendp)
7610 			goto invalid_data;
7611 		      break;
7612 
7613 		    case DW_FORM_block2:
7614 		      if (readp + 2 > readendp)
7615 			goto invalid_data;
7616 		      val = read_2ubyte_unaligned_inc (dbg, readp);
7617 		      printf (" block[%" PRIu64 "]", val);
7618 		      if (readp + val > readendp)
7619 			goto invalid_data;
7620 		      break;
7621 
7622 		    case DW_FORM_block4:
7623 		      if (readp + 2 > readendp)
7624 			goto invalid_data;
7625 		      val =read_4ubyte_unaligned_inc (dbg, readp);
7626 		      printf (" block[%" PRIu64 "]", val);
7627 		      if (readp + val > readendp)
7628 			goto invalid_data;
7629 		      break;
7630 
7631 		    case DW_FORM_flag:
7632 		      if (readp + 1 > readendp)
7633 			goto invalid_data;
7634 		      val = *readp++;
7635 		      printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7636 		      break;
7637 
7638 		    case DW_FORM_string:
7639 		      endp = memchr (readp, '\0', readendp - readp);
7640 		      if (endp == NULL)
7641 			goto invalid_data;
7642 		      printf (" %s", readp);
7643 		      readp = endp + 1;
7644 		      break;
7645 
7646 		    case DW_FORM_strp:
7647 		      if (readp + offset_len > readendp)
7648 			goto invalid_data;
7649 		      if (offset_len == 8)
7650 			val = read_8ubyte_unaligned_inc (dbg, readp);
7651 		      else
7652 			val = read_4ubyte_unaligned_inc (dbg, readp);
7653 		      printf (" %s", dwarf_getstring (dbg, val, NULL));
7654 		      break;
7655 
7656 		    case DW_FORM_sec_offset:
7657 		      if (readp + offset_len > readendp)
7658 			goto invalid_data;
7659 		      if (offset_len == 8)
7660 			val = read_8ubyte_unaligned_inc (dbg, readp);
7661 		      else
7662 			val = read_4ubyte_unaligned_inc (dbg, readp);
7663 		      printf (" %" PRIx64, val);
7664 		      break;
7665 
7666 		      default:
7667 			error (0, 0, gettext ("vendor opcode not verified?"));
7668 			return;
7669 		    }
7670 
7671 		  args--;
7672 		  if (args > 0)
7673 		    putchar_unlocked (',');
7674 		}
7675 	      putchar_unlocked ('\n');
7676 	    }
7677 
7678 	  if (readp + 1 > readendp)
7679 	    goto invalid_data;
7680 	  opcode = *readp++;
7681 	  if (opcode == 0)
7682 	    putchar_unlocked ('\n');
7683 	}
7684     }
7685 }
7686 
7687 
7688 /* Callback for printing global names.  */
7689 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)7690 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7691 		void *arg)
7692 {
7693   int *np = (int *) arg;
7694 
7695   printf (gettext (" [%5d] DIE offset: %6" PRId64
7696 		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7697 	  (*np)++, global->die_offset, global->cu_offset, global->name);
7698 
7699   return 0;
7700 }
7701 
7702 
7703 /* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
7704 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7705 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7706 			      Ebl *ebl, GElf_Ehdr *ehdr,
7707 			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7708 {
7709   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7710 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7711 	  (uint64_t) shdr->sh_offset);
7712 
7713   int n = 0;
7714   (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7715 }
7716 
7717 /* Print the content of the DWARF string section '.debug_str'.  */
7718 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7719 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7720 			 Ebl *ebl, GElf_Ehdr *ehdr,
7721 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7722 {
7723   const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7724 			  dbg->sectiondata[IDX_debug_str]->d_size : 0);
7725 
7726   /* Compute floor(log16(shdr->sh_size)).  */
7727   GElf_Addr tmp = sh_size;
7728   int digits = 1;
7729   while (tmp >= 16)
7730     {
7731       ++digits;
7732       tmp >>= 4;
7733     }
7734   digits = MAX (4, digits);
7735 
7736   printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7737 		   " %*s  String\n"),
7738 	  elf_ndxscn (scn),
7739 	  section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7740 	  /* TRANS: the debugstr| prefix makes the string unique.  */
7741 	  digits + 2, sgettext ("debugstr|Offset"));
7742 
7743   Dwarf_Off offset = 0;
7744   while (offset < sh_size)
7745     {
7746       size_t len;
7747       const char *str = dwarf_getstring (dbg, offset, &len);
7748       if (unlikely (str == NULL))
7749 	{
7750 	  printf (gettext (" *** error while reading strings: %s\n"),
7751 		  dwarf_errmsg (-1));
7752 	  break;
7753 	}
7754 
7755       printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
7756 
7757       offset += len + 1;
7758     }
7759 }
7760 
7761 
7762 /* Print the content of the call frame search table section
7763    '.eh_frame_hdr'.  */
7764 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7765 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7766 			       Ebl *ebl __attribute__ ((unused)),
7767 			       GElf_Ehdr *ehdr __attribute__ ((unused)),
7768 			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7769 {
7770   printf (gettext ("\
7771 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7772 	  elf_ndxscn (scn));
7773 
7774   Elf_Data *data = elf_rawdata (scn, NULL);
7775 
7776   if (unlikely (data == NULL))
7777     {
7778       error (0, 0, gettext ("cannot get %s content: %s"),
7779 	     ".eh_frame_hdr", elf_errmsg (-1));
7780       return;
7781     }
7782 
7783   const unsigned char *readp = data->d_buf;
7784   const unsigned char *const dataend = ((unsigned char *) data->d_buf
7785 					+ data->d_size);
7786 
7787   if (unlikely (readp + 4 > dataend))
7788     {
7789     invalid_data:
7790       error (0, 0, gettext ("invalid data"));
7791       return;
7792     }
7793 
7794   unsigned int version = *readp++;
7795   unsigned int eh_frame_ptr_enc = *readp++;
7796   unsigned int fde_count_enc = *readp++;
7797   unsigned int table_enc = *readp++;
7798 
7799   printf (" version:          %u\n"
7800 	  " eh_frame_ptr_enc: %#x ",
7801 	  version, eh_frame_ptr_enc);
7802   print_encoding_base ("", eh_frame_ptr_enc);
7803   printf (" fde_count_enc:    %#x ", fde_count_enc);
7804   print_encoding_base ("", fde_count_enc);
7805   printf (" table_enc:        %#x ", table_enc);
7806   print_encoding_base ("", table_enc);
7807 
7808   uint64_t eh_frame_ptr = 0;
7809   if (eh_frame_ptr_enc != DW_EH_PE_omit)
7810     {
7811       readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7812 			    dbg);
7813       if (unlikely (readp == NULL))
7814 	goto invalid_data;
7815 
7816       printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
7817       if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7818 	printf (" (offset: %#" PRIx64 ")",
7819 		/* +4 because of the 4 byte header of the section.  */
7820 		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7821 
7822       putchar_unlocked ('\n');
7823     }
7824 
7825   uint64_t fde_count = 0;
7826   if (fde_count_enc != DW_EH_PE_omit)
7827     {
7828       readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7829       if (unlikely (readp == NULL))
7830 	goto invalid_data;
7831 
7832       printf (" fde_count:        %" PRIu64 "\n", fde_count);
7833     }
7834 
7835   if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7836     return;
7837 
7838   puts (" Table:");
7839 
7840   /* Optimize for the most common case.  */
7841   if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7842     while (fde_count > 0 && readp + 8 <= dataend)
7843       {
7844 	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7845 	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7846 				   + (int64_t) initial_location);
7847 	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7848 	// XXX Possibly print symbol name or section offset for initial_offset
7849 	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7850 		" fde=[%6" PRIx64 "]\n",
7851 		initial_location, initial_offset,
7852 		address, address - (eh_frame_ptr + 4));
7853       }
7854   else
7855     while (0 && readp < dataend)
7856       {
7857 
7858       }
7859 }
7860 
7861 
7862 /* Print the content of the exception handling table section
7863    '.eh_frame_hdr'.  */
7864 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7865 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7866 			     Ebl *ebl __attribute__ ((unused)),
7867 			     GElf_Ehdr *ehdr __attribute__ ((unused)),
7868 			     Elf_Scn *scn,
7869 			     GElf_Shdr *shdr __attribute__ ((unused)),
7870 			     Dwarf *dbg __attribute__ ((unused)))
7871 {
7872   printf (gettext ("\
7873 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7874 	  elf_ndxscn (scn));
7875 
7876   Elf_Data *data = elf_rawdata (scn, NULL);
7877 
7878   if (unlikely (data == NULL))
7879     {
7880       error (0, 0, gettext ("cannot get %s content: %s"),
7881 	     ".gcc_except_table", elf_errmsg (-1));
7882       return;
7883     }
7884 
7885   const unsigned char *readp = data->d_buf;
7886   const unsigned char *const dataend = readp + data->d_size;
7887 
7888   if (unlikely (readp + 1 > dataend))
7889     {
7890     invalid_data:
7891       error (0, 0, gettext ("invalid data"));
7892       return;
7893     }
7894   unsigned int lpstart_encoding = *readp++;
7895   printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
7896   print_encoding_base ("", lpstart_encoding);
7897   if (lpstart_encoding != DW_EH_PE_omit)
7898     {
7899       uint64_t lpstart;
7900       readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7901       printf (" LPStart:             %#" PRIx64 "\n", lpstart);
7902     }
7903 
7904   if (unlikely (readp + 1 > dataend))
7905     goto invalid_data;
7906   unsigned int ttype_encoding = *readp++;
7907   printf (gettext (" TType encoding:      %#x "), ttype_encoding);
7908   print_encoding_base ("", ttype_encoding);
7909   const unsigned char *ttype_base = NULL;
7910   if (ttype_encoding != DW_EH_PE_omit)
7911     {
7912       unsigned int ttype_base_offset;
7913       get_uleb128 (ttype_base_offset, readp, dataend);
7914       printf (" TType base offset:   %#x\n", ttype_base_offset);
7915       if ((size_t) (dataend - readp) > ttype_base_offset)
7916         ttype_base = readp + ttype_base_offset;
7917     }
7918 
7919   if (unlikely (readp + 1 > dataend))
7920     goto invalid_data;
7921   unsigned int call_site_encoding = *readp++;
7922   printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
7923   print_encoding_base ("", call_site_encoding);
7924   unsigned int call_site_table_len;
7925   get_uleb128 (call_site_table_len, readp, dataend);
7926 
7927   const unsigned char *const action_table = readp + call_site_table_len;
7928   if (unlikely (action_table > dataend))
7929     goto invalid_data;
7930   unsigned int u = 0;
7931   unsigned int max_action = 0;
7932   while (readp < action_table)
7933     {
7934       if (u == 0)
7935 	puts (gettext ("\n Call site table:"));
7936 
7937       uint64_t call_site_start;
7938       readp = read_encoded (call_site_encoding, readp, dataend,
7939 			    &call_site_start, dbg);
7940       uint64_t call_site_length;
7941       readp = read_encoded (call_site_encoding, readp, dataend,
7942 			    &call_site_length, dbg);
7943       uint64_t landing_pad;
7944       readp = read_encoded (call_site_encoding, readp, dataend,
7945 			    &landing_pad, dbg);
7946       unsigned int action;
7947       get_uleb128 (action, readp, dataend);
7948       max_action = MAX (action, max_action);
7949       printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
7950 		       "        Call site length:  %" PRIu64 "\n"
7951 		       "        Landing pad:       %#" PRIx64 "\n"
7952 		       "        Action:            %u\n"),
7953 	      u++, call_site_start, call_site_length, landing_pad, action);
7954     }
7955   if (readp != action_table)
7956     goto invalid_data;
7957 
7958   unsigned int max_ar_filter = 0;
7959   if (max_action > 0)
7960     {
7961       puts ("\n Action table:");
7962 
7963       size_t maxdata = (size_t) (dataend - action_table);
7964       if (max_action > maxdata || maxdata - max_action < 1)
7965 	{
7966 	invalid_action_table:
7967 	  fputs (gettext ("   <INVALID DATA>\n"), stdout);
7968 	  return;
7969 	}
7970 
7971       const unsigned char *const action_table_end
7972 	= action_table + max_action + 1;
7973 
7974       u = 0;
7975       do
7976 	{
7977 	  int ar_filter;
7978 	  get_sleb128 (ar_filter, readp, action_table_end);
7979 	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7980 	    max_ar_filter = ar_filter;
7981 	  int ar_disp;
7982 	  if (readp >= action_table_end)
7983 	    goto invalid_action_table;
7984 	  get_sleb128 (ar_disp, readp, action_table_end);
7985 
7986 	  printf (" [%4u] ar_filter:  % d\n"
7987 		  "        ar_disp:    % -5d",
7988 		  u, ar_filter, ar_disp);
7989 	  if (abs (ar_disp) & 1)
7990 	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7991 	  else if (ar_disp != 0)
7992 	    puts (" -> ???");
7993 	  else
7994 	    putchar_unlocked ('\n');
7995 	  ++u;
7996 	}
7997       while (readp < action_table_end);
7998     }
7999 
8000   if (max_ar_filter > 0 && ttype_base != NULL)
8001     {
8002       unsigned char dsize;
8003       puts ("\n TType table:");
8004 
8005       // XXX Not *4, size of encoding;
8006       switch (ttype_encoding & 7)
8007 	{
8008 	case DW_EH_PE_udata2:
8009 	case DW_EH_PE_sdata2:
8010 	  dsize = 2;
8011 	  break;
8012 	case DW_EH_PE_udata4:
8013 	case DW_EH_PE_sdata4:
8014 	  dsize = 4;
8015 	  break;
8016 	case DW_EH_PE_udata8:
8017 	case DW_EH_PE_sdata8:
8018 	  dsize = 8;
8019 	  break;
8020 	default:
8021 	  dsize = 0;
8022 	  error (1, 0, gettext ("invalid TType encoding"));
8023 	}
8024 
8025       if (max_ar_filter
8026 	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
8027 	goto invalid_data;
8028 
8029       readp = ttype_base - max_ar_filter * dsize;
8030       do
8031 	{
8032 	  uint64_t ttype;
8033 	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
8034 				dbg);
8035 	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
8036 	}
8037       while (readp < ttype_base);
8038     }
8039 }
8040 
8041 /* Print the content of the '.gdb_index' section.
8042    http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
8043 */
8044 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8045 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8046 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8047 {
8048   printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
8049 		   " contains %" PRId64 " bytes :\n"),
8050 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
8051 	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
8052 
8053   Elf_Data *data = elf_rawdata (scn, NULL);
8054 
8055   if (unlikely (data == NULL))
8056     {
8057       error (0, 0, gettext ("cannot get %s content: %s"),
8058 	     ".gdb_index", elf_errmsg (-1));
8059       return;
8060     }
8061 
8062   // .gdb_index is always in little endian.
8063   Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
8064   dbg = &dummy_dbg;
8065 
8066   const unsigned char *readp = data->d_buf;
8067   const unsigned char *const dataend = readp + data->d_size;
8068 
8069   if (unlikely (readp + 4 > dataend))
8070     {
8071     invalid_data:
8072       error (0, 0, gettext ("invalid data"));
8073       return;
8074     }
8075 
8076   int32_t vers = read_4ubyte_unaligned (dbg, readp);
8077   printf (gettext (" Version:         %" PRId32 "\n"), vers);
8078 
8079   // The only difference between version 4 and version 5 is the
8080   // hash used for generating the table.  Version 6 contains symbols
8081   // for inlined functions, older versions didn't.  Version 7 adds
8082   // symbol kinds.  Version 8 just indicates that it correctly includes
8083   // TUs for symbols.
8084   if (vers < 4 || vers > 8)
8085     {
8086       printf (gettext ("  unknown version, cannot parse section\n"));
8087       return;
8088     }
8089 
8090   readp += 4;
8091   if (unlikely (readp + 4 > dataend))
8092     goto invalid_data;
8093 
8094   uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
8095   printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
8096 
8097   readp += 4;
8098   if (unlikely (readp + 4 > dataend))
8099     goto invalid_data;
8100 
8101   uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
8102   printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
8103 
8104   readp += 4;
8105   if (unlikely (readp + 4 > dataend))
8106     goto invalid_data;
8107 
8108   uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
8109   printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
8110 
8111   readp += 4;
8112   if (unlikely (readp + 4 > dataend))
8113     goto invalid_data;
8114 
8115   uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8116   printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
8117 
8118   readp += 4;
8119   if (unlikely (readp + 4 > dataend))
8120     goto invalid_data;
8121 
8122   uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8123   printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8124 
8125   if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
8126 		< const_off))
8127     goto invalid_data;
8128 
8129   readp = data->d_buf + cu_off;
8130 
8131   const unsigned char *nextp = data->d_buf + tu_off;
8132   if (tu_off >= data->d_size)
8133     goto invalid_data;
8134 
8135   size_t cu_nr = (nextp - readp) / 16;
8136 
8137   printf (gettext ("\n CU list at offset %#" PRIx32
8138 		   " contains %zu entries:\n"),
8139 	  cu_off, cu_nr);
8140 
8141   size_t n = 0;
8142   while (dataend - readp >= 16 && n < cu_nr)
8143     {
8144       uint64_t off = read_8ubyte_unaligned (dbg, readp);
8145       readp += 8;
8146 
8147       uint64_t len = read_8ubyte_unaligned (dbg, readp);
8148       readp += 8;
8149 
8150       printf (" [%4zu] start: %0#8" PRIx64
8151 	      ", length: %5" PRIu64 "\n", n, off, len);
8152       n++;
8153     }
8154 
8155   readp = data->d_buf + tu_off;
8156   nextp = data->d_buf + addr_off;
8157   if (addr_off >= data->d_size)
8158     goto invalid_data;
8159 
8160   size_t tu_nr = (nextp - readp) / 24;
8161 
8162   printf (gettext ("\n TU list at offset %#" PRIx32
8163 		   " contains %zu entries:\n"),
8164 	  tu_off, tu_nr);
8165 
8166   n = 0;
8167   while (dataend - readp >= 24 && n < tu_nr)
8168     {
8169       uint64_t off = read_8ubyte_unaligned (dbg, readp);
8170       readp += 8;
8171 
8172       uint64_t type = read_8ubyte_unaligned (dbg, readp);
8173       readp += 8;
8174 
8175       uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8176       readp += 8;
8177 
8178       printf (" [%4zu] CU offset: %5" PRId64
8179 	      ", type offset: %5" PRId64
8180 	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8181       n++;
8182     }
8183 
8184   readp = data->d_buf + addr_off;
8185   nextp = data->d_buf + sym_off;
8186   if (sym_off >= data->d_size)
8187     goto invalid_data;
8188 
8189   size_t addr_nr = (nextp - readp) / 20;
8190 
8191   printf (gettext ("\n Address list at offset %#" PRIx32
8192 		   " contains %zu entries:\n"),
8193 	  addr_off, addr_nr);
8194 
8195   n = 0;
8196   while (dataend - readp >= 20 && n < addr_nr)
8197     {
8198       uint64_t low = read_8ubyte_unaligned (dbg, readp);
8199       readp += 8;
8200 
8201       uint64_t high = read_8ubyte_unaligned (dbg, readp);
8202       readp += 8;
8203 
8204       uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8205       readp += 4;
8206 
8207       char *l = format_dwarf_addr (dwflmod, 8, low, low);
8208       char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8209       printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8210 	      n, l, h, idx);
8211       free (l);
8212       free (h);
8213       n++;
8214     }
8215 
8216   const unsigned char *const_start = data->d_buf + const_off;
8217   if (const_off >= data->d_size)
8218     goto invalid_data;
8219 
8220   readp = data->d_buf + sym_off;
8221   nextp = const_start;
8222   size_t sym_nr = (nextp - readp) / 8;
8223 
8224   printf (gettext ("\n Symbol table at offset %#" PRIx32
8225 		   " contains %zu slots:\n"),
8226 	  addr_off, sym_nr);
8227 
8228   n = 0;
8229   while (dataend - readp >= 8 && n < sym_nr)
8230     {
8231       uint32_t name = read_4ubyte_unaligned (dbg, readp);
8232       readp += 4;
8233 
8234       uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8235       readp += 4;
8236 
8237       if (name != 0 || vector != 0)
8238 	{
8239 	  const unsigned char *sym = const_start + name;
8240 	  if (unlikely ((size_t) (dataend - const_start) < name
8241 			|| memchr (sym, '\0', dataend - sym) == NULL))
8242 	    goto invalid_data;
8243 
8244 	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8245 
8246 	  const unsigned char *readcus = const_start + vector;
8247 	  if (unlikely ((size_t) (dataend - const_start) < vector))
8248 	    goto invalid_data;
8249 	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8250 	  while (cus--)
8251 	    {
8252 	      uint32_t cu_kind, cu, kind;
8253 	      bool is_static;
8254 	      readcus += 4;
8255 	      if (unlikely (readcus + 4 > dataend))
8256 		goto invalid_data;
8257 	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
8258 	      cu = cu_kind & ((1 << 24) - 1);
8259 	      kind = (cu_kind >> 28) & 7;
8260 	      is_static = cu_kind & (1U << 31);
8261 	      if (cu > cu_nr - 1)
8262 		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8263 	      else
8264 		printf ("%" PRId32, cu);
8265 	      if (kind != 0)
8266 		{
8267 		  printf (" (");
8268 		  switch (kind)
8269 		    {
8270 		    case 1:
8271 		      printf ("type");
8272 		      break;
8273 		    case 2:
8274 		      printf ("var");
8275 		      break;
8276 		    case 3:
8277 		      printf ("func");
8278 		      break;
8279 		    case 4:
8280 		      printf ("other");
8281 		      break;
8282 		    default:
8283 		      printf ("unknown-0x%" PRIx32, kind);
8284 		      break;
8285 		    }
8286 		  printf (":%c)", (is_static ? 'S' : 'G'));
8287 		}
8288 	      if (cus > 0)
8289 		printf (", ");
8290 	    }
8291 	  printf ("\n");
8292 	}
8293       n++;
8294     }
8295 }
8296 
8297 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)8298 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8299 {
8300   /* Before we start the real work get a debug context descriptor.  */
8301   Dwarf_Addr dwbias;
8302   Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8303   Dwarf dummy_dbg =
8304     {
8305       .elf = ebl->elf,
8306       .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8307     };
8308   if (dbg == NULL)
8309     {
8310       if ((print_debug_sections & ~section_exception) != 0)
8311 	error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8312 	       dwfl_errmsg (-1));
8313       dbg = &dummy_dbg;
8314     }
8315 
8316   /* Get the section header string table index.  */
8317   size_t shstrndx;
8318   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8319     error (EXIT_FAILURE, 0,
8320 	   gettext ("cannot get section header string table index"));
8321 
8322   /* Look through all the sections for the debugging sections to print.  */
8323   Elf_Scn *scn = NULL;
8324   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8325     {
8326       GElf_Shdr shdr_mem;
8327       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8328 
8329       if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8330 	{
8331 	  static const struct
8332 	  {
8333 	    const char *name;
8334 	    enum section_e bitmask;
8335 	    void (*fp) (Dwfl_Module *, Ebl *,
8336 			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8337 	  } debug_sections[] =
8338 	    {
8339 #define NEW_SECTION(name) \
8340 	      { ".debug_" #name, section_##name, print_debug_##name##_section }
8341 	      NEW_SECTION (abbrev),
8342 	      NEW_SECTION (aranges),
8343 	      NEW_SECTION (frame),
8344 	      NEW_SECTION (info),
8345 	      NEW_SECTION (types),
8346 	      NEW_SECTION (line),
8347 	      NEW_SECTION (loc),
8348 	      NEW_SECTION (pubnames),
8349 	      NEW_SECTION (str),
8350 	      NEW_SECTION (macinfo),
8351 	      NEW_SECTION (macro),
8352 	      NEW_SECTION (ranges),
8353 	      { ".eh_frame", section_frame | section_exception,
8354 		print_debug_frame_section },
8355 	      { ".eh_frame_hdr", section_frame | section_exception,
8356 		print_debug_frame_hdr_section },
8357 	      { ".gcc_except_table", section_frame | section_exception,
8358 		print_debug_exception_table },
8359 	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
8360 	    };
8361 	  const int ndebug_sections = (sizeof (debug_sections)
8362 				       / sizeof (debug_sections[0]));
8363 	  const char *name = elf_strptr (ebl->elf, shstrndx,
8364 					 shdr->sh_name);
8365 	  if (name == NULL)
8366 	    continue;
8367 
8368 	  int n;
8369 	  for (n = 0; n < ndebug_sections; ++n)
8370 	    if (strcmp (name, debug_sections[n].name) == 0
8371 		|| (name[0] == '.' && name[1] == 'z'
8372 		    && debug_sections[n].name[1] == 'd'
8373 		    && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8374 		)
8375 	      {
8376 		if ((print_debug_sections | implicit_debug_sections)
8377 		    & debug_sections[n].bitmask)
8378 		  debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8379 		break;
8380 	      }
8381 	}
8382     }
8383 
8384   reset_listptr (&known_loclistptr);
8385   reset_listptr (&known_rangelistptr);
8386 }
8387 
8388 
8389 #define ITEM_INDENT		4
8390 #define WRAP_COLUMN		75
8391 
8392 /* Print "NAME: FORMAT", wrapping when output text would make the line
8393    exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
8394    but this function is also used for registers which should be printed
8395    aligned.  Fortunately registers output uses fixed fields width (such
8396    as %11d) for the alignment.
8397 
8398    Line breaks should not depend on the particular values although that
8399    may happen in some cases of the core items.  */
8400 
8401 static unsigned int
8402 __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,...)8403 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8404 		 size_t name_width, const char *name, const char *format, ...)
8405 {
8406   size_t len = strlen (name);
8407   if (name_width < len)
8408     name_width = len;
8409 
8410   char *out;
8411   va_list ap;
8412   va_start (ap, format);
8413   int out_len = vasprintf (&out, format, ap);
8414   va_end (ap);
8415   if (out_len == -1)
8416     error (EXIT_FAILURE, 0, _("memory exhausted"));
8417 
8418   size_t n = name_width + sizeof ": " - 1 + out_len;
8419 
8420   if (colno == 0)
8421     {
8422       printf ("%*s", ITEM_INDENT, "");
8423       colno = ITEM_INDENT + n;
8424     }
8425   else if (colno + 2 + n < wrap)
8426     {
8427       printf ("%c ", sep);
8428       colno += 2 + n;
8429     }
8430   else
8431     {
8432       printf ("\n%*s", ITEM_INDENT, "");
8433       colno = ITEM_INDENT + n;
8434     }
8435 
8436   printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8437 
8438   free (out);
8439 
8440   return colno;
8441 }
8442 
8443 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)8444 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8445 	 void *value, const void *data, size_t size)
8446 {
8447   Elf_Data valuedata =
8448     {
8449       .d_type = type,
8450       .d_buf = value,
8451       .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8452       .d_version = EV_CURRENT,
8453     };
8454   Elf_Data indata =
8455     {
8456       .d_type = type,
8457       .d_buf = (void *) data,
8458       .d_size = valuedata.d_size,
8459       .d_version = EV_CURRENT,
8460     };
8461 
8462   Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8463 		 ? elf32_xlatetom : elf64_xlatetom)
8464     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8465   if (d == NULL)
8466     error (EXIT_FAILURE, 0,
8467 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8468 
8469   return data + indata.d_size;
8470 }
8471 
8472 typedef uint8_t GElf_Byte;
8473 
8474 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)8475 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8476 		  unsigned int colno, size_t *repeated_size)
8477 {
8478   uint_fast16_t count = item->count ?: 1;
8479   /* Ebl_Core_Item count is always a small number.
8480      Make sure the backend didn't put in some large bogus value.  */
8481   assert (count < 128);
8482 
8483 #define TYPES								      \
8484   DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
8485   DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
8486   DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
8487   DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
8488   DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
8489   DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8490 
8491 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
8492   typedef union { TYPES; } value_t;
8493   void *data = alloca (count * sizeof (value_t));
8494 #undef DO_TYPE
8495 
8496 #define DO_TYPE(NAME, Name, hex, dec) \
8497     GElf_##Name *value_##Name __attribute__((unused)) = data
8498   TYPES;
8499 #undef DO_TYPE
8500 
8501   size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8502   size_t convsize = size;
8503   if (repeated_size != NULL)
8504     {
8505       if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8506 	{
8507 	  data = alloca (*repeated_size);
8508 	  count *= *repeated_size / size;
8509 	  convsize = count * size;
8510 	  *repeated_size -= convsize;
8511 	}
8512       else if (item->count != 0 || item->format != '\n')
8513 	*repeated_size -= size;
8514     }
8515 
8516   convert (core, item->type, count, data, desc + item->offset, convsize);
8517 
8518   Elf_Type type = item->type;
8519   if (type == ELF_T_ADDR)
8520     type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8521 
8522   switch (item->format)
8523     {
8524     case 'd':
8525       assert (count == 1);
8526       switch (type)
8527 	{
8528 #define DO_TYPE(NAME, Name, hex, dec)					      \
8529 	  case ELF_T_##NAME:						      \
8530 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
8531 				     0, item->name, dec, value_##Name[0]); \
8532 	    break
8533 	  TYPES;
8534 #undef DO_TYPE
8535 	default:
8536 	  abort ();
8537 	}
8538       break;
8539 
8540     case 'x':
8541       assert (count == 1);
8542       switch (type)
8543 	{
8544 #define DO_TYPE(NAME, Name, hex, dec)					      \
8545 	  case ELF_T_##NAME:						      \
8546 	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
8547 				     0, item->name, hex, value_##Name[0]);      \
8548 	    break
8549 	  TYPES;
8550 #undef DO_TYPE
8551 	default:
8552 	  abort ();
8553 	}
8554       break;
8555 
8556     case 'b':
8557     case 'B':
8558       assert (size % sizeof (unsigned int) == 0);
8559       unsigned int nbits = count * size * 8;
8560       unsigned int pop = 0;
8561       for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8562 	pop += __builtin_popcount (*i);
8563       bool negate = pop > nbits / 2;
8564       const unsigned int bias = item->format == 'b';
8565 
8566       {
8567 	char printed[(negate ? nbits - pop : pop) * 16 + 1];
8568 	char *p = printed;
8569 	*p = '\0';
8570 
8571 	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8572 	  {
8573 	    assert (size == sizeof (unsigned int) * 2);
8574 	    for (unsigned int *i = data;
8575 		 (void *) i < data + count * size; i += 2)
8576 	      {
8577 		unsigned int w = i[1];
8578 		i[1] = i[0];
8579 		i[0] = w;
8580 	      }
8581 	  }
8582 
8583 	unsigned int lastbit = 0;
8584 	unsigned int run = 0;
8585 	for (const unsigned int *i = data;
8586 	     (void *) i < data + count * size; ++i)
8587 	  {
8588 	    unsigned int bit = ((void *) i - data) * 8;
8589 	    unsigned int w = negate ? ~*i : *i;
8590 	    while (w != 0)
8591 	      {
8592 		/* Note that a right shift equal to (or greater than)
8593 		   the number of bits of w is undefined behaviour.  In
8594 		   particular when the least significant bit is bit 32
8595 		   (w = 0x8000000) then w >>= n is undefined.  So
8596 		   explicitly handle that case separately.  */
8597 		unsigned int n = ffs (w);
8598 		if (n < sizeof (w) * 8)
8599 		  w >>= n;
8600 		else
8601 		  w = 0;
8602 		bit += n;
8603 
8604 		if (lastbit != 0 && lastbit + 1 == bit)
8605 		  ++run;
8606 		else
8607 		  {
8608 		    if (lastbit == 0)
8609 		      p += sprintf (p, "%u", bit - bias);
8610 		    else if (run == 0)
8611 		      p += sprintf (p, ",%u", bit - bias);
8612 		    else
8613 		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8614 		    run = 0;
8615 		  }
8616 
8617 		lastbit = bit;
8618 	      }
8619 	  }
8620 	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8621 	  p += sprintf (p, "-%u", lastbit - bias);
8622 
8623 	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8624 				 negate ? "~<%s>" : "<%s>", printed);
8625       }
8626       break;
8627 
8628     case 'T':
8629     case (char) ('T'|0x80):
8630       assert (count == 2);
8631       Dwarf_Word sec;
8632       Dwarf_Word usec;
8633       switch (type)
8634 	{
8635 #define DO_TYPE(NAME, Name, hex, dec)					      \
8636 	  case ELF_T_##NAME:						      \
8637 	    sec = value_##Name[0];					      \
8638 	    usec = value_##Name[1];					      \
8639 	    break
8640 	  TYPES;
8641 #undef DO_TYPE
8642 	default:
8643 	  abort ();
8644 	}
8645       if (unlikely (item->format == (char) ('T'|0x80)))
8646 	{
8647 	  /* This is a hack for an ill-considered 64-bit ABI where
8648 	     tv_usec is actually a 32-bit field with 32 bits of padding
8649 	     rounding out struct timeval.  We've already converted it as
8650 	     a 64-bit field.  For little-endian, this just means the
8651 	     high half is the padding; it's presumably zero, but should
8652 	     be ignored anyway.  For big-endian, it means the 32-bit
8653 	     field went into the high half of USEC.  */
8654 	  GElf_Ehdr ehdr_mem;
8655 	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8656 	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8657 	    usec >>= 32;
8658 	  else
8659 	    usec &= UINT32_MAX;
8660 	}
8661       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8662 			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
8663       break;
8664 
8665     case 'c':
8666       assert (count == 1);
8667       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8668 			       "%c", value_Byte[0]);
8669       break;
8670 
8671     case 's':
8672       colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8673 			       "%.*s", (int) count, value_Byte);
8674       break;
8675 
8676     case '\n':
8677       /* This is a list of strings separated by '\n'.  */
8678       assert (item->count == 0);
8679       assert (repeated_size != NULL);
8680       assert (item->name == NULL);
8681       if (unlikely (item->offset >= *repeated_size))
8682 	break;
8683 
8684       const char *s = desc + item->offset;
8685       size = *repeated_size - item->offset;
8686       *repeated_size = 0;
8687       while (size > 0)
8688 	{
8689 	  const char *eol = memchr (s, '\n', size);
8690 	  int len = size;
8691 	  if (eol != NULL)
8692 	    len = eol - s;
8693 	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8694 	  if (eol == NULL)
8695 	    break;
8696 	  size -= eol + 1 - s;
8697 	  s = eol + 1;
8698 	}
8699 
8700       colno = WRAP_COLUMN;
8701       break;
8702 
8703     case 'h':
8704       break;
8705 
8706     default:
8707       error (0, 0, "XXX not handling format '%c' for %s",
8708 	     item->format, item->name);
8709       break;
8710     }
8711 
8712 #undef TYPES
8713 
8714   return colno;
8715 }
8716 
8717 
8718 /* Sort items by group, and by layout offset within each group.  */
8719 static int
compare_core_items(const void * a,const void * b)8720 compare_core_items (const void *a, const void *b)
8721 {
8722   const Ebl_Core_Item *const *p1 = a;
8723   const Ebl_Core_Item *const *p2 = b;
8724   const Ebl_Core_Item *item1 = *p1;
8725   const Ebl_Core_Item *item2 = *p2;
8726 
8727   return ((item1->group == item2->group ? 0
8728 	   : strcmp (item1->group, item2->group))
8729 	  ?: (int) item1->offset - (int) item2->offset);
8730 }
8731 
8732 /* Sort item groups by layout offset of the first item in the group.  */
8733 static int
compare_core_item_groups(const void * a,const void * b)8734 compare_core_item_groups (const void *a, const void *b)
8735 {
8736   const Ebl_Core_Item *const *const *p1 = a;
8737   const Ebl_Core_Item *const *const *p2 = b;
8738   const Ebl_Core_Item *const *group1 = *p1;
8739   const Ebl_Core_Item *const *group2 = *p2;
8740   const Ebl_Core_Item *item1 = *group1;
8741   const Ebl_Core_Item *item2 = *group2;
8742 
8743   return (int) item1->offset - (int) item2->offset;
8744 }
8745 
8746 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)8747 handle_core_items (Elf *core, const void *desc, size_t descsz,
8748 		   const Ebl_Core_Item *items, size_t nitems)
8749 {
8750   if (nitems == 0)
8751     return 0;
8752   unsigned int colno = 0;
8753 
8754   /* FORMAT '\n' makes sense to be present only as a single item as it
8755      processes all the data of a note.  FORMATs 'b' and 'B' have a special case
8756      if present as a single item but they can be also processed with other
8757      items below.  */
8758   if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8759 		      || items[0].format == 'B'))
8760     {
8761       assert (items[0].offset == 0);
8762       size_t size = descsz;
8763       colno = handle_core_item (core, items, desc, colno, &size);
8764       /* If SIZE is not zero here there is some remaining data.  But we do not
8765 	 know how to process it anyway.  */
8766       return colno;
8767     }
8768   for (size_t i = 0; i < nitems; ++i)
8769     assert (items[i].format != '\n');
8770 
8771   /* Sort to collect the groups together.  */
8772   const Ebl_Core_Item *sorted_items[nitems];
8773   for (size_t i = 0; i < nitems; ++i)
8774     sorted_items[i] = &items[i];
8775   qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8776 
8777   /* Collect the unique groups and sort them.  */
8778   const Ebl_Core_Item **groups[nitems];
8779   groups[0] = &sorted_items[0];
8780   size_t ngroups = 1;
8781   for (size_t i = 1; i < nitems; ++i)
8782     if (sorted_items[i]->group != sorted_items[i - 1]->group
8783 	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8784       groups[ngroups++] = &sorted_items[i];
8785   qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8786 
8787   /* Write out all the groups.  */
8788   const void *last = desc;
8789   do
8790     {
8791       for (size_t i = 0; i < ngroups; ++i)
8792 	{
8793 	  for (const Ebl_Core_Item **item = groups[i];
8794 	       (item < &sorted_items[nitems]
8795 		&& ((*item)->group == groups[i][0]->group
8796 		    || !strcmp ((*item)->group, groups[i][0]->group)));
8797 	       ++item)
8798 	    colno = handle_core_item (core, *item, desc, colno, NULL);
8799 
8800 	  /* Force a line break at the end of the group.  */
8801 	  colno = WRAP_COLUMN;
8802 	}
8803 
8804       if (descsz == 0)
8805 	break;
8806 
8807       /* This set of items consumed a certain amount of the note's data.
8808 	 If there is more data there, we have another unit of the same size.
8809 	 Loop to print that out too.  */
8810       const Ebl_Core_Item *item = &items[nitems - 1];
8811       size_t eltsz = item->offset + gelf_fsize (core, item->type,
8812 						item->count ?: 1, EV_CURRENT);
8813 
8814       int reps = -1;
8815       do
8816 	{
8817 	  ++reps;
8818 	  desc += eltsz;
8819 	  descsz -= eltsz;
8820 	}
8821       while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8822 
8823       if (reps == 1)
8824 	{
8825 	  /* For just one repeat, print it unabridged twice.  */
8826 	  desc -= eltsz;
8827 	  descsz += eltsz;
8828 	}
8829       else if (reps > 1)
8830 	printf (gettext ("\n%*s... <repeats %u more times> ..."),
8831 		ITEM_INDENT, "", reps);
8832 
8833       last = desc;
8834     }
8835   while (descsz > 0);
8836 
8837   return colno;
8838 }
8839 
8840 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)8841 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8842 		      unsigned int colno)
8843 {
8844   desc += regloc->offset;
8845 
8846   abort ();			/* XXX */
8847   return colno;
8848 }
8849 
8850 
8851 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)8852 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8853 		      const Ebl_Register_Location *regloc, const void *desc,
8854 		      unsigned int colno)
8855 {
8856   if (regloc->bits % 8 != 0)
8857     return handle_bit_registers (regloc, desc, colno);
8858 
8859   desc += regloc->offset;
8860 
8861   for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8862     {
8863       char name[REGNAMESZ];
8864       int bits;
8865       int type;
8866       register_info (ebl, reg, regloc, name, &bits, &type);
8867 
8868 #define TYPES								      \
8869       BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
8870       BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
8871       BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
8872       BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
8873 
8874 #define BITS(bits, xtype, sfmt, ufmt)				\
8875       uint##bits##_t b##bits; int##bits##_t b##bits##s
8876       union { TYPES; uint64_t b128[2]; } value;
8877 #undef	BITS
8878 
8879       switch (type)
8880 	{
8881 	case DW_ATE_unsigned:
8882 	case DW_ATE_signed:
8883 	case DW_ATE_address:
8884 	  switch (bits)
8885 	    {
8886 #define BITS(bits, xtype, sfmt, ufmt)					      \
8887 	    case bits:							      \
8888 	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
8889 	      if (type == DW_ATE_signed)				      \
8890 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
8891 					 maxregname, name,		      \
8892 					 sfmt, value.b##bits##s);	      \
8893 	      else							      \
8894 		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
8895 					 maxregname, name,		      \
8896 					 ufmt, value.b##bits);		      \
8897 	      break
8898 
8899 	    TYPES;
8900 
8901 	    case 128:
8902 	      assert (type == DW_ATE_unsigned);
8903 	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8904 	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8905 	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
8906 				       maxregname, name,
8907 				       "0x%.16" PRIx64 "%.16" PRIx64,
8908 				       value.b128[!be], value.b128[be]);
8909 	      break;
8910 
8911 	    default:
8912 	      abort ();
8913 #undef	BITS
8914 	    }
8915 	  break;
8916 
8917 	default:
8918 	  /* Print each byte in hex, the whole thing in native byte order.  */
8919 	  assert (bits % 8 == 0);
8920 	  const uint8_t *bytes = desc;
8921 	  desc += bits / 8;
8922 	  char hex[bits / 4 + 1];
8923 	  hex[bits / 4] = '\0';
8924 	  int incr = 1;
8925 	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8926 	    {
8927 	      bytes += bits / 8 - 1;
8928 	      incr = -1;
8929 	    }
8930 	  size_t idx = 0;
8931 	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8932 	    {
8933 	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8934 	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8935 	    }
8936 	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
8937 				   maxregname, name, "0x%s", hex);
8938 	  break;
8939 	}
8940       desc += regloc->pad;
8941 
8942 #undef TYPES
8943     }
8944 
8945   return colno;
8946 }
8947 
8948 
8949 struct register_info
8950 {
8951   const Ebl_Register_Location *regloc;
8952   const char *set;
8953   char name[REGNAMESZ];
8954   int regno;
8955   int bits;
8956   int type;
8957 };
8958 
8959 static int
register_bitpos(const struct register_info * r)8960 register_bitpos (const struct register_info *r)
8961 {
8962   return (r->regloc->offset * 8
8963 	  + ((r->regno - r->regloc->regno)
8964 	     * (r->regloc->bits + r->regloc->pad * 8)));
8965 }
8966 
8967 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)8968 compare_sets_by_info (const struct register_info *r1,
8969 		      const struct register_info *r2)
8970 {
8971   return ((int) r2->bits - (int) r1->bits
8972 	  ?: register_bitpos (r1) - register_bitpos (r2));
8973 }
8974 
8975 /* Sort registers by set, and by size and layout offset within each set.  */
8976 static int
compare_registers(const void * a,const void * b)8977 compare_registers (const void *a, const void *b)
8978 {
8979   const struct register_info *r1 = a;
8980   const struct register_info *r2 = b;
8981 
8982   /* Unused elements sort last.  */
8983   if (r1->regloc == NULL)
8984     return r2->regloc == NULL ? 0 : 1;
8985   if (r2->regloc == NULL)
8986     return -1;
8987 
8988   return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8989 	  ?: compare_sets_by_info (r1, r2));
8990 }
8991 
8992 /* Sort register sets by layout offset of the first register in the set.  */
8993 static int
compare_register_sets(const void * a,const void * b)8994 compare_register_sets (const void *a, const void *b)
8995 {
8996   const struct register_info *const *p1 = a;
8997   const struct register_info *const *p2 = b;
8998   return compare_sets_by_info (*p1, *p2);
8999 }
9000 
9001 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)9002 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
9003 		       const Ebl_Register_Location *reglocs, size_t nregloc)
9004 {
9005   if (nregloc == 0)
9006     return 0;
9007 
9008   ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
9009   if (maxnreg <= 0)
9010     {
9011       for (size_t i = 0; i < nregloc; ++i)
9012 	if (maxnreg < reglocs[i].regno + reglocs[i].count)
9013 	  maxnreg = reglocs[i].regno + reglocs[i].count;
9014       assert (maxnreg > 0);
9015     }
9016 
9017   struct register_info regs[maxnreg];
9018   memset (regs, 0, sizeof regs);
9019 
9020   /* Sort to collect the sets together.  */
9021   int maxreg = 0;
9022   for (size_t i = 0; i < nregloc; ++i)
9023     for (int reg = reglocs[i].regno;
9024 	 reg < reglocs[i].regno + reglocs[i].count;
9025 	 ++reg)
9026       {
9027 	assert (reg < maxnreg);
9028 	if (reg > maxreg)
9029 	  maxreg = reg;
9030 	struct register_info *info = &regs[reg];
9031 	info->regloc = &reglocs[i];
9032 	info->regno = reg;
9033 	info->set = register_info (ebl, reg, &reglocs[i],
9034 				   info->name, &info->bits, &info->type);
9035       }
9036   qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
9037 
9038   /* Collect the unique sets and sort them.  */
9039   inline bool same_set (const struct register_info *a,
9040 			const struct register_info *b)
9041   {
9042     return (a < &regs[maxnreg] && a->regloc != NULL
9043 	    && b < &regs[maxnreg] && b->regloc != NULL
9044 	    && a->bits == b->bits
9045 	    && (a->set == b->set || !strcmp (a->set, b->set)));
9046   }
9047   struct register_info *sets[maxreg + 1];
9048   sets[0] = &regs[0];
9049   size_t nsets = 1;
9050   for (int i = 1; i <= maxreg; ++i)
9051     if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
9052       sets[nsets++] = &regs[i];
9053   qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
9054 
9055   /* Write out all the sets.  */
9056   unsigned int colno = 0;
9057   for (size_t i = 0; i < nsets; ++i)
9058     {
9059       /* Find the longest name of a register in this set.  */
9060       size_t maxname = 0;
9061       const struct register_info *end;
9062       for (end = sets[i]; same_set (sets[i], end); ++end)
9063 	{
9064 	  size_t len = strlen (end->name);
9065 	  if (len > maxname)
9066 	    maxname = len;
9067 	}
9068 
9069       for (const struct register_info *reg = sets[i];
9070 	   reg < end;
9071 	   reg += reg->regloc->count ?: 1)
9072 	colno = handle_core_register (ebl, core, maxname,
9073 				      reg->regloc, desc, colno);
9074 
9075       /* Force a line break at the end of the group.  */
9076       colno = WRAP_COLUMN;
9077     }
9078 
9079   return colno;
9080 }
9081 
9082 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)9083 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9084 {
9085   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
9086   if (data == NULL)
9087   elf_error:
9088     error (EXIT_FAILURE, 0,
9089 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9090 
9091   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
9092   for (size_t i = 0; i < nauxv; ++i)
9093     {
9094       GElf_auxv_t av_mem;
9095       GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
9096       if (av == NULL)
9097 	goto elf_error;
9098 
9099       const char *name;
9100       const char *fmt;
9101       if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
9102 	{
9103 	  /* Unknown type.  */
9104 	  if (av->a_un.a_val == 0)
9105 	    printf ("    %" PRIu64 "\n", av->a_type);
9106 	  else
9107 	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
9108 		    av->a_type, av->a_un.a_val);
9109 	}
9110       else
9111 	switch (fmt[0])
9112 	  {
9113 	  case '\0':		/* Normally zero.  */
9114 	    if (av->a_un.a_val == 0)
9115 	      {
9116 		printf ("    %s\n", name);
9117 		break;
9118 	      }
9119 	    /* Fall through */
9120 	  case 'x':		/* hex */
9121 	  case 'p':		/* address */
9122 	  case 's':		/* address of string */
9123 	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
9124 	    break;
9125 	  case 'u':
9126 	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
9127 	    break;
9128 	  case 'd':
9129 	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
9130 	    break;
9131 
9132 	  case 'b':
9133 	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
9134 	    GElf_Xword bit = 1;
9135 	    const char *pfx = "<";
9136 	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9137 	      {
9138 		if (av->a_un.a_val & bit)
9139 		  {
9140 		    printf ("%s%s", pfx, p);
9141 		    pfx = " ";
9142 		  }
9143 		bit <<= 1;
9144 	      }
9145 	    printf (">\n");
9146 	    break;
9147 
9148 	  default:
9149 	    abort ();
9150 	  }
9151     }
9152 }
9153 
9154 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)9155 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9156 {
9157   return ptr < end && (size_t) (end - ptr) >= sz;
9158 }
9159 
9160 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)9161 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9162 	      int *retp)
9163 {
9164   if (! buf_has_data (*ptrp, end, 4))
9165     return false;
9166 
9167   *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9168   return true;
9169 }
9170 
9171 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)9172 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9173 		uint64_t *retp)
9174 {
9175   size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9176   if (! buf_has_data (*ptrp, end, sz))
9177     return false;
9178 
9179   union
9180   {
9181     uint64_t u64;
9182     uint32_t u32;
9183   } u;
9184 
9185   *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9186 
9187   if (sz == 4)
9188     *retp = u.u32;
9189   else
9190     *retp = u.u64;
9191   return true;
9192 }
9193 
9194 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)9195 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9196 {
9197   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9198   if (data == NULL)
9199     error (EXIT_FAILURE, 0,
9200 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9201 
9202   unsigned char const *ptr = data->d_buf;
9203   unsigned char const *const end = data->d_buf + data->d_size;
9204 
9205   /* Siginfo head is three ints: signal number, error number, origin
9206      code.  */
9207   int si_signo, si_errno, si_code;
9208   if (! buf_read_int (core, &ptr, end, &si_signo)
9209       || ! buf_read_int (core, &ptr, end, &si_errno)
9210       || ! buf_read_int (core, &ptr, end, &si_code))
9211     {
9212     fail:
9213       printf ("    Not enough data in NT_SIGINFO note.\n");
9214       return;
9215     }
9216 
9217   /* Next is a pointer-aligned union of structures.  On 64-bit
9218      machines, that implies a word of padding.  */
9219   if (gelf_getclass (core) == ELFCLASS64)
9220     ptr += 4;
9221 
9222   printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
9223 	  si_signo, si_errno, si_code);
9224 
9225   if (si_code > 0)
9226     switch (si_signo)
9227       {
9228       case SIGILL:
9229       case SIGFPE:
9230       case SIGSEGV:
9231       case SIGBUS:
9232 	{
9233 	  uint64_t addr;
9234 	  if (! buf_read_ulong (core, &ptr, end, &addr))
9235 	    goto fail;
9236 	  printf ("    fault address: %#" PRIx64 "\n", addr);
9237 	  break;
9238 	}
9239       default:
9240 	;
9241       }
9242   else if (si_code == SI_USER)
9243     {
9244       int pid, uid;
9245       if (! buf_read_int (core, &ptr, end, &pid)
9246 	  || ! buf_read_int (core, &ptr, end, &uid))
9247 	goto fail;
9248       printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
9249     }
9250 }
9251 
9252 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)9253 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9254 {
9255   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9256   if (data == NULL)
9257     error (EXIT_FAILURE, 0,
9258 	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9259 
9260   unsigned char const *ptr = data->d_buf;
9261   unsigned char const *const end = data->d_buf + data->d_size;
9262 
9263   uint64_t count, page_size;
9264   if (! buf_read_ulong (core, &ptr, end, &count)
9265       || ! buf_read_ulong (core, &ptr, end, &page_size))
9266     {
9267     fail:
9268       printf ("    Not enough data in NT_FILE note.\n");
9269       return;
9270     }
9271 
9272   size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9273   uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9274   if (count > maxcount)
9275     goto fail;
9276 
9277   /* Where file names are stored.  */
9278   unsigned char const *const fstart = ptr + 3 * count * addrsize;
9279   char const *fptr = (char *) fstart;
9280 
9281   printf ("    %" PRId64 " files:\n", count);
9282   for (uint64_t i = 0; i < count; ++i)
9283     {
9284       uint64_t mstart, mend, moffset;
9285       if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9286 	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
9287 	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9288 	goto fail;
9289 
9290       const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9291       if (fnext == NULL)
9292 	goto fail;
9293 
9294       int ct = printf ("      %08" PRIx64 "-%08" PRIx64
9295 		       " %08" PRIx64 " %" PRId64,
9296 		       mstart, mend, moffset * page_size, mend - mstart);
9297       printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9298 
9299       fptr = fnext + 1;
9300     }
9301 }
9302 
9303 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)9304 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9305 		  const char *name, const void *desc)
9306 {
9307   GElf_Word regs_offset;
9308   size_t nregloc;
9309   const Ebl_Register_Location *reglocs;
9310   size_t nitems;
9311   const Ebl_Core_Item *items;
9312 
9313   if (! ebl_core_note (ebl, nhdr, name,
9314 		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
9315     return;
9316 
9317   /* Pass 0 for DESCSZ when there are registers in the note,
9318      so that the ITEMS array does not describe the whole thing.
9319      For non-register notes, the actual descsz might be a multiple
9320      of the unit size, not just exactly the unit size.  */
9321   unsigned int colno = handle_core_items (ebl->elf, desc,
9322 					  nregloc == 0 ? nhdr->n_descsz : 0,
9323 					  items, nitems);
9324   if (colno != 0)
9325     putchar_unlocked ('\n');
9326 
9327   colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9328 				 reglocs, nregloc);
9329   if (colno != 0)
9330     putchar_unlocked ('\n');
9331 }
9332 
9333 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)9334 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9335 		   GElf_Off start, Elf_Data *data)
9336 {
9337   fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
9338 
9339   if (data == NULL)
9340     goto bad_note;
9341 
9342   size_t offset = 0;
9343   GElf_Nhdr nhdr;
9344   size_t name_offset;
9345   size_t desc_offset;
9346   while (offset < data->d_size
9347 	 && (offset = gelf_getnote (data, offset,
9348 				    &nhdr, &name_offset, &desc_offset)) > 0)
9349     {
9350       const char *name = data->d_buf + name_offset;
9351       const char *desc = data->d_buf + desc_offset;
9352 
9353       char buf[100];
9354       char buf2[100];
9355       printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
9356 	      (int) nhdr.n_namesz, name, nhdr.n_descsz,
9357 	      ehdr->e_type == ET_CORE
9358 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
9359 					 buf, sizeof (buf))
9360 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9361 					   buf2, sizeof (buf2)));
9362 
9363       /* Filter out invalid entries.  */
9364       if (memchr (name, '\0', nhdr.n_namesz) != NULL
9365 	  /* XXX For now help broken Linux kernels.  */
9366 	  || 1)
9367 	{
9368 	  if (ehdr->e_type == ET_CORE)
9369 	    {
9370 	      if (nhdr.n_type == NT_AUXV
9371 		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
9372 		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
9373 		  && !memcmp (name, "CORE", 4))
9374 		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9375 				  start + desc_offset);
9376 	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9377 		switch (nhdr.n_type)
9378 		  {
9379 		  case NT_SIGINFO:
9380 		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9381 					 start + desc_offset);
9382 		    break;
9383 
9384 		  case NT_FILE:
9385 		    handle_file_note (ebl->elf, nhdr.n_descsz,
9386 				      start + desc_offset);
9387 		    break;
9388 
9389 		  default:
9390 		    handle_core_note (ebl, &nhdr, name, desc);
9391 		  }
9392 	      else
9393 		handle_core_note (ebl, &nhdr, name, desc);
9394 	    }
9395 	  else
9396 	    ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9397 	}
9398     }
9399 
9400   if (offset == data->d_size)
9401     return;
9402 
9403  bad_note:
9404   error (EXIT_FAILURE, 0,
9405 	 gettext ("cannot get content of note section: %s"),
9406 	 elf_errmsg (-1));
9407 }
9408 
9409 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)9410 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9411 {
9412   /* If we have section headers, just look for SHT_NOTE sections.
9413      In a debuginfo file, the program headers are not reliable.  */
9414   if (shnum != 0)
9415     {
9416       /* Get the section header string table index.  */
9417       size_t shstrndx;
9418       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9419 	error (EXIT_FAILURE, 0,
9420 	       gettext ("cannot get section header string table index"));
9421 
9422       Elf_Scn *scn = NULL;
9423       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9424 	{
9425 	  GElf_Shdr shdr_mem;
9426 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9427 
9428 	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9429 	    /* Not what we are looking for.  */
9430 	    continue;
9431 
9432 	  printf (gettext ("\
9433 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9434 		  elf_ndxscn (scn),
9435 		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9436 		  shdr->sh_size, shdr->sh_offset);
9437 
9438 	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
9439 			     elf_getdata (scn, NULL));
9440 	}
9441       return;
9442     }
9443 
9444   /* We have to look through the program header to find the note
9445      sections.  There can be more than one.  */
9446   for (size_t cnt = 0; cnt < phnum; ++cnt)
9447     {
9448       GElf_Phdr mem;
9449       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9450 
9451       if (phdr == NULL || phdr->p_type != PT_NOTE)
9452 	/* Not what we are looking for.  */
9453 	continue;
9454 
9455       printf (gettext ("\
9456 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9457 	      phdr->p_filesz, phdr->p_offset);
9458 
9459       handle_notes_data (ebl, ehdr, phdr->p_offset,
9460 			 elf_getdata_rawchunk (ebl->elf,
9461 					       phdr->p_offset, phdr->p_filesz,
9462 					       ELF_T_NHDR));
9463     }
9464 }
9465 
9466 
9467 static void
hex_dump(const uint8_t * data,size_t len)9468 hex_dump (const uint8_t *data, size_t len)
9469 {
9470   size_t pos = 0;
9471   while (pos < len)
9472     {
9473       printf ("  0x%08zx ", pos);
9474 
9475       const size_t chunk = MIN (len - pos, 16);
9476 
9477       for (size_t i = 0; i < chunk; ++i)
9478 	if (i % 4 == 3)
9479 	  printf ("%02x ", data[pos + i]);
9480 	else
9481 	  printf ("%02x", data[pos + i]);
9482 
9483       if (chunk < 16)
9484 	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9485 
9486       for (size_t i = 0; i < chunk; ++i)
9487 	{
9488 	  unsigned char b = data[pos + i];
9489 	  printf ("%c", isprint (b) ? b : '.');
9490 	}
9491 
9492       putchar ('\n');
9493       pos += chunk;
9494     }
9495 }
9496 
9497 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)9498 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9499 {
9500   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9501     printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
9502 	    elf_ndxscn (scn), name);
9503   else
9504     {
9505       if (print_decompress)
9506 	{
9507 	  /* We try to decompress the section, but keep the old shdr around
9508 	     so we can show both the original shdr size and the uncompressed
9509 	     data size.   */
9510 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9511 	    elf_compress (scn, 0, 0);
9512 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9513 	    elf_compress_gnu (scn, 0, 0);
9514 	}
9515 
9516       Elf_Data *data = elf_rawdata (scn, NULL);
9517       if (data == NULL)
9518 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9519 	       elf_ndxscn (scn), name, elf_errmsg (-1));
9520       else
9521 	{
9522 	  if (data->d_size == shdr->sh_size)
9523 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9524 			     " bytes at offset %#0" PRIx64 ":\n"),
9525 		    elf_ndxscn (scn), name,
9526 		    shdr->sh_size, shdr->sh_offset);
9527 	  else
9528 	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9529 			     " bytes (%zd uncompressed) at offset %#0"
9530 			     PRIx64 ":\n"),
9531 		    elf_ndxscn (scn), name,
9532 		    shdr->sh_size, data->d_size, shdr->sh_offset);
9533 	  hex_dump (data->d_buf, data->d_size);
9534 	}
9535     }
9536 }
9537 
9538 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)9539 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9540 {
9541   if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9542     printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
9543 	    elf_ndxscn (scn), name);
9544   else
9545     {
9546       if (print_decompress)
9547 	{
9548 	  /* We try to decompress the section, but keep the old shdr around
9549 	     so we can show both the original shdr size and the uncompressed
9550 	     data size.  */
9551 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9552 	    elf_compress (scn, 0, 0);
9553 	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9554 	    elf_compress_gnu (scn, 0, 0);
9555 	}
9556 
9557       Elf_Data *data = elf_rawdata (scn, NULL);
9558       if (data == NULL)
9559 	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9560 	       elf_ndxscn (scn), name, elf_errmsg (-1));
9561       else
9562 	{
9563 	  if (data->d_size == shdr->sh_size)
9564 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9565 			     " bytes at offset %#0" PRIx64 ":\n"),
9566 		    elf_ndxscn (scn), name,
9567 		    shdr->sh_size, shdr->sh_offset);
9568 	  else
9569 	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9570 			     " bytes (%zd uncompressed) at offset %#0"
9571 			     PRIx64 ":\n"),
9572 		    elf_ndxscn (scn), name,
9573 		    shdr->sh_size, data->d_size, shdr->sh_offset);
9574 
9575 	  const char *start = data->d_buf;
9576 	  const char *const limit = start + data->d_size;
9577 	  do
9578 	    {
9579 	      const char *end = memchr (start, '\0', limit - start);
9580 	      const size_t pos = start - (const char *) data->d_buf;
9581 	      if (unlikely (end == NULL))
9582 		{
9583 		  printf ("  [%6zx]- %.*s\n",
9584 			  pos, (int) (limit - start), start);
9585 		  break;
9586 		}
9587 	      printf ("  [%6zx]  %s\n", pos, start);
9588 	      start = end + 1;
9589 	    } while (start < limit);
9590 	}
9591     }
9592 }
9593 
9594 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))9595 for_each_section_argument (Elf *elf, const struct section_argument *list,
9596 			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9597 					 const char *name))
9598 {
9599   /* Get the section header string table index.  */
9600   size_t shstrndx;
9601   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9602     error (EXIT_FAILURE, 0,
9603 	   gettext ("cannot get section header string table index"));
9604 
9605   for (const struct section_argument *a = list; a != NULL; a = a->next)
9606     {
9607       Elf_Scn *scn;
9608       GElf_Shdr shdr_mem;
9609       const char *name = NULL;
9610 
9611       char *endp = NULL;
9612       unsigned long int shndx = strtoul (a->arg, &endp, 0);
9613       if (endp != a->arg && *endp == '\0')
9614 	{
9615 	  scn = elf_getscn (elf, shndx);
9616 	  if (scn == NULL)
9617 	    {
9618 	      error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9619 	      continue;
9620 	    }
9621 
9622 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
9623 	    error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9624 		   elf_errmsg (-1));
9625 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9626 	}
9627       else
9628 	{
9629 	  /* Need to look up the section by name.  */
9630 	  scn = NULL;
9631 	  bool found = false;
9632 	  while ((scn = elf_nextscn (elf, scn)) != NULL)
9633 	    {
9634 	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
9635 		continue;
9636 	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9637 	      if (name == NULL)
9638 		continue;
9639 	      if (!strcmp (name, a->arg))
9640 		{
9641 		  found = true;
9642 		  (*dump) (scn, &shdr_mem, name);
9643 		}
9644 	    }
9645 
9646 	  if (unlikely (!found) && !a->implicit)
9647 	    error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9648 	}
9649     }
9650 }
9651 
9652 static void
dump_data(Ebl * ebl)9653 dump_data (Ebl *ebl)
9654 {
9655   for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9656 }
9657 
9658 static void
dump_strings(Ebl * ebl)9659 dump_strings (Ebl *ebl)
9660 {
9661   for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9662 }
9663 
9664 static void
print_strings(Ebl * ebl)9665 print_strings (Ebl *ebl)
9666 {
9667   /* Get the section header string table index.  */
9668   size_t shstrndx;
9669   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9670     error (EXIT_FAILURE, 0,
9671 	   gettext ("cannot get section header string table index"));
9672 
9673   Elf_Scn *scn;
9674   GElf_Shdr shdr_mem;
9675   const char *name;
9676   scn = NULL;
9677   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9678     {
9679       if (gelf_getshdr (scn, &shdr_mem) == NULL)
9680 	continue;
9681 
9682       if (shdr_mem.sh_type != SHT_PROGBITS
9683 	  || !(shdr_mem.sh_flags & SHF_STRINGS))
9684 	continue;
9685 
9686       name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9687       if (name == NULL)
9688 	continue;
9689 
9690       print_string_section (scn, &shdr_mem, name);
9691     }
9692 }
9693 
9694 static void
dump_archive_index(Elf * elf,const char * fname)9695 dump_archive_index (Elf *elf, const char *fname)
9696 {
9697   size_t narsym;
9698   const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9699   if (arsym == NULL)
9700     {
9701       int result = elf_errno ();
9702       if (unlikely (result != ELF_E_NO_INDEX))
9703 	error (EXIT_FAILURE, 0,
9704 	       gettext ("cannot get symbol index of archive '%s': %s"),
9705 	       fname, elf_errmsg (result));
9706       else
9707 	printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9708       return;
9709     }
9710 
9711   printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
9712 	  fname, narsym);
9713 
9714   size_t as_off = 0;
9715   for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9716     {
9717       if (s->as_off != as_off)
9718 	{
9719 	  as_off = s->as_off;
9720 
9721 	  Elf *subelf = NULL;
9722 	  if (unlikely (elf_rand (elf, as_off) == 0)
9723 	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9724 			   == NULL))
9725 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9726 	    while (1)
9727 #endif
9728 	      error (EXIT_FAILURE, 0,
9729 		     gettext ("cannot extract member at offset %zu in '%s': %s"),
9730 		     as_off, fname, elf_errmsg (-1));
9731 
9732 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
9733 
9734 	  printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9735 
9736 	  elf_end (subelf);
9737 	}
9738 
9739       printf ("\t%s\n", s->as_name);
9740     }
9741 }
9742 
9743 #include "debugpred.h"
9744