1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2018 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <argp.h>
23 #include <assert.h>
24 #include <ctype.h>
25 #include <dwarf.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <gelf.h>
29 #include <inttypes.h>
30 #include <langinfo.h>
31 #include <libdw.h>
32 #include <libdwfl.h>
33 #include <libintl.h>
34 #include <locale.h>
35 #include <stdarg.h>
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <stdio_ext.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <time.h>
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46
47 #include <libeu.h>
48 #include <system.h>
49 #include <printversion.h>
50 #include "../libelf/libelfP.h"
51 #include "../libelf/common.h"
52 #include "../libebl/libeblP.h"
53 #include "../libdwelf/libdwelf.h"
54 #include "../libdw/libdwP.h"
55 #include "../libdwfl/libdwflP.h"
56 #include "../libdw/memory-access.h"
57
58 #include "../libdw/known-dwarf.h"
59
60 #ifdef __linux__
61 #define CORE_SIGILL SIGILL
62 #define CORE_SIGBUS SIGBUS
63 #define CORE_SIGFPE SIGFPE
64 #define CORE_SIGSEGV SIGSEGV
65 #define CORE_SI_USER SI_USER
66 #else
67 /* We want the linux version of those as that is what shows up in the core files. */
68 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
69 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
70 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
72 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */
73 #endif
74
75 /* Name and version of program. */
76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
77
78 /* Bug report address. */
79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
80
81 /* argp key value for --elf-section, non-ascii. */
82 #define ELF_INPUT_SECTION 256
83
84 /* argp key value for --dwarf-skeleton, non-ascii. */
85 #define DWARF_SKELETON 257
86
87 /* argp key value for --dyn-syms, non-ascii. */
88 #define PRINT_DYNSYM_TABLE 258
89
90 /* Terrible hack for hooking unrelated skeleton/split compile units,
91 see __libdw_link_skel_split in print_debug. */
92 static bool do_not_close_dwfl = false;
93
94 /* Definitions of arguments for argp functions. */
95 static const struct argp_option options[] =
96 {
97 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
98 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
99 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
100 "input data"), 0 },
101 { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
102 N_("Used with -w to find the skeleton Compile Units in FILE associated "
103 "with the Split Compile units in a .dwo input file"), 0 },
104 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
105 { "all", 'a', NULL, 0,
106 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
107 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
108 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
109 { "histogram", 'I', NULL, 0,
110 N_("Display histogram of bucket list lengths"), 0 },
111 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
112 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
113 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
114 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
115 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
116 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
117 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
118 N_("Display the symbol table sections"), 0 },
119 { "dyn-syms", PRINT_DYNSYM_TABLE, NULL, 0,
120 N_("Display (only) the dynamic symbol table"), 0 },
121 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
122 { "notes", 'n', "SECTION", OPTION_ARG_OPTIONAL, N_("Display the ELF notes"), 0 },
123 { "arch-specific", 'A', NULL, 0,
124 N_("Display architecture specific information, if any"), 0 },
125 { "exception", 'e', NULL, 0,
126 N_("Display sections for exception handling"), 0 },
127
128 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
129 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
130 N_("Display DWARF section content. SECTION can be one of abbrev, addr, "
131 "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
132 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
133 { "hex-dump", 'x', "SECTION", 0,
134 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
135 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
136 N_("Print string contents of sections"), 0 },
137 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
138 { "archive-index", 'c', NULL, 0,
139 N_("Display the symbol index of an archive"), 0 },
140
141 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
142 { "numeric-addresses", 'N', NULL, 0,
143 N_("Do not find symbol names for addresses in DWARF data"), 0 },
144 { "unresolved-address-offsets", 'U', NULL, 0,
145 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
146 { "wide", 'W', NULL, 0,
147 N_("Ignored for compatibility (lines always wide)"), 0 },
148 { "decompress", 'z', NULL, 0,
149 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
150 { NULL, 0, NULL, 0, NULL, 0 }
151 };
152
153 /* Short description of program. */
154 static const char doc[] = N_("\
155 Print information from ELF file in human-readable form.");
156
157 /* Strings for arguments in help texts. */
158 static const char args_doc[] = N_("FILE...");
159
160 /* Prototype for option handler. */
161 static error_t parse_opt (int key, char *arg, struct argp_state *state);
162
163 /* Data structure to communicate with argp functions. */
164 static struct argp argp =
165 {
166 options, parse_opt, args_doc, doc, NULL, NULL, NULL
167 };
168
169 /* If non-null, the section from which we should read to (compressed) ELF. */
170 static const char *elf_input_section = NULL;
171
172 /* If non-null, the file that contains the skeleton CUs. */
173 static const char *dwarf_skeleton = NULL;
174
175 /* Flags set by the option controlling the output. */
176
177 /* True if dynamic segment should be printed. */
178 static bool print_dynamic_table;
179
180 /* True if the file header should be printed. */
181 static bool print_file_header;
182
183 /* True if the program headers should be printed. */
184 static bool print_program_header;
185
186 /* True if relocations should be printed. */
187 static bool print_relocations;
188
189 /* True if the section headers should be printed. */
190 static bool print_section_header;
191
192 /* True if the symbol table should be printed. */
193 static bool print_symbol_table;
194
195 /* True if (only) the dynsym table should be printed. */
196 static bool print_dynsym_table;
197
198 /* A specific section name, or NULL to print all symbol tables. */
199 static char *symbol_table_section;
200
201 /* A specific section name, or NULL to print all ELF notes. */
202 static char *notes_section;
203
204 /* True if the version information should be printed. */
205 static bool print_version_info;
206
207 /* True if section groups should be printed. */
208 static bool print_section_groups;
209
210 /* True if bucket list length histogram should be printed. */
211 static bool print_histogram;
212
213 /* True if the architecture specific data should be printed. */
214 static bool print_arch;
215
216 /* True if note section content should be printed. */
217 static bool print_notes;
218
219 /* True if SHF_STRINGS section content should be printed. */
220 static bool print_string_sections;
221
222 /* True if archive index should be printed. */
223 static bool print_archive_index;
224
225 /* True if any of the control options except print_archive_index is set. */
226 static bool any_control_option;
227
228 /* True if we should print addresses from DWARF in symbolic form. */
229 static bool print_address_names = true;
230
231 /* True if we should print raw values instead of relativized addresses. */
232 static bool print_unresolved_addresses = false;
233
234 /* True if we should print the .debug_aranges section using libdw. */
235 static bool decodedaranges = false;
236
237 /* True if we should print the .debug_aranges section using libdw. */
238 static bool decodedline = false;
239
240 /* True if we want to show more information about compressed sections. */
241 static bool print_decompress = false;
242
243 /* True if we want to show split compile units for debug_info skeletons. */
244 static bool show_split_units = false;
245
246 /* Select printing of debugging sections. */
247 static enum section_e
248 {
249 section_abbrev = 1, /* .debug_abbrev */
250 section_aranges = 2, /* .debug_aranges */
251 section_frame = 4, /* .debug_frame or .eh_frame & al. */
252 section_info = 8, /* .debug_info, (implies .debug_types) */
253 section_line = 16, /* .debug_line */
254 section_loc = 32, /* .debug_loc */
255 section_pubnames = 64, /* .debug_pubnames */
256 section_str = 128, /* .debug_str */
257 section_macinfo = 256, /* .debug_macinfo */
258 section_ranges = 512, /* .debug_ranges */
259 section_exception = 1024, /* .eh_frame & al. */
260 section_gdb_index = 2048, /* .gdb_index */
261 section_macro = 4096, /* .debug_macro */
262 section_addr = 8192, /* .debug_addr */
263 section_types = 16384, /* .debug_types (implied by .debug_info) */
264 section_all = (section_abbrev | section_aranges | section_frame
265 | section_info | section_line | section_loc
266 | section_pubnames | section_str | section_macinfo
267 | section_ranges | section_exception | section_gdb_index
268 | section_macro | section_addr | section_types)
269 } print_debug_sections, implicit_debug_sections;
270
271 /* Select hex dumping of sections. */
272 static struct section_argument *dump_data_sections;
273 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
274
275 /* Select string dumping of sections. */
276 static struct section_argument *string_sections;
277 static struct section_argument **string_sections_tail = &string_sections;
278
279 struct section_argument
280 {
281 struct section_argument *next;
282 const char *arg;
283 bool implicit;
284 };
285
286 /* Numbers of sections and program headers in the file. */
287 static size_t shnum;
288 static size_t phnum;
289
290
291 /* Declarations of local functions. */
292 static void process_file (int fd, const char *fname, bool only_one);
293 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
294 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
295 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
296 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
297 static void print_scngrp (Ebl *ebl);
298 static void print_dynamic (Ebl *ebl);
299 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
300 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
301 GElf_Shdr *shdr);
302 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
303 GElf_Shdr *shdr);
304 static void print_symtab (Ebl *ebl, int type);
305 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
306 static void print_verinfo (Ebl *ebl);
307 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
308 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
309 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
310 GElf_Shdr *shdr);
311 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
312 static void handle_hash (Ebl *ebl);
313 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
314 static void print_liblist (Ebl *ebl);
315 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
316 static void dump_data (Ebl *ebl);
317 static void dump_strings (Ebl *ebl);
318 static void print_strings (Ebl *ebl);
319 static void dump_archive_index (Elf *, const char *);
320
321
322 /* Looked up once with gettext in main. */
323 static char *yes_str;
324 static char *no_str;
325
326 static void
cleanup_list(struct section_argument * list)327 cleanup_list (struct section_argument *list)
328 {
329 while (list != NULL)
330 {
331 struct section_argument *a = list;
332 list = a->next;
333 free (a);
334 }
335 }
336
337 int
main(int argc,char * argv[])338 main (int argc, char *argv[])
339 {
340 /* We use no threads here which can interfere with handling a stream. */
341 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
342
343 /* Set locale. */
344 setlocale (LC_ALL, "");
345
346 /* Initialize the message catalog. */
347 textdomain (PACKAGE_TARNAME);
348
349 /* Look up once. */
350 yes_str = gettext ("yes");
351 no_str = gettext ("no");
352
353 /* Parse and process arguments. */
354 int remaining;
355 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
356
357 /* Before we start tell the ELF library which version we are using. */
358 elf_version (EV_CURRENT);
359
360 /* Now process all the files given at the command line. */
361 bool only_one = remaining + 1 == argc;
362 do
363 {
364 /* Open the file. */
365 int fd = open (argv[remaining], O_RDONLY);
366 if (fd == -1)
367 {
368 error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
369 continue;
370 }
371
372 process_file (fd, argv[remaining], only_one);
373
374 close (fd);
375 }
376 while (++remaining < argc);
377
378 cleanup_list (dump_data_sections);
379 cleanup_list (string_sections);
380
381 return error_message_count != 0;
382 }
383
384
385 /* Handle program arguments. */
386 static error_t
parse_opt(int key,char * arg,struct argp_state * state)387 parse_opt (int key, char *arg,
388 struct argp_state *state __attribute__ ((unused)))
389 {
390 void add_dump_section (const char *name, bool implicit)
391 {
392 struct section_argument *a = xmalloc (sizeof *a);
393 a->arg = name;
394 a->next = NULL;
395 a->implicit = implicit;
396 struct section_argument ***tailp
397 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
398 **tailp = a;
399 *tailp = &a->next;
400 }
401
402 switch (key)
403 {
404 case 'a':
405 print_file_header = true;
406 print_program_header = true;
407 print_relocations = true;
408 print_section_header = true;
409 print_symbol_table = true;
410 print_version_info = true;
411 print_dynamic_table = true;
412 print_section_groups = true;
413 print_histogram = true;
414 print_arch = true;
415 print_notes = true;
416 implicit_debug_sections |= section_exception;
417 add_dump_section (".strtab", true);
418 add_dump_section (".dynstr", true);
419 add_dump_section (".comment", true);
420 any_control_option = true;
421 break;
422 case 'A':
423 print_arch = true;
424 any_control_option = true;
425 break;
426 case 'd':
427 print_dynamic_table = true;
428 any_control_option = true;
429 break;
430 case 'e':
431 print_debug_sections |= section_exception;
432 any_control_option = true;
433 break;
434 case 'g':
435 print_section_groups = true;
436 any_control_option = true;
437 break;
438 case 'h':
439 print_file_header = true;
440 any_control_option = true;
441 break;
442 case 'I':
443 print_histogram = true;
444 any_control_option = true;
445 break;
446 case 'l':
447 print_program_header = true;
448 any_control_option = true;
449 break;
450 case 'n':
451 print_notes = true;
452 any_control_option = true;
453 notes_section = arg;
454 break;
455 case 'r':
456 print_relocations = true;
457 any_control_option = true;
458 break;
459 case 'S':
460 print_section_header = true;
461 any_control_option = true;
462 break;
463 case 's':
464 print_symbol_table = true;
465 any_control_option = true;
466 symbol_table_section = arg;
467 break;
468 case PRINT_DYNSYM_TABLE:
469 print_dynsym_table = true;
470 any_control_option = true;
471 break;
472 case 'V':
473 print_version_info = true;
474 any_control_option = true;
475 break;
476 case 'c':
477 print_archive_index = true;
478 break;
479 case 'w':
480 if (arg == NULL)
481 {
482 print_debug_sections = section_all;
483 implicit_debug_sections = section_info;
484 show_split_units = true;
485 }
486 else if (strcmp (arg, "abbrev") == 0)
487 print_debug_sections |= section_abbrev;
488 else if (strcmp (arg, "addr") == 0)
489 {
490 print_debug_sections |= section_addr;
491 implicit_debug_sections |= section_info;
492 }
493 else if (strcmp (arg, "aranges") == 0)
494 print_debug_sections |= section_aranges;
495 else if (strcmp (arg, "decodedaranges") == 0)
496 {
497 print_debug_sections |= section_aranges;
498 decodedaranges = true;
499 }
500 else if (strcmp (arg, "ranges") == 0)
501 {
502 print_debug_sections |= section_ranges;
503 implicit_debug_sections |= section_info;
504 }
505 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
506 print_debug_sections |= section_frame;
507 else if (strcmp (arg, "info") == 0)
508 {
509 print_debug_sections |= section_info;
510 print_debug_sections |= section_types;
511 }
512 else if (strcmp (arg, "info+") == 0)
513 {
514 print_debug_sections |= section_info;
515 print_debug_sections |= section_types;
516 show_split_units = true;
517 }
518 else if (strcmp (arg, "loc") == 0)
519 {
520 print_debug_sections |= section_loc;
521 implicit_debug_sections |= section_info;
522 }
523 else if (strcmp (arg, "line") == 0)
524 print_debug_sections |= section_line;
525 else if (strcmp (arg, "decodedline") == 0)
526 {
527 print_debug_sections |= section_line;
528 decodedline = true;
529 }
530 else if (strcmp (arg, "pubnames") == 0)
531 print_debug_sections |= section_pubnames;
532 else if (strcmp (arg, "str") == 0)
533 {
534 print_debug_sections |= section_str;
535 /* For mapping string offset tables to CUs. */
536 implicit_debug_sections |= section_info;
537 }
538 else if (strcmp (arg, "macinfo") == 0)
539 print_debug_sections |= section_macinfo;
540 else if (strcmp (arg, "macro") == 0)
541 print_debug_sections |= section_macro;
542 else if (strcmp (arg, "exception") == 0)
543 print_debug_sections |= section_exception;
544 else if (strcmp (arg, "gdb_index") == 0)
545 print_debug_sections |= section_gdb_index;
546 else
547 {
548 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
549 arg);
550 argp_help (&argp, stderr, ARGP_HELP_SEE,
551 program_invocation_short_name);
552 exit (1);
553 }
554 any_control_option = true;
555 break;
556 case 'p':
557 any_control_option = true;
558 if (arg == NULL)
559 {
560 print_string_sections = true;
561 break;
562 }
563 FALLTHROUGH;
564 case 'x':
565 add_dump_section (arg, false);
566 any_control_option = true;
567 break;
568 case 'N':
569 print_address_names = false;
570 break;
571 case 'U':
572 print_unresolved_addresses = true;
573 break;
574 case ARGP_KEY_NO_ARGS:
575 fputs (gettext ("Missing file name.\n"), stderr);
576 goto do_argp_help;
577 case ARGP_KEY_FINI:
578 if (! any_control_option && ! print_archive_index)
579 {
580 fputs (gettext ("No operation specified.\n"), stderr);
581 do_argp_help:
582 argp_help (&argp, stderr, ARGP_HELP_SEE,
583 program_invocation_short_name);
584 exit (EXIT_FAILURE);
585 }
586 break;
587 case 'W': /* Ignored. */
588 break;
589 case 'z':
590 print_decompress = true;
591 break;
592 case ELF_INPUT_SECTION:
593 if (arg == NULL)
594 elf_input_section = ".gnu_debugdata";
595 else
596 elf_input_section = arg;
597 break;
598 case DWARF_SKELETON:
599 dwarf_skeleton = arg;
600 break;
601 default:
602 return ARGP_ERR_UNKNOWN;
603 }
604 return 0;
605 }
606
607
608 /* Create a file descriptor to read the data from the
609 elf_input_section given a file descriptor to an ELF file. */
610 static int
open_input_section(int fd)611 open_input_section (int fd)
612 {
613 size_t shnums;
614 size_t cnt;
615 size_t shstrndx;
616 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
617 if (elf == NULL)
618 {
619 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
620 elf_errmsg (-1));
621 return -1;
622 }
623
624 if (elf_getshdrnum (elf, &shnums) < 0)
625 {
626 error (0, 0, gettext ("cannot determine number of sections: %s"),
627 elf_errmsg (-1));
628 open_error:
629 elf_end (elf);
630 return -1;
631 }
632
633 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
634 {
635 error (0, 0, gettext ("cannot get section header string table index"));
636 goto open_error;
637 }
638
639 for (cnt = 0; cnt < shnums; ++cnt)
640 {
641 Elf_Scn *scn = elf_getscn (elf, cnt);
642 if (scn == NULL)
643 {
644 error (0, 0, gettext ("cannot get section: %s"),
645 elf_errmsg (-1));
646 goto open_error;
647 }
648
649 GElf_Shdr shdr_mem;
650 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
651 if (unlikely (shdr == NULL))
652 {
653 error (0, 0, gettext ("cannot get section header: %s"),
654 elf_errmsg (-1));
655 goto open_error;
656 }
657
658 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
659 if (sname == NULL)
660 {
661 error (0, 0, gettext ("cannot get section name"));
662 goto open_error;
663 }
664
665 if (strcmp (sname, elf_input_section) == 0)
666 {
667 Elf_Data *data = elf_rawdata (scn, NULL);
668 if (data == NULL)
669 {
670 error (0, 0, gettext ("cannot get %s content: %s"),
671 sname, elf_errmsg (-1));
672 goto open_error;
673 }
674
675 /* Create (and immediately unlink) a temporary file to store
676 section data in to create a file descriptor for it. */
677 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
678 static const char suffix[] = "/readelfXXXXXX";
679 int tmplen = strlen (tmpdir) + sizeof (suffix);
680 char *tempname = alloca (tmplen);
681 sprintf (tempname, "%s%s", tmpdir, suffix);
682
683 int sfd = mkstemp (tempname);
684 if (sfd == -1)
685 {
686 error (0, 0, gettext ("cannot create temp file '%s'"),
687 tempname);
688 goto open_error;
689 }
690 unlink (tempname);
691
692 ssize_t size = data->d_size;
693 if (write_retry (sfd, data->d_buf, size) != size)
694 {
695 error (0, 0, gettext ("cannot write section data"));
696 goto open_error;
697 }
698
699 if (elf_end (elf) != 0)
700 {
701 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
702 elf_errmsg (-1));
703 return -1;
704 }
705
706 if (lseek (sfd, 0, SEEK_SET) == -1)
707 {
708 error (0, 0, gettext ("error while rewinding file descriptor"));
709 return -1;
710 }
711
712 return sfd;
713 }
714 }
715
716 /* Named section not found. */
717 if (elf_end (elf) != 0)
718 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
719 elf_errmsg (-1));
720 return -1;
721 }
722
723 /* Check if the file is an archive, and if so dump its index. */
724 static void
check_archive_index(int fd,const char * fname,bool only_one)725 check_archive_index (int fd, const char *fname, bool only_one)
726 {
727 /* Create an `Elf' descriptor. */
728 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
729 if (elf == NULL)
730 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
731 elf_errmsg (-1));
732 else
733 {
734 if (elf_kind (elf) == ELF_K_AR)
735 {
736 if (!only_one)
737 printf ("\n%s:\n\n", fname);
738 dump_archive_index (elf, fname);
739 }
740 else
741 error (0, 0,
742 gettext ("'%s' is not an archive, cannot print archive index"),
743 fname);
744
745 /* Now we can close the descriptor. */
746 if (elf_end (elf) != 0)
747 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
748 elf_errmsg (-1));
749 }
750 }
751
752 /* Trivial callback used for checking if we opened an archive. */
753 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)754 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
755 void **userdata __attribute__ ((unused)),
756 const char *name __attribute__ ((unused)),
757 Dwarf_Addr base __attribute__ ((unused)),
758 void *arg)
759 {
760 if (*(bool *) arg)
761 return DWARF_CB_ABORT;
762 *(bool *) arg = true;
763 return DWARF_CB_OK;
764 }
765
766 struct process_dwflmod_args
767 {
768 int fd;
769 bool only_one;
770 };
771
772 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)773 process_dwflmod (Dwfl_Module *dwflmod,
774 void **userdata __attribute__ ((unused)),
775 const char *name __attribute__ ((unused)),
776 Dwarf_Addr base __attribute__ ((unused)),
777 void *arg)
778 {
779 const struct process_dwflmod_args *a = arg;
780
781 /* Print the file name. */
782 if (!a->only_one)
783 {
784 const char *fname;
785 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
786
787 printf ("\n%s:\n\n", fname);
788 }
789
790 process_elf_file (dwflmod, a->fd);
791
792 return DWARF_CB_OK;
793 }
794
795 /* Stub libdwfl callback, only the ELF handle already open is ever used.
796 Only used for finding the alternate debug file if the Dwarf comes from
797 the main file. We are not interested in separate debuginfo. */
798 static int
find_no_debuginfo(Dwfl_Module * mod,void ** userdata,const char * modname,Dwarf_Addr base,const char * file_name,const char * debuglink_file,GElf_Word debuglink_crc,char ** debuginfo_file_name)799 find_no_debuginfo (Dwfl_Module *mod,
800 void **userdata,
801 const char *modname,
802 Dwarf_Addr base,
803 const char *file_name,
804 const char *debuglink_file,
805 GElf_Word debuglink_crc,
806 char **debuginfo_file_name)
807 {
808 Dwarf_Addr dwbias;
809 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
810
811 /* We are only interested if the Dwarf has been setup on the main
812 elf file but is only missing the alternate debug link. If dwbias
813 hasn't even been setup, this is searching for separate debuginfo
814 for the main elf. We don't care in that case. */
815 if (dwbias == (Dwarf_Addr) -1)
816 return -1;
817
818 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
819 file_name, debuglink_file,
820 debuglink_crc, debuginfo_file_name);
821 }
822
823 static Dwfl *
create_dwfl(int fd,const char * fname)824 create_dwfl (int fd, const char *fname)
825 {
826 /* Duplicate an fd for dwfl_report_offline to swallow. */
827 int dwfl_fd = dup (fd);
828 if (unlikely (dwfl_fd < 0))
829 error (EXIT_FAILURE, errno, "dup");
830
831 /* Use libdwfl in a trivial way to open the libdw handle for us.
832 This takes care of applying relocations to DWARF data in ET_REL files. */
833 static const Dwfl_Callbacks callbacks =
834 {
835 .section_address = dwfl_offline_section_address,
836 .find_debuginfo = find_no_debuginfo
837 };
838 Dwfl *dwfl = dwfl_begin (&callbacks);
839 if (likely (dwfl != NULL))
840 /* Let 0 be the logical address of the file (or first in archive). */
841 dwfl->offline_next_address = 0;
842 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
843 {
844 struct stat st;
845 if (fstat (dwfl_fd, &st) != 0)
846 error (0, errno, gettext ("cannot stat input file"));
847 else if (unlikely (st.st_size == 0))
848 error (0, 0, gettext ("input file is empty"));
849 else
850 error (0, 0, gettext ("failed reading '%s': %s"),
851 fname, dwfl_errmsg (-1));
852 close (dwfl_fd); /* Consumed on success, not on failure. */
853 dwfl = NULL;
854 }
855 else
856 dwfl_report_end (dwfl, NULL, NULL);
857
858 return dwfl;
859 }
860
861 /* Process one input file. */
862 static void
process_file(int fd,const char * fname,bool only_one)863 process_file (int fd, const char *fname, bool only_one)
864 {
865 if (print_archive_index)
866 check_archive_index (fd, fname, only_one);
867
868 if (!any_control_option)
869 return;
870
871 if (elf_input_section != NULL)
872 {
873 /* Replace fname and fd with section content. */
874 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
875 sprintf (fnname, "%s:%s", fname, elf_input_section);
876 fd = open_input_section (fd);
877 if (fd == -1)
878 {
879 error (0, 0, gettext ("No such section '%s' in '%s'"),
880 elf_input_section, fname);
881 return;
882 }
883 fname = fnname;
884 }
885
886 Dwfl *dwfl = create_dwfl (fd, fname);
887 if (dwfl != NULL)
888 {
889 if (only_one)
890 {
891 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
892 bool seen = false;
893 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
894 }
895
896 /* Process the one or more modules gleaned from this file. */
897 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
898 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
899 }
900 /* Terrible hack for hooking unrelated skeleton/split compile units,
901 see __libdw_link_skel_split in print_debug. */
902 if (! do_not_close_dwfl)
903 dwfl_end (dwfl);
904
905 /* Need to close the replaced fd if we created it. Caller takes
906 care of original. */
907 if (elf_input_section != NULL)
908 close (fd);
909 }
910
911 /* Check whether there are any compressed sections in the ELF file. */
912 static bool
elf_contains_chdrs(Elf * elf)913 elf_contains_chdrs (Elf *elf)
914 {
915 Elf_Scn *scn = NULL;
916 while ((scn = elf_nextscn (elf, scn)) != NULL)
917 {
918 GElf_Shdr shdr_mem;
919 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
920 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
921 return true;
922 }
923 return false;
924 }
925
926 /* Process one ELF file. */
927 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)928 process_elf_file (Dwfl_Module *dwflmod, int fd)
929 {
930 GElf_Addr dwflbias;
931 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
932
933 GElf_Ehdr ehdr_mem;
934 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
935
936 if (ehdr == NULL)
937 {
938 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
939 return;
940 }
941
942 Ebl *ebl = ebl_openbackend (elf);
943 if (unlikely (ebl == NULL))
944 {
945 ebl_error:
946 error (0, errno, gettext ("cannot create EBL handle"));
947 return;
948 }
949
950 /* Determine the number of sections. */
951 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
952 error (EXIT_FAILURE, 0,
953 gettext ("cannot determine number of sections: %s"),
954 elf_errmsg (-1));
955
956 /* Determine the number of phdrs. */
957 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
958 error (EXIT_FAILURE, 0,
959 gettext ("cannot determine number of program headers: %s"),
960 elf_errmsg (-1));
961
962 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
963 may have applied relocation to some sections. If there are any
964 compressed sections, any pass (or libdw/libdwfl) might have
965 uncompressed them. So we need to get a fresh Elf handle on the
966 file to display those. */
967 bool print_unchanged = ((print_section_header
968 || print_relocations
969 || dump_data_sections != NULL
970 || print_notes)
971 && (ehdr->e_type == ET_REL
972 || elf_contains_chdrs (ebl->elf)));
973
974 Elf *pure_elf = NULL;
975 Ebl *pure_ebl = ebl;
976 if (print_unchanged)
977 {
978 /* Read the file afresh. */
979 off_t aroff = elf_getaroff (elf);
980 pure_elf = dwelf_elf_begin (fd);
981 if (aroff > 0)
982 {
983 /* Archive member. */
984 (void) elf_rand (pure_elf, aroff);
985 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
986 elf_end (pure_elf);
987 pure_elf = armem;
988 }
989 if (pure_elf == NULL)
990 {
991 error (0, 0, gettext ("cannot read ELF: %s"), elf_errmsg (-1));
992 return;
993 }
994 pure_ebl = ebl_openbackend (pure_elf);
995 if (pure_ebl == NULL)
996 goto ebl_error;
997 }
998
999 if (print_file_header)
1000 print_ehdr (ebl, ehdr);
1001 if (print_section_header)
1002 print_shdr (pure_ebl, ehdr);
1003 if (print_program_header)
1004 print_phdr (ebl, ehdr);
1005 if (print_section_groups)
1006 print_scngrp (ebl);
1007 if (print_dynamic_table)
1008 print_dynamic (ebl);
1009 if (print_relocations)
1010 print_relocs (pure_ebl, ehdr);
1011 if (print_histogram)
1012 handle_hash (ebl);
1013 if (print_symbol_table || print_dynsym_table)
1014 print_symtab (ebl, SHT_DYNSYM);
1015 if (print_version_info)
1016 print_verinfo (ebl);
1017 if (print_symbol_table)
1018 print_symtab (ebl, SHT_SYMTAB);
1019 if (print_arch)
1020 print_liblist (ebl);
1021 if (print_arch)
1022 print_attributes (ebl, ehdr);
1023 if (dump_data_sections != NULL)
1024 dump_data (pure_ebl);
1025 if (string_sections != NULL)
1026 dump_strings (ebl);
1027 if ((print_debug_sections | implicit_debug_sections) != 0)
1028 print_debug (dwflmod, ebl, ehdr);
1029 if (print_notes)
1030 handle_notes (pure_ebl, ehdr);
1031 if (print_string_sections)
1032 print_strings (ebl);
1033
1034 ebl_closebackend (ebl);
1035
1036 if (pure_ebl != ebl)
1037 {
1038 ebl_closebackend (pure_ebl);
1039 elf_end (pure_elf);
1040 }
1041 }
1042
1043
1044 /* Print file type. */
1045 static void
print_file_type(unsigned short int e_type)1046 print_file_type (unsigned short int e_type)
1047 {
1048 if (likely (e_type <= ET_CORE))
1049 {
1050 static const char *const knowntypes[] =
1051 {
1052 N_("NONE (None)"),
1053 N_("REL (Relocatable file)"),
1054 N_("EXEC (Executable file)"),
1055 N_("DYN (Shared object file)"),
1056 N_("CORE (Core file)")
1057 };
1058 puts (gettext (knowntypes[e_type]));
1059 }
1060 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1061 printf (gettext ("OS Specific: (%x)\n"), e_type);
1062 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1063 printf (gettext ("Processor Specific: (%x)\n"), e_type);
1064 else
1065 puts ("???");
1066 }
1067
1068
1069 /* Print ELF header. */
1070 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1071 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1072 {
1073 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
1074 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1075 printf (" %02hhx", ehdr->e_ident[cnt]);
1076
1077 printf (gettext ("\n Class: %s\n"),
1078 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1079 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1080 : "\?\?\?");
1081
1082 printf (gettext (" Data: %s\n"),
1083 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1084 ? "2's complement, little endian"
1085 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1086 ? "2's complement, big endian" : "\?\?\?");
1087
1088 printf (gettext (" Ident Version: %hhd %s\n"),
1089 ehdr->e_ident[EI_VERSION],
1090 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
1091 : "(\?\?\?)");
1092
1093 char buf[512];
1094 printf (gettext (" OS/ABI: %s\n"),
1095 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1096
1097 printf (gettext (" ABI Version: %hhd\n"),
1098 ehdr->e_ident[EI_ABIVERSION]);
1099
1100 fputs_unlocked (gettext (" Type: "), stdout);
1101 print_file_type (ehdr->e_type);
1102
1103 const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1104 if (machine != NULL)
1105 printf (gettext (" Machine: %s\n"), machine);
1106 else
1107 printf (gettext (" Machine: <unknown>: 0x%x\n"),
1108 ehdr->e_machine);
1109
1110 printf (gettext (" Version: %d %s\n"),
1111 ehdr->e_version,
1112 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1113
1114 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
1115 ehdr->e_entry);
1116
1117 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
1118 ehdr->e_phoff, gettext ("(bytes into file)"));
1119
1120 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
1121 ehdr->e_shoff, gettext ("(bytes into file)"));
1122
1123 printf (gettext (" Flags: %s\n"),
1124 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1125
1126 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
1127 ehdr->e_ehsize, gettext ("(bytes)"));
1128
1129 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
1130 ehdr->e_phentsize, gettext ("(bytes)"));
1131
1132 printf (gettext (" Number of program headers entries: %" PRId16),
1133 ehdr->e_phnum);
1134 if (ehdr->e_phnum == PN_XNUM)
1135 {
1136 GElf_Shdr shdr_mem;
1137 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1138 if (shdr != NULL)
1139 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1140 (uint32_t) shdr->sh_info);
1141 else
1142 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1143 }
1144 fputc_unlocked ('\n', stdout);
1145
1146 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1147 ehdr->e_shentsize, gettext ("(bytes)"));
1148
1149 printf (gettext (" Number of section headers entries: %" PRId16),
1150 ehdr->e_shnum);
1151 if (ehdr->e_shnum == 0)
1152 {
1153 GElf_Shdr shdr_mem;
1154 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1155 if (shdr != NULL)
1156 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1157 (uint32_t) shdr->sh_size);
1158 else
1159 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1160 }
1161 fputc_unlocked ('\n', stdout);
1162
1163 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1164 {
1165 GElf_Shdr shdr_mem;
1166 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1167 if (shdr != NULL)
1168 /* We managed to get the zeroth section. */
1169 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1170 (uint32_t) shdr->sh_link);
1171 else
1172 {
1173 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1174 buf[sizeof (buf) - 1] = '\0';
1175 }
1176
1177 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1178 buf);
1179 }
1180 else
1181 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1182 ehdr->e_shstrndx);
1183 }
1184
1185
1186 static const char *
get_visibility_type(int value)1187 get_visibility_type (int value)
1188 {
1189 switch (value)
1190 {
1191 case STV_DEFAULT:
1192 return "DEFAULT";
1193 case STV_INTERNAL:
1194 return "INTERNAL";
1195 case STV_HIDDEN:
1196 return "HIDDEN";
1197 case STV_PROTECTED:
1198 return "PROTECTED";
1199 default:
1200 return "???";
1201 }
1202 }
1203
1204 static const char *
elf_ch_type_name(unsigned int code)1205 elf_ch_type_name (unsigned int code)
1206 {
1207 if (code == 0)
1208 return "NONE";
1209
1210 if (code == ELFCOMPRESS_ZLIB)
1211 return "ZLIB";
1212
1213 return "UNKNOWN";
1214 }
1215
1216 /* Print the section headers. */
1217 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1218 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1219 {
1220 size_t cnt;
1221 size_t shstrndx;
1222
1223 if (! print_file_header)
1224 {
1225 size_t sections;
1226 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1227 error (EXIT_FAILURE, 0,
1228 gettext ("cannot get number of sections: %s"),
1229 elf_errmsg (-1));
1230
1231 printf (gettext ("\
1232 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1233 \n"),
1234 sections, ehdr->e_shoff);
1235 }
1236
1237 /* Get the section header string table index. */
1238 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1239 error (EXIT_FAILURE, 0,
1240 gettext ("cannot get section header string table index: %s"),
1241 elf_errmsg (-1));
1242
1243 puts (gettext ("Section Headers:"));
1244
1245 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1246 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1247 else
1248 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1249
1250 if (print_decompress)
1251 {
1252 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1253 puts (gettext (" [Compression Size Al]"));
1254 else
1255 puts (gettext (" [Compression Size Al]"));
1256 }
1257
1258 for (cnt = 0; cnt < shnum; ++cnt)
1259 {
1260 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1261
1262 if (unlikely (scn == NULL))
1263 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1264 elf_errmsg (-1));
1265
1266 /* Get the section header. */
1267 GElf_Shdr shdr_mem;
1268 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1269 if (unlikely (shdr == NULL))
1270 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1271 elf_errmsg (-1));
1272
1273 char flagbuf[20];
1274 char *cp = flagbuf;
1275 if (shdr->sh_flags & SHF_WRITE)
1276 *cp++ = 'W';
1277 if (shdr->sh_flags & SHF_ALLOC)
1278 *cp++ = 'A';
1279 if (shdr->sh_flags & SHF_EXECINSTR)
1280 *cp++ = 'X';
1281 if (shdr->sh_flags & SHF_MERGE)
1282 *cp++ = 'M';
1283 if (shdr->sh_flags & SHF_STRINGS)
1284 *cp++ = 'S';
1285 if (shdr->sh_flags & SHF_INFO_LINK)
1286 *cp++ = 'I';
1287 if (shdr->sh_flags & SHF_LINK_ORDER)
1288 *cp++ = 'L';
1289 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1290 *cp++ = 'N';
1291 if (shdr->sh_flags & SHF_GROUP)
1292 *cp++ = 'G';
1293 if (shdr->sh_flags & SHF_TLS)
1294 *cp++ = 'T';
1295 if (shdr->sh_flags & SHF_COMPRESSED)
1296 *cp++ = 'C';
1297 if (shdr->sh_flags & SHF_ORDERED)
1298 *cp++ = 'O';
1299 if (shdr->sh_flags & SHF_EXCLUDE)
1300 *cp++ = 'E';
1301 *cp = '\0';
1302
1303 const char *sname;
1304 char buf[128];
1305 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1306 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1307 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1308 " %2" PRId64 "\n",
1309 cnt, sname,
1310 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1311 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1312 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1313 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1314 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1315 shdr->sh_addralign);
1316
1317 if (print_decompress)
1318 {
1319 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1320 {
1321 GElf_Chdr chdr;
1322 if (gelf_getchdr (scn, &chdr) != NULL)
1323 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1324 " %2" PRId64 "]\n",
1325 elf_ch_type_name (chdr.ch_type),
1326 chdr.ch_type,
1327 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1328 chdr.ch_size, chdr.ch_addralign);
1329 else
1330 error (0, 0,
1331 gettext ("bad compression header for section %zd: %s"),
1332 elf_ndxscn (scn), elf_errmsg (-1));
1333 }
1334 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1335 {
1336 ssize_t size;
1337 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1338 printf (" [GNU ZLIB %0*zx ]\n",
1339 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1340 else
1341 error (0, 0,
1342 gettext ("bad gnu compressed size for section %zd: %s"),
1343 elf_ndxscn (scn), elf_errmsg (-1));
1344 }
1345 }
1346 }
1347
1348 fputc_unlocked ('\n', stdout);
1349 }
1350
1351
1352 /* Print the program header. */
1353 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1354 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1355 {
1356 if (phnum == 0)
1357 /* No program header, this is OK in relocatable objects. */
1358 return;
1359
1360 puts (gettext ("Program Headers:"));
1361 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1362 puts (gettext ("\
1363 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1364 else
1365 puts (gettext ("\
1366 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1367
1368 /* Process all program headers. */
1369 bool has_relro = false;
1370 GElf_Addr relro_from = 0;
1371 GElf_Addr relro_to = 0;
1372 for (size_t cnt = 0; cnt < phnum; ++cnt)
1373 {
1374 char buf[128];
1375 GElf_Phdr mem;
1376 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1377
1378 /* If for some reason the header cannot be returned show this. */
1379 if (unlikely (phdr == NULL))
1380 {
1381 puts (" ???");
1382 continue;
1383 }
1384
1385 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1386 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1387 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1388 phdr->p_offset,
1389 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1390 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1391 phdr->p_filesz,
1392 phdr->p_memsz,
1393 phdr->p_flags & PF_R ? 'R' : ' ',
1394 phdr->p_flags & PF_W ? 'W' : ' ',
1395 phdr->p_flags & PF_X ? 'E' : ' ',
1396 phdr->p_align);
1397
1398 if (phdr->p_type == PT_INTERP)
1399 {
1400 /* If we are sure the file offset is valid then we can show
1401 the user the name of the interpreter. We check whether
1402 there is a section at the file offset. Normally there
1403 would be a section called ".interp". But in separate
1404 .debug files it is a NOBITS section (and so doesn't match
1405 with gelf_offscn). Which probably means the offset is
1406 not valid another reason could be because the ELF file
1407 just doesn't contain any section headers, in that case
1408 just play it safe and don't display anything. */
1409
1410 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1411 GElf_Shdr shdr_mem;
1412 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1413
1414 size_t maxsize;
1415 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1416
1417 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1418 && filedata != NULL && phdr->p_offset < maxsize
1419 && phdr->p_filesz <= maxsize - phdr->p_offset
1420 && memchr (filedata + phdr->p_offset, '\0',
1421 phdr->p_filesz) != NULL)
1422 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1423 filedata + phdr->p_offset);
1424 }
1425 else if (phdr->p_type == PT_GNU_RELRO)
1426 {
1427 has_relro = true;
1428 relro_from = phdr->p_vaddr;
1429 relro_to = relro_from + phdr->p_memsz;
1430 }
1431 }
1432
1433 size_t sections;
1434 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1435 error (EXIT_FAILURE, 0,
1436 gettext ("cannot get number of sections: %s"),
1437 elf_errmsg (-1));
1438
1439 if (sections == 0)
1440 /* No sections in the file. Punt. */
1441 return;
1442
1443 /* Get the section header string table index. */
1444 size_t shstrndx;
1445 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1446 error (EXIT_FAILURE, 0,
1447 gettext ("cannot get section header string table index"));
1448
1449 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1450
1451 for (size_t cnt = 0; cnt < phnum; ++cnt)
1452 {
1453 /* Print the segment number. */
1454 printf (" %2.2zu ", cnt);
1455
1456 GElf_Phdr phdr_mem;
1457 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1458 /* This must not happen. */
1459 if (unlikely (phdr == NULL))
1460 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1461 elf_errmsg (-1));
1462
1463 /* Iterate over the sections. */
1464 bool in_relro = false;
1465 bool in_ro = false;
1466 for (size_t inner = 1; inner < shnum; ++inner)
1467 {
1468 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1469 /* This should not happen. */
1470 if (unlikely (scn == NULL))
1471 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1472 elf_errmsg (-1));
1473
1474 /* Get the section header. */
1475 GElf_Shdr shdr_mem;
1476 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1477 if (unlikely (shdr == NULL))
1478 error (EXIT_FAILURE, 0,
1479 gettext ("cannot get section header: %s"),
1480 elf_errmsg (-1));
1481
1482 if (shdr->sh_size > 0
1483 /* Compare allocated sections by VMA, unallocated
1484 sections by file offset. */
1485 && (shdr->sh_flags & SHF_ALLOC
1486 ? (shdr->sh_addr >= phdr->p_vaddr
1487 && (shdr->sh_addr + shdr->sh_size
1488 <= phdr->p_vaddr + phdr->p_memsz))
1489 : (shdr->sh_offset >= phdr->p_offset
1490 && (shdr->sh_offset + shdr->sh_size
1491 <= phdr->p_offset + phdr->p_filesz))))
1492 {
1493 if (has_relro && !in_relro
1494 && shdr->sh_addr >= relro_from
1495 && shdr->sh_addr + shdr->sh_size <= relro_to)
1496 {
1497 fputs_unlocked (" [RELRO:", stdout);
1498 in_relro = true;
1499 }
1500 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1501 {
1502 fputs_unlocked ("]", stdout);
1503 in_relro = false;
1504 }
1505 else if (has_relro && in_relro
1506 && shdr->sh_addr + shdr->sh_size > relro_to)
1507 fputs_unlocked ("] <RELRO:", stdout);
1508 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1509 {
1510 if (!in_ro)
1511 {
1512 fputs_unlocked (" [RO:", stdout);
1513 in_ro = true;
1514 }
1515 }
1516 else
1517 {
1518 /* Determine the segment this section is part of. */
1519 size_t cnt2;
1520 GElf_Phdr phdr2_mem;
1521 GElf_Phdr *phdr2 = NULL;
1522 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1523 {
1524 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1525
1526 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1527 && shdr->sh_addr >= phdr2->p_vaddr
1528 && (shdr->sh_addr + shdr->sh_size
1529 <= phdr2->p_vaddr + phdr2->p_memsz))
1530 break;
1531 }
1532
1533 if (cnt2 < phnum)
1534 {
1535 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1536 {
1537 fputs_unlocked (" [RO:", stdout);
1538 in_ro = true;
1539 }
1540 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1541 {
1542 fputs_unlocked ("]", stdout);
1543 in_ro = false;
1544 }
1545 }
1546 }
1547
1548 printf (" %s",
1549 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1550
1551 /* Signal that this sectin is only partially covered. */
1552 if (has_relro && in_relro
1553 && shdr->sh_addr + shdr->sh_size > relro_to)
1554 {
1555 fputs_unlocked (">", stdout);
1556 in_relro = false;
1557 }
1558 }
1559 }
1560 if (in_relro || in_ro)
1561 fputs_unlocked ("]", stdout);
1562
1563 /* Finish the line. */
1564 fputc_unlocked ('\n', stdout);
1565 }
1566 }
1567
1568
1569 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1570 section_name (Ebl *ebl, GElf_Shdr *shdr)
1571 {
1572 size_t shstrndx;
1573 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1574 return "???";
1575 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1576 }
1577
1578
1579 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1580 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1581 {
1582 /* Get the data of the section. */
1583 Elf_Data *data = elf_getdata (scn, NULL);
1584
1585 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1586 GElf_Shdr symshdr_mem;
1587 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1588 Elf_Data *symdata = elf_getdata (symscn, NULL);
1589
1590 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1591 || symdata == NULL)
1592 return;
1593
1594 /* Get the section header string table index. */
1595 size_t shstrndx;
1596 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1597 error (EXIT_FAILURE, 0,
1598 gettext ("cannot get section header string table index"));
1599
1600 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1601
1602 GElf_Sym sym_mem;
1603 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1604
1605 printf ((grpref[0] & GRP_COMDAT)
1606 ? ngettext ("\
1607 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1608 "\
1609 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1610 data->d_size / sizeof (Elf32_Word) - 1)
1611 : ngettext ("\
1612 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1613 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1614 data->d_size / sizeof (Elf32_Word) - 1),
1615 elf_ndxscn (scn),
1616 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1617 (sym == NULL ? NULL
1618 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1619 ?: gettext ("<INVALID SYMBOL>"),
1620 data->d_size / sizeof (Elf32_Word) - 1);
1621
1622 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1623 {
1624 GElf_Shdr grpshdr_mem;
1625 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1626 &grpshdr_mem);
1627
1628 const char *str;
1629 printf (" [%2u] %s\n",
1630 grpref[cnt],
1631 grpshdr != NULL
1632 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1633 ? str : gettext ("<INVALID SECTION>"));
1634 }
1635 }
1636
1637
1638 static void
print_scngrp(Ebl * ebl)1639 print_scngrp (Ebl *ebl)
1640 {
1641 /* Find all relocation sections and handle them. */
1642 Elf_Scn *scn = NULL;
1643
1644 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1645 {
1646 /* Handle the section if it is a symbol table. */
1647 GElf_Shdr shdr_mem;
1648 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1649
1650 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1651 {
1652 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1653 {
1654 if (elf_compress (scn, 0, 0) < 0)
1655 printf ("WARNING: %s [%zd]\n",
1656 gettext ("Couldn't uncompress section"),
1657 elf_ndxscn (scn));
1658 shdr = gelf_getshdr (scn, &shdr_mem);
1659 if (unlikely (shdr == NULL))
1660 error (EXIT_FAILURE, 0,
1661 gettext ("cannot get section [%zd] header: %s"),
1662 elf_ndxscn (scn),
1663 elf_errmsg (-1));
1664 }
1665 handle_scngrp (ebl, scn, shdr);
1666 }
1667 }
1668 }
1669
1670
1671 static const struct flags
1672 {
1673 int mask;
1674 const char *str;
1675 } dt_flags[] =
1676 {
1677 { DF_ORIGIN, "ORIGIN" },
1678 { DF_SYMBOLIC, "SYMBOLIC" },
1679 { DF_TEXTREL, "TEXTREL" },
1680 { DF_BIND_NOW, "BIND_NOW" },
1681 { DF_STATIC_TLS, "STATIC_TLS" }
1682 };
1683 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1684
1685 static const struct flags dt_flags_1[] =
1686 {
1687 { DF_1_NOW, "NOW" },
1688 { DF_1_GLOBAL, "GLOBAL" },
1689 { DF_1_GROUP, "GROUP" },
1690 { DF_1_NODELETE, "NODELETE" },
1691 { DF_1_LOADFLTR, "LOADFLTR" },
1692 { DF_1_INITFIRST, "INITFIRST" },
1693 { DF_1_NOOPEN, "NOOPEN" },
1694 { DF_1_ORIGIN, "ORIGIN" },
1695 { DF_1_DIRECT, "DIRECT" },
1696 { DF_1_TRANS, "TRANS" },
1697 { DF_1_INTERPOSE, "INTERPOSE" },
1698 { DF_1_NODEFLIB, "NODEFLIB" },
1699 { DF_1_NODUMP, "NODUMP" },
1700 { DF_1_CONFALT, "CONFALT" },
1701 { DF_1_ENDFILTEE, "ENDFILTEE" },
1702 { DF_1_DISPRELDNE, "DISPRELDNE" },
1703 { DF_1_DISPRELPND, "DISPRELPND" },
1704 };
1705 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1706
1707 static const struct flags dt_feature_1[] =
1708 {
1709 { DTF_1_PARINIT, "PARINIT" },
1710 { DTF_1_CONFEXP, "CONFEXP" }
1711 };
1712 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1713 / sizeof (dt_feature_1[0]));
1714
1715 static const struct flags dt_posflag_1[] =
1716 {
1717 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1718 { DF_P1_GROUPPERM, "GROUPPERM" }
1719 };
1720 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1721 / sizeof (dt_posflag_1[0]));
1722
1723
1724 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1725 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1726 int nflags)
1727 {
1728 bool first = true;
1729 int cnt;
1730
1731 for (cnt = 0; cnt < nflags; ++cnt)
1732 if (d_val & flags[cnt].mask)
1733 {
1734 if (!first)
1735 putchar_unlocked (' ');
1736 fputs_unlocked (flags[cnt].str, stdout);
1737 d_val &= ~flags[cnt].mask;
1738 first = false;
1739 }
1740
1741 if (d_val != 0)
1742 {
1743 if (!first)
1744 putchar_unlocked (' ');
1745 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1746 }
1747
1748 putchar_unlocked ('\n');
1749 }
1750
1751
1752 static void
print_dt_flags(int class,GElf_Xword d_val)1753 print_dt_flags (int class, GElf_Xword d_val)
1754 {
1755 print_flags (class, d_val, dt_flags, ndt_flags);
1756 }
1757
1758
1759 static void
print_dt_flags_1(int class,GElf_Xword d_val)1760 print_dt_flags_1 (int class, GElf_Xword d_val)
1761 {
1762 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1763 }
1764
1765
1766 static void
print_dt_feature_1(int class,GElf_Xword d_val)1767 print_dt_feature_1 (int class, GElf_Xword d_val)
1768 {
1769 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1770 }
1771
1772
1773 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1774 print_dt_posflag_1 (int class, GElf_Xword d_val)
1775 {
1776 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1777 }
1778
1779
1780 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1781 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1782 {
1783 int class = gelf_getclass (ebl->elf);
1784 GElf_Shdr glink_mem;
1785 GElf_Shdr *glink;
1786 Elf_Data *data;
1787 size_t cnt;
1788 size_t shstrndx;
1789 size_t sh_entsize;
1790
1791 /* Get the data of the section. */
1792 data = elf_getdata (scn, NULL);
1793 if (data == NULL)
1794 return;
1795
1796 /* Get the section header string table index. */
1797 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1798 error (EXIT_FAILURE, 0,
1799 gettext ("cannot get section header string table index"));
1800
1801 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1802
1803 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1804 if (glink == NULL)
1805 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1806 elf_ndxscn (scn));
1807
1808 printf (ngettext ("\
1809 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1810 "\
1811 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1812 shdr->sh_size / sh_entsize),
1813 (unsigned long int) (shdr->sh_size / sh_entsize),
1814 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1815 shdr->sh_offset,
1816 (int) shdr->sh_link,
1817 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1818 fputs_unlocked (gettext (" Type Value\n"), stdout);
1819
1820 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1821 {
1822 GElf_Dyn dynmem;
1823 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1824 if (dyn == NULL)
1825 break;
1826
1827 char buf[64];
1828 printf (" %-17s ",
1829 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1830
1831 switch (dyn->d_tag)
1832 {
1833 case DT_NULL:
1834 case DT_DEBUG:
1835 case DT_BIND_NOW:
1836 case DT_TEXTREL:
1837 /* No further output. */
1838 fputc_unlocked ('\n', stdout);
1839 break;
1840
1841 case DT_NEEDED:
1842 printf (gettext ("Shared library: [%s]\n"),
1843 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1844 break;
1845
1846 case DT_SONAME:
1847 printf (gettext ("Library soname: [%s]\n"),
1848 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1849 break;
1850
1851 case DT_RPATH:
1852 printf (gettext ("Library rpath: [%s]\n"),
1853 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1854 break;
1855
1856 case DT_RUNPATH:
1857 printf (gettext ("Library runpath: [%s]\n"),
1858 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1859 break;
1860
1861 case DT_PLTRELSZ:
1862 case DT_RELASZ:
1863 case DT_STRSZ:
1864 case DT_RELSZ:
1865 case DT_RELAENT:
1866 case DT_SYMENT:
1867 case DT_RELENT:
1868 case DT_PLTPADSZ:
1869 case DT_MOVEENT:
1870 case DT_MOVESZ:
1871 case DT_INIT_ARRAYSZ:
1872 case DT_FINI_ARRAYSZ:
1873 case DT_SYMINSZ:
1874 case DT_SYMINENT:
1875 case DT_GNU_CONFLICTSZ:
1876 case DT_GNU_LIBLISTSZ:
1877 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1878 break;
1879
1880 case DT_VERDEFNUM:
1881 case DT_VERNEEDNUM:
1882 case DT_RELACOUNT:
1883 case DT_RELCOUNT:
1884 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1885 break;
1886
1887 case DT_PLTREL:;
1888 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1889 NULL, 0);
1890 puts (tagname ?: "???");
1891 break;
1892
1893 case DT_FLAGS:
1894 print_dt_flags (class, dyn->d_un.d_val);
1895 break;
1896
1897 case DT_FLAGS_1:
1898 print_dt_flags_1 (class, dyn->d_un.d_val);
1899 break;
1900
1901 case DT_FEATURE_1:
1902 print_dt_feature_1 (class, dyn->d_un.d_val);
1903 break;
1904
1905 case DT_POSFLAG_1:
1906 print_dt_posflag_1 (class, dyn->d_un.d_val);
1907 break;
1908
1909 default:
1910 printf ("%#0*" PRIx64 "\n",
1911 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1912 break;
1913 }
1914 }
1915 }
1916
1917
1918 /* Print the dynamic segment. */
1919 static void
print_dynamic(Ebl * ebl)1920 print_dynamic (Ebl *ebl)
1921 {
1922 for (size_t i = 0; i < phnum; ++i)
1923 {
1924 GElf_Phdr phdr_mem;
1925 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1926
1927 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1928 {
1929 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1930 GElf_Shdr shdr_mem;
1931 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1932 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1933 handle_dynamic (ebl, scn, shdr);
1934 break;
1935 }
1936 }
1937 }
1938
1939
1940 /* Print relocations. */
1941 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1942 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1943 {
1944 /* Find all relocation sections and handle them. */
1945 Elf_Scn *scn = NULL;
1946
1947 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1948 {
1949 /* Handle the section if it is a symbol table. */
1950 GElf_Shdr shdr_mem;
1951 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1952
1953 if (likely (shdr != NULL))
1954 {
1955 if (shdr->sh_type == SHT_REL)
1956 handle_relocs_rel (ebl, ehdr, scn, shdr);
1957 else if (shdr->sh_type == SHT_RELA)
1958 handle_relocs_rela (ebl, ehdr, scn, shdr);
1959 }
1960 }
1961 }
1962
1963
1964 /* Handle a relocation section. */
1965 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1966 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1967 {
1968 int class = gelf_getclass (ebl->elf);
1969 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1970 int nentries = shdr->sh_size / sh_entsize;
1971
1972 /* Get the data of the section. */
1973 Elf_Data *data = elf_getdata (scn, NULL);
1974 if (data == NULL)
1975 return;
1976
1977 /* Get the symbol table information. */
1978 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1979 GElf_Shdr symshdr_mem;
1980 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1981 Elf_Data *symdata = elf_getdata (symscn, NULL);
1982
1983 /* Get the section header of the section the relocations are for. */
1984 GElf_Shdr destshdr_mem;
1985 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1986 &destshdr_mem);
1987
1988 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1989 {
1990 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1991 shdr->sh_offset);
1992 return;
1993 }
1994
1995 /* Search for the optional extended section index table. */
1996 Elf_Data *xndxdata = NULL;
1997 int xndxscnidx = elf_scnshndx (scn);
1998 if (unlikely (xndxscnidx > 0))
1999 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2000
2001 /* Get the section header string table index. */
2002 size_t shstrndx;
2003 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2004 error (EXIT_FAILURE, 0,
2005 gettext ("cannot get section header string table index"));
2006
2007 if (shdr->sh_info != 0)
2008 printf (ngettext ("\
2009 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2010 "\
2011 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2012 nentries),
2013 elf_ndxscn (scn),
2014 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2015 (unsigned int) shdr->sh_info,
2016 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2017 shdr->sh_offset,
2018 nentries);
2019 else
2020 /* The .rel.dyn section does not refer to a specific section but
2021 instead of section index zero. Do not try to print a section
2022 name. */
2023 printf (ngettext ("\
2024 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2025 "\
2026 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2027 nentries),
2028 (unsigned int) elf_ndxscn (scn),
2029 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2030 shdr->sh_offset,
2031 nentries);
2032 fputs_unlocked (class == ELFCLASS32
2033 ? gettext ("\
2034 Offset Type Value Name\n")
2035 : gettext ("\
2036 Offset Type Value Name\n"),
2037 stdout);
2038
2039 int is_statically_linked = 0;
2040 for (int cnt = 0; cnt < nentries; ++cnt)
2041 {
2042 GElf_Rel relmem;
2043 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2044 if (likely (rel != NULL))
2045 {
2046 char buf[128];
2047 GElf_Sym symmem;
2048 Elf32_Word xndx;
2049 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2050 GELF_R_SYM (rel->r_info),
2051 &symmem, &xndx);
2052 if (unlikely (sym == NULL))
2053 {
2054 /* As a special case we have to handle relocations in static
2055 executables. This only happens for IRELATIVE relocations
2056 (so far). There is no symbol table. */
2057 if (is_statically_linked == 0)
2058 {
2059 /* Find the program header and look for a PT_INTERP entry. */
2060 is_statically_linked = -1;
2061 if (ehdr->e_type == ET_EXEC)
2062 {
2063 is_statically_linked = 1;
2064
2065 for (size_t inner = 0; inner < phnum; ++inner)
2066 {
2067 GElf_Phdr phdr_mem;
2068 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2069 &phdr_mem);
2070 if (phdr != NULL && phdr->p_type == PT_INTERP)
2071 {
2072 is_statically_linked = -1;
2073 break;
2074 }
2075 }
2076 }
2077 }
2078
2079 if (is_statically_linked > 0 && shdr->sh_link == 0)
2080 printf ("\
2081 %#0*" PRIx64 " %-20s %*s %s\n",
2082 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2083 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2084 /* Avoid the leading R_ which isn't carrying any
2085 information. */
2086 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2087 buf, sizeof (buf)) + 2
2088 : gettext ("<INVALID RELOC>"),
2089 class == ELFCLASS32 ? 10 : 18, "",
2090 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2091 else
2092 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2093 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2094 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2095 /* Avoid the leading R_ which isn't carrying any
2096 information. */
2097 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2098 buf, sizeof (buf)) + 2
2099 : gettext ("<INVALID RELOC>"),
2100 gettext ("INVALID SYMBOL"),
2101 (long int) GELF_R_SYM (rel->r_info));
2102 }
2103 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2104 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2105 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2106 likely (ebl_reloc_type_check (ebl,
2107 GELF_R_TYPE (rel->r_info)))
2108 /* Avoid the leading R_ which isn't carrying any
2109 information. */
2110 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2111 buf, sizeof (buf)) + 2
2112 : gettext ("<INVALID RELOC>"),
2113 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2114 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2115 else
2116 {
2117 /* This is a relocation against a STT_SECTION symbol. */
2118 GElf_Shdr secshdr_mem;
2119 GElf_Shdr *secshdr;
2120 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2121 sym->st_shndx == SHN_XINDEX
2122 ? xndx : sym->st_shndx),
2123 &secshdr_mem);
2124
2125 if (unlikely (secshdr == NULL))
2126 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2127 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2128 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2129 /* Avoid the leading R_ which isn't carrying any
2130 information. */
2131 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2132 buf, sizeof (buf)) + 2
2133 : gettext ("<INVALID RELOC>"),
2134 gettext ("INVALID SECTION"),
2135 (long int) (sym->st_shndx == SHN_XINDEX
2136 ? xndx : sym->st_shndx));
2137 else
2138 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2139 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2140 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2141 /* Avoid the leading R_ which isn't carrying any
2142 information. */
2143 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2144 buf, sizeof (buf)) + 2
2145 : gettext ("<INVALID RELOC>"),
2146 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2147 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2148 }
2149 }
2150 }
2151 }
2152
2153
2154 /* Handle a relocation section. */
2155 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2156 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2157 {
2158 int class = gelf_getclass (ebl->elf);
2159 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2160 int nentries = shdr->sh_size / sh_entsize;
2161
2162 /* Get the data of the section. */
2163 Elf_Data *data = elf_getdata (scn, NULL);
2164 if (data == NULL)
2165 return;
2166
2167 /* Get the symbol table information. */
2168 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2169 GElf_Shdr symshdr_mem;
2170 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2171 Elf_Data *symdata = elf_getdata (symscn, NULL);
2172
2173 /* Get the section header of the section the relocations are for. */
2174 GElf_Shdr destshdr_mem;
2175 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2176 &destshdr_mem);
2177
2178 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2179 {
2180 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2181 shdr->sh_offset);
2182 return;
2183 }
2184
2185 /* Search for the optional extended section index table. */
2186 Elf_Data *xndxdata = NULL;
2187 int xndxscnidx = elf_scnshndx (scn);
2188 if (unlikely (xndxscnidx > 0))
2189 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2190
2191 /* Get the section header string table index. */
2192 size_t shstrndx;
2193 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2194 error (EXIT_FAILURE, 0,
2195 gettext ("cannot get section header string table index"));
2196
2197 if (shdr->sh_info != 0)
2198 printf (ngettext ("\
2199 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2200 "\
2201 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2202 nentries),
2203 elf_ndxscn (scn),
2204 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2205 (unsigned int) shdr->sh_info,
2206 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2207 shdr->sh_offset,
2208 nentries);
2209 else
2210 /* The .rela.dyn section does not refer to a specific section but
2211 instead of section index zero. Do not try to print a section
2212 name. */
2213 printf (ngettext ("\
2214 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2215 "\
2216 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2217 nentries),
2218 (unsigned int) elf_ndxscn (scn),
2219 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2220 shdr->sh_offset,
2221 nentries);
2222 fputs_unlocked (class == ELFCLASS32
2223 ? gettext ("\
2224 Offset Type Value Addend Name\n")
2225 : gettext ("\
2226 Offset Type Value Addend Name\n"),
2227 stdout);
2228
2229 int is_statically_linked = 0;
2230 for (int cnt = 0; cnt < nentries; ++cnt)
2231 {
2232 GElf_Rela relmem;
2233 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2234 if (likely (rel != NULL))
2235 {
2236 char buf[64];
2237 GElf_Sym symmem;
2238 Elf32_Word xndx;
2239 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2240 GELF_R_SYM (rel->r_info),
2241 &symmem, &xndx);
2242
2243 if (unlikely (sym == NULL))
2244 {
2245 /* As a special case we have to handle relocations in static
2246 executables. This only happens for IRELATIVE relocations
2247 (so far). There is no symbol table. */
2248 if (is_statically_linked == 0)
2249 {
2250 /* Find the program header and look for a PT_INTERP entry. */
2251 is_statically_linked = -1;
2252 if (ehdr->e_type == ET_EXEC)
2253 {
2254 is_statically_linked = 1;
2255
2256 for (size_t inner = 0; inner < phnum; ++inner)
2257 {
2258 GElf_Phdr phdr_mem;
2259 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2260 &phdr_mem);
2261 if (phdr != NULL && phdr->p_type == PT_INTERP)
2262 {
2263 is_statically_linked = -1;
2264 break;
2265 }
2266 }
2267 }
2268 }
2269
2270 if (is_statically_linked > 0 && shdr->sh_link == 0)
2271 printf ("\
2272 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2273 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2274 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2275 /* Avoid the leading R_ which isn't carrying any
2276 information. */
2277 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2278 buf, sizeof (buf)) + 2
2279 : gettext ("<INVALID RELOC>"),
2280 class == ELFCLASS32 ? 10 : 18, "",
2281 rel->r_addend,
2282 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2283 else
2284 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2285 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2286 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2287 /* Avoid the leading R_ which isn't carrying any
2288 information. */
2289 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2290 buf, sizeof (buf)) + 2
2291 : gettext ("<INVALID RELOC>"),
2292 gettext ("INVALID SYMBOL"),
2293 (long int) GELF_R_SYM (rel->r_info));
2294 }
2295 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2296 printf ("\
2297 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2298 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2299 likely (ebl_reloc_type_check (ebl,
2300 GELF_R_TYPE (rel->r_info)))
2301 /* Avoid the leading R_ which isn't carrying any
2302 information. */
2303 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2304 buf, sizeof (buf)) + 2
2305 : gettext ("<INVALID RELOC>"),
2306 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2307 rel->r_addend,
2308 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2309 else
2310 {
2311 /* This is a relocation against a STT_SECTION symbol. */
2312 GElf_Shdr secshdr_mem;
2313 GElf_Shdr *secshdr;
2314 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2315 sym->st_shndx == SHN_XINDEX
2316 ? xndx : sym->st_shndx),
2317 &secshdr_mem);
2318
2319 if (unlikely (secshdr == NULL))
2320 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2321 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2322 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2323 /* Avoid the leading R_ which isn't carrying any
2324 information. */
2325 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2326 buf, sizeof (buf)) + 2
2327 : gettext ("<INVALID RELOC>"),
2328 gettext ("INVALID SECTION"),
2329 (long int) (sym->st_shndx == SHN_XINDEX
2330 ? xndx : sym->st_shndx));
2331 else
2332 printf ("\
2333 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2334 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2335 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2336 /* Avoid the leading R_ which isn't carrying any
2337 information. */
2338 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2339 buf, sizeof (buf)) + 2
2340 : gettext ("<INVALID RELOC>"),
2341 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2342 rel->r_addend,
2343 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2344 }
2345 }
2346 }
2347 }
2348
2349
2350 /* Print the program header. */
2351 static void
print_symtab(Ebl * ebl,int type)2352 print_symtab (Ebl *ebl, int type)
2353 {
2354 /* Find the symbol table(s). For this we have to search through the
2355 section table. */
2356 Elf_Scn *scn = NULL;
2357
2358 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2359 {
2360 /* Handle the section if it is a symbol table. */
2361 GElf_Shdr shdr_mem;
2362 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2363
2364 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2365 {
2366 if (symbol_table_section != NULL)
2367 {
2368 /* Get the section header string table index. */
2369 size_t shstrndx;
2370 const char *sname;
2371 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2372 error (EXIT_FAILURE, 0,
2373 gettext ("cannot get section header string table index"));
2374 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2375 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2376 continue;
2377 }
2378
2379 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2380 {
2381 if (elf_compress (scn, 0, 0) < 0)
2382 printf ("WARNING: %s [%zd]\n",
2383 gettext ("Couldn't uncompress section"),
2384 elf_ndxscn (scn));
2385 shdr = gelf_getshdr (scn, &shdr_mem);
2386 if (unlikely (shdr == NULL))
2387 error (EXIT_FAILURE, 0,
2388 gettext ("cannot get section [%zd] header: %s"),
2389 elf_ndxscn (scn), elf_errmsg (-1));
2390 }
2391 handle_symtab (ebl, scn, shdr);
2392 }
2393 }
2394 }
2395
2396
2397 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2398 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2399 {
2400 Elf_Data *versym_data = NULL;
2401 Elf_Data *verneed_data = NULL;
2402 Elf_Data *verdef_data = NULL;
2403 Elf_Data *xndx_data = NULL;
2404 int class = gelf_getclass (ebl->elf);
2405 Elf32_Word verneed_stridx = 0;
2406 Elf32_Word verdef_stridx = 0;
2407
2408 /* Get the data of the section. */
2409 Elf_Data *data = elf_getdata (scn, NULL);
2410 if (data == NULL)
2411 return;
2412
2413 /* Find out whether we have other sections we might need. */
2414 Elf_Scn *runscn = NULL;
2415 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2416 {
2417 GElf_Shdr runshdr_mem;
2418 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2419
2420 if (likely (runshdr != NULL))
2421 {
2422 if (runshdr->sh_type == SHT_GNU_versym
2423 && runshdr->sh_link == elf_ndxscn (scn))
2424 /* Bingo, found the version information. Now get the data. */
2425 versym_data = elf_getdata (runscn, NULL);
2426 else if (runshdr->sh_type == SHT_GNU_verneed)
2427 {
2428 /* This is the information about the needed versions. */
2429 verneed_data = elf_getdata (runscn, NULL);
2430 verneed_stridx = runshdr->sh_link;
2431 }
2432 else if (runshdr->sh_type == SHT_GNU_verdef)
2433 {
2434 /* This is the information about the defined versions. */
2435 verdef_data = elf_getdata (runscn, NULL);
2436 verdef_stridx = runshdr->sh_link;
2437 }
2438 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2439 && runshdr->sh_link == elf_ndxscn (scn))
2440 /* Extended section index. */
2441 xndx_data = elf_getdata (runscn, NULL);
2442 }
2443 }
2444
2445 /* Get the section header string table index. */
2446 size_t shstrndx;
2447 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2448 error (EXIT_FAILURE, 0,
2449 gettext ("cannot get section header string table index"));
2450
2451 GElf_Shdr glink_mem;
2452 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2453 &glink_mem);
2454 if (glink == NULL)
2455 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2456 elf_ndxscn (scn));
2457
2458 /* Now we can compute the number of entries in the section. */
2459 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2460 ? sizeof (Elf32_Sym)
2461 : sizeof (Elf64_Sym));
2462
2463 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2464 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2465 nsyms),
2466 (unsigned int) elf_ndxscn (scn),
2467 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2468 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2469 " %lu local symbols String table: [%2u] '%s'\n",
2470 shdr->sh_info),
2471 (unsigned long int) shdr->sh_info,
2472 (unsigned int) shdr->sh_link,
2473 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2474
2475 fputs_unlocked (class == ELFCLASS32
2476 ? gettext ("\
2477 Num: Value Size Type Bind Vis Ndx Name\n")
2478 : gettext ("\
2479 Num: Value Size Type Bind Vis Ndx Name\n"),
2480 stdout);
2481
2482 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2483 {
2484 char typebuf[64];
2485 char bindbuf[64];
2486 char scnbuf[64];
2487 Elf32_Word xndx;
2488 GElf_Sym sym_mem;
2489 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2490
2491 if (unlikely (sym == NULL))
2492 continue;
2493
2494 /* Determine the real section index. */
2495 if (likely (sym->st_shndx != SHN_XINDEX))
2496 xndx = sym->st_shndx;
2497
2498 printf (gettext ("\
2499 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2500 cnt,
2501 class == ELFCLASS32 ? 8 : 16,
2502 sym->st_value,
2503 sym->st_size,
2504 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2505 typebuf, sizeof (typebuf)),
2506 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2507 bindbuf, sizeof (bindbuf)),
2508 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2509 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2510 sizeof (scnbuf), NULL, shnum),
2511 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2512
2513 if (versym_data != NULL)
2514 {
2515 /* Get the version information. */
2516 GElf_Versym versym_mem;
2517 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2518
2519 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2520 {
2521 bool is_nobits = false;
2522 bool check_def = xndx != SHN_UNDEF;
2523
2524 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2525 {
2526 GElf_Shdr symshdr_mem;
2527 GElf_Shdr *symshdr =
2528 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2529
2530 is_nobits = (symshdr != NULL
2531 && symshdr->sh_type == SHT_NOBITS);
2532 }
2533
2534 if (is_nobits || ! check_def)
2535 {
2536 /* We must test both. */
2537 GElf_Vernaux vernaux_mem;
2538 GElf_Vernaux *vernaux = NULL;
2539 size_t vn_offset = 0;
2540
2541 GElf_Verneed verneed_mem;
2542 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2543 &verneed_mem);
2544 while (verneed != NULL)
2545 {
2546 size_t vna_offset = vn_offset;
2547
2548 vernaux = gelf_getvernaux (verneed_data,
2549 vna_offset += verneed->vn_aux,
2550 &vernaux_mem);
2551 while (vernaux != NULL
2552 && vernaux->vna_other != *versym
2553 && vernaux->vna_next != 0)
2554 {
2555 /* Update the offset. */
2556 vna_offset += vernaux->vna_next;
2557
2558 vernaux = (vernaux->vna_next == 0
2559 ? NULL
2560 : gelf_getvernaux (verneed_data,
2561 vna_offset,
2562 &vernaux_mem));
2563 }
2564
2565 /* Check whether we found the version. */
2566 if (vernaux != NULL && vernaux->vna_other == *versym)
2567 /* Found it. */
2568 break;
2569
2570 vn_offset += verneed->vn_next;
2571 verneed = (verneed->vn_next == 0
2572 ? NULL
2573 : gelf_getverneed (verneed_data, vn_offset,
2574 &verneed_mem));
2575 }
2576
2577 if (vernaux != NULL && vernaux->vna_other == *versym)
2578 {
2579 printf ("@%s (%u)",
2580 elf_strptr (ebl->elf, verneed_stridx,
2581 vernaux->vna_name),
2582 (unsigned int) vernaux->vna_other);
2583 check_def = 0;
2584 }
2585 else if (unlikely (! is_nobits))
2586 error (0, 0, gettext ("bad dynamic symbol"));
2587 else
2588 check_def = 1;
2589 }
2590
2591 if (check_def && *versym != 0x8001)
2592 {
2593 /* We must test both. */
2594 size_t vd_offset = 0;
2595
2596 GElf_Verdef verdef_mem;
2597 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2598 &verdef_mem);
2599 while (verdef != NULL)
2600 {
2601 if (verdef->vd_ndx == (*versym & 0x7fff))
2602 /* Found the definition. */
2603 break;
2604
2605 vd_offset += verdef->vd_next;
2606 verdef = (verdef->vd_next == 0
2607 ? NULL
2608 : gelf_getverdef (verdef_data, vd_offset,
2609 &verdef_mem));
2610 }
2611
2612 if (verdef != NULL)
2613 {
2614 GElf_Verdaux verdaux_mem;
2615 GElf_Verdaux *verdaux
2616 = gelf_getverdaux (verdef_data,
2617 vd_offset + verdef->vd_aux,
2618 &verdaux_mem);
2619
2620 if (verdaux != NULL)
2621 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2622 elf_strptr (ebl->elf, verdef_stridx,
2623 verdaux->vda_name));
2624 }
2625 }
2626 }
2627 }
2628
2629 putchar_unlocked ('\n');
2630 }
2631 }
2632
2633
2634 /* Print version information. */
2635 static void
print_verinfo(Ebl * ebl)2636 print_verinfo (Ebl *ebl)
2637 {
2638 /* Find the version information sections. For this we have to
2639 search through the section table. */
2640 Elf_Scn *scn = NULL;
2641
2642 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2643 {
2644 /* Handle the section if it is part of the versioning handling. */
2645 GElf_Shdr shdr_mem;
2646 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2647
2648 if (likely (shdr != NULL))
2649 {
2650 if (shdr->sh_type == SHT_GNU_verneed)
2651 handle_verneed (ebl, scn, shdr);
2652 else if (shdr->sh_type == SHT_GNU_verdef)
2653 handle_verdef (ebl, scn, shdr);
2654 else if (shdr->sh_type == SHT_GNU_versym)
2655 handle_versym (ebl, scn, shdr);
2656 }
2657 }
2658 }
2659
2660
2661 static const char *
get_ver_flags(unsigned int flags)2662 get_ver_flags (unsigned int flags)
2663 {
2664 static char buf[32];
2665 char *endp;
2666
2667 if (flags == 0)
2668 return gettext ("none");
2669
2670 if (flags & VER_FLG_BASE)
2671 endp = stpcpy (buf, "BASE ");
2672 else
2673 endp = buf;
2674
2675 if (flags & VER_FLG_WEAK)
2676 {
2677 if (endp != buf)
2678 endp = stpcpy (endp, "| ");
2679
2680 endp = stpcpy (endp, "WEAK ");
2681 }
2682
2683 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2684 {
2685 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2686 buf[sizeof (buf) - 1] = '\0';
2687 }
2688
2689 return buf;
2690 }
2691
2692
2693 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2694 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2695 {
2696 int class = gelf_getclass (ebl->elf);
2697
2698 /* Get the data of the section. */
2699 Elf_Data *data = elf_getdata (scn, NULL);
2700 if (data == NULL)
2701 return;
2702
2703 /* Get the section header string table index. */
2704 size_t shstrndx;
2705 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2706 error (EXIT_FAILURE, 0,
2707 gettext ("cannot get section header string table index"));
2708
2709 GElf_Shdr glink_mem;
2710 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2711 &glink_mem);
2712 if (glink == NULL)
2713 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2714 elf_ndxscn (scn));
2715
2716 printf (ngettext ("\
2717 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2718 "\
2719 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2720 shdr->sh_info),
2721 (unsigned int) elf_ndxscn (scn),
2722 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2723 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2724 shdr->sh_offset,
2725 (unsigned int) shdr->sh_link,
2726 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2727
2728 unsigned int offset = 0;
2729 for (int cnt = shdr->sh_info; --cnt >= 0; )
2730 {
2731 /* Get the data at the next offset. */
2732 GElf_Verneed needmem;
2733 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2734 if (unlikely (need == NULL))
2735 break;
2736
2737 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2738 offset, (unsigned short int) need->vn_version,
2739 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2740 (unsigned short int) need->vn_cnt);
2741
2742 unsigned int auxoffset = offset + need->vn_aux;
2743 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2744 {
2745 GElf_Vernaux auxmem;
2746 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2747 if (unlikely (aux == NULL))
2748 break;
2749
2750 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2751 auxoffset,
2752 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2753 get_ver_flags (aux->vna_flags),
2754 (unsigned short int) aux->vna_other);
2755
2756 if (aux->vna_next == 0)
2757 break;
2758
2759 auxoffset += aux->vna_next;
2760 }
2761
2762 /* Find the next offset. */
2763 if (need->vn_next == 0)
2764 break;
2765
2766 offset += need->vn_next;
2767 }
2768 }
2769
2770
2771 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2772 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2773 {
2774 /* Get the data of the section. */
2775 Elf_Data *data = elf_getdata (scn, NULL);
2776 if (data == NULL)
2777 return;
2778
2779 /* Get the section header string table index. */
2780 size_t shstrndx;
2781 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2782 error (EXIT_FAILURE, 0,
2783 gettext ("cannot get section header string table index"));
2784
2785 GElf_Shdr glink_mem;
2786 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2787 &glink_mem);
2788 if (glink == NULL)
2789 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2790 elf_ndxscn (scn));
2791
2792 int class = gelf_getclass (ebl->elf);
2793 printf (ngettext ("\
2794 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2795 "\
2796 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2797 shdr->sh_info),
2798 (unsigned int) elf_ndxscn (scn),
2799 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2800 shdr->sh_info,
2801 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2802 shdr->sh_offset,
2803 (unsigned int) shdr->sh_link,
2804 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2805
2806 unsigned int offset = 0;
2807 for (int cnt = shdr->sh_info; --cnt >= 0; )
2808 {
2809 /* Get the data at the next offset. */
2810 GElf_Verdef defmem;
2811 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2812 if (unlikely (def == NULL))
2813 break;
2814
2815 unsigned int auxoffset = offset + def->vd_aux;
2816 GElf_Verdaux auxmem;
2817 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2818 if (unlikely (aux == NULL))
2819 break;
2820
2821 printf (gettext ("\
2822 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2823 offset, def->vd_version,
2824 get_ver_flags (def->vd_flags),
2825 def->vd_ndx,
2826 def->vd_cnt,
2827 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2828
2829 auxoffset += aux->vda_next;
2830 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2831 {
2832 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2833 if (unlikely (aux == NULL))
2834 break;
2835
2836 printf (gettext (" %#06x: Parent %d: %s\n"),
2837 auxoffset, cnt2,
2838 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2839
2840 if (aux->vda_next == 0)
2841 break;
2842
2843 auxoffset += aux->vda_next;
2844 }
2845
2846 /* Find the next offset. */
2847 if (def->vd_next == 0)
2848 break;
2849 offset += def->vd_next;
2850 }
2851 }
2852
2853
2854 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2855 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2856 {
2857 int class = gelf_getclass (ebl->elf);
2858 const char **vername;
2859 const char **filename;
2860
2861 /* Get the data of the section. */
2862 Elf_Data *data = elf_getdata (scn, NULL);
2863 if (data == NULL)
2864 return;
2865
2866 /* Get the section header string table index. */
2867 size_t shstrndx;
2868 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2869 error (EXIT_FAILURE, 0,
2870 gettext ("cannot get section header string table index"));
2871
2872 /* We have to find the version definition section and extract the
2873 version names. */
2874 Elf_Scn *defscn = NULL;
2875 Elf_Scn *needscn = NULL;
2876
2877 Elf_Scn *verscn = NULL;
2878 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2879 {
2880 GElf_Shdr vershdr_mem;
2881 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2882
2883 if (likely (vershdr != NULL))
2884 {
2885 if (vershdr->sh_type == SHT_GNU_verdef)
2886 defscn = verscn;
2887 else if (vershdr->sh_type == SHT_GNU_verneed)
2888 needscn = verscn;
2889 }
2890 }
2891
2892 size_t nvername;
2893 if (defscn != NULL || needscn != NULL)
2894 {
2895 /* We have a version information (better should have). Now get
2896 the version names. First find the maximum version number. */
2897 nvername = 0;
2898 if (defscn != NULL)
2899 {
2900 /* Run through the version definitions and find the highest
2901 index. */
2902 unsigned int offset = 0;
2903 Elf_Data *defdata;
2904 GElf_Shdr defshdrmem;
2905 GElf_Shdr *defshdr;
2906
2907 defdata = elf_getdata (defscn, NULL);
2908 if (unlikely (defdata == NULL))
2909 return;
2910
2911 defshdr = gelf_getshdr (defscn, &defshdrmem);
2912 if (unlikely (defshdr == NULL))
2913 return;
2914
2915 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2916 {
2917 GElf_Verdef defmem;
2918 GElf_Verdef *def;
2919
2920 /* Get the data at the next offset. */
2921 def = gelf_getverdef (defdata, offset, &defmem);
2922 if (unlikely (def == NULL))
2923 break;
2924
2925 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2926
2927 if (def->vd_next == 0)
2928 break;
2929 offset += def->vd_next;
2930 }
2931 }
2932 if (needscn != NULL)
2933 {
2934 unsigned int offset = 0;
2935 Elf_Data *needdata;
2936 GElf_Shdr needshdrmem;
2937 GElf_Shdr *needshdr;
2938
2939 needdata = elf_getdata (needscn, NULL);
2940 if (unlikely (needdata == NULL))
2941 return;
2942
2943 needshdr = gelf_getshdr (needscn, &needshdrmem);
2944 if (unlikely (needshdr == NULL))
2945 return;
2946
2947 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2948 {
2949 GElf_Verneed needmem;
2950 GElf_Verneed *need;
2951 unsigned int auxoffset;
2952 int cnt2;
2953
2954 /* Get the data at the next offset. */
2955 need = gelf_getverneed (needdata, offset, &needmem);
2956 if (unlikely (need == NULL))
2957 break;
2958
2959 /* Run through the auxiliary entries. */
2960 auxoffset = offset + need->vn_aux;
2961 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2962 {
2963 GElf_Vernaux auxmem;
2964 GElf_Vernaux *aux;
2965
2966 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2967 if (unlikely (aux == NULL))
2968 break;
2969
2970 nvername = MAX (nvername,
2971 (size_t) (aux->vna_other & 0x7fff));
2972
2973 if (aux->vna_next == 0)
2974 break;
2975 auxoffset += aux->vna_next;
2976 }
2977
2978 if (need->vn_next == 0)
2979 break;
2980 offset += need->vn_next;
2981 }
2982 }
2983
2984 /* This is the number of versions we know about. */
2985 ++nvername;
2986
2987 /* Allocate the array. */
2988 vername = (const char **) alloca (nvername * sizeof (const char *));
2989 memset(vername, 0, nvername * sizeof (const char *));
2990 filename = (const char **) alloca (nvername * sizeof (const char *));
2991 memset(filename, 0, nvername * sizeof (const char *));
2992
2993 /* Run through the data structures again and collect the strings. */
2994 if (defscn != NULL)
2995 {
2996 /* Run through the version definitions and find the highest
2997 index. */
2998 unsigned int offset = 0;
2999 Elf_Data *defdata;
3000 GElf_Shdr defshdrmem;
3001 GElf_Shdr *defshdr;
3002
3003 defdata = elf_getdata (defscn, NULL);
3004 if (unlikely (defdata == NULL))
3005 return;
3006
3007 defshdr = gelf_getshdr (defscn, &defshdrmem);
3008 if (unlikely (defshdr == NULL))
3009 return;
3010
3011 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3012 {
3013
3014 /* Get the data at the next offset. */
3015 GElf_Verdef defmem;
3016 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3017 if (unlikely (def == NULL))
3018 break;
3019
3020 GElf_Verdaux auxmem;
3021 GElf_Verdaux *aux = gelf_getverdaux (defdata,
3022 offset + def->vd_aux,
3023 &auxmem);
3024 if (unlikely (aux == NULL))
3025 break;
3026
3027 vername[def->vd_ndx & 0x7fff]
3028 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3029 filename[def->vd_ndx & 0x7fff] = NULL;
3030
3031 if (def->vd_next == 0)
3032 break;
3033 offset += def->vd_next;
3034 }
3035 }
3036 if (needscn != NULL)
3037 {
3038 unsigned int offset = 0;
3039
3040 Elf_Data *needdata = elf_getdata (needscn, NULL);
3041 GElf_Shdr needshdrmem;
3042 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3043 if (unlikely (needdata == NULL || needshdr == NULL))
3044 return;
3045
3046 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3047 {
3048 /* Get the data at the next offset. */
3049 GElf_Verneed needmem;
3050 GElf_Verneed *need = gelf_getverneed (needdata, offset,
3051 &needmem);
3052 if (unlikely (need == NULL))
3053 break;
3054
3055 /* Run through the auxiliary entries. */
3056 unsigned int auxoffset = offset + need->vn_aux;
3057 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3058 {
3059 GElf_Vernaux auxmem;
3060 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3061 &auxmem);
3062 if (unlikely (aux == NULL))
3063 break;
3064
3065 vername[aux->vna_other & 0x7fff]
3066 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3067 filename[aux->vna_other & 0x7fff]
3068 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3069
3070 if (aux->vna_next == 0)
3071 break;
3072 auxoffset += aux->vna_next;
3073 }
3074
3075 if (need->vn_next == 0)
3076 break;
3077 offset += need->vn_next;
3078 }
3079 }
3080 }
3081 else
3082 {
3083 vername = NULL;
3084 nvername = 1;
3085 filename = NULL;
3086 }
3087
3088 GElf_Shdr glink_mem;
3089 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3090 &glink_mem);
3091 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3092 if (glink == NULL)
3093 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
3094 elf_ndxscn (scn));
3095
3096 /* Print the header. */
3097 printf (ngettext ("\
3098 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3099 "\
3100 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3101 shdr->sh_size / sh_entsize),
3102 (unsigned int) elf_ndxscn (scn),
3103 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3104 (int) (shdr->sh_size / sh_entsize),
3105 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3106 shdr->sh_offset,
3107 (unsigned int) shdr->sh_link,
3108 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3109
3110 /* Now we can finally look at the actual contents of this section. */
3111 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3112 {
3113 if (cnt % 2 == 0)
3114 printf ("\n %4d:", cnt);
3115
3116 GElf_Versym symmem;
3117 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3118 if (sym == NULL)
3119 break;
3120
3121 switch (*sym)
3122 {
3123 ssize_t n;
3124 case 0:
3125 fputs_unlocked (gettext (" 0 *local* "),
3126 stdout);
3127 break;
3128
3129 case 1:
3130 fputs_unlocked (gettext (" 1 *global* "),
3131 stdout);
3132 break;
3133
3134 default:
3135 n = printf ("%4d%c%s",
3136 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3137 (vername != NULL
3138 && (unsigned int) (*sym & 0x7fff) < nvername)
3139 ? vername[*sym & 0x7fff] : "???");
3140 if ((unsigned int) (*sym & 0x7fff) < nvername
3141 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3142 n += printf ("(%s)", filename[*sym & 0x7fff]);
3143 printf ("%*s", MAX (0, 33 - (int) n), " ");
3144 break;
3145 }
3146 }
3147 putchar_unlocked ('\n');
3148 }
3149
3150
3151 static void
print_hash_info(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx,uint_fast32_t maxlength,Elf32_Word nbucket,uint_fast32_t nsyms,uint32_t * lengths,const char * extrastr)3152 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3153 uint_fast32_t maxlength, Elf32_Word nbucket,
3154 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3155 {
3156 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3157
3158 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3159 ++counts[lengths[cnt]];
3160
3161 GElf_Shdr glink_mem;
3162 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3163 shdr->sh_link),
3164 &glink_mem);
3165 if (glink == NULL)
3166 {
3167 error (0, 0, gettext ("invalid sh_link value in section %zu"),
3168 elf_ndxscn (scn));
3169 return;
3170 }
3171
3172 printf (ngettext ("\
3173 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3174 "\
3175 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3176 nbucket),
3177 (unsigned int) elf_ndxscn (scn),
3178 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3179 (int) nbucket,
3180 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3181 shdr->sh_addr,
3182 shdr->sh_offset,
3183 (unsigned int) shdr->sh_link,
3184 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3185
3186 if (extrastr != NULL)
3187 fputs (extrastr, stdout);
3188
3189 if (likely (nbucket > 0))
3190 {
3191 uint64_t success = 0;
3192
3193 /* xgettext:no-c-format */
3194 fputs_unlocked (gettext ("\
3195 Length Number % of total Coverage\n"), stdout);
3196 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
3197 counts[0], (counts[0] * 100.0) / nbucket);
3198
3199 uint64_t nzero_counts = 0;
3200 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3201 {
3202 nzero_counts += counts[cnt] * cnt;
3203 printf (gettext ("\
3204 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3205 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3206 (nzero_counts * 100.0) / nsyms);
3207 }
3208
3209 Elf32_Word acc = 0;
3210 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3211 {
3212 acc += cnt;
3213 success += counts[cnt] * acc;
3214 }
3215
3216 printf (gettext ("\
3217 Average number of tests: successful lookup: %f\n\
3218 unsuccessful lookup: %f\n"),
3219 (double) success / (double) nzero_counts,
3220 (double) nzero_counts / (double) nbucket);
3221 }
3222
3223 free (counts);
3224 }
3225
3226
3227 /* This function handles the traditional System V-style hash table format. */
3228 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3229 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3230 {
3231 Elf_Data *data = elf_getdata (scn, NULL);
3232 if (unlikely (data == NULL))
3233 {
3234 error (0, 0, gettext ("cannot get data for section %d: %s"),
3235 (int) elf_ndxscn (scn), elf_errmsg (-1));
3236 return;
3237 }
3238
3239 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3240 {
3241 invalid_data:
3242 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3243 (int) elf_ndxscn (scn));
3244 return;
3245 }
3246
3247 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3248 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3249
3250 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3251 if (used_buf > data->d_size)
3252 goto invalid_data;
3253
3254 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3255 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3256
3257 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3258
3259 uint_fast32_t maxlength = 0;
3260 uint_fast32_t nsyms = 0;
3261 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3262 {
3263 Elf32_Word inner = bucket[cnt];
3264 Elf32_Word chain_len = 0;
3265 while (inner > 0 && inner < nchain)
3266 {
3267 ++nsyms;
3268 ++chain_len;
3269 if (chain_len > nchain)
3270 {
3271 error (0, 0, gettext ("invalid chain in sysv.hash section %d"),
3272 (int) elf_ndxscn (scn));
3273 free (lengths);
3274 return;
3275 }
3276 if (maxlength < ++lengths[cnt])
3277 ++maxlength;
3278
3279 inner = chain[inner];
3280 }
3281 }
3282
3283 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3284 lengths, NULL);
3285
3286 free (lengths);
3287 }
3288
3289
3290 /* This function handles the incorrect, System V-style hash table
3291 format some 64-bit architectures use. */
3292 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3293 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3294 {
3295 Elf_Data *data = elf_getdata (scn, NULL);
3296 if (unlikely (data == NULL))
3297 {
3298 error (0, 0, gettext ("cannot get data for section %d: %s"),
3299 (int) elf_ndxscn (scn), elf_errmsg (-1));
3300 return;
3301 }
3302
3303 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3304 {
3305 invalid_data:
3306 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3307 (int) elf_ndxscn (scn));
3308 return;
3309 }
3310
3311 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3312 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3313
3314 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3315 if (maxwords < 2
3316 || maxwords - 2 < nbucket
3317 || maxwords - 2 - nbucket < nchain)
3318 goto invalid_data;
3319
3320 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3321 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3322
3323 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3324
3325 uint_fast32_t maxlength = 0;
3326 uint_fast32_t nsyms = 0;
3327 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3328 {
3329 Elf64_Xword inner = bucket[cnt];
3330 Elf64_Xword chain_len = 0;
3331 while (inner > 0 && inner < nchain)
3332 {
3333 ++nsyms;
3334 ++chain_len;
3335 if (chain_len > nchain)
3336 {
3337 error (0, 0, gettext ("invalid chain in sysv.hash64 section %d"),
3338 (int) elf_ndxscn (scn));
3339 free (lengths);
3340 return;
3341 }
3342 if (maxlength < ++lengths[cnt])
3343 ++maxlength;
3344
3345 inner = chain[inner];
3346 }
3347 }
3348
3349 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3350 lengths, NULL);
3351
3352 free (lengths);
3353 }
3354
3355
3356 /* This function handles the GNU-style hash table format. */
3357 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3358 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3359 {
3360 uint32_t *lengths = NULL;
3361 Elf_Data *data = elf_getdata (scn, NULL);
3362 if (unlikely (data == NULL))
3363 {
3364 error (0, 0, gettext ("cannot get data for section %d: %s"),
3365 (int) elf_ndxscn (scn), elf_errmsg (-1));
3366 return;
3367 }
3368
3369 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3370 {
3371 invalid_data:
3372 free (lengths);
3373 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3374 (int) elf_ndxscn (scn));
3375 return;
3376 }
3377
3378 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3379 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3380
3381 /* Next comes the size of the bitmap. It's measured in words for
3382 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3383 64 bit archs. There is always a bloom filter present, so zero is
3384 an invalid value. */
3385 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3386 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3387 bitmask_words *= 2;
3388
3389 if (bitmask_words == 0)
3390 goto invalid_data;
3391
3392 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3393
3394 /* Is there still room for the sym chain?
3395 Use uint64_t calculation to prevent 32bit overlow. */
3396 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3397 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3398 if (used_buf > data->d_size)
3399 goto invalid_data;
3400
3401 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3402
3403 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3404 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3405 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3406 + nbucket];
3407
3408 /* Compute distribution of chain lengths. */
3409 uint_fast32_t maxlength = 0;
3410 uint_fast32_t nsyms = 0;
3411 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3412 if (bucket[cnt] != 0)
3413 {
3414 Elf32_Word inner = bucket[cnt] - symbias;
3415 do
3416 {
3417 ++nsyms;
3418 if (maxlength < ++lengths[cnt])
3419 ++maxlength;
3420 if (inner >= max_nsyms)
3421 goto invalid_data;
3422 }
3423 while ((chain[inner++] & 1) == 0);
3424 }
3425
3426 /* Count bits in bitmask. */
3427 uint_fast32_t nbits = 0;
3428 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3429 {
3430 uint_fast32_t word = bitmask[cnt];
3431
3432 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3433 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3434 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3435 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3436 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3437 }
3438
3439 char *str;
3440 if (unlikely (asprintf (&str, gettext ("\
3441 Symbol Bias: %u\n\
3442 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3443 (unsigned int) symbias,
3444 bitmask_words * sizeof (Elf32_Word),
3445 ((nbits * 100 + 50)
3446 / (uint_fast32_t) (bitmask_words
3447 * sizeof (Elf32_Word) * 8)),
3448 (unsigned int) shift) == -1))
3449 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3450
3451 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3452 lengths, str);
3453
3454 free (str);
3455 free (lengths);
3456 }
3457
3458
3459 /* Find the symbol table(s). For this we have to search through the
3460 section table. */
3461 static void
handle_hash(Ebl * ebl)3462 handle_hash (Ebl *ebl)
3463 {
3464 /* Get the section header string table index. */
3465 size_t shstrndx;
3466 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3467 error (EXIT_FAILURE, 0,
3468 gettext ("cannot get section header string table index"));
3469
3470 Elf_Scn *scn = NULL;
3471 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3472 {
3473 /* Handle the section if it is a symbol table. */
3474 GElf_Shdr shdr_mem;
3475 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3476
3477 if (likely (shdr != NULL))
3478 {
3479 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3480 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3481 {
3482 if (elf_compress (scn, 0, 0) < 0)
3483 printf ("WARNING: %s [%zd]\n",
3484 gettext ("Couldn't uncompress section"),
3485 elf_ndxscn (scn));
3486 shdr = gelf_getshdr (scn, &shdr_mem);
3487 if (unlikely (shdr == NULL))
3488 error (EXIT_FAILURE, 0,
3489 gettext ("cannot get section [%zd] header: %s"),
3490 elf_ndxscn (scn), elf_errmsg (-1));
3491 }
3492
3493 if (shdr->sh_type == SHT_HASH)
3494 {
3495 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3496 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3497 else
3498 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3499 }
3500 else if (shdr->sh_type == SHT_GNU_HASH)
3501 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3502 }
3503 }
3504 }
3505
3506
3507 static void
print_liblist(Ebl * ebl)3508 print_liblist (Ebl *ebl)
3509 {
3510 /* Find the library list sections. For this we have to search
3511 through the section table. */
3512 Elf_Scn *scn = NULL;
3513
3514 /* Get the section header string table index. */
3515 size_t shstrndx;
3516 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3517 error (EXIT_FAILURE, 0,
3518 gettext ("cannot get section header string table index"));
3519
3520 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3521 {
3522 GElf_Shdr shdr_mem;
3523 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3524
3525 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3526 {
3527 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3528 int nentries = shdr->sh_size / sh_entsize;
3529 printf (ngettext ("\
3530 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3531 "\
3532 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3533 nentries),
3534 elf_ndxscn (scn),
3535 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3536 shdr->sh_offset,
3537 nentries);
3538
3539 Elf_Data *data = elf_getdata (scn, NULL);
3540 if (data == NULL)
3541 return;
3542
3543 puts (gettext ("\
3544 Library Time Stamp Checksum Version Flags"));
3545
3546 for (int cnt = 0; cnt < nentries; ++cnt)
3547 {
3548 GElf_Lib lib_mem;
3549 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3550 if (unlikely (lib == NULL))
3551 continue;
3552
3553 time_t t = (time_t) lib->l_time_stamp;
3554 struct tm *tm = gmtime (&t);
3555 if (unlikely (tm == NULL))
3556 continue;
3557
3558 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3559 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3560 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3561 tm->tm_hour, tm->tm_min, tm->tm_sec,
3562 (unsigned int) lib->l_checksum,
3563 (unsigned int) lib->l_version,
3564 (unsigned int) lib->l_flags);
3565 }
3566 }
3567 }
3568 }
3569
3570 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3571 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3572 {
3573 /* Find the object attributes sections. For this we have to search
3574 through the section table. */
3575 Elf_Scn *scn = NULL;
3576
3577 /* Get the section header string table index. */
3578 size_t shstrndx;
3579 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3580 error (EXIT_FAILURE, 0,
3581 gettext ("cannot get section header string table index"));
3582
3583 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3584 {
3585 GElf_Shdr shdr_mem;
3586 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3587
3588 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3589 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3590 || ehdr->e_machine != EM_ARM)
3591 && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
3592 || ehdr->e_machine != EM_CSKY)))
3593 continue;
3594
3595 printf (gettext ("\
3596 \nObject attributes section [%2zu] '%s' of %" PRIu64
3597 " bytes at offset %#0" PRIx64 ":\n"),
3598 elf_ndxscn (scn),
3599 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3600 shdr->sh_size, shdr->sh_offset);
3601
3602 Elf_Data *data = elf_rawdata (scn, NULL);
3603 if (unlikely (data == NULL || data->d_size == 0))
3604 return;
3605
3606 const unsigned char *p = data->d_buf;
3607
3608 /* There is only one 'version', A. */
3609 if (unlikely (*p++ != 'A'))
3610 return;
3611
3612 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3613
3614 inline size_t left (void)
3615 {
3616 return (const unsigned char *) data->d_buf + data->d_size - p;
3617 }
3618
3619 /* Loop over the sections. */
3620 while (left () >= 4)
3621 {
3622 /* Section length. */
3623 uint32_t len;
3624 memcpy (&len, p, sizeof len);
3625
3626 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3627 CONVERT (len);
3628
3629 if (unlikely (len > left ()))
3630 break;
3631
3632 /* Section vendor name. */
3633 const unsigned char *name = p + sizeof len;
3634 p += len;
3635
3636 unsigned const char *q = memchr (name, '\0', len);
3637 if (unlikely (q == NULL))
3638 break;
3639 ++q;
3640
3641 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3642
3643 bool gnu_vendor = (q - name == sizeof "gnu"
3644 && !memcmp (name, "gnu", sizeof "gnu"));
3645
3646 /* Loop over subsections. */
3647 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3648 || gnu_vendor)
3649 while (q < p)
3650 {
3651 const unsigned char *const sub = q;
3652
3653 unsigned int subsection_tag;
3654 get_uleb128 (subsection_tag, q, p);
3655 if (unlikely (q >= p))
3656 break;
3657
3658 uint32_t subsection_len;
3659 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3660 break;
3661
3662 memcpy (&subsection_len, q, sizeof subsection_len);
3663
3664 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3665 CONVERT (subsection_len);
3666
3667 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3668 if (unlikely (subsection_len == 0
3669 || subsection_len >= (uint32_t) PTRDIFF_MAX
3670 || p - sub < (ptrdiff_t) subsection_len))
3671 break;
3672
3673 const unsigned char *r = q + sizeof subsection_len;
3674 q = sub + subsection_len;
3675
3676 switch (subsection_tag)
3677 {
3678 default:
3679 /* Unknown subsection, print and skip. */
3680 printf (gettext (" %-4u %12" PRIu32 "\n"),
3681 subsection_tag, subsection_len);
3682 break;
3683
3684 case 1: /* Tag_File */
3685 printf (gettext (" File: %11" PRIu32 "\n"),
3686 subsection_len);
3687
3688 while (r < q)
3689 {
3690 unsigned int tag;
3691 get_uleb128 (tag, r, q);
3692 if (unlikely (r >= q))
3693 break;
3694
3695 /* GNU style tags have either a uleb128 value,
3696 when lowest bit is not set, or a string
3697 when the lowest bit is set.
3698 "compatibility" (32) is special. It has
3699 both a string and a uleb128 value. For
3700 non-gnu we assume 6 till 31 only take ints.
3701 XXX see arm backend, do we need a separate
3702 hook? */
3703 uint64_t value = 0;
3704 const char *string = NULL;
3705 if (tag == 32 || (tag & 1) == 0
3706 || (! gnu_vendor && (tag > 5 && tag < 32)))
3707 {
3708 get_uleb128 (value, r, q);
3709 if (r > q)
3710 break;
3711 }
3712 if (tag == 32
3713 || ((tag & 1) != 0
3714 && (gnu_vendor
3715 || (! gnu_vendor && tag > 32)))
3716 || (! gnu_vendor && tag > 3 && tag < 6))
3717 {
3718 string = (const char *) r;
3719 r = memchr (r, '\0', q - r);
3720 if (r == NULL)
3721 break;
3722 ++r;
3723 }
3724
3725 const char *tag_name = NULL;
3726 const char *value_name = NULL;
3727 ebl_check_object_attribute (ebl, (const char *) name,
3728 tag, value,
3729 &tag_name, &value_name);
3730
3731 if (tag_name != NULL)
3732 {
3733 if (tag == 32)
3734 printf (gettext (" %s: %" PRId64 ", %s\n"),
3735 tag_name, value, string);
3736 else if (string == NULL && value_name == NULL)
3737 printf (gettext (" %s: %" PRId64 "\n"),
3738 tag_name, value);
3739 else
3740 printf (gettext (" %s: %s\n"),
3741 tag_name, string ?: value_name);
3742 }
3743 else
3744 {
3745 /* For "gnu" vendor 32 "compatibility" has
3746 already been handled above. */
3747 assert (tag != 32
3748 || strcmp ((const char *) name, "gnu"));
3749 if (string == NULL)
3750 printf (gettext (" %u: %" PRId64 "\n"),
3751 tag, value);
3752 else
3753 printf (gettext (" %u: %s\n"),
3754 tag, string);
3755 }
3756 }
3757 }
3758 }
3759 }
3760 }
3761 }
3762
3763
3764 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3765 print_dwarf_addr (Dwfl_Module *dwflmod,
3766 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3767 {
3768 /* See if there is a name we can give for this address. */
3769 GElf_Sym sym;
3770 GElf_Off off = 0;
3771 const char *name = (print_address_names && ! print_unresolved_addresses)
3772 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3773 : NULL;
3774
3775 const char *scn;
3776 if (print_unresolved_addresses)
3777 {
3778 address = raw;
3779 scn = NULL;
3780 }
3781 else
3782 {
3783 /* Relativize the address. */
3784 int n = dwfl_module_relocations (dwflmod);
3785 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3786
3787 /* In an ET_REL file there is a section name to refer to. */
3788 scn = (i < 0 ? NULL
3789 : dwfl_module_relocation_info (dwflmod, i, NULL));
3790 }
3791
3792 if ((name != NULL
3793 ? (off != 0
3794 ? (scn != NULL
3795 ? (address_size == 0
3796 ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3797 scn, address, name, off)
3798 : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3799 scn, 2 + address_size * 2, address,
3800 name, off))
3801 : (address_size == 0
3802 ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3803 address, name, off)
3804 : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3805 2 + address_size * 2, address,
3806 name, off)))
3807 : (scn != NULL
3808 ? (address_size == 0
3809 ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3810 : printf ("%s+%#0*" PRIx64 " <%s>",
3811 scn, 2 + address_size * 2, address, name))
3812 : (address_size == 0
3813 ? printf ("%#" PRIx64 " <%s>", address, name)
3814 : printf ("%#0*" PRIx64 " <%s>",
3815 2 + address_size * 2, address, name))))
3816 : (scn != NULL
3817 ? (address_size == 0
3818 ? printf ("%s+%#" PRIx64, scn, address)
3819 : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3820 : (address_size == 0
3821 ? printf ("%#" PRIx64, address)
3822 : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3823 error (EXIT_FAILURE, 0, _("sprintf failure"));
3824 }
3825
3826
3827 static const char *
dwarf_tag_string(unsigned int tag)3828 dwarf_tag_string (unsigned int tag)
3829 {
3830 switch (tag)
3831 {
3832 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3833 DWARF_ALL_KNOWN_DW_TAG
3834 #undef DWARF_ONE_KNOWN_DW_TAG
3835 default:
3836 return NULL;
3837 }
3838 }
3839
3840
3841 static const char *
dwarf_attr_string(unsigned int attrnum)3842 dwarf_attr_string (unsigned int attrnum)
3843 {
3844 switch (attrnum)
3845 {
3846 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3847 DWARF_ALL_KNOWN_DW_AT
3848 #undef DWARF_ONE_KNOWN_DW_AT
3849 default:
3850 return NULL;
3851 }
3852 }
3853
3854
3855 static const char *
dwarf_form_string(unsigned int form)3856 dwarf_form_string (unsigned int form)
3857 {
3858 switch (form)
3859 {
3860 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3861 DWARF_ALL_KNOWN_DW_FORM
3862 #undef DWARF_ONE_KNOWN_DW_FORM
3863 default:
3864 return NULL;
3865 }
3866 }
3867
3868
3869 static const char *
dwarf_lang_string(unsigned int lang)3870 dwarf_lang_string (unsigned int lang)
3871 {
3872 switch (lang)
3873 {
3874 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3875 DWARF_ALL_KNOWN_DW_LANG
3876 #undef DWARF_ONE_KNOWN_DW_LANG
3877 default:
3878 return NULL;
3879 }
3880 }
3881
3882
3883 static const char *
dwarf_inline_string(unsigned int code)3884 dwarf_inline_string (unsigned int code)
3885 {
3886 static const char *const known[] =
3887 {
3888 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3889 DWARF_ALL_KNOWN_DW_INL
3890 #undef DWARF_ONE_KNOWN_DW_INL
3891 };
3892
3893 if (likely (code < sizeof (known) / sizeof (known[0])))
3894 return known[code];
3895
3896 return NULL;
3897 }
3898
3899
3900 static const char *
dwarf_encoding_string(unsigned int code)3901 dwarf_encoding_string (unsigned int code)
3902 {
3903 static const char *const known[] =
3904 {
3905 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3906 DWARF_ALL_KNOWN_DW_ATE
3907 #undef DWARF_ONE_KNOWN_DW_ATE
3908 };
3909
3910 if (likely (code < sizeof (known) / sizeof (known[0])))
3911 return known[code];
3912
3913 return NULL;
3914 }
3915
3916
3917 static const char *
dwarf_access_string(unsigned int code)3918 dwarf_access_string (unsigned int code)
3919 {
3920 static const char *const known[] =
3921 {
3922 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3923 DWARF_ALL_KNOWN_DW_ACCESS
3924 #undef DWARF_ONE_KNOWN_DW_ACCESS
3925 };
3926
3927 if (likely (code < sizeof (known) / sizeof (known[0])))
3928 return known[code];
3929
3930 return NULL;
3931 }
3932
3933
3934 static const char *
dwarf_defaulted_string(unsigned int code)3935 dwarf_defaulted_string (unsigned int code)
3936 {
3937 static const char *const known[] =
3938 {
3939 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3940 DWARF_ALL_KNOWN_DW_DEFAULTED
3941 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3942 };
3943
3944 if (likely (code < sizeof (known) / sizeof (known[0])))
3945 return known[code];
3946
3947 return NULL;
3948 }
3949
3950
3951 static const char *
dwarf_visibility_string(unsigned int code)3952 dwarf_visibility_string (unsigned int code)
3953 {
3954 static const char *const known[] =
3955 {
3956 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3957 DWARF_ALL_KNOWN_DW_VIS
3958 #undef DWARF_ONE_KNOWN_DW_VIS
3959 };
3960
3961 if (likely (code < sizeof (known) / sizeof (known[0])))
3962 return known[code];
3963
3964 return NULL;
3965 }
3966
3967
3968 static const char *
dwarf_virtuality_string(unsigned int code)3969 dwarf_virtuality_string (unsigned int code)
3970 {
3971 static const char *const known[] =
3972 {
3973 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3974 DWARF_ALL_KNOWN_DW_VIRTUALITY
3975 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3976 };
3977
3978 if (likely (code < sizeof (known) / sizeof (known[0])))
3979 return known[code];
3980
3981 return NULL;
3982 }
3983
3984
3985 static const char *
dwarf_identifier_case_string(unsigned int code)3986 dwarf_identifier_case_string (unsigned int code)
3987 {
3988 static const char *const known[] =
3989 {
3990 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3991 DWARF_ALL_KNOWN_DW_ID
3992 #undef DWARF_ONE_KNOWN_DW_ID
3993 };
3994
3995 if (likely (code < sizeof (known) / sizeof (known[0])))
3996 return known[code];
3997
3998 return NULL;
3999 }
4000
4001
4002 static const char *
dwarf_calling_convention_string(unsigned int code)4003 dwarf_calling_convention_string (unsigned int code)
4004 {
4005 static const char *const known[] =
4006 {
4007 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4008 DWARF_ALL_KNOWN_DW_CC
4009 #undef DWARF_ONE_KNOWN_DW_CC
4010 };
4011
4012 if (likely (code < sizeof (known) / sizeof (known[0])))
4013 return known[code];
4014
4015 return NULL;
4016 }
4017
4018
4019 static const char *
dwarf_ordering_string(unsigned int code)4020 dwarf_ordering_string (unsigned int code)
4021 {
4022 static const char *const known[] =
4023 {
4024 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4025 DWARF_ALL_KNOWN_DW_ORD
4026 #undef DWARF_ONE_KNOWN_DW_ORD
4027 };
4028
4029 if (likely (code < sizeof (known) / sizeof (known[0])))
4030 return known[code];
4031
4032 return NULL;
4033 }
4034
4035
4036 static const char *
dwarf_discr_list_string(unsigned int code)4037 dwarf_discr_list_string (unsigned int code)
4038 {
4039 static const char *const known[] =
4040 {
4041 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4042 DWARF_ALL_KNOWN_DW_DSC
4043 #undef DWARF_ONE_KNOWN_DW_DSC
4044 };
4045
4046 if (likely (code < sizeof (known) / sizeof (known[0])))
4047 return known[code];
4048
4049 return NULL;
4050 }
4051
4052
4053 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4054 dwarf_locexpr_opcode_string (unsigned int code)
4055 {
4056 static const char *const known[] =
4057 {
4058 /* Normally we can't affort building huge table of 64K entries,
4059 most of them zero, just because there are a couple defined
4060 values at the far end. In case of opcodes, it's OK. */
4061 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4062 DWARF_ALL_KNOWN_DW_OP
4063 #undef DWARF_ONE_KNOWN_DW_OP
4064 };
4065
4066 if (likely (code < sizeof (known) / sizeof (known[0])))
4067 return known[code];
4068
4069 return NULL;
4070 }
4071
4072
4073 static const char *
dwarf_unit_string(unsigned int type)4074 dwarf_unit_string (unsigned int type)
4075 {
4076 switch (type)
4077 {
4078 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4079 DWARF_ALL_KNOWN_DW_UT
4080 #undef DWARF_ONE_KNOWN_DW_UT
4081 default:
4082 return NULL;
4083 }
4084 }
4085
4086
4087 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4088 dwarf_range_list_encoding_string (unsigned int kind)
4089 {
4090 switch (kind)
4091 {
4092 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4093 DWARF_ALL_KNOWN_DW_RLE
4094 #undef DWARF_ONE_KNOWN_DW_RLE
4095 default:
4096 return NULL;
4097 }
4098 }
4099
4100
4101 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4102 dwarf_loc_list_encoding_string (unsigned int kind)
4103 {
4104 switch (kind)
4105 {
4106 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4107 DWARF_ALL_KNOWN_DW_LLE
4108 #undef DWARF_ONE_KNOWN_DW_LLE
4109 default:
4110 return NULL;
4111 }
4112 }
4113
4114
4115 static const char *
dwarf_line_content_description_string(unsigned int kind)4116 dwarf_line_content_description_string (unsigned int kind)
4117 {
4118 switch (kind)
4119 {
4120 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4121 DWARF_ALL_KNOWN_DW_LNCT
4122 #undef DWARF_ONE_KNOWN_DW_LNCT
4123 default:
4124 return NULL;
4125 }
4126 }
4127
4128
4129 /* Used by all dwarf_foo_name functions. */
4130 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4131 string_or_unknown (const char *known, unsigned int code,
4132 unsigned int lo_user, unsigned int hi_user,
4133 bool print_unknown_num)
4134 {
4135 static char unknown_buf[20];
4136
4137 if (likely (known != NULL))
4138 return known;
4139
4140 if (lo_user != 0 && code >= lo_user && code <= hi_user)
4141 {
4142 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4143 code - lo_user);
4144 return unknown_buf;
4145 }
4146
4147 if (print_unknown_num)
4148 {
4149 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4150 return unknown_buf;
4151 }
4152
4153 return "???";
4154 }
4155
4156
4157 static const char *
dwarf_tag_name(unsigned int tag)4158 dwarf_tag_name (unsigned int tag)
4159 {
4160 const char *ret = dwarf_tag_string (tag);
4161 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4162 }
4163
4164 static const char *
dwarf_attr_name(unsigned int attr)4165 dwarf_attr_name (unsigned int attr)
4166 {
4167 const char *ret = dwarf_attr_string (attr);
4168 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4169 }
4170
4171
4172 static const char *
dwarf_form_name(unsigned int form)4173 dwarf_form_name (unsigned int form)
4174 {
4175 const char *ret = dwarf_form_string (form);
4176 return string_or_unknown (ret, form, 0, 0, true);
4177 }
4178
4179
4180 static const char *
dwarf_lang_name(unsigned int lang)4181 dwarf_lang_name (unsigned int lang)
4182 {
4183 const char *ret = dwarf_lang_string (lang);
4184 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4185 }
4186
4187
4188 static const char *
dwarf_inline_name(unsigned int code)4189 dwarf_inline_name (unsigned int code)
4190 {
4191 const char *ret = dwarf_inline_string (code);
4192 return string_or_unknown (ret, code, 0, 0, false);
4193 }
4194
4195
4196 static const char *
dwarf_encoding_name(unsigned int code)4197 dwarf_encoding_name (unsigned int code)
4198 {
4199 const char *ret = dwarf_encoding_string (code);
4200 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4201 }
4202
4203
4204 static const char *
dwarf_access_name(unsigned int code)4205 dwarf_access_name (unsigned int code)
4206 {
4207 const char *ret = dwarf_access_string (code);
4208 return string_or_unknown (ret, code, 0, 0, false);
4209 }
4210
4211
4212 static const char *
dwarf_defaulted_name(unsigned int code)4213 dwarf_defaulted_name (unsigned int code)
4214 {
4215 const char *ret = dwarf_defaulted_string (code);
4216 return string_or_unknown (ret, code, 0, 0, false);
4217 }
4218
4219
4220 static const char *
dwarf_visibility_name(unsigned int code)4221 dwarf_visibility_name (unsigned int code)
4222 {
4223 const char *ret = dwarf_visibility_string (code);
4224 return string_or_unknown (ret, code, 0, 0, false);
4225 }
4226
4227
4228 static const char *
dwarf_virtuality_name(unsigned int code)4229 dwarf_virtuality_name (unsigned int code)
4230 {
4231 const char *ret = dwarf_virtuality_string (code);
4232 return string_or_unknown (ret, code, 0, 0, false);
4233 }
4234
4235
4236 static const char *
dwarf_identifier_case_name(unsigned int code)4237 dwarf_identifier_case_name (unsigned int code)
4238 {
4239 const char *ret = dwarf_identifier_case_string (code);
4240 return string_or_unknown (ret, code, 0, 0, false);
4241 }
4242
4243
4244 static const char *
dwarf_calling_convention_name(unsigned int code)4245 dwarf_calling_convention_name (unsigned int code)
4246 {
4247 const char *ret = dwarf_calling_convention_string (code);
4248 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4249 }
4250
4251
4252 static const char *
dwarf_ordering_name(unsigned int code)4253 dwarf_ordering_name (unsigned int code)
4254 {
4255 const char *ret = dwarf_ordering_string (code);
4256 return string_or_unknown (ret, code, 0, 0, false);
4257 }
4258
4259
4260 static const char *
dwarf_discr_list_name(unsigned int code)4261 dwarf_discr_list_name (unsigned int code)
4262 {
4263 const char *ret = dwarf_discr_list_string (code);
4264 return string_or_unknown (ret, code, 0, 0, false);
4265 }
4266
4267
4268 static const char *
dwarf_unit_name(unsigned int type)4269 dwarf_unit_name (unsigned int type)
4270 {
4271 const char *ret = dwarf_unit_string (type);
4272 return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4273 }
4274
4275
4276 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4277 dwarf_range_list_encoding_name (unsigned int kind)
4278 {
4279 const char *ret = dwarf_range_list_encoding_string (kind);
4280 return string_or_unknown (ret, kind, 0, 0, false);
4281 }
4282
4283
4284 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4285 dwarf_loc_list_encoding_name (unsigned int kind)
4286 {
4287 const char *ret = dwarf_loc_list_encoding_string (kind);
4288 return string_or_unknown (ret, kind, 0, 0, false);
4289 }
4290
4291
4292 static const char *
dwarf_line_content_description_name(unsigned int kind)4293 dwarf_line_content_description_name (unsigned int kind)
4294 {
4295 const char *ret = dwarf_line_content_description_string (kind);
4296 return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4297 false);
4298 }
4299
4300
4301 static void
print_block(size_t n,const void * block)4302 print_block (size_t n, const void *block)
4303 {
4304 if (n == 0)
4305 puts (_("empty block"));
4306 else
4307 {
4308 printf (_("%zu byte block:"), n);
4309 const unsigned char *data = block;
4310 do
4311 printf (" %02x", *data++);
4312 while (--n > 0);
4313 putchar ('\n');
4314 }
4315 }
4316
4317 static void
print_bytes(size_t n,const unsigned char * bytes)4318 print_bytes (size_t n, const unsigned char *bytes)
4319 {
4320 while (n-- > 0)
4321 {
4322 printf ("%02x", *bytes++);
4323 if (n > 0)
4324 printf (" ");
4325 }
4326 }
4327
4328 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4329 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4330 {
4331 if (cu == NULL)
4332 return -1;
4333
4334 Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4335 if (debug_addr == NULL)
4336 return -1;
4337
4338 Dwarf_Off base = __libdw_cu_addr_base (cu);
4339 Dwarf_Word off = idx * cu->address_size;
4340 if (base > debug_addr->d_size
4341 || off > debug_addr->d_size - base
4342 || cu->address_size > debug_addr->d_size - base - off)
4343 return -1;
4344
4345 const unsigned char *addrp = debug_addr->d_buf + base + off;
4346 if (cu->address_size == 4)
4347 *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4348 else
4349 *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4350
4351 return 0;
4352 }
4353
4354 static void
print_ops(Dwfl_Module * dwflmod,Dwarf * dbg,int indent,int indentrest,unsigned int vers,unsigned int addrsize,unsigned int offset_size,struct Dwarf_CU * cu,Dwarf_Word len,const unsigned char * data)4355 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4356 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4357 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4358 {
4359 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4360
4361 if (len == 0)
4362 {
4363 printf ("%*s(empty)\n", indent, "");
4364 return;
4365 }
4366
4367 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4368 #define CONSUME(n) NEED (n); else len -= (n)
4369
4370 Dwarf_Word offset = 0;
4371 while (len-- > 0)
4372 {
4373 uint_fast8_t op = *data++;
4374
4375 const char *op_name = dwarf_locexpr_opcode_string (op);
4376 if (unlikely (op_name == NULL))
4377 {
4378 static char buf[20];
4379 if (op >= DW_OP_lo_user)
4380 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4381 else
4382 snprintf (buf, sizeof buf, "??? (%#x)", op);
4383 op_name = buf;
4384 }
4385
4386 switch (op)
4387 {
4388 case DW_OP_addr:;
4389 /* Address operand. */
4390 Dwarf_Word addr;
4391 NEED (addrsize);
4392 if (addrsize == 4)
4393 addr = read_4ubyte_unaligned (dbg, data);
4394 else if (addrsize == 8)
4395 addr = read_8ubyte_unaligned (dbg, data);
4396 else
4397 goto invalid;
4398 data += addrsize;
4399 CONSUME (addrsize);
4400
4401 printf ("%*s[%2" PRIuMAX "] %s ",
4402 indent, "", (uintmax_t) offset, op_name);
4403 print_dwarf_addr (dwflmod, 0, addr, addr);
4404 printf ("\n");
4405
4406 offset += 1 + addrsize;
4407 break;
4408
4409 case DW_OP_call_ref:
4410 case DW_OP_GNU_variable_value:
4411 /* Offset operand. */
4412 if (ref_size != 4 && ref_size != 8)
4413 goto invalid; /* Cannot be used in CFA. */
4414 NEED (ref_size);
4415 if (ref_size == 4)
4416 addr = read_4ubyte_unaligned (dbg, data);
4417 else
4418 addr = read_8ubyte_unaligned (dbg, data);
4419 data += ref_size;
4420 CONSUME (ref_size);
4421 /* addr is a DIE offset, so format it as one. */
4422 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4423 indent, "", (uintmax_t) offset,
4424 op_name, (uintmax_t) addr);
4425 offset += 1 + ref_size;
4426 break;
4427
4428 case DW_OP_deref_size:
4429 case DW_OP_xderef_size:
4430 case DW_OP_pick:
4431 case DW_OP_const1u:
4432 // XXX value might be modified by relocation
4433 NEED (1);
4434 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4435 indent, "", (uintmax_t) offset,
4436 op_name, *((uint8_t *) data));
4437 ++data;
4438 --len;
4439 offset += 2;
4440 break;
4441
4442 case DW_OP_const2u:
4443 NEED (2);
4444 // XXX value might be modified by relocation
4445 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4446 indent, "", (uintmax_t) offset,
4447 op_name, read_2ubyte_unaligned (dbg, data));
4448 CONSUME (2);
4449 data += 2;
4450 offset += 3;
4451 break;
4452
4453 case DW_OP_const4u:
4454 NEED (4);
4455 // XXX value might be modified by relocation
4456 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4457 indent, "", (uintmax_t) offset,
4458 op_name, read_4ubyte_unaligned (dbg, data));
4459 CONSUME (4);
4460 data += 4;
4461 offset += 5;
4462 break;
4463
4464 case DW_OP_const8u:
4465 NEED (8);
4466 // XXX value might be modified by relocation
4467 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4468 indent, "", (uintmax_t) offset,
4469 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4470 CONSUME (8);
4471 data += 8;
4472 offset += 9;
4473 break;
4474
4475 case DW_OP_const1s:
4476 NEED (1);
4477 // XXX value might be modified by relocation
4478 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4479 indent, "", (uintmax_t) offset,
4480 op_name, *((int8_t *) data));
4481 ++data;
4482 --len;
4483 offset += 2;
4484 break;
4485
4486 case DW_OP_const2s:
4487 NEED (2);
4488 // XXX value might be modified by relocation
4489 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4490 indent, "", (uintmax_t) offset,
4491 op_name, read_2sbyte_unaligned (dbg, data));
4492 CONSUME (2);
4493 data += 2;
4494 offset += 3;
4495 break;
4496
4497 case DW_OP_const4s:
4498 NEED (4);
4499 // XXX value might be modified by relocation
4500 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4501 indent, "", (uintmax_t) offset,
4502 op_name, read_4sbyte_unaligned (dbg, data));
4503 CONSUME (4);
4504 data += 4;
4505 offset += 5;
4506 break;
4507
4508 case DW_OP_const8s:
4509 NEED (8);
4510 // XXX value might be modified by relocation
4511 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4512 indent, "", (uintmax_t) offset,
4513 op_name, read_8sbyte_unaligned (dbg, data));
4514 CONSUME (8);
4515 data += 8;
4516 offset += 9;
4517 break;
4518
4519 case DW_OP_piece:
4520 case DW_OP_regx:
4521 case DW_OP_plus_uconst:
4522 case DW_OP_constu:;
4523 const unsigned char *start = data;
4524 uint64_t uleb;
4525 NEED (1);
4526 get_uleb128 (uleb, data, data + len);
4527 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4528 indent, "", (uintmax_t) offset, op_name, uleb);
4529 CONSUME (data - start);
4530 offset += 1 + (data - start);
4531 break;
4532
4533 case DW_OP_addrx:
4534 case DW_OP_GNU_addr_index:
4535 case DW_OP_constx:
4536 case DW_OP_GNU_const_index:;
4537 start = data;
4538 NEED (1);
4539 get_uleb128 (uleb, data, data + len);
4540 printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4541 indent, "", (uintmax_t) offset, op_name, uleb);
4542 CONSUME (data - start);
4543 offset += 1 + (data - start);
4544 if (get_indexed_addr (cu, uleb, &addr) != 0)
4545 printf ("???\n");
4546 else
4547 {
4548 print_dwarf_addr (dwflmod, 0, addr, addr);
4549 printf ("\n");
4550 }
4551 break;
4552
4553 case DW_OP_bit_piece:
4554 start = data;
4555 uint64_t uleb2;
4556 NEED (1);
4557 get_uleb128 (uleb, data, data + len);
4558 NEED (1);
4559 get_uleb128 (uleb2, data, data + len);
4560 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4561 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4562 CONSUME (data - start);
4563 offset += 1 + (data - start);
4564 break;
4565
4566 case DW_OP_fbreg:
4567 case DW_OP_breg0 ... DW_OP_breg31:
4568 case DW_OP_consts:
4569 start = data;
4570 int64_t sleb;
4571 NEED (1);
4572 get_sleb128 (sleb, data, data + len);
4573 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4574 indent, "", (uintmax_t) offset, op_name, sleb);
4575 CONSUME (data - start);
4576 offset += 1 + (data - start);
4577 break;
4578
4579 case DW_OP_bregx:
4580 start = data;
4581 NEED (1);
4582 get_uleb128 (uleb, data, data + len);
4583 NEED (1);
4584 get_sleb128 (sleb, data, data + len);
4585 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4586 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4587 CONSUME (data - start);
4588 offset += 1 + (data - start);
4589 break;
4590
4591 case DW_OP_call2:
4592 NEED (2);
4593 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4594 indent, "", (uintmax_t) offset, op_name,
4595 read_2ubyte_unaligned (dbg, data));
4596 CONSUME (2);
4597 data += 2;
4598 offset += 3;
4599 break;
4600
4601 case DW_OP_call4:
4602 NEED (4);
4603 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4604 indent, "", (uintmax_t) offset, op_name,
4605 read_4ubyte_unaligned (dbg, data));
4606 CONSUME (4);
4607 data += 4;
4608 offset += 5;
4609 break;
4610
4611 case DW_OP_skip:
4612 case DW_OP_bra:
4613 NEED (2);
4614 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4615 indent, "", (uintmax_t) offset, op_name,
4616 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4617 CONSUME (2);
4618 data += 2;
4619 offset += 3;
4620 break;
4621
4622 case DW_OP_implicit_value:
4623 start = data;
4624 NEED (1);
4625 get_uleb128 (uleb, data, data + len);
4626 printf ("%*s[%2" PRIuMAX "] %s: ",
4627 indent, "", (uintmax_t) offset, op_name);
4628 NEED (uleb);
4629 print_block (uleb, data);
4630 data += uleb;
4631 CONSUME (data - start);
4632 offset += 1 + (data - start);
4633 break;
4634
4635 case DW_OP_implicit_pointer:
4636 case DW_OP_GNU_implicit_pointer:
4637 /* DIE offset operand. */
4638 start = data;
4639 NEED (ref_size);
4640 if (ref_size != 4 && ref_size != 8)
4641 goto invalid; /* Cannot be used in CFA. */
4642 if (ref_size == 4)
4643 addr = read_4ubyte_unaligned (dbg, data);
4644 else
4645 addr = read_8ubyte_unaligned (dbg, data);
4646 data += ref_size;
4647 /* Byte offset operand. */
4648 NEED (1);
4649 get_sleb128 (sleb, data, data + len);
4650
4651 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4652 indent, "", (intmax_t) offset,
4653 op_name, (uintmax_t) addr, sleb);
4654 CONSUME (data - start);
4655 offset += 1 + (data - start);
4656 break;
4657
4658 case DW_OP_entry_value:
4659 case DW_OP_GNU_entry_value:
4660 /* Size plus expression block. */
4661 start = data;
4662 NEED (1);
4663 get_uleb128 (uleb, data, data + len);
4664 printf ("%*s[%2" PRIuMAX "] %s:\n",
4665 indent, "", (uintmax_t) offset, op_name);
4666 NEED (uleb);
4667 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4668 addrsize, offset_size, cu, uleb, data);
4669 data += uleb;
4670 CONSUME (data - start);
4671 offset += 1 + (data - start);
4672 break;
4673
4674 case DW_OP_const_type:
4675 case DW_OP_GNU_const_type:
4676 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4677 unsigned size plus block. */
4678 start = data;
4679 NEED (1);
4680 get_uleb128 (uleb, data, data + len);
4681 if (! print_unresolved_addresses && cu != NULL)
4682 uleb += cu->start;
4683 NEED (1);
4684 uint8_t usize = *(uint8_t *) data++;
4685 NEED (usize);
4686 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4687 indent, "", (uintmax_t) offset, op_name, uleb);
4688 print_block (usize, data);
4689 data += usize;
4690 CONSUME (data - start);
4691 offset += 1 + (data - start);
4692 break;
4693
4694 case DW_OP_regval_type:
4695 case DW_OP_GNU_regval_type:
4696 /* uleb128 register number, uleb128 CU relative
4697 DW_TAG_base_type DIE offset. */
4698 start = data;
4699 NEED (1);
4700 get_uleb128 (uleb, data, data + len);
4701 NEED (1);
4702 get_uleb128 (uleb2, data, data + len);
4703 if (! print_unresolved_addresses && cu != NULL)
4704 uleb2 += cu->start;
4705 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4706 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4707 CONSUME (data - start);
4708 offset += 1 + (data - start);
4709 break;
4710
4711 case DW_OP_deref_type:
4712 case DW_OP_GNU_deref_type:
4713 /* 1-byte unsigned size of value, uleb128 CU relative
4714 DW_TAG_base_type DIE offset. */
4715 start = data;
4716 NEED (1);
4717 usize = *(uint8_t *) data++;
4718 NEED (1);
4719 get_uleb128 (uleb, data, data + len);
4720 if (! print_unresolved_addresses && cu != NULL)
4721 uleb += cu->start;
4722 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4723 indent, "", (uintmax_t) offset,
4724 op_name, usize, uleb);
4725 CONSUME (data - start);
4726 offset += 1 + (data - start);
4727 break;
4728
4729 case DW_OP_xderef_type:
4730 /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */
4731 start = data;
4732 NEED (1);
4733 usize = *(uint8_t *) data++;
4734 NEED (1);
4735 get_uleb128 (uleb, data, data + len);
4736 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4737 indent, "", (uintmax_t) offset,
4738 op_name, usize, uleb);
4739 CONSUME (data - start);
4740 offset += 1 + (data - start);
4741 break;
4742
4743 case DW_OP_convert:
4744 case DW_OP_GNU_convert:
4745 case DW_OP_reinterpret:
4746 case DW_OP_GNU_reinterpret:
4747 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4748 for conversion to untyped. */
4749 start = data;
4750 NEED (1);
4751 get_uleb128 (uleb, data, data + len);
4752 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4753 uleb += cu->start;
4754 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4755 indent, "", (uintmax_t) offset, op_name, uleb);
4756 CONSUME (data - start);
4757 offset += 1 + (data - start);
4758 break;
4759
4760 case DW_OP_GNU_parameter_ref:
4761 /* 4 byte CU relative reference to the abstract optimized away
4762 DW_TAG_formal_parameter. */
4763 NEED (4);
4764 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4765 if (! print_unresolved_addresses && cu != NULL)
4766 param_off += cu->start;
4767 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4768 indent, "", (uintmax_t) offset, op_name, param_off);
4769 CONSUME (4);
4770 data += 4;
4771 offset += 5;
4772 break;
4773
4774 default:
4775 /* No Operand. */
4776 printf ("%*s[%2" PRIuMAX "] %s\n",
4777 indent, "", (uintmax_t) offset, op_name);
4778 ++offset;
4779 break;
4780 }
4781
4782 indent = indentrest;
4783 continue;
4784
4785 invalid:
4786 printf (gettext ("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
4787 indent, "", (uintmax_t) offset, op_name);
4788 break;
4789 }
4790 }
4791
4792
4793 struct listptr
4794 {
4795 Dwarf_Off offset:(64 - 3);
4796 bool addr64:1;
4797 bool dwarf64:1;
4798 bool warned:1;
4799 struct Dwarf_CU *cu;
4800 unsigned int attr;
4801 };
4802
4803 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4804 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4805
4806 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4807 cudie_base (Dwarf_Die *cudie)
4808 {
4809 Dwarf_Addr base;
4810 /* Find the base address of the compilation unit. It will normally
4811 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4812 address could be overridden by DW_AT_entry_pc. It's been
4813 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4814 compilation units with discontinuous ranges. */
4815 if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4816 {
4817 Dwarf_Attribute attr_mem;
4818 if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4819 &base) != 0)
4820 base = 0;
4821 }
4822 return base;
4823 }
4824
4825 static Dwarf_Addr
listptr_base(struct listptr * p)4826 listptr_base (struct listptr *p)
4827 {
4828 Dwarf_Die cu = CUDIE (p->cu);
4829 return cudie_base (&cu);
4830 }
4831
4832 static int
4833 #if defined(__DragonFly__)
compare_listptr(void * arg,const void * a,const void * b)4834 compare_listptr (void *arg, const void *a, const void *b)
4835 #else
4836 compare_listptr (const void *a, const void *b, void *arg)
4837 #endif
4838 {
4839 const char *name = arg;
4840 struct listptr *p1 = (void *) a;
4841 struct listptr *p2 = (void *) b;
4842
4843 if (p1->offset < p2->offset)
4844 return -1;
4845 if (p1->offset > p2->offset)
4846 return 1;
4847
4848 if (!p1->warned && !p2->warned)
4849 {
4850 if (p1->addr64 != p2->addr64)
4851 {
4852 p1->warned = p2->warned = true;
4853 error (0, 0,
4854 gettext ("%s %#" PRIx64 " used with different address sizes"),
4855 name, (uint64_t) p1->offset);
4856 }
4857 if (p1->dwarf64 != p2->dwarf64)
4858 {
4859 p1->warned = p2->warned = true;
4860 error (0, 0,
4861 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4862 name, (uint64_t) p1->offset);
4863 }
4864 if (listptr_base (p1) != listptr_base (p2))
4865 {
4866 p1->warned = p2->warned = true;
4867 error (0, 0,
4868 gettext ("%s %#" PRIx64 " used with different base addresses"),
4869 name, (uint64_t) p1->offset);
4870 }
4871 if (p1->attr != p2 ->attr)
4872 {
4873 p1->warned = p2->warned = true;
4874 error (0, 0,
4875 gettext ("%s %#" PRIx64
4876 " used with different attribute %s and %s"),
4877 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
4878 dwarf_attr_name (p2->attr));
4879 }
4880 }
4881
4882 return 0;
4883 }
4884
4885 struct listptr_table
4886 {
4887 size_t n;
4888 size_t alloc;
4889 struct listptr *table;
4890 };
4891
4892 static struct listptr_table known_locsptr;
4893 static struct listptr_table known_loclistsptr;
4894 static struct listptr_table known_rangelistptr;
4895 static struct listptr_table known_rnglistptr;
4896 static struct listptr_table known_addrbases;
4897 static struct listptr_table known_stroffbases;
4898
4899 static void
reset_listptr(struct listptr_table * table)4900 reset_listptr (struct listptr_table *table)
4901 {
4902 free (table->table);
4903 table->table = NULL;
4904 table->n = table->alloc = 0;
4905 }
4906
4907 /* Returns false if offset doesn't fit. See struct listptr. */
4908 static bool
notice_listptr(enum section_e section,struct listptr_table * table,uint_fast8_t address_size,uint_fast8_t offset_size,struct Dwarf_CU * cu,Dwarf_Off offset,unsigned int attr)4909 notice_listptr (enum section_e section, struct listptr_table *table,
4910 uint_fast8_t address_size, uint_fast8_t offset_size,
4911 struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4912 {
4913 if (print_debug_sections & section)
4914 {
4915 if (table->n == table->alloc)
4916 {
4917 if (table->alloc == 0)
4918 table->alloc = 128;
4919 else
4920 table->alloc *= 2;
4921 table->table = xrealloc (table->table,
4922 table->alloc * sizeof table->table[0]);
4923 }
4924
4925 struct listptr *p = &table->table[table->n++];
4926
4927 *p = (struct listptr)
4928 {
4929 .addr64 = address_size == 8,
4930 .dwarf64 = offset_size == 8,
4931 .offset = offset,
4932 .cu = cu,
4933 .attr = attr
4934 };
4935
4936 if (p->offset != offset)
4937 {
4938 table->n--;
4939 return false;
4940 }
4941 }
4942 return true;
4943 }
4944
4945 static void
sort_listptr(struct listptr_table * table,const char * name)4946 sort_listptr (struct listptr_table *table, const char *name)
4947 {
4948 if (table->n > 0)
4949 #if defined(__DragonFly__)
4950 qsort_r (table->table, table->n, sizeof table->table[0],
4951 (void *) name, &compare_listptr);
4952 #else
4953 qsort_r (table->table, table->n, sizeof table->table[0],
4954 &compare_listptr, (void *) name);
4955 #endif
4956 }
4957
4958 static bool
skip_listptr_hole(struct listptr_table * table,size_t * idxp,uint_fast8_t * address_sizep,uint_fast8_t * offset_sizep,Dwarf_Addr * base,struct Dwarf_CU ** cu,ptrdiff_t offset,unsigned char ** readp,unsigned char * endp,unsigned int * attr)4959 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4960 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4961 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4962 unsigned char **readp, unsigned char *endp,
4963 unsigned int *attr)
4964 {
4965 if (table->n == 0)
4966 return false;
4967
4968 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4969 ++*idxp;
4970
4971 struct listptr *p = &table->table[*idxp];
4972
4973 if (*idxp == table->n
4974 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4975 {
4976 *readp = endp;
4977 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4978 offset);
4979 return true;
4980 }
4981
4982 if (p->offset != (Dwarf_Off) offset)
4983 {
4984 *readp += p->offset - offset;
4985 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4986 offset, (Dwarf_Off) p->offset - offset);
4987 return true;
4988 }
4989
4990 if (address_sizep != NULL)
4991 *address_sizep = listptr_address_size (p);
4992 if (offset_sizep != NULL)
4993 *offset_sizep = listptr_offset_size (p);
4994 if (base != NULL)
4995 *base = listptr_base (p);
4996 if (cu != NULL)
4997 *cu = p->cu;
4998 if (attr != NULL)
4999 *attr = p->attr;
5000
5001 return false;
5002 }
5003
5004 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t idx)5005 next_listptr_offset (struct listptr_table *table, size_t idx)
5006 {
5007 /* Note that multiple attributes could in theory point to the same loclist
5008 offset, so make sure we pick one that is bigger than the current one.
5009 The table is sorted on offset. */
5010 Dwarf_Off offset = table->table[idx].offset;
5011 while (++idx < table->n)
5012 {
5013 Dwarf_Off next = table->table[idx].offset;
5014 if (next > offset)
5015 return next;
5016 }
5017 return 0;
5018 }
5019
5020 /* Returns the listptr associated with the given index, or NULL. */
5021 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5022 get_listptr (struct listptr_table *table, size_t idx)
5023 {
5024 if (idx >= table->n)
5025 return NULL;
5026 return &table->table[idx];
5027 }
5028
5029 /* Returns the next index, base address and CU associated with the
5030 list unit offsets. If there is none false is returned, otherwise
5031 true. Assumes the table has been sorted. */
5032 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5033 listptr_cu (struct listptr_table *table, size_t *idxp,
5034 Dwarf_Off start, Dwarf_Off end,
5035 Dwarf_Addr *base, struct Dwarf_CU **cu)
5036 {
5037 while (*idxp < table->n
5038 && table->table[*idxp].offset < start)
5039 ++*idxp;
5040
5041 if (*idxp < table->n
5042 && table->table[*idxp].offset >= start
5043 && table->table[*idxp].offset < end)
5044 {
5045 struct listptr *p = &table->table[*idxp];
5046 *base = listptr_base (p);
5047 *cu = p->cu;
5048 ++*idxp;
5049 return true;
5050 }
5051
5052 return false;
5053 }
5054
5055 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5056 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5057 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5058 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5059 {
5060 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5061 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5062
5063 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5064 " [ Code]\n"),
5065 elf_ndxscn (scn), section_name (ebl, shdr),
5066 (uint64_t) shdr->sh_offset);
5067
5068 Dwarf_Off offset = 0;
5069 while (offset < sh_size)
5070 {
5071 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
5072 offset);
5073
5074 while (1)
5075 {
5076 size_t length;
5077 Dwarf_Abbrev abbrev;
5078
5079 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5080 if (res != 0)
5081 {
5082 if (unlikely (res < 0))
5083 {
5084 printf (gettext ("\
5085 *** error while reading abbreviation: %s\n"),
5086 dwarf_errmsg (-1));
5087 return;
5088 }
5089
5090 /* This is the NUL byte at the end of the section. */
5091 ++offset;
5092 break;
5093 }
5094
5095 /* We know these calls can never fail. */
5096 unsigned int code = dwarf_getabbrevcode (&abbrev);
5097 unsigned int tag = dwarf_getabbrevtag (&abbrev);
5098 int has_children = dwarf_abbrevhaschildren (&abbrev);
5099
5100 printf (gettext (" [%5u] offset: %" PRId64
5101 ", children: %s, tag: %s\n"),
5102 code, (int64_t) offset,
5103 has_children ? yes_str : no_str,
5104 dwarf_tag_name (tag));
5105
5106 size_t cnt = 0;
5107 unsigned int name;
5108 unsigned int form;
5109 Dwarf_Sword data;
5110 Dwarf_Off enoffset;
5111 while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5112 &data, &enoffset) == 0)
5113 {
5114 printf (" attr: %s, form: %s",
5115 dwarf_attr_name (name), dwarf_form_name (form));
5116 if (form == DW_FORM_implicit_const)
5117 printf (" (%" PRId64 ")", data);
5118 printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5119 ++cnt;
5120 }
5121
5122 offset += length;
5123 }
5124 }
5125 }
5126
5127
5128 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5129 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5130 Ebl *ebl, GElf_Ehdr *ehdr,
5131 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5132 {
5133 printf (gettext ("\
5134 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5135 elf_ndxscn (scn), section_name (ebl, shdr),
5136 (uint64_t) shdr->sh_offset);
5137
5138 if (shdr->sh_size == 0)
5139 return;
5140
5141 /* We like to get the section from libdw to make sure they are relocated. */
5142 Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5143 ?: elf_rawdata (scn, NULL));
5144 if (unlikely (data == NULL))
5145 {
5146 error (0, 0, gettext ("cannot get .debug_addr section data: %s"),
5147 elf_errmsg (-1));
5148 return;
5149 }
5150
5151 size_t idx = 0;
5152 sort_listptr (&known_addrbases, "addr_base");
5153
5154 const unsigned char *start = (const unsigned char *) data->d_buf;
5155 const unsigned char *readp = start;
5156 const unsigned char *readendp = ((const unsigned char *) data->d_buf
5157 + data->d_size);
5158
5159 while (readp < readendp)
5160 {
5161 /* We cannot really know whether or not there is an header. The
5162 DebugFission extension to DWARF4 doesn't add one. The DWARF5
5163 .debug_addr variant does. Whether or not we have an header,
5164 DW_AT_[GNU_]addr_base points at "index 0". So if the current
5165 offset equals the CU addr_base then we can just start
5166 printing addresses. If there is no CU with an exact match
5167 then we'll try to parse the header first. */
5168 Dwarf_Off off = (Dwarf_Off) (readp
5169 - (const unsigned char *) data->d_buf);
5170
5171 printf ("Table at offset %" PRIx64 " ", off);
5172
5173 struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5174 const unsigned char *next_unitp;
5175
5176 uint64_t unit_length;
5177 uint16_t version;
5178 uint8_t address_size;
5179 uint8_t segment_size;
5180 if (listptr == NULL)
5181 {
5182 error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5183 off);
5184
5185 /* We will have to assume it is just addresses to the end... */
5186 address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5187 next_unitp = readendp;
5188 printf ("Unknown CU:\n");
5189 }
5190 else
5191 {
5192 Dwarf_Die cudie;
5193 if (dwarf_cu_die (listptr->cu, &cudie,
5194 NULL, NULL, NULL, NULL,
5195 NULL, NULL) == NULL)
5196 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5197 else
5198 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5199
5200 if (listptr->offset == off)
5201 {
5202 address_size = listptr_address_size (listptr);
5203 segment_size = 0;
5204 version = 4;
5205
5206 /* The addresses start here, but where do they end? */
5207 listptr = get_listptr (&known_addrbases, idx);
5208 if (listptr == NULL)
5209 next_unitp = readendp;
5210 else if (listptr->cu->version < 5)
5211 {
5212 next_unitp = start + listptr->offset;
5213 if (listptr->offset < off || listptr->offset > data->d_size)
5214 {
5215 error (0, 0,
5216 "Warning: Bad address base for next unit at %"
5217 PRIx64, off);
5218 next_unitp = readendp;
5219 }
5220 }
5221 else
5222 {
5223 /* Tricky, we don't have a header for this unit, but
5224 there is one for the next. We will have to
5225 "guess" how big it is and subtract it from the
5226 offset (because that points after the header). */
5227 unsigned int offset_size = listptr_offset_size (listptr);
5228 Dwarf_Off next_off = (listptr->offset
5229 - (offset_size == 4 ? 4 : 12) /* len */
5230 - 2 /* version */
5231 - 1 /* address size */
5232 - 1); /* segment selector size */
5233 next_unitp = start + next_off;
5234 if (next_off < off || next_off > data->d_size)
5235 {
5236 error (0, 0,
5237 "Warning: Couldn't calculate .debug_addr "
5238 " unit lenght at %" PRIx64, off);
5239 next_unitp = readendp;
5240 }
5241 }
5242 unit_length = (uint64_t) (next_unitp - readp);
5243
5244 /* Pretend we have a header. */
5245 printf ("\n");
5246 printf (gettext (" Length: %8" PRIu64 "\n"),
5247 unit_length);
5248 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5249 printf (gettext (" Address size: %8" PRIu64 "\n"),
5250 (uint64_t) address_size);
5251 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5252 (uint64_t) segment_size);
5253 printf ("\n");
5254 }
5255 else
5256 {
5257 /* OK, we have to parse an header first. */
5258 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5259 if (unlikely (unit_length == 0xffffffff))
5260 {
5261 if (unlikely (readp > readendp - 8))
5262 {
5263 invalid_data:
5264 error (0, 0, "Invalid data");
5265 return;
5266 }
5267 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5268 }
5269 printf ("\n");
5270 printf (gettext (" Length: %8" PRIu64 "\n"),
5271 unit_length);
5272
5273 /* We need at least 2-bytes (version) + 1-byte
5274 (addr_size) + 1-byte (segment_size) = 4 bytes to
5275 complete the header. And this unit cannot go beyond
5276 the section data. */
5277 if (readp > readendp - 4
5278 || unit_length < 4
5279 || unit_length > (uint64_t) (readendp - readp))
5280 goto invalid_data;
5281
5282 next_unitp = readp + unit_length;
5283
5284 version = read_2ubyte_unaligned_inc (dbg, readp);
5285 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5286
5287 if (version != 5)
5288 {
5289 error (0, 0, gettext ("Unknown version"));
5290 goto next_unit;
5291 }
5292
5293 address_size = *readp++;
5294 printf (gettext (" Address size: %8" PRIu64 "\n"),
5295 (uint64_t) address_size);
5296
5297 if (address_size != 4 && address_size != 8)
5298 {
5299 error (0, 0, gettext ("unsupported address size"));
5300 goto next_unit;
5301 }
5302
5303 segment_size = *readp++;
5304 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5305 (uint64_t) segment_size);
5306 printf ("\n");
5307
5308 if (segment_size != 0)
5309 {
5310 error (0, 0, gettext ("unsupported segment size"));
5311 goto next_unit;
5312 }
5313
5314 if (listptr->offset != (Dwarf_Off) (readp - start))
5315 {
5316 error (0, 0, "Address index doesn't start after header");
5317 goto next_unit;
5318 }
5319 }
5320 }
5321
5322 int digits = 1;
5323 size_t addresses = (next_unitp - readp) / address_size;
5324 while (addresses >= 10)
5325 {
5326 ++digits;
5327 addresses /= 10;
5328 }
5329
5330 unsigned int uidx = 0;
5331 size_t index_offset = readp - (const unsigned char *) data->d_buf;
5332 printf (" Addresses start at offset 0x%zx:\n", index_offset);
5333 while (readp <= next_unitp - address_size)
5334 {
5335 Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5336 readp);
5337 printf (" [%*u] ", digits, uidx++);
5338 print_dwarf_addr (dwflmod, address_size, addr, addr);
5339 printf ("\n");
5340 }
5341 printf ("\n");
5342
5343 if (readp != next_unitp)
5344 error (0, 0, "extra %zd bytes at end of unit",
5345 (size_t) (next_unitp - readp));
5346
5347 next_unit:
5348 readp = next_unitp;
5349 }
5350 }
5351
5352 /* Print content of DWARF .debug_aranges section. We fortunately do
5353 not have to know a bit about the structure of the section, libdwarf
5354 takes care of it. */
5355 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5356 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5357 GElf_Shdr *shdr, Dwarf *dbg)
5358 {
5359 Dwarf_Aranges *aranges;
5360 size_t cnt;
5361 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5362 {
5363 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5364 dwarf_errmsg (-1));
5365 return;
5366 }
5367
5368 GElf_Shdr glink_mem;
5369 GElf_Shdr *glink;
5370 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5371 if (glink == NULL)
5372 {
5373 error (0, 0, gettext ("invalid sh_link value in section %zu"),
5374 elf_ndxscn (scn));
5375 return;
5376 }
5377
5378 printf (ngettext ("\
5379 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5380 "\
5381 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5382 cnt),
5383 elf_ndxscn (scn), section_name (ebl, shdr),
5384 (uint64_t) shdr->sh_offset, cnt);
5385
5386 /* Compute floor(log16(cnt)). */
5387 size_t tmp = cnt;
5388 int digits = 1;
5389 while (tmp >= 16)
5390 {
5391 ++digits;
5392 tmp >>= 4;
5393 }
5394
5395 for (size_t n = 0; n < cnt; ++n)
5396 {
5397 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5398 if (unlikely (runp == NULL))
5399 {
5400 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5401 return;
5402 }
5403
5404 Dwarf_Addr start;
5405 Dwarf_Word length;
5406 Dwarf_Off offset;
5407
5408 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5409 printf (gettext (" [%*zu] ???\n"), digits, n);
5410 else
5411 printf (gettext (" [%*zu] start: %0#*" PRIx64
5412 ", length: %5" PRIu64 ", CU DIE offset: %6"
5413 PRId64 "\n"),
5414 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5415 (uint64_t) start, (uint64_t) length, (int64_t) offset);
5416 }
5417 }
5418
5419
5420 /* Print content of DWARF .debug_aranges section. */
5421 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5422 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5423 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5424 GElf_Shdr *shdr, Dwarf *dbg)
5425 {
5426 if (decodedaranges)
5427 {
5428 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5429 return;
5430 }
5431
5432 Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5433 ?: elf_rawdata (scn, NULL));
5434
5435 if (unlikely (data == NULL))
5436 {
5437 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5438 elf_errmsg (-1));
5439 return;
5440 }
5441
5442 printf (gettext ("\
5443 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5444 elf_ndxscn (scn), section_name (ebl, shdr),
5445 (uint64_t) shdr->sh_offset);
5446
5447 const unsigned char *readp = data->d_buf;
5448 const unsigned char *readendp = readp + data->d_size;
5449
5450 while (readp < readendp)
5451 {
5452 const unsigned char *hdrstart = readp;
5453 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5454
5455 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
5456 if (readp + 4 > readendp)
5457 {
5458 invalid_data:
5459 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5460 elf_ndxscn (scn), section_name (ebl, shdr));
5461 return;
5462 }
5463
5464 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5465 unsigned int length_bytes = 4;
5466 if (length == DWARF3_LENGTH_64_BIT)
5467 {
5468 if (readp + 8 > readendp)
5469 goto invalid_data;
5470 length = read_8ubyte_unaligned_inc (dbg, readp);
5471 length_bytes = 8;
5472 }
5473
5474 const unsigned char *nexthdr = readp + length;
5475 printf (gettext ("\n Length: %6" PRIu64 "\n"),
5476 (uint64_t) length);
5477
5478 if (unlikely (length > (size_t) (readendp - readp)))
5479 goto invalid_data;
5480
5481 if (length == 0)
5482 continue;
5483
5484 if (readp + 2 > readendp)
5485 goto invalid_data;
5486 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5487 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
5488 version);
5489 if (version != 2)
5490 {
5491 error (0, 0, gettext ("unsupported aranges version"));
5492 goto next_table;
5493 }
5494
5495 Dwarf_Word offset;
5496 if (readp + length_bytes > readendp)
5497 goto invalid_data;
5498 if (length_bytes == 8)
5499 offset = read_8ubyte_unaligned_inc (dbg, readp);
5500 else
5501 offset = read_4ubyte_unaligned_inc (dbg, readp);
5502 printf (gettext (" CU offset: %6" PRIx64 "\n"),
5503 (uint64_t) offset);
5504
5505 if (readp + 1 > readendp)
5506 goto invalid_data;
5507 unsigned int address_size = *readp++;
5508 printf (gettext (" Address size: %6" PRIu64 "\n"),
5509 (uint64_t) address_size);
5510 if (address_size != 4 && address_size != 8)
5511 {
5512 error (0, 0, gettext ("unsupported address size"));
5513 goto next_table;
5514 }
5515
5516 if (readp + 1 > readendp)
5517 goto invalid_data;
5518 unsigned int segment_size = *readp++;
5519 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
5520 (uint64_t) segment_size);
5521 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5522 {
5523 error (0, 0, gettext ("unsupported segment size"));
5524 goto next_table;
5525 }
5526
5527 /* Round the address to the next multiple of 2*address_size. */
5528 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5529 % (2 * address_size));
5530
5531 while (readp < nexthdr)
5532 {
5533 Dwarf_Word range_address;
5534 Dwarf_Word range_length;
5535 Dwarf_Word segment = 0;
5536 if (readp + 2 * address_size + segment_size > readendp)
5537 goto invalid_data;
5538 if (address_size == 4)
5539 {
5540 range_address = read_4ubyte_unaligned_inc (dbg, readp);
5541 range_length = read_4ubyte_unaligned_inc (dbg, readp);
5542 }
5543 else
5544 {
5545 range_address = read_8ubyte_unaligned_inc (dbg, readp);
5546 range_length = read_8ubyte_unaligned_inc (dbg, readp);
5547 }
5548
5549 if (segment_size == 4)
5550 segment = read_4ubyte_unaligned_inc (dbg, readp);
5551 else if (segment_size == 8)
5552 segment = read_8ubyte_unaligned_inc (dbg, readp);
5553
5554 if (range_address == 0 && range_length == 0 && segment == 0)
5555 break;
5556
5557 printf (" ");
5558 print_dwarf_addr (dwflmod, address_size, range_address,
5559 range_address);
5560 printf ("..");
5561 print_dwarf_addr (dwflmod, address_size,
5562 range_address + range_length - 1,
5563 range_length);
5564 if (segment_size != 0)
5565 printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5566 else
5567 printf ("\n");
5568 }
5569
5570 next_table:
5571 if (readp != nexthdr)
5572 {
5573 size_t padding = nexthdr - readp;
5574 printf (gettext (" %zu padding bytes\n"), padding);
5575 readp = nexthdr;
5576 }
5577 }
5578 }
5579
5580
5581 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5582
5583 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5584 DWARF (.dwo) file. */
5585 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5586 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5587 {
5588 uint64_t id;
5589 if (is_split_dwarf (dbg, &id, cu))
5590 {
5591 Dwarf_Die cudie;
5592 if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5593 {
5594 *cu_base = cudie_base (&cudie);
5595 return true;
5596 }
5597 }
5598 return false;
5599 }
5600
5601 /* Print content of DWARF .debug_rnglists section. */
5602 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5603 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5604 Ebl *ebl,
5605 GElf_Ehdr *ehdr __attribute__ ((unused)),
5606 Elf_Scn *scn, GElf_Shdr *shdr,
5607 Dwarf *dbg __attribute__((unused)))
5608 {
5609 printf (gettext ("\
5610 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5611 elf_ndxscn (scn), section_name (ebl, shdr),
5612 (uint64_t) shdr->sh_offset);
5613
5614 Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5615 ?: elf_rawdata (scn, NULL));
5616 if (unlikely (data == NULL))
5617 {
5618 error (0, 0, gettext ("cannot get .debug_rnglists content: %s"),
5619 elf_errmsg (-1));
5620 return;
5621 }
5622
5623 /* For the listptr to get the base address/CU. */
5624 sort_listptr (&known_rnglistptr, "rnglistptr");
5625 size_t listptr_idx = 0;
5626
5627 const unsigned char *readp = data->d_buf;
5628 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5629 + data->d_size);
5630 while (readp < dataend)
5631 {
5632 if (unlikely (readp > dataend - 4))
5633 {
5634 invalid_data:
5635 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5636 elf_ndxscn (scn), section_name (ebl, shdr));
5637 return;
5638 }
5639
5640 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5641 printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
5642 (uint64_t) offset);
5643
5644 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5645 unsigned int offset_size = 4;
5646 if (unlikely (unit_length == 0xffffffff))
5647 {
5648 if (unlikely (readp > dataend - 8))
5649 goto invalid_data;
5650
5651 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5652 offset_size = 8;
5653 }
5654 printf (gettext (" Length: %8" PRIu64 "\n"), unit_length);
5655
5656 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5657 bytes to complete the header. And this unit cannot go beyond
5658 the section data. */
5659 if (readp > dataend - 8
5660 || unit_length < 8
5661 || unit_length > (uint64_t) (dataend - readp))
5662 goto invalid_data;
5663
5664 const unsigned char *nexthdr = readp + unit_length;
5665
5666 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5667 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5668
5669 if (version != 5)
5670 {
5671 error (0, 0, gettext ("Unknown version"));
5672 goto next_table;
5673 }
5674
5675 uint8_t address_size = *readp++;
5676 printf (gettext (" Address size: %8" PRIu64 "\n"),
5677 (uint64_t) address_size);
5678
5679 if (address_size != 4 && address_size != 8)
5680 {
5681 error (0, 0, gettext ("unsupported address size"));
5682 goto next_table;
5683 }
5684
5685 uint8_t segment_size = *readp++;
5686 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5687 (uint64_t) segment_size);
5688
5689 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5690 {
5691 error (0, 0, gettext ("unsupported segment size"));
5692 goto next_table;
5693 }
5694
5695 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5696 printf (gettext (" Offset entries: %8" PRIu64 "\n"),
5697 (uint64_t) offset_entry_count);
5698
5699 /* We need the CU that uses this unit to get the initial base address. */
5700 Dwarf_Addr cu_base = 0;
5701 struct Dwarf_CU *cu = NULL;
5702 if (listptr_cu (&known_rnglistptr, &listptr_idx,
5703 (Dwarf_Off) offset,
5704 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5705 &cu_base, &cu)
5706 || split_dwarf_cu_base (dbg, &cu, &cu_base))
5707 {
5708 Dwarf_Die cudie;
5709 if (dwarf_cu_die (cu, &cudie,
5710 NULL, NULL, NULL, NULL,
5711 NULL, NULL) == NULL)
5712 printf (gettext (" Unknown CU base: "));
5713 else
5714 printf (gettext (" CU [%6" PRIx64 "] base: "),
5715 dwarf_dieoffset (&cudie));
5716 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5717 printf ("\n");
5718 }
5719 else
5720 printf (gettext (" Not associated with a CU.\n"));
5721
5722 printf ("\n");
5723
5724 const unsigned char *offset_array_start = readp;
5725 if (offset_entry_count > 0)
5726 {
5727 uint64_t max_entries = (unit_length - 8) / offset_size;
5728 if (offset_entry_count > max_entries)
5729 {
5730 error (0, 0,
5731 gettext ("too many offset entries for unit length"));
5732 offset_entry_count = max_entries;
5733 }
5734
5735 printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),
5736 (uint64_t) (offset_array_start
5737 - (unsigned char *) data->d_buf));
5738 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5739 {
5740 printf (" [%6" PRIu32 "] ", idx);
5741 if (offset_size == 4)
5742 {
5743 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5744 printf ("0x%" PRIx32 "\n", off);
5745 }
5746 else
5747 {
5748 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5749 printf ("0x%" PRIx64 "\n", off);
5750 }
5751 }
5752 printf ("\n");
5753 }
5754
5755 Dwarf_Addr base = cu_base;
5756 bool start_of_list = true;
5757 while (readp < nexthdr)
5758 {
5759 uint8_t kind = *readp++;
5760 uint64_t op1, op2;
5761
5762 /* Skip padding. */
5763 if (start_of_list && kind == DW_RLE_end_of_list)
5764 continue;
5765
5766 if (start_of_list)
5767 {
5768 base = cu_base;
5769 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5770 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5771 (uint64_t) (readp - offset_array_start - 1));
5772 start_of_list = false;
5773 }
5774
5775 printf (" %s", dwarf_range_list_encoding_name (kind));
5776 switch (kind)
5777 {
5778 case DW_RLE_end_of_list:
5779 start_of_list = true;
5780 printf ("\n\n");
5781 break;
5782
5783 case DW_RLE_base_addressx:
5784 if ((uint64_t) (nexthdr - readp) < 1)
5785 {
5786 invalid_range:
5787 error (0, 0, gettext ("invalid range list data"));
5788 goto next_table;
5789 }
5790 get_uleb128 (op1, readp, nexthdr);
5791 printf (" %" PRIx64 "\n", op1);
5792 if (! print_unresolved_addresses)
5793 {
5794 Dwarf_Addr addr;
5795 if (get_indexed_addr (cu, op1, &addr) != 0)
5796 printf (" ???\n");
5797 else
5798 {
5799 printf (" ");
5800 print_dwarf_addr (dwflmod, address_size, addr, addr);
5801 printf ("\n");
5802 }
5803 }
5804 break;
5805
5806 case DW_RLE_startx_endx:
5807 if ((uint64_t) (nexthdr - readp) < 1)
5808 goto invalid_range;
5809 get_uleb128 (op1, readp, nexthdr);
5810 if ((uint64_t) (nexthdr - readp) < 1)
5811 goto invalid_range;
5812 get_uleb128 (op2, readp, nexthdr);
5813 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5814 if (! print_unresolved_addresses)
5815 {
5816 Dwarf_Addr addr1;
5817 Dwarf_Addr addr2;
5818 if (get_indexed_addr (cu, op1, &addr1) != 0
5819 || get_indexed_addr (cu, op2, &addr2) != 0)
5820 {
5821 printf (" ???..\n");
5822 printf (" ???\n");
5823 }
5824 else
5825 {
5826 printf (" ");
5827 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5828 printf ("..\n ");
5829 print_dwarf_addr (dwflmod, address_size,
5830 addr2 - 1, addr2);
5831 printf ("\n");
5832 }
5833 }
5834 break;
5835
5836 case DW_RLE_startx_length:
5837 if ((uint64_t) (nexthdr - readp) < 1)
5838 goto invalid_range;
5839 get_uleb128 (op1, readp, nexthdr);
5840 if ((uint64_t) (nexthdr - readp) < 1)
5841 goto invalid_range;
5842 get_uleb128 (op2, readp, nexthdr);
5843 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5844 if (! print_unresolved_addresses)
5845 {
5846 Dwarf_Addr addr1;
5847 Dwarf_Addr addr2;
5848 if (get_indexed_addr (cu, op1, &addr1) != 0)
5849 {
5850 printf (" ???..\n");
5851 printf (" ???\n");
5852 }
5853 else
5854 {
5855 addr2 = addr1 + op2;
5856 printf (" ");
5857 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5858 printf ("..\n ");
5859 print_dwarf_addr (dwflmod, address_size,
5860 addr2 - 1, addr2);
5861 printf ("\n");
5862 }
5863 }
5864 break;
5865
5866 case DW_RLE_offset_pair:
5867 if ((uint64_t) (nexthdr - readp) < 1)
5868 goto invalid_range;
5869 get_uleb128 (op1, readp, nexthdr);
5870 if ((uint64_t) (nexthdr - readp) < 1)
5871 goto invalid_range;
5872 get_uleb128 (op2, readp, nexthdr);
5873 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5874 if (! print_unresolved_addresses)
5875 {
5876 op1 += base;
5877 op2 += base;
5878 printf (" ");
5879 print_dwarf_addr (dwflmod, address_size, op1, op1);
5880 printf ("..\n ");
5881 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5882 printf ("\n");
5883 }
5884 break;
5885
5886 case DW_RLE_base_address:
5887 if (address_size == 4)
5888 {
5889 if ((uint64_t) (nexthdr - readp) < 4)
5890 goto invalid_range;
5891 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5892 }
5893 else
5894 {
5895 if ((uint64_t) (nexthdr - readp) < 8)
5896 goto invalid_range;
5897 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5898 }
5899 base = op1;
5900 printf (" 0x%" PRIx64 "\n", base);
5901 if (! print_unresolved_addresses)
5902 {
5903 printf (" ");
5904 print_dwarf_addr (dwflmod, address_size, base, base);
5905 printf ("\n");
5906 }
5907 break;
5908
5909 case DW_RLE_start_end:
5910 if (address_size == 4)
5911 {
5912 if ((uint64_t) (nexthdr - readp) < 8)
5913 goto invalid_range;
5914 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5915 op2 = read_4ubyte_unaligned_inc (dbg, readp);
5916 }
5917 else
5918 {
5919 if ((uint64_t) (nexthdr - readp) < 16)
5920 goto invalid_range;
5921 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5922 op2 = read_8ubyte_unaligned_inc (dbg, readp);
5923 }
5924 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5925 if (! print_unresolved_addresses)
5926 {
5927 printf (" ");
5928 print_dwarf_addr (dwflmod, address_size, op1, op1);
5929 printf ("..\n ");
5930 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5931 printf ("\n");
5932 }
5933 break;
5934
5935 case DW_RLE_start_length:
5936 if (address_size == 4)
5937 {
5938 if ((uint64_t) (nexthdr - readp) < 4)
5939 goto invalid_range;
5940 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5941 }
5942 else
5943 {
5944 if ((uint64_t) (nexthdr - readp) < 8)
5945 goto invalid_range;
5946 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5947 }
5948 if ((uint64_t) (nexthdr - readp) < 1)
5949 goto invalid_range;
5950 get_uleb128 (op2, readp, nexthdr);
5951 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5952 if (! print_unresolved_addresses)
5953 {
5954 op2 = op1 + op2;
5955 printf (" ");
5956 print_dwarf_addr (dwflmod, address_size, op1, op1);
5957 printf ("..\n ");
5958 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5959 printf ("\n");
5960 }
5961 break;
5962
5963 default:
5964 goto invalid_range;
5965 }
5966 }
5967
5968 next_table:
5969 if (readp != nexthdr)
5970 {
5971 size_t padding = nexthdr - readp;
5972 printf (gettext (" %zu padding bytes\n\n"), padding);
5973 readp = nexthdr;
5974 }
5975 }
5976 }
5977
5978 /* Print content of DWARF .debug_ranges section. */
5979 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5980 print_debug_ranges_section (Dwfl_Module *dwflmod,
5981 Ebl *ebl, GElf_Ehdr *ehdr,
5982 Elf_Scn *scn, GElf_Shdr *shdr,
5983 Dwarf *dbg)
5984 {
5985 Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
5986 ?: elf_rawdata (scn, NULL));
5987 if (unlikely (data == NULL))
5988 {
5989 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
5990 elf_errmsg (-1));
5991 return;
5992 }
5993
5994 printf (gettext ("\
5995 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5996 elf_ndxscn (scn), section_name (ebl, shdr),
5997 (uint64_t) shdr->sh_offset);
5998
5999 sort_listptr (&known_rangelistptr, "rangelistptr");
6000 size_t listptr_idx = 0;
6001
6002 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6003
6004 bool first = true;
6005 Dwarf_Addr base = 0;
6006 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6007 unsigned char *readp = data->d_buf;
6008 Dwarf_CU *last_cu = NULL;
6009 while (readp < endp)
6010 {
6011 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6012 Dwarf_CU *cu = last_cu;
6013
6014 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6015 &address_size, NULL, &base, &cu,
6016 offset, &readp, endp, NULL))
6017 continue;
6018
6019 if (last_cu != cu)
6020 {
6021 Dwarf_Die cudie;
6022 if (dwarf_cu_die (cu, &cudie,
6023 NULL, NULL, NULL, NULL,
6024 NULL, NULL) == NULL)
6025 printf (gettext ("\n Unknown CU base: "));
6026 else
6027 printf (gettext ("\n CU [%6" PRIx64 "] base: "),
6028 dwarf_dieoffset (&cudie));
6029 print_dwarf_addr (dwflmod, address_size, base, base);
6030 printf ("\n");
6031 }
6032 last_cu = cu;
6033
6034 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6035 {
6036 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6037 break;
6038 }
6039
6040 Dwarf_Addr begin;
6041 Dwarf_Addr end;
6042 if (address_size == 8)
6043 {
6044 begin = read_8ubyte_unaligned_inc (dbg, readp);
6045 end = read_8ubyte_unaligned_inc (dbg, readp);
6046 }
6047 else
6048 {
6049 begin = read_4ubyte_unaligned_inc (dbg, readp);
6050 end = read_4ubyte_unaligned_inc (dbg, readp);
6051 if (begin == (Dwarf_Addr) (uint32_t) -1)
6052 begin = (Dwarf_Addr) -1l;
6053 }
6054
6055 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6056 {
6057 printf (gettext (" [%6tx] base address\n "), offset);
6058 print_dwarf_addr (dwflmod, address_size, end, end);
6059 printf ("\n");
6060 base = end;
6061 }
6062 else if (begin == 0 && end == 0) /* End of list entry. */
6063 {
6064 if (first)
6065 printf (gettext (" [%6tx] empty list\n"), offset);
6066 first = true;
6067 }
6068 else
6069 {
6070 /* We have an address range entry. */
6071 if (first) /* First address range entry in a list. */
6072 printf (" [%6tx] ", offset);
6073 else
6074 printf (" ");
6075
6076 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6077 if (! print_unresolved_addresses)
6078 {
6079 printf (" ");
6080 print_dwarf_addr (dwflmod, address_size, base + begin,
6081 base + begin);
6082 printf ("..\n ");
6083 print_dwarf_addr (dwflmod, address_size,
6084 base + end - 1, base + end);
6085 printf ("\n");
6086 }
6087
6088 first = false;
6089 }
6090 }
6091 }
6092
6093 #define REGNAMESZ 16
6094 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6095 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6096 char name[REGNAMESZ], int *bits, int *type)
6097 {
6098 const char *set;
6099 const char *pfx;
6100 int ignore;
6101 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6102 bits ?: &ignore, type ?: &ignore);
6103 if (n <= 0)
6104 {
6105 if (loc != NULL)
6106 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6107 else
6108 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6109 if (bits != NULL)
6110 *bits = loc != NULL ? loc->bits : 0;
6111 if (type != NULL)
6112 *type = DW_ATE_unsigned;
6113 set = "??? unrecognized";
6114 }
6115 else
6116 {
6117 if (bits != NULL && *bits <= 0)
6118 *bits = loc != NULL ? loc->bits : 0;
6119 if (type != NULL && *type == DW_ATE_void)
6120 *type = DW_ATE_unsigned;
6121
6122 }
6123 return set;
6124 }
6125
6126 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6127 read_encoded (unsigned int encoding, const unsigned char *readp,
6128 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6129 {
6130 if ((encoding & 0xf) == DW_EH_PE_absptr)
6131 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6132 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6133
6134 switch (encoding & 0xf)
6135 {
6136 case DW_EH_PE_uleb128:
6137 get_uleb128 (*res, readp, endp);
6138 break;
6139 case DW_EH_PE_sleb128:
6140 get_sleb128 (*res, readp, endp);
6141 break;
6142 case DW_EH_PE_udata2:
6143 if (readp + 2 > endp)
6144 goto invalid;
6145 *res = read_2ubyte_unaligned_inc (dbg, readp);
6146 break;
6147 case DW_EH_PE_udata4:
6148 if (readp + 4 > endp)
6149 goto invalid;
6150 *res = read_4ubyte_unaligned_inc (dbg, readp);
6151 break;
6152 case DW_EH_PE_udata8:
6153 if (readp + 8 > endp)
6154 goto invalid;
6155 *res = read_8ubyte_unaligned_inc (dbg, readp);
6156 break;
6157 case DW_EH_PE_sdata2:
6158 if (readp + 2 > endp)
6159 goto invalid;
6160 *res = read_2sbyte_unaligned_inc (dbg, readp);
6161 break;
6162 case DW_EH_PE_sdata4:
6163 if (readp + 4 > endp)
6164 goto invalid;
6165 *res = read_4sbyte_unaligned_inc (dbg, readp);
6166 break;
6167 case DW_EH_PE_sdata8:
6168 if (readp + 8 > endp)
6169 goto invalid;
6170 *res = read_8sbyte_unaligned_inc (dbg, readp);
6171 break;
6172 default:
6173 invalid:
6174 error (1, 0,
6175 gettext ("invalid encoding"));
6176 }
6177
6178 return readp;
6179 }
6180
6181
6182 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)6183 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6184 Dwarf_Word vma_base, unsigned int code_align,
6185 int data_align,
6186 unsigned int version, unsigned int ptr_size,
6187 unsigned int encoding,
6188 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
6189 {
6190 char regnamebuf[REGNAMESZ];
6191 const char *regname (unsigned int regno)
6192 {
6193 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6194 return regnamebuf;
6195 }
6196
6197 puts ("\n Program:");
6198 Dwarf_Word pc = vma_base;
6199 while (readp < endp)
6200 {
6201 unsigned int opcode = *readp++;
6202
6203 if (opcode < DW_CFA_advance_loc)
6204 /* Extended opcode. */
6205 switch (opcode)
6206 {
6207 uint64_t op1;
6208 int64_t sop1;
6209 uint64_t op2;
6210 int64_t sop2;
6211
6212 case DW_CFA_nop:
6213 puts (" nop");
6214 break;
6215 case DW_CFA_set_loc:
6216 if ((uint64_t) (endp - readp) < 1)
6217 goto invalid;
6218 readp = read_encoded (encoding, readp, endp, &op1, dbg);
6219 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6220 op1, pc = vma_base + op1);
6221 break;
6222 case DW_CFA_advance_loc1:
6223 if ((uint64_t) (endp - readp) < 1)
6224 goto invalid;
6225 printf (" advance_loc1 %u to %#" PRIx64 "\n",
6226 *readp, pc += *readp * code_align);
6227 ++readp;
6228 break;
6229 case DW_CFA_advance_loc2:
6230 if ((uint64_t) (endp - readp) < 2)
6231 goto invalid;
6232 op1 = read_2ubyte_unaligned_inc (dbg, readp);
6233 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6234 op1, pc += op1 * code_align);
6235 break;
6236 case DW_CFA_advance_loc4:
6237 if ((uint64_t) (endp - readp) < 4)
6238 goto invalid;
6239 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6240 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6241 op1, pc += op1 * code_align);
6242 break;
6243 case DW_CFA_offset_extended:
6244 if ((uint64_t) (endp - readp) < 1)
6245 goto invalid;
6246 get_uleb128 (op1, readp, endp);
6247 if ((uint64_t) (endp - readp) < 1)
6248 goto invalid;
6249 get_uleb128 (op2, readp, endp);
6250 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6251 "\n",
6252 op1, regname (op1), op2 * data_align);
6253 break;
6254 case DW_CFA_restore_extended:
6255 if ((uint64_t) (endp - readp) < 1)
6256 goto invalid;
6257 get_uleb128 (op1, readp, endp);
6258 printf (" restore_extended r%" PRIu64 " (%s)\n",
6259 op1, regname (op1));
6260 break;
6261 case DW_CFA_undefined:
6262 if ((uint64_t) (endp - readp) < 1)
6263 goto invalid;
6264 get_uleb128 (op1, readp, endp);
6265 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
6266 break;
6267 case DW_CFA_same_value:
6268 if ((uint64_t) (endp - readp) < 1)
6269 goto invalid;
6270 get_uleb128 (op1, readp, endp);
6271 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
6272 break;
6273 case DW_CFA_register:
6274 if ((uint64_t) (endp - readp) < 1)
6275 goto invalid;
6276 get_uleb128 (op1, readp, endp);
6277 if ((uint64_t) (endp - readp) < 1)
6278 goto invalid;
6279 get_uleb128 (op2, readp, endp);
6280 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6281 op1, regname (op1), op2, regname (op2));
6282 break;
6283 case DW_CFA_remember_state:
6284 puts (" remember_state");
6285 break;
6286 case DW_CFA_restore_state:
6287 puts (" restore_state");
6288 break;
6289 case DW_CFA_def_cfa:
6290 if ((uint64_t) (endp - readp) < 1)
6291 goto invalid;
6292 get_uleb128 (op1, readp, endp);
6293 if ((uint64_t) (endp - readp) < 1)
6294 goto invalid;
6295 get_uleb128 (op2, readp, endp);
6296 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6297 op1, regname (op1), op2);
6298 break;
6299 case DW_CFA_def_cfa_register:
6300 if ((uint64_t) (endp - readp) < 1)
6301 goto invalid;
6302 get_uleb128 (op1, readp, endp);
6303 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
6304 op1, regname (op1));
6305 break;
6306 case DW_CFA_def_cfa_offset:
6307 if ((uint64_t) (endp - readp) < 1)
6308 goto invalid;
6309 get_uleb128 (op1, readp, endp);
6310 printf (" def_cfa_offset %" PRIu64 "\n", op1);
6311 break;
6312 case DW_CFA_def_cfa_expression:
6313 if ((uint64_t) (endp - readp) < 1)
6314 goto invalid;
6315 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
6316 printf (" def_cfa_expression %" PRIu64 "\n", op1);
6317 if ((uint64_t) (endp - readp) < op1)
6318 {
6319 invalid:
6320 fputs (gettext (" <INVALID DATA>\n"), stdout);
6321 return;
6322 }
6323 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6324 op1, readp);
6325 readp += op1;
6326 break;
6327 case DW_CFA_expression:
6328 if ((uint64_t) (endp - readp) < 1)
6329 goto invalid;
6330 get_uleb128 (op1, readp, endp);
6331 if ((uint64_t) (endp - readp) < 1)
6332 goto invalid;
6333 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6334 printf (" expression r%" PRIu64 " (%s) \n",
6335 op1, regname (op1));
6336 if ((uint64_t) (endp - readp) < op2)
6337 goto invalid;
6338 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6339 op2, readp);
6340 readp += op2;
6341 break;
6342 case DW_CFA_offset_extended_sf:
6343 if ((uint64_t) (endp - readp) < 1)
6344 goto invalid;
6345 get_uleb128 (op1, readp, endp);
6346 if ((uint64_t) (endp - readp) < 1)
6347 goto invalid;
6348 get_sleb128 (sop2, readp, endp);
6349 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6350 PRId64 "\n",
6351 op1, regname (op1), sop2 * data_align);
6352 break;
6353 case DW_CFA_def_cfa_sf:
6354 if ((uint64_t) (endp - readp) < 1)
6355 goto invalid;
6356 get_uleb128 (op1, readp, endp);
6357 if ((uint64_t) (endp - readp) < 1)
6358 goto invalid;
6359 get_sleb128 (sop2, readp, endp);
6360 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6361 op1, regname (op1), sop2 * data_align);
6362 break;
6363 case DW_CFA_def_cfa_offset_sf:
6364 if ((uint64_t) (endp - readp) < 1)
6365 goto invalid;
6366 get_sleb128 (sop1, readp, endp);
6367 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6368 break;
6369 case DW_CFA_val_offset:
6370 if ((uint64_t) (endp - readp) < 1)
6371 goto invalid;
6372 get_uleb128 (op1, readp, endp);
6373 if ((uint64_t) (endp - readp) < 1)
6374 goto invalid;
6375 get_uleb128 (op2, readp, endp);
6376 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6377 op1, op2 * data_align);
6378 break;
6379 case DW_CFA_val_offset_sf:
6380 if ((uint64_t) (endp - readp) < 1)
6381 goto invalid;
6382 get_uleb128 (op1, readp, endp);
6383 if ((uint64_t) (endp - readp) < 1)
6384 goto invalid;
6385 get_sleb128 (sop2, readp, endp);
6386 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6387 op1, sop2 * data_align);
6388 break;
6389 case DW_CFA_val_expression:
6390 if ((uint64_t) (endp - readp) < 1)
6391 goto invalid;
6392 get_uleb128 (op1, readp, endp);
6393 if ((uint64_t) (endp - readp) < 1)
6394 goto invalid;
6395 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6396 printf (" val_expression r%" PRIu64 " (%s)\n",
6397 op1, regname (op1));
6398 if ((uint64_t) (endp - readp) < op2)
6399 goto invalid;
6400 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6401 NULL, op2, readp);
6402 readp += op2;
6403 break;
6404 case DW_CFA_MIPS_advance_loc8:
6405 if ((uint64_t) (endp - readp) < 8)
6406 goto invalid;
6407 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6408 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6409 op1, pc += op1 * code_align);
6410 break;
6411 case DW_CFA_GNU_window_save:
6412 puts (" GNU_window_save");
6413 break;
6414 case DW_CFA_GNU_args_size:
6415 if ((uint64_t) (endp - readp) < 1)
6416 goto invalid;
6417 get_uleb128 (op1, readp, endp);
6418 printf (" args_size %" PRIu64 "\n", op1);
6419 break;
6420 default:
6421 printf (" ??? (%u)\n", opcode);
6422 break;
6423 }
6424 else if (opcode < DW_CFA_offset)
6425 printf (" advance_loc %u to %#" PRIx64 "\n",
6426 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6427 else if (opcode < DW_CFA_restore)
6428 {
6429 uint64_t offset;
6430 if ((uint64_t) (endp - readp) < 1)
6431 goto invalid;
6432 get_uleb128 (offset, readp, endp);
6433 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
6434 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
6435 }
6436 else
6437 printf (" restore r%u (%s)\n",
6438 opcode & 0x3f, regname (opcode & 0x3f));
6439 }
6440 }
6441
6442
6443 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6444 encoded_ptr_size (int encoding, unsigned int ptr_size)
6445 {
6446 switch (encoding & 7)
6447 {
6448 case DW_EH_PE_udata4:
6449 return 4;
6450 case DW_EH_PE_udata8:
6451 return 8;
6452 case 0:
6453 return ptr_size;
6454 }
6455
6456 fprintf (stderr, "Unsupported pointer encoding: %#x, "
6457 "assuming pointer size of %d.\n", encoding, ptr_size);
6458 return ptr_size;
6459 }
6460
6461
6462 static unsigned int
print_encoding(unsigned int val)6463 print_encoding (unsigned int val)
6464 {
6465 switch (val & 0xf)
6466 {
6467 case DW_EH_PE_absptr:
6468 fputs ("absptr", stdout);
6469 break;
6470 case DW_EH_PE_uleb128:
6471 fputs ("uleb128", stdout);
6472 break;
6473 case DW_EH_PE_udata2:
6474 fputs ("udata2", stdout);
6475 break;
6476 case DW_EH_PE_udata4:
6477 fputs ("udata4", stdout);
6478 break;
6479 case DW_EH_PE_udata8:
6480 fputs ("udata8", stdout);
6481 break;
6482 case DW_EH_PE_sleb128:
6483 fputs ("sleb128", stdout);
6484 break;
6485 case DW_EH_PE_sdata2:
6486 fputs ("sdata2", stdout);
6487 break;
6488 case DW_EH_PE_sdata4:
6489 fputs ("sdata4", stdout);
6490 break;
6491 case DW_EH_PE_sdata8:
6492 fputs ("sdata8", stdout);
6493 break;
6494 default:
6495 /* We did not use any of the bits after all. */
6496 return val;
6497 }
6498
6499 return val & ~0xf;
6500 }
6501
6502
6503 static unsigned int
print_relinfo(unsigned int val)6504 print_relinfo (unsigned int val)
6505 {
6506 switch (val & 0x70)
6507 {
6508 case DW_EH_PE_pcrel:
6509 fputs ("pcrel", stdout);
6510 break;
6511 case DW_EH_PE_textrel:
6512 fputs ("textrel", stdout);
6513 break;
6514 case DW_EH_PE_datarel:
6515 fputs ("datarel", stdout);
6516 break;
6517 case DW_EH_PE_funcrel:
6518 fputs ("funcrel", stdout);
6519 break;
6520 case DW_EH_PE_aligned:
6521 fputs ("aligned", stdout);
6522 break;
6523 default:
6524 return val;
6525 }
6526
6527 return val & ~0x70;
6528 }
6529
6530
6531 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6532 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6533 {
6534 printf ("(%s", pfx);
6535
6536 if (fde_encoding == DW_EH_PE_omit)
6537 puts ("omit)");
6538 else
6539 {
6540 unsigned int w = fde_encoding;
6541
6542 w = print_encoding (w);
6543
6544 if (w & 0x70)
6545 {
6546 if (w != fde_encoding)
6547 fputc_unlocked (' ', stdout);
6548
6549 w = print_relinfo (w);
6550 }
6551
6552 if (w != 0)
6553 printf ("%s%x", w != fde_encoding ? " " : "", w);
6554
6555 puts (")");
6556 }
6557 }
6558
6559
6560 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6561 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6562 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6563 {
6564 size_t shstrndx;
6565 /* We know this call will succeed since it did in the caller. */
6566 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6567 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6568
6569 /* Needed if we find PC-relative addresses. */
6570 GElf_Addr bias;
6571 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6572 {
6573 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
6574 return;
6575 }
6576
6577 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6578 Elf_Data *data = (is_eh_frame
6579 ? elf_rawdata (scn, NULL)
6580 : (dbg->sectiondata[IDX_debug_frame]
6581 ?: elf_rawdata (scn, NULL)));
6582
6583 if (unlikely (data == NULL))
6584 {
6585 error (0, 0, gettext ("cannot get %s content: %s"),
6586 scnname, elf_errmsg (-1));
6587 return;
6588 }
6589
6590 if (is_eh_frame)
6591 printf (gettext ("\
6592 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6593 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6594 else
6595 printf (gettext ("\
6596 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6597 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6598
6599 struct cieinfo
6600 {
6601 ptrdiff_t cie_offset;
6602 const char *augmentation;
6603 unsigned int code_alignment_factor;
6604 unsigned int data_alignment_factor;
6605 uint8_t address_size;
6606 uint8_t fde_encoding;
6607 uint8_t lsda_encoding;
6608 struct cieinfo *next;
6609 } *cies = NULL;
6610
6611 const unsigned char *readp = data->d_buf;
6612 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6613 + data->d_size);
6614 while (readp < dataend)
6615 {
6616 if (unlikely (readp + 4 > dataend))
6617 {
6618 invalid_data:
6619 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6620 elf_ndxscn (scn), scnname);
6621 return;
6622 }
6623
6624 /* At the beginning there must be a CIE. There can be multiple,
6625 hence we test tis in a loop. */
6626 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6627
6628 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6629 unsigned int length = 4;
6630 if (unlikely (unit_length == 0xffffffff))
6631 {
6632 if (unlikely (readp + 8 > dataend))
6633 goto invalid_data;
6634
6635 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6636 length = 8;
6637 }
6638
6639 if (unlikely (unit_length == 0))
6640 {
6641 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
6642 continue;
6643 }
6644
6645 Dwarf_Word maxsize = dataend - readp;
6646 if (unlikely (unit_length > maxsize))
6647 goto invalid_data;
6648
6649 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6650
6651 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6652 const unsigned char *const cieend = readp + unit_length;
6653 if (unlikely (cieend > dataend))
6654 goto invalid_data;
6655
6656 Dwarf_Off cie_id;
6657 if (length == 4)
6658 {
6659 if (unlikely (cieend - readp < 4))
6660 goto invalid_data;
6661 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6662 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6663 cie_id = DW_CIE_ID_64;
6664 }
6665 else
6666 {
6667 if (unlikely (cieend - readp < 8))
6668 goto invalid_data;
6669 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6670 }
6671
6672 uint_fast8_t version = 2;
6673 unsigned int code_alignment_factor;
6674 int data_alignment_factor;
6675 unsigned int fde_encoding = 0;
6676 unsigned int lsda_encoding = 0;
6677 Dwarf_Word initial_location = 0;
6678 Dwarf_Word vma_base = 0;
6679
6680 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6681 {
6682 if (unlikely (cieend - readp < 2))
6683 goto invalid_data;
6684 version = *readp++;
6685 const char *const augmentation = (const char *) readp;
6686 readp = memchr (readp, '\0', cieend - readp);
6687 if (unlikely (readp == NULL))
6688 goto invalid_data;
6689 ++readp;
6690
6691 uint_fast8_t segment_size = 0;
6692 if (version >= 4)
6693 {
6694 if (cieend - readp < 5)
6695 goto invalid_data;
6696 ptr_size = *readp++;
6697 segment_size = *readp++;
6698 }
6699
6700 if (cieend - readp < 1)
6701 goto invalid_data;
6702 get_uleb128 (code_alignment_factor, readp, cieend);
6703 if (cieend - readp < 1)
6704 goto invalid_data;
6705 get_sleb128 (data_alignment_factor, readp, cieend);
6706
6707 /* In some variant for unwind data there is another field. */
6708 if (strcmp (augmentation, "eh") == 0)
6709 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6710
6711 unsigned int return_address_register;
6712 if (cieend - readp < 1)
6713 goto invalid_data;
6714 if (unlikely (version == 1))
6715 return_address_register = *readp++;
6716 else
6717 get_uleb128 (return_address_register, readp, cieend);
6718
6719 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6720 " CIE_id: %" PRIu64 "\n"
6721 " version: %u\n"
6722 " augmentation: \"%s\"\n",
6723 offset, (uint64_t) unit_length, (uint64_t) cie_id,
6724 version, augmentation);
6725 if (version >= 4)
6726 printf (" address_size: %u\n"
6727 " segment_size: %u\n",
6728 ptr_size, segment_size);
6729 printf (" code_alignment_factor: %u\n"
6730 " data_alignment_factor: %d\n"
6731 " return_address_register: %u\n",
6732 code_alignment_factor,
6733 data_alignment_factor, return_address_register);
6734
6735 if (augmentation[0] == 'z')
6736 {
6737 unsigned int augmentationlen;
6738 get_uleb128 (augmentationlen, readp, cieend);
6739
6740 if (augmentationlen > (size_t) (cieend - readp))
6741 {
6742 error (0, 0, gettext ("invalid augmentation length"));
6743 readp = cieend;
6744 continue;
6745 }
6746
6747 const char *hdr = "Augmentation data:";
6748 const char *cp = augmentation + 1;
6749 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6750 {
6751 printf (" %-26s%#x ", hdr, *readp);
6752 hdr = "";
6753
6754 if (*cp == 'R')
6755 {
6756 fde_encoding = *readp++;
6757 print_encoding_base (gettext ("FDE address encoding: "),
6758 fde_encoding);
6759 }
6760 else if (*cp == 'L')
6761 {
6762 lsda_encoding = *readp++;
6763 print_encoding_base (gettext ("LSDA pointer encoding: "),
6764 lsda_encoding);
6765 }
6766 else if (*cp == 'P')
6767 {
6768 /* Personality. This field usually has a relocation
6769 attached pointing to __gcc_personality_v0. */
6770 const unsigned char *startp = readp;
6771 unsigned int encoding = *readp++;
6772 uint64_t val = 0;
6773 readp = read_encoded (encoding, readp,
6774 readp - 1 + augmentationlen,
6775 &val, dbg);
6776
6777 while (++startp < readp)
6778 printf ("%#x ", *startp);
6779
6780 putchar ('(');
6781 print_encoding (encoding);
6782 putchar (' ');
6783 switch (encoding & 0xf)
6784 {
6785 case DW_EH_PE_sleb128:
6786 case DW_EH_PE_sdata2:
6787 case DW_EH_PE_sdata4:
6788 printf ("%" PRId64 ")\n", val);
6789 break;
6790 default:
6791 printf ("%#" PRIx64 ")\n", val);
6792 break;
6793 }
6794 }
6795 else
6796 printf ("(%x)\n", *readp++);
6797
6798 ++cp;
6799 }
6800 }
6801
6802 if (likely (ptr_size == 4 || ptr_size == 8))
6803 {
6804 struct cieinfo *newp = alloca (sizeof (*newp));
6805 newp->cie_offset = offset;
6806 newp->augmentation = augmentation;
6807 newp->fde_encoding = fde_encoding;
6808 newp->lsda_encoding = lsda_encoding;
6809 newp->address_size = ptr_size;
6810 newp->code_alignment_factor = code_alignment_factor;
6811 newp->data_alignment_factor = data_alignment_factor;
6812 newp->next = cies;
6813 cies = newp;
6814 }
6815 }
6816 else
6817 {
6818 struct cieinfo *cie = cies;
6819 while (cie != NULL)
6820 if (is_eh_frame
6821 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6822 : cie_id == (Dwarf_Off) cie->cie_offset)
6823 break;
6824 else
6825 cie = cie->next;
6826 if (unlikely (cie == NULL))
6827 {
6828 puts ("invalid CIE reference in FDE");
6829 return;
6830 }
6831
6832 /* Initialize from CIE data. */
6833 fde_encoding = cie->fde_encoding;
6834 lsda_encoding = cie->lsda_encoding;
6835 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6836 code_alignment_factor = cie->code_alignment_factor;
6837 data_alignment_factor = cie->data_alignment_factor;
6838
6839 const unsigned char *base = readp;
6840 // XXX There are sometimes relocations for this value
6841 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6842 Dwarf_Word address_range
6843 = read_addr_unaligned_inc (ptr_size, dbg, readp);
6844
6845 /* pcrel for an FDE address is relative to the runtime
6846 address of the start_address field itself. Sign extend
6847 if necessary to make sure the calculation is done on the
6848 full 64 bit address even when initial_location only holds
6849 the lower 32 bits. */
6850 Dwarf_Addr pc_start = initial_location;
6851 if (ptr_size == 4)
6852 pc_start = (uint64_t) (int32_t) pc_start;
6853 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6854 pc_start += ((uint64_t) shdr->sh_addr
6855 + (base - (const unsigned char *) data->d_buf)
6856 - bias);
6857
6858 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6859 " CIE_pointer: %" PRIu64 "\n"
6860 " initial_location: ",
6861 offset, (uint64_t) unit_length,
6862 cie->cie_offset, (uint64_t) cie_id);
6863 print_dwarf_addr (dwflmod, cie->address_size,
6864 pc_start, initial_location);
6865 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6866 {
6867 vma_base = (((uint64_t) shdr->sh_offset
6868 + (base - (const unsigned char *) data->d_buf)
6869 + (uint64_t) initial_location)
6870 & (ptr_size == 4
6871 ? UINT64_C (0xffffffff)
6872 : UINT64_C (0xffffffffffffffff)));
6873 printf (gettext (" (offset: %#" PRIx64 ")"),
6874 (uint64_t) vma_base);
6875 }
6876
6877 printf ("\n address_range: %#" PRIx64,
6878 (uint64_t) address_range);
6879 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6880 printf (gettext (" (end offset: %#" PRIx64 ")"),
6881 ((uint64_t) vma_base + (uint64_t) address_range)
6882 & (ptr_size == 4
6883 ? UINT64_C (0xffffffff)
6884 : UINT64_C (0xffffffffffffffff)));
6885 putchar ('\n');
6886
6887 if (cie->augmentation[0] == 'z')
6888 {
6889 unsigned int augmentationlen;
6890 if (cieend - readp < 1)
6891 goto invalid_data;
6892 get_uleb128 (augmentationlen, readp, cieend);
6893
6894 if (augmentationlen > (size_t) (cieend - readp))
6895 {
6896 error (0, 0, gettext ("invalid augmentation length"));
6897 readp = cieend;
6898 continue;
6899 }
6900
6901 if (augmentationlen > 0)
6902 {
6903 const char *hdr = "Augmentation data:";
6904 const char *cp = cie->augmentation + 1;
6905 unsigned int u = 0;
6906 while (*cp != '\0'
6907 && cp < cie->augmentation + augmentationlen + 1)
6908 {
6909 if (*cp == 'L')
6910 {
6911 uint64_t lsda_pointer;
6912 const unsigned char *p
6913 = read_encoded (lsda_encoding, &readp[u],
6914 &readp[augmentationlen],
6915 &lsda_pointer, dbg);
6916 u = p - readp;
6917 printf (gettext ("\
6918 %-26sLSDA pointer: %#" PRIx64 "\n"),
6919 hdr, lsda_pointer);
6920 hdr = "";
6921 }
6922 ++cp;
6923 }
6924
6925 while (u < augmentationlen)
6926 {
6927 printf (" %-26s%#x\n", hdr, readp[u++]);
6928 hdr = "";
6929 }
6930 }
6931
6932 readp += augmentationlen;
6933 }
6934 }
6935
6936 /* Handle the initialization instructions. */
6937 if (ptr_size != 4 && ptr_size !=8)
6938 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6939 else
6940 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6941 data_alignment_factor, version, ptr_size,
6942 fde_encoding, dwflmod, ebl, dbg);
6943 readp = cieend;
6944 }
6945 }
6946
6947
6948 /* Returns the signedness (or false if it cannot be determined) and
6949 the byte size (or zero if it cannot be gotten) of the given DIE
6950 DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */
6951 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)6952 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
6953 {
6954 Dwarf_Attribute attr;
6955 Dwarf_Die type;
6956
6957 *bytes = 0;
6958 *is_signed = false;
6959
6960 if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
6961 DW_AT_type,
6962 &attr), &type),
6963 &type) == 0)
6964 {
6965 Dwarf_Word val;
6966 *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
6967 &attr), &val) == 0
6968 && (val == DW_ATE_signed || val == DW_ATE_signed_char));
6969
6970 if (dwarf_aggregate_size (&type, &val) == 0)
6971 *bytes = val;
6972 }
6973 }
6974
6975 struct attrcb_args
6976 {
6977 Dwfl_Module *dwflmod;
6978 Dwarf *dbg;
6979 Dwarf_Die *dies;
6980 int level;
6981 bool silent;
6982 bool is_split;
6983 unsigned int version;
6984 unsigned int addrsize;
6985 unsigned int offset_size;
6986 struct Dwarf_CU *cu;
6987 };
6988
6989
6990 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)6991 attr_callback (Dwarf_Attribute *attrp, void *arg)
6992 {
6993 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
6994 const int level = cbargs->level;
6995 Dwarf_Die *die = &cbargs->dies[level];
6996 bool is_split = cbargs->is_split;
6997
6998 unsigned int attr = dwarf_whatattr (attrp);
6999 if (unlikely (attr == 0))
7000 {
7001 if (!cbargs->silent)
7002 error (0, 0, gettext ("DIE [%" PRIx64 "] "
7003 "cannot get attribute code: %s"),
7004 dwarf_dieoffset (die), dwarf_errmsg (-1));
7005 return DWARF_CB_ABORT;
7006 }
7007
7008 unsigned int form = dwarf_whatform (attrp);
7009 if (unlikely (form == 0))
7010 {
7011 if (!cbargs->silent)
7012 error (0, 0, gettext ("DIE [%" PRIx64 "] "
7013 "cannot get attribute form: %s"),
7014 dwarf_dieoffset (die), dwarf_errmsg (-1));
7015 return DWARF_CB_ABORT;
7016 }
7017
7018 switch (form)
7019 {
7020 case DW_FORM_addr:
7021 case DW_FORM_addrx:
7022 case DW_FORM_addrx1:
7023 case DW_FORM_addrx2:
7024 case DW_FORM_addrx3:
7025 case DW_FORM_addrx4:
7026 case DW_FORM_GNU_addr_index:
7027 if (!cbargs->silent)
7028 {
7029 Dwarf_Addr addr;
7030 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7031 {
7032 attrval_out:
7033 if (!cbargs->silent)
7034 error (0, 0, gettext ("DIE [%" PRIx64 "] "
7035 "cannot get attribute '%s' (%s) value: "
7036 "%s"),
7037 dwarf_dieoffset (die),
7038 dwarf_attr_name (attr),
7039 dwarf_form_name (form),
7040 dwarf_errmsg (-1));
7041 /* Don't ABORT, it might be other attributes can be resolved. */
7042 return DWARF_CB_OK;
7043 }
7044 if (form != DW_FORM_addr )
7045 {
7046 Dwarf_Word word;
7047 if (dwarf_formudata (attrp, &word) != 0)
7048 goto attrval_out;
7049 printf (" %*s%-20s (%s) [%" PRIx64 "] ",
7050 (int) (level * 2), "", dwarf_attr_name (attr),
7051 dwarf_form_name (form), word);
7052 }
7053 else
7054 printf (" %*s%-20s (%s) ",
7055 (int) (level * 2), "", dwarf_attr_name (attr),
7056 dwarf_form_name (form));
7057 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7058 printf ("\n");
7059 }
7060 break;
7061
7062 case DW_FORM_indirect:
7063 case DW_FORM_strp:
7064 case DW_FORM_line_strp:
7065 case DW_FORM_strx:
7066 case DW_FORM_strx1:
7067 case DW_FORM_strx2:
7068 case DW_FORM_strx3:
7069 case DW_FORM_strx4:
7070 case DW_FORM_string:
7071 case DW_FORM_GNU_strp_alt:
7072 case DW_FORM_GNU_str_index:
7073 if (cbargs->silent)
7074 break;
7075 const char *str = dwarf_formstring (attrp);
7076 if (unlikely (str == NULL))
7077 goto attrval_out;
7078 printf (" %*s%-20s (%s) \"%s\"\n",
7079 (int) (level * 2), "", dwarf_attr_name (attr),
7080 dwarf_form_name (form), str);
7081 break;
7082
7083 case DW_FORM_ref_addr:
7084 case DW_FORM_ref_udata:
7085 case DW_FORM_ref8:
7086 case DW_FORM_ref4:
7087 case DW_FORM_ref2:
7088 case DW_FORM_ref1:
7089 case DW_FORM_GNU_ref_alt:
7090 case DW_FORM_ref_sup4:
7091 case DW_FORM_ref_sup8:
7092 if (cbargs->silent)
7093 break;
7094 Dwarf_Die ref;
7095 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7096 goto attrval_out;
7097
7098 printf (" %*s%-20s (%s) ",
7099 (int) (level * 2), "", dwarf_attr_name (attr),
7100 dwarf_form_name (form));
7101 if (is_split)
7102 printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7103 else
7104 printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7105 break;
7106
7107 case DW_FORM_ref_sig8:
7108 if (cbargs->silent)
7109 break;
7110 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
7111 (int) (level * 2), "", dwarf_attr_name (attr),
7112 dwarf_form_name (form),
7113 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7114 break;
7115
7116 case DW_FORM_sec_offset:
7117 case DW_FORM_rnglistx:
7118 case DW_FORM_loclistx:
7119 case DW_FORM_implicit_const:
7120 case DW_FORM_udata:
7121 case DW_FORM_sdata:
7122 case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7123 case DW_FORM_data4:
7124 case DW_FORM_data2:
7125 case DW_FORM_data1:;
7126 Dwarf_Word num;
7127 if (unlikely (dwarf_formudata (attrp, &num) != 0))
7128 goto attrval_out;
7129
7130 const char *valuestr = NULL;
7131 bool as_hex_id = false;
7132 switch (attr)
7133 {
7134 /* This case can take either a constant or a loclistptr. */
7135 case DW_AT_data_member_location:
7136 if (form != DW_FORM_sec_offset
7137 && (cbargs->version >= 4
7138 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7139 {
7140 if (!cbargs->silent)
7141 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
7142 (int) (level * 2), "", dwarf_attr_name (attr),
7143 dwarf_form_name (form), (uintmax_t) num);
7144 return DWARF_CB_OK;
7145 }
7146 FALLTHROUGH;
7147
7148 /* These cases always take a loclist[ptr] and no constant. */
7149 case DW_AT_location:
7150 case DW_AT_data_location:
7151 case DW_AT_vtable_elem_location:
7152 case DW_AT_string_length:
7153 case DW_AT_use_location:
7154 case DW_AT_frame_base:
7155 case DW_AT_return_addr:
7156 case DW_AT_static_link:
7157 case DW_AT_segment:
7158 case DW_AT_GNU_call_site_value:
7159 case DW_AT_GNU_call_site_data_value:
7160 case DW_AT_GNU_call_site_target:
7161 case DW_AT_GNU_call_site_target_clobbered:
7162 case DW_AT_GNU_locviews:
7163 {
7164 bool nlpt;
7165 if (cbargs->cu->version < 5)
7166 {
7167 if (! cbargs->is_split)
7168 {
7169 nlpt = notice_listptr (section_loc, &known_locsptr,
7170 cbargs->addrsize,
7171 cbargs->offset_size,
7172 cbargs->cu, num, attr);
7173 }
7174 else
7175 nlpt = true;
7176 }
7177 else
7178 {
7179 /* Only register for a real section offset. Otherwise
7180 it is a DW_FORM_loclistx which is just an index
7181 number and we should already have registered the
7182 section offset for the index when we saw the
7183 DW_AT_loclists_base CU attribute. */
7184 if (form == DW_FORM_sec_offset)
7185 nlpt = notice_listptr (section_loc, &known_loclistsptr,
7186 cbargs->addrsize, cbargs->offset_size,
7187 cbargs->cu, num, attr);
7188 else
7189 nlpt = true;
7190
7191 }
7192
7193 if (!cbargs->silent)
7194 {
7195 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7196 printf (" %*s%-20s (%s) location list [%6"
7197 PRIxMAX "]%s\n",
7198 (int) (level * 2), "", dwarf_attr_name (attr),
7199 dwarf_form_name (form), (uintmax_t) num,
7200 nlpt ? "" : " <WARNING offset too big>");
7201 else
7202 printf (" %*s%-20s (%s) location index [%6"
7203 PRIxMAX "]\n",
7204 (int) (level * 2), "", dwarf_attr_name (attr),
7205 dwarf_form_name (form), (uintmax_t) num);
7206 }
7207 }
7208 return DWARF_CB_OK;
7209
7210 case DW_AT_loclists_base:
7211 {
7212 bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7213 cbargs->addrsize, cbargs->offset_size,
7214 cbargs->cu, num, attr);
7215
7216 if (!cbargs->silent)
7217 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7218 (int) (level * 2), "", dwarf_attr_name (attr),
7219 dwarf_form_name (form), (uintmax_t) num,
7220 nlpt ? "" : " <WARNING offset too big>");
7221 }
7222 return DWARF_CB_OK;
7223
7224 case DW_AT_ranges:
7225 case DW_AT_start_scope:
7226 {
7227 bool nlpt;
7228 if (cbargs->cu->version < 5)
7229 nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7230 cbargs->addrsize, cbargs->offset_size,
7231 cbargs->cu, num, attr);
7232 else
7233 {
7234 /* Only register for a real section offset. Otherwise
7235 it is a DW_FORM_rangelistx which is just an index
7236 number and we should already have registered the
7237 section offset for the index when we saw the
7238 DW_AT_rnglists_base CU attribute. */
7239 if (form == DW_FORM_sec_offset)
7240 nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7241 cbargs->addrsize, cbargs->offset_size,
7242 cbargs->cu, num, attr);
7243 else
7244 nlpt = true;
7245 }
7246
7247 if (!cbargs->silent)
7248 {
7249 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7250 printf (" %*s%-20s (%s) range list [%6"
7251 PRIxMAX "]%s\n",
7252 (int) (level * 2), "", dwarf_attr_name (attr),
7253 dwarf_form_name (form), (uintmax_t) num,
7254 nlpt ? "" : " <WARNING offset too big>");
7255 else
7256 printf (" %*s%-20s (%s) range index [%6"
7257 PRIxMAX "]\n",
7258 (int) (level * 2), "", dwarf_attr_name (attr),
7259 dwarf_form_name (form), (uintmax_t) num);
7260 }
7261 }
7262 return DWARF_CB_OK;
7263
7264 case DW_AT_rnglists_base:
7265 {
7266 bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7267 cbargs->addrsize, cbargs->offset_size,
7268 cbargs->cu, num, attr);
7269 if (!cbargs->silent)
7270 printf (" %*s%-20s (%s) range list [%6"
7271 PRIxMAX "]%s\n",
7272 (int) (level * 2), "", dwarf_attr_name (attr),
7273 dwarf_form_name (form), (uintmax_t) num,
7274 nlpt ? "" : " <WARNING offset too big>");
7275 }
7276 return DWARF_CB_OK;
7277
7278 case DW_AT_addr_base:
7279 case DW_AT_GNU_addr_base:
7280 {
7281 bool addrbase = notice_listptr (section_addr, &known_addrbases,
7282 cbargs->addrsize,
7283 cbargs->offset_size,
7284 cbargs->cu, num, attr);
7285 if (!cbargs->silent)
7286 printf (" %*s%-20s (%s) address base [%6"
7287 PRIxMAX "]%s\n",
7288 (int) (level * 2), "", dwarf_attr_name (attr),
7289 dwarf_form_name (form), (uintmax_t) num,
7290 addrbase ? "" : " <WARNING offset too big>");
7291 }
7292 return DWARF_CB_OK;
7293
7294 case DW_AT_str_offsets_base:
7295 {
7296 bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7297 cbargs->addrsize,
7298 cbargs->offset_size,
7299 cbargs->cu, num, attr);
7300 if (!cbargs->silent)
7301 printf (" %*s%-20s (%s) str offsets base [%6"
7302 PRIxMAX "]%s\n",
7303 (int) (level * 2), "", dwarf_attr_name (attr),
7304 dwarf_form_name (form), (uintmax_t) num,
7305 stroffbase ? "" : " <WARNING offset too big>");
7306 }
7307 return DWARF_CB_OK;
7308
7309 case DW_AT_language:
7310 valuestr = dwarf_lang_name (num);
7311 break;
7312 case DW_AT_encoding:
7313 valuestr = dwarf_encoding_name (num);
7314 break;
7315 case DW_AT_accessibility:
7316 valuestr = dwarf_access_name (num);
7317 break;
7318 case DW_AT_defaulted:
7319 valuestr = dwarf_defaulted_name (num);
7320 break;
7321 case DW_AT_visibility:
7322 valuestr = dwarf_visibility_name (num);
7323 break;
7324 case DW_AT_virtuality:
7325 valuestr = dwarf_virtuality_name (num);
7326 break;
7327 case DW_AT_identifier_case:
7328 valuestr = dwarf_identifier_case_name (num);
7329 break;
7330 case DW_AT_calling_convention:
7331 valuestr = dwarf_calling_convention_name (num);
7332 break;
7333 case DW_AT_inline:
7334 valuestr = dwarf_inline_name (num);
7335 break;
7336 case DW_AT_ordering:
7337 valuestr = dwarf_ordering_name (num);
7338 break;
7339 case DW_AT_decl_file:
7340 case DW_AT_call_file:
7341 {
7342 if (cbargs->silent)
7343 break;
7344
7345 /* Try to get the actual file, the current interface only
7346 gives us full paths, but we only want to show the file
7347 name for now. */
7348 Dwarf_Die cudie;
7349 if (dwarf_cu_die (cbargs->cu, &cudie,
7350 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7351 {
7352 Dwarf_Files *files;
7353 size_t nfiles;
7354 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7355 {
7356 valuestr = dwarf_filesrc (files, num, NULL, NULL);
7357 if (valuestr != NULL)
7358 {
7359 char *filename = strrchr (valuestr, '/');
7360 if (filename != NULL)
7361 valuestr = filename + 1;
7362 }
7363 else
7364 error (0, 0, gettext ("invalid file (%" PRId64 "): %s"),
7365 num, dwarf_errmsg (-1));
7366 }
7367 else
7368 error (0, 0, gettext ("no srcfiles for CU [%" PRIx64 "]"),
7369 dwarf_dieoffset (&cudie));
7370 }
7371 else
7372 error (0, 0, gettext ("couldn't get DWARF CU: %s"),
7373 dwarf_errmsg (-1));
7374 if (valuestr == NULL)
7375 valuestr = "???";
7376 }
7377 break;
7378 case DW_AT_GNU_dwo_id:
7379 as_hex_id = true;
7380 break;
7381
7382 default:
7383 /* Nothing. */
7384 break;
7385 }
7386
7387 if (cbargs->silent)
7388 break;
7389
7390 /* When highpc is in constant form it is relative to lowpc.
7391 In that case also show the address. */
7392 Dwarf_Addr highpc;
7393 if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7394 {
7395 printf (" %*s%-20s (%s) %" PRIuMAX " (",
7396 (int) (level * 2), "", dwarf_attr_name (attr),
7397 dwarf_form_name (form), (uintmax_t) num);
7398 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7399 printf (")\n");
7400 }
7401 else
7402 {
7403 if (as_hex_id)
7404 {
7405 printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7406 (int) (level * 2), "", dwarf_attr_name (attr),
7407 dwarf_form_name (form), num);
7408 }
7409 else
7410 {
7411 Dwarf_Sword snum = 0;
7412 bool is_signed;
7413 int bytes = 0;
7414 if (attr == DW_AT_const_value)
7415 die_type_sign_bytes (die, &is_signed, &bytes);
7416 else
7417 is_signed = (form == DW_FORM_sdata
7418 || form == DW_FORM_implicit_const);
7419
7420 if (is_signed)
7421 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7422 goto attrval_out;
7423
7424 if (valuestr == NULL)
7425 {
7426 printf (" %*s%-20s (%s) ",
7427 (int) (level * 2), "", dwarf_attr_name (attr),
7428 dwarf_form_name (form));
7429 }
7430 else
7431 {
7432 printf (" %*s%-20s (%s) %s (",
7433 (int) (level * 2), "", dwarf_attr_name (attr),
7434 dwarf_form_name (form), valuestr);
7435 }
7436
7437 switch (bytes)
7438 {
7439 case 1:
7440 if (is_signed)
7441 printf ("%" PRId8, (int8_t) snum);
7442 else
7443 printf ("%" PRIu8, (uint8_t) num);
7444 break;
7445
7446 case 2:
7447 if (is_signed)
7448 printf ("%" PRId16, (int16_t) snum);
7449 else
7450 printf ("%" PRIu16, (uint16_t) num);
7451 break;
7452
7453 case 4:
7454 if (is_signed)
7455 printf ("%" PRId32, (int32_t) snum);
7456 else
7457 printf ("%" PRIu32, (uint32_t) num);
7458 break;
7459
7460 case 8:
7461 if (is_signed)
7462 printf ("%" PRId64, (int64_t) snum);
7463 else
7464 printf ("%" PRIu64, (uint64_t) num);
7465 break;
7466
7467 default:
7468 if (is_signed)
7469 printf ("%" PRIdMAX, (intmax_t) snum);
7470 else
7471 printf ("%" PRIuMAX, (uintmax_t) num);
7472 break;
7473 }
7474
7475 /* Make clear if we switched from a signed encoding to
7476 an unsigned value. */
7477 if (attr == DW_AT_const_value
7478 && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7479 && !is_signed)
7480 printf (" (%" PRIdMAX ")", (intmax_t) num);
7481
7482 if (valuestr == NULL)
7483 printf ("\n");
7484 else
7485 printf (")\n");
7486 }
7487 }
7488 break;
7489
7490 case DW_FORM_flag:
7491 if (cbargs->silent)
7492 break;
7493 bool flag;
7494 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7495 goto attrval_out;
7496
7497 printf (" %*s%-20s (%s) %s\n",
7498 (int) (level * 2), "", dwarf_attr_name (attr),
7499 dwarf_form_name (form), flag ? yes_str : no_str);
7500 break;
7501
7502 case DW_FORM_flag_present:
7503 if (cbargs->silent)
7504 break;
7505 printf (" %*s%-20s (%s) %s\n",
7506 (int) (level * 2), "", dwarf_attr_name (attr),
7507 dwarf_form_name (form), yes_str);
7508 break;
7509
7510 case DW_FORM_exprloc:
7511 case DW_FORM_block4:
7512 case DW_FORM_block2:
7513 case DW_FORM_block1:
7514 case DW_FORM_block:
7515 case DW_FORM_data16: /* DWARF5 calls this a constant class. */
7516 if (cbargs->silent)
7517 break;
7518 Dwarf_Block block;
7519 if (unlikely (dwarf_formblock (attrp, &block) != 0))
7520 goto attrval_out;
7521
7522 printf (" %*s%-20s (%s) ",
7523 (int) (level * 2), "", dwarf_attr_name (attr),
7524 dwarf_form_name (form));
7525
7526 switch (attr)
7527 {
7528 default:
7529 if (form != DW_FORM_exprloc)
7530 {
7531 print_block (block.length, block.data);
7532 break;
7533 }
7534 FALLTHROUGH;
7535
7536 case DW_AT_location:
7537 case DW_AT_data_location:
7538 case DW_AT_data_member_location:
7539 case DW_AT_vtable_elem_location:
7540 case DW_AT_string_length:
7541 case DW_AT_use_location:
7542 case DW_AT_frame_base:
7543 case DW_AT_return_addr:
7544 case DW_AT_static_link:
7545 case DW_AT_allocated:
7546 case DW_AT_associated:
7547 case DW_AT_bit_size:
7548 case DW_AT_bit_offset:
7549 case DW_AT_bit_stride:
7550 case DW_AT_byte_size:
7551 case DW_AT_byte_stride:
7552 case DW_AT_count:
7553 case DW_AT_lower_bound:
7554 case DW_AT_upper_bound:
7555 case DW_AT_GNU_call_site_value:
7556 case DW_AT_GNU_call_site_data_value:
7557 case DW_AT_GNU_call_site_target:
7558 case DW_AT_GNU_call_site_target_clobbered:
7559 if (form != DW_FORM_data16)
7560 {
7561 putchar ('\n');
7562 print_ops (cbargs->dwflmod, cbargs->dbg,
7563 12 + level * 2, 12 + level * 2,
7564 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7565 attrp->cu, block.length, block.data);
7566 }
7567 else
7568 print_block (block.length, block.data);
7569 break;
7570
7571 case DW_AT_discr_list:
7572 if (block.length == 0)
7573 puts ("<default>");
7574 else if (form != DW_FORM_data16)
7575 {
7576 const unsigned char *readp = block.data;
7577 const unsigned char *readendp = readp + block.length;
7578
7579 /* See if we are dealing with a signed or unsigned
7580 values. If the parent of this variant DIE is a
7581 variant_part then it will either have a discriminant
7582 which points to the member which type is the
7583 discriminant type. Or the variant_part itself has a
7584 type representing the discriminant. */
7585 bool is_signed = false;
7586 if (level > 0)
7587 {
7588 Dwarf_Die *parent = &cbargs->dies[level - 1];
7589 if (dwarf_tag (die) == DW_TAG_variant
7590 && dwarf_tag (parent) == DW_TAG_variant_part)
7591 {
7592 Dwarf_Die member;
7593 Dwarf_Attribute discr_attr;
7594 int bytes;
7595 if (dwarf_formref_die (dwarf_attr (parent,
7596 DW_AT_discr,
7597 &discr_attr),
7598 &member) != NULL)
7599 die_type_sign_bytes (&member, &is_signed, &bytes);
7600 else
7601 die_type_sign_bytes (parent, &is_signed, &bytes);
7602 }
7603 }
7604 while (readp < readendp)
7605 {
7606 int d = (int) *readp++;
7607 printf ("%s ", dwarf_discr_list_name (d));
7608 if (readp >= readendp)
7609 goto attrval_out;
7610
7611 Dwarf_Word val;
7612 Dwarf_Sword sval;
7613 if (d == DW_DSC_label)
7614 {
7615 if (is_signed)
7616 {
7617 get_sleb128 (sval, readp, readendp);
7618 printf ("%" PRId64 "", sval);
7619 }
7620 else
7621 {
7622 get_uleb128 (val, readp, readendp);
7623 printf ("%" PRIu64 "", val);
7624 }
7625 }
7626 else if (d == DW_DSC_range)
7627 {
7628 if (is_signed)
7629 {
7630 get_sleb128 (sval, readp, readendp);
7631 printf ("%" PRId64 "..", sval);
7632 if (readp >= readendp)
7633 goto attrval_out;
7634 get_sleb128 (sval, readp, readendp);
7635 printf ("%" PRId64 "", sval);
7636 }
7637 else
7638 {
7639 get_uleb128 (val, readp, readendp);
7640 printf ("%" PRIu64 "..", val);
7641 if (readp >= readendp)
7642 goto attrval_out;
7643 get_uleb128 (val, readp, readendp);
7644 printf ("%" PRIu64 "", val);
7645 }
7646 }
7647 else
7648 {
7649 print_block (readendp - readp, readp);
7650 break;
7651 }
7652 if (readp < readendp)
7653 printf (", ");
7654 }
7655 putchar ('\n');
7656 }
7657 else
7658 print_block (block.length, block.data);
7659 break;
7660 }
7661 break;
7662
7663 default:
7664 if (cbargs->silent)
7665 break;
7666 printf (" %*s%-20s (%s) ???\n",
7667 (int) (level * 2), "", dwarf_attr_name (attr),
7668 dwarf_form_name (form));
7669 break;
7670 }
7671
7672 return DWARF_CB_OK;
7673 }
7674
7675 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7676 print_debug_units (Dwfl_Module *dwflmod,
7677 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7678 Elf_Scn *scn, GElf_Shdr *shdr,
7679 Dwarf *dbg, bool debug_types)
7680 {
7681 const bool silent = !(print_debug_sections & section_info) && !debug_types;
7682 const char *secname = section_name (ebl, shdr);
7683
7684 if (!silent)
7685 printf (gettext ("\
7686 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7687 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7688
7689 /* If the section is empty we don't have to do anything. */
7690 if (!silent && shdr->sh_size == 0)
7691 return;
7692
7693 int maxdies = 20;
7694 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
7695
7696 /* New compilation unit. */
7697 Dwarf_Half version;
7698
7699 Dwarf_Die result;
7700 Dwarf_Off abbroffset;
7701 uint8_t addrsize;
7702 uint8_t offsize;
7703 uint64_t unit_id;
7704 Dwarf_Off subdie_off;
7705
7706 int unit_res;
7707 Dwarf_CU *cu;
7708 Dwarf_CU cu_mem;
7709 uint8_t unit_type;
7710 Dwarf_Die cudie;
7711
7712 /* We cheat a little because we want to see only the CUs from .debug_info
7713 or .debug_types. We know the Dwarf_CU struct layout. Set it up at
7714 the end of .debug_info if we want .debug_types only. Check the returned
7715 Dwarf_CU is still in the expected section. */
7716 if (debug_types)
7717 {
7718 cu_mem.dbg = dbg;
7719 cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7720 cu_mem.sec_idx = IDX_debug_info;
7721 cu = &cu_mem;
7722 }
7723 else
7724 cu = NULL;
7725
7726 next_cu:
7727 unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7728 &cudie, NULL);
7729 if (unit_res == 1)
7730 goto do_return;
7731
7732 if (unit_res == -1)
7733 {
7734 if (!silent)
7735 error (0, 0, gettext ("cannot get next unit: %s"), dwarf_errmsg (-1));
7736 goto do_return;
7737 }
7738
7739 if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7740 goto do_return;
7741
7742 dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7743 &unit_id, &subdie_off);
7744
7745 if (!silent)
7746 {
7747 Dwarf_Off offset = cu->start;
7748 if (debug_types && version < 5)
7749 {
7750 Dwarf_Die typedie;
7751 Dwarf_Off dieoffset;
7752 dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
7753 &typedie));
7754 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
7755 " Version: %" PRIu16
7756 ", Abbreviation section offset: %" PRIu64
7757 ", Address size: %" PRIu8
7758 ", Offset size: %" PRIu8
7759 "\n Type signature: %#" PRIx64
7760 ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7761 (uint64_t) offset, version, abbroffset, addrsize, offsize,
7762 unit_id, (uint64_t) subdie_off, dieoffset);
7763 }
7764 else
7765 {
7766 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
7767 " Version: %" PRIu16
7768 ", Abbreviation section offset: %" PRIu64
7769 ", Address size: %" PRIu8
7770 ", Offset size: %" PRIu8 "\n"),
7771 (uint64_t) offset, version, abbroffset, addrsize, offsize);
7772
7773 if (version >= 5 || (unit_type != DW_UT_compile
7774 && unit_type != DW_UT_partial))
7775 {
7776 printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7777 dwarf_unit_name (unit_type), unit_type);
7778 if (unit_type == DW_UT_type
7779 || unit_type == DW_UT_skeleton
7780 || unit_type == DW_UT_split_compile
7781 || unit_type == DW_UT_split_type)
7782 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7783 if (unit_type == DW_UT_type
7784 || unit_type == DW_UT_split_type)
7785 {
7786 Dwarf_Die typedie;
7787 Dwarf_Off dieoffset;
7788 dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7789 NULL, NULL, NULL);
7790 dieoffset = dwarf_dieoffset (&typedie);
7791 printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7792 subdie_off, dieoffset);
7793 }
7794 printf ("\n");
7795 }
7796 }
7797 }
7798
7799 if (version < 2 || version > 5
7800 || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7801 {
7802 if (!silent)
7803 error (0, 0, gettext ("unknown version (%d) or unit type (%d)"),
7804 version, unit_type);
7805 goto next_cu;
7806 }
7807
7808 struct attrcb_args args =
7809 {
7810 .dwflmod = dwflmod,
7811 .silent = silent,
7812 .version = version,
7813 .addrsize = addrsize,
7814 .offset_size = offsize
7815 };
7816
7817 bool is_split = false;
7818 int level = 0;
7819 dies[0] = cudie;
7820 args.cu = dies[0].cu;
7821 args.dbg = dbg;
7822 args.is_split = is_split;
7823
7824 /* We might return here again for the split CU subdie. */
7825 do_cu:
7826 do
7827 {
7828 Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7829 if (unlikely (offset == (Dwarf_Off) -1))
7830 {
7831 if (!silent)
7832 error (0, 0, gettext ("cannot get DIE offset: %s"),
7833 dwarf_errmsg (-1));
7834 goto do_return;
7835 }
7836
7837 int tag = dwarf_tag (&dies[level]);
7838 if (unlikely (tag == DW_TAG_invalid))
7839 {
7840 if (!silent)
7841 error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
7842 "] in section '%s': %s"),
7843 (uint64_t) offset, secname, dwarf_errmsg (-1));
7844 goto do_return;
7845 }
7846
7847 if (!silent)
7848 {
7849 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7850 if (is_split)
7851 printf (" {%6" PRIx64 "} ", (uint64_t) offset);
7852 else
7853 printf (" [%6" PRIx64 "] ", (uint64_t) offset);
7854 printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7855 dwarf_tag_name (tag), code);
7856 }
7857
7858 /* Print the attribute values. */
7859 args.level = level;
7860 args.dies = dies;
7861 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7862
7863 /* Make room for the next level's DIE. */
7864 if (level + 1 == maxdies)
7865 dies = (Dwarf_Die *) xrealloc (dies,
7866 (maxdies += 10)
7867 * sizeof (Dwarf_Die));
7868
7869 int res = dwarf_child (&dies[level], &dies[level + 1]);
7870 if (res > 0)
7871 {
7872 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7873 if (level-- == 0)
7874 break;
7875
7876 if (unlikely (res == -1))
7877 {
7878 if (!silent)
7879 error (0, 0, gettext ("cannot get next DIE: %s\n"),
7880 dwarf_errmsg (-1));
7881 goto do_return;
7882 }
7883 }
7884 else if (unlikely (res < 0))
7885 {
7886 if (!silent)
7887 error (0, 0, gettext ("cannot get next DIE: %s"),
7888 dwarf_errmsg (-1));
7889 goto do_return;
7890 }
7891 else
7892 ++level;
7893 }
7894 while (level >= 0);
7895
7896 /* We might want to show the split compile unit if this was a skeleton.
7897 We need to scan it if we are requesting printing .debug_ranges for
7898 DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7899 section. */
7900 if (unit_type == DW_UT_skeleton
7901 && ((!silent && show_split_units)
7902 || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7903 {
7904 Dwarf_Die subdie;
7905 if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7906 || dwarf_tag (&subdie) == DW_TAG_invalid)
7907 {
7908 if (!silent)
7909 {
7910 Dwarf_Attribute dwo_at;
7911 const char *dwo_name =
7912 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7913 &dwo_at))
7914 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7915 &dwo_at))
7916 ?: "<unknown>"));
7917 fprintf (stderr,
7918 "Could not find split unit '%s', id: %" PRIx64 "\n",
7919 dwo_name, unit_id);
7920 }
7921 }
7922 else
7923 {
7924 Dwarf_CU *split_cu = subdie.cu;
7925 dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7926 &addrsize, &offsize, &unit_id, &subdie_off);
7927 Dwarf_Off offset = cu->start;
7928
7929 if (!silent)
7930 {
7931 printf (gettext (" Split compilation unit at offset %"
7932 PRIu64 ":\n"
7933 " Version: %" PRIu16
7934 ", Abbreviation section offset: %" PRIu64
7935 ", Address size: %" PRIu8
7936 ", Offset size: %" PRIu8 "\n"),
7937 (uint64_t) offset, version, abbroffset,
7938 addrsize, offsize);
7939 printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7940 dwarf_unit_name (unit_type), unit_type);
7941 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7942 printf ("\n");
7943 }
7944
7945 unit_type = DW_UT_split_compile;
7946 is_split = true;
7947 level = 0;
7948 dies[0] = subdie;
7949 args.cu = dies[0].cu;
7950 args.dbg = split_cu->dbg;
7951 args.is_split = is_split;
7952 goto do_cu;
7953 }
7954 }
7955
7956 /* And again... */
7957 goto next_cu;
7958
7959 do_return:
7960 free (dies);
7961 }
7962
7963 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7964 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7965 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7966 {
7967 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
7968 }
7969
7970 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7971 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7972 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7973 {
7974 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
7975 }
7976
7977
7978 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7979 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
7980 GElf_Ehdr *ehdr __attribute__ ((unused)),
7981 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7982 {
7983 printf (gettext ("\
7984 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
7985 elf_ndxscn (scn), section_name (ebl, shdr),
7986 (uint64_t) shdr->sh_offset);
7987
7988 size_t address_size
7989 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7990
7991 Dwarf_Lines *lines;
7992 size_t nlines;
7993 Dwarf_Off off, next_off = 0;
7994 Dwarf_CU *cu = NULL;
7995 while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
7996 &lines, &nlines) == 0)
7997 {
7998 Dwarf_Die cudie;
7999 if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8000 NULL, NULL, NULL, NULL) == 0)
8001 printf (" CU [%" PRIx64 "] %s\n",
8002 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8003 else
8004 {
8005 /* DWARF5 lines can be independent of any CU, but they probably
8006 are used by some CU. Determine the CU this block is for. */
8007 Dwarf_Off cuoffset;
8008 Dwarf_Off ncuoffset = 0;
8009 size_t hsize;
8010 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8011 NULL, NULL, NULL) == 0)
8012 {
8013 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8014 continue;
8015 Dwarf_Attribute stmt_list;
8016 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8017 continue;
8018 Dwarf_Word lineoff;
8019 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8020 continue;
8021 if (lineoff == off)
8022 {
8023 /* Found the CU. */
8024 cu = cudie.cu;
8025 break;
8026 }
8027 }
8028
8029 if (cu != NULL)
8030 printf (" CU [%" PRIx64 "] %s\n",
8031 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8032 else
8033 printf (" No CU\n");
8034 }
8035
8036 printf (" line:col SBPE* disc isa op address"
8037 " (Statement Block Prologue Epilogue *End)\n");
8038 const char *last_file = "";
8039 for (size_t n = 0; n < nlines; n++)
8040 {
8041 Dwarf_Line *line = dwarf_onesrcline (lines, n);
8042 if (line == NULL)
8043 {
8044 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8045 continue;
8046 }
8047 Dwarf_Word mtime, length;
8048 const char *file = dwarf_linesrc (line, &mtime, &length);
8049 if (file == NULL)
8050 {
8051 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8052 last_file = "";
8053 }
8054 else if (strcmp (last_file, file) != 0)
8055 {
8056 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8057 file, mtime, length);
8058 last_file = file;
8059 }
8060
8061 int lineno, colno;
8062 bool statement, endseq, block, prologue_end, epilogue_begin;
8063 unsigned int lineop, isa, disc;
8064 Dwarf_Addr address;
8065 dwarf_lineaddr (line, &address);
8066 dwarf_lineno (line, &lineno);
8067 dwarf_linecol (line, &colno);
8068 dwarf_lineop_index (line, &lineop);
8069 dwarf_linebeginstatement (line, &statement);
8070 dwarf_lineendsequence (line, &endseq);
8071 dwarf_lineblock (line, &block);
8072 dwarf_lineprologueend (line, &prologue_end);
8073 dwarf_lineepiloguebegin (line, &epilogue_begin);
8074 dwarf_lineisa (line, &isa);
8075 dwarf_linediscriminator (line, &disc);
8076
8077 /* End sequence is special, it is one byte past. */
8078 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8079 lineno, colno,
8080 (statement ? 'S' : ' '),
8081 (block ? 'B' : ' '),
8082 (prologue_end ? 'P' : ' '),
8083 (epilogue_begin ? 'E' : ' '),
8084 (endseq ? '*' : ' '),
8085 disc, isa, lineop);
8086 print_dwarf_addr (dwflmod, address_size,
8087 address - (endseq ? 1 : 0), address);
8088 printf ("\n");
8089
8090 if (endseq)
8091 printf("\n");
8092 }
8093 }
8094 }
8095
8096
8097 /* Print the value of a form.
8098 Returns new value of readp, or readendp on failure. */
8099 static const unsigned char *
print_form_data(Dwarf * dbg,int form,const unsigned char * readp,const unsigned char * readendp,unsigned int offset_len,Dwarf_Off str_offsets_base)8100 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8101 const unsigned char *readendp, unsigned int offset_len,
8102 Dwarf_Off str_offsets_base)
8103 {
8104 Dwarf_Word val;
8105 unsigned char *endp;
8106 Elf_Data *data;
8107 char *str;
8108 switch (form)
8109 {
8110 case DW_FORM_data1:
8111 if (readendp - readp < 1)
8112 {
8113 invalid_data:
8114 error (0, 0, "invalid data");
8115 return readendp;
8116 }
8117 val = *readp++;
8118 printf (" %" PRIx8, (unsigned int) val);
8119 break;
8120
8121 case DW_FORM_data2:
8122 if (readendp - readp < 2)
8123 goto invalid_data;
8124 val = read_2ubyte_unaligned_inc (dbg, readp);
8125 printf(" %" PRIx16, (unsigned int) val);
8126 break;
8127
8128 case DW_FORM_data4:
8129 if (readendp - readp < 4)
8130 goto invalid_data;
8131 val = read_4ubyte_unaligned_inc (dbg, readp);
8132 printf (" %" PRIx32, (unsigned int) val);
8133 break;
8134
8135 case DW_FORM_data8:
8136 if (readendp - readp < 8)
8137 goto invalid_data;
8138 val = read_8ubyte_unaligned_inc (dbg, readp);
8139 printf (" %" PRIx64, val);
8140 break;
8141
8142 case DW_FORM_sdata:
8143 if (readendp - readp < 1)
8144 goto invalid_data;
8145 get_sleb128 (val, readp, readendp);
8146 printf (" %" PRIx64, val);
8147 break;
8148
8149 case DW_FORM_udata:
8150 if (readendp - readp < 1)
8151 goto invalid_data;
8152 get_uleb128 (val, readp, readendp);
8153 printf (" %" PRIx64, val);
8154 break;
8155
8156 case DW_FORM_block:
8157 if (readendp - readp < 1)
8158 goto invalid_data;
8159 get_uleb128 (val, readp, readendp);
8160 if ((size_t) (readendp - readp) < val)
8161 goto invalid_data;
8162 print_bytes (val, readp);
8163 readp += val;
8164 break;
8165
8166 case DW_FORM_block1:
8167 if (readendp - readp < 1)
8168 goto invalid_data;
8169 val = *readp++;
8170 if ((size_t) (readendp - readp) < val)
8171 goto invalid_data;
8172 print_bytes (val, readp);
8173 readp += val;
8174 break;
8175
8176 case DW_FORM_block2:
8177 if (readendp - readp < 2)
8178 goto invalid_data;
8179 val = read_2ubyte_unaligned_inc (dbg, readp);
8180 if ((size_t) (readendp - readp) < val)
8181 goto invalid_data;
8182 print_bytes (val, readp);
8183 readp += val;
8184 break;
8185
8186 case DW_FORM_block4:
8187 if (readendp - readp < 4)
8188 goto invalid_data;
8189 val = read_4ubyte_unaligned_inc (dbg, readp);
8190 if ((size_t) (readendp - readp) < val)
8191 goto invalid_data;
8192 print_bytes (val, readp);
8193 readp += val;
8194 break;
8195
8196 case DW_FORM_data16:
8197 if (readendp - readp < 16)
8198 goto invalid_data;
8199 print_bytes (16, readp);
8200 readp += 16;
8201 break;
8202
8203 case DW_FORM_flag:
8204 if (readendp - readp < 1)
8205 goto invalid_data;
8206 val = *readp++;
8207 printf ("%s", val != 0 ? yes_str : no_str);
8208 break;
8209
8210 case DW_FORM_string:
8211 endp = memchr (readp, '\0', readendp - readp);
8212 if (endp == NULL)
8213 goto invalid_data;
8214 printf ("%s", readp);
8215 readp = endp + 1;
8216 break;
8217
8218 case DW_FORM_strp:
8219 case DW_FORM_line_strp:
8220 case DW_FORM_strp_sup:
8221 if ((size_t) (readendp - readp) < offset_len)
8222 goto invalid_data;
8223 if (offset_len == 8)
8224 val = read_8ubyte_unaligned_inc (dbg, readp);
8225 else
8226 val = read_4ubyte_unaligned_inc (dbg, readp);
8227 if (form == DW_FORM_strp)
8228 data = dbg->sectiondata[IDX_debug_str];
8229 else if (form == DW_FORM_line_strp)
8230 data = dbg->sectiondata[IDX_debug_line_str];
8231 else /* form == DW_FORM_strp_sup */
8232 {
8233 Dwarf *alt = dwarf_getalt (dbg);
8234 data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8235 }
8236 if (data == NULL || val >= data->d_size
8237 || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8238 str = "???";
8239 else
8240 str = (char *) data->d_buf + val;
8241 printf ("%s (%" PRIu64 ")", str, val);
8242 break;
8243
8244 case DW_FORM_sec_offset:
8245 if ((size_t) (readendp - readp) < offset_len)
8246 goto invalid_data;
8247 if (offset_len == 8)
8248 val = read_8ubyte_unaligned_inc (dbg, readp);
8249 else
8250 val = read_4ubyte_unaligned_inc (dbg, readp);
8251 printf ("[%" PRIx64 "]", val);
8252 break;
8253
8254 case DW_FORM_strx:
8255 case DW_FORM_GNU_str_index:
8256 if (readendp - readp < 1)
8257 goto invalid_data;
8258 get_uleb128 (val, readp, readendp);
8259 strx_val:
8260 data = dbg->sectiondata[IDX_debug_str_offsets];
8261 if (data == NULL
8262 || data->d_size - str_offsets_base < val)
8263 str = "???";
8264 else
8265 {
8266 const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8267 const unsigned char *strreadendp = data->d_buf + data->d_size;
8268 if ((size_t) (strreadendp - strreadp) < offset_len)
8269 str = "???";
8270 else
8271 {
8272 Dwarf_Off idx;
8273 if (offset_len == 8)
8274 idx = read_8ubyte_unaligned (dbg, strreadp);
8275 else
8276 idx = read_4ubyte_unaligned (dbg, strreadp);
8277
8278 data = dbg->sectiondata[IDX_debug_str];
8279 if (data == NULL || idx >= data->d_size
8280 || memchr (data->d_buf + idx, '\0',
8281 data->d_size - idx) == NULL)
8282 str = "???";
8283 else
8284 str = (char *) data->d_buf + idx;
8285 }
8286 }
8287 printf ("%s (%" PRIu64 ")", str, val);
8288 break;
8289
8290 case DW_FORM_strx1:
8291 if (readendp - readp < 1)
8292 goto invalid_data;
8293 val = *readp++;
8294 goto strx_val;
8295
8296 case DW_FORM_strx2:
8297 if (readendp - readp < 2)
8298 goto invalid_data;
8299 val = read_2ubyte_unaligned_inc (dbg, readp);
8300 goto strx_val;
8301
8302 case DW_FORM_strx3:
8303 if (readendp - readp < 3)
8304 goto invalid_data;
8305 val = read_3ubyte_unaligned_inc (dbg, readp);
8306 goto strx_val;
8307
8308 case DW_FORM_strx4:
8309 if (readendp - readp < 4)
8310 goto invalid_data;
8311 val = read_4ubyte_unaligned_inc (dbg, readp);
8312 goto strx_val;
8313
8314 default:
8315 error (0, 0, gettext ("unknown form: %s"), dwarf_form_name (form));
8316 return readendp;
8317 }
8318
8319 return readp;
8320 }
8321
8322 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8323 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8324 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8325 {
8326 if (decodedline)
8327 {
8328 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8329 return;
8330 }
8331
8332 printf (gettext ("\
8333 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8334 elf_ndxscn (scn), section_name (ebl, shdr),
8335 (uint64_t) shdr->sh_offset);
8336
8337 if (shdr->sh_size == 0)
8338 return;
8339
8340 /* There is no functionality in libdw to read the information in the
8341 way it is represented here. Hardcode the decoder. */
8342 Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8343 ?: elf_rawdata (scn, NULL));
8344 if (unlikely (data == NULL))
8345 {
8346 error (0, 0, gettext ("cannot get line data section data: %s"),
8347 elf_errmsg (-1));
8348 return;
8349 }
8350
8351 const unsigned char *linep = (const unsigned char *) data->d_buf;
8352 const unsigned char *lineendp;
8353
8354 while (linep
8355 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8356 {
8357 size_t start_offset = linep - (const unsigned char *) data->d_buf;
8358
8359 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
8360
8361 if (unlikely (linep + 4 > lineendp))
8362 goto invalid_data;
8363 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8364 unsigned int length = 4;
8365 if (unlikely (unit_length == 0xffffffff))
8366 {
8367 if (unlikely (linep + 8 > lineendp))
8368 {
8369 invalid_data:
8370 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8371 elf_ndxscn (scn), section_name (ebl, shdr));
8372 return;
8373 }
8374 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8375 length = 8;
8376 }
8377
8378 /* Check whether we have enough room in the section. */
8379 if (unlikely (unit_length > (size_t) (lineendp - linep)))
8380 goto invalid_data;
8381 lineendp = linep + unit_length;
8382
8383 /* The next element of the header is the version identifier. */
8384 if ((size_t) (lineendp - linep) < 2)
8385 goto invalid_data;
8386 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8387
8388 size_t address_size
8389 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8390 unsigned char segment_selector_size = 0;
8391 if (version > 4)
8392 {
8393 if ((size_t) (lineendp - linep) < 2)
8394 goto invalid_data;
8395 address_size = *linep++;
8396 segment_selector_size = *linep++;
8397 }
8398
8399 /* Next comes the header length. */
8400 Dwarf_Word header_length;
8401 if (length == 4)
8402 {
8403 if ((size_t) (lineendp - linep) < 4)
8404 goto invalid_data;
8405 header_length = read_4ubyte_unaligned_inc (dbg, linep);
8406 }
8407 else
8408 {
8409 if ((size_t) (lineendp - linep) < 8)
8410 goto invalid_data;
8411 header_length = read_8ubyte_unaligned_inc (dbg, linep);
8412 }
8413
8414 /* Next the minimum instruction length. */
8415 if ((size_t) (lineendp - linep) < 1)
8416 goto invalid_data;
8417 uint_fast8_t minimum_instr_len = *linep++;
8418
8419 /* Next the maximum operations per instruction, in version 4 format. */
8420 uint_fast8_t max_ops_per_instr;
8421 if (version < 4)
8422 max_ops_per_instr = 1;
8423 else
8424 {
8425 if ((size_t) (lineendp - linep) < 1)
8426 goto invalid_data;
8427 max_ops_per_instr = *linep++;
8428 }
8429
8430 /* We need at least 4 more bytes. */
8431 if ((size_t) (lineendp - linep) < 4)
8432 goto invalid_data;
8433
8434 /* Then the flag determining the default value of the is_stmt
8435 register. */
8436 uint_fast8_t default_is_stmt = *linep++;
8437
8438 /* Now the line base. */
8439 int_fast8_t line_base = (const char)*linep++;
8440
8441 /* And the line range. */
8442 uint_fast8_t line_range = *linep++;
8443
8444 /* The opcode base. */
8445 uint_fast8_t opcode_base = *linep++;
8446
8447 /* Print what we got so far. */
8448 printf (gettext ("\n"
8449 " Length: %" PRIu64 "\n"
8450 " DWARF version: %" PRIuFAST16 "\n"
8451 " Prologue length: %" PRIu64 "\n"
8452 " Address size: %zd\n"
8453 " Segment selector size: %zd\n"
8454 " Min instruction length: %" PRIuFAST8 "\n"
8455 " Max operations per instruction: %" PRIuFAST8 "\n"
8456 " Initial value if 'is_stmt': %" PRIuFAST8 "\n"
8457 " Line base: %" PRIdFAST8 "\n"
8458 " Line range: %" PRIuFAST8 "\n"
8459 " Opcode base: %" PRIuFAST8 "\n"
8460 "\n"
8461 "Opcodes:\n"),
8462 (uint64_t) unit_length, version, (uint64_t) header_length,
8463 address_size, (size_t) segment_selector_size,
8464 minimum_instr_len, max_ops_per_instr,
8465 default_is_stmt, line_base,
8466 line_range, opcode_base);
8467
8468 if (version < 2 || version > 5)
8469 {
8470 error (0, 0, gettext ("cannot handle .debug_line version: %u\n"),
8471 (unsigned int) version);
8472 linep = lineendp;
8473 continue;
8474 }
8475
8476 if (address_size != 4 && address_size != 8)
8477 {
8478 error (0, 0, gettext ("cannot handle address size: %u\n"),
8479 (unsigned int) address_size);
8480 linep = lineendp;
8481 continue;
8482 }
8483
8484 if (segment_selector_size != 0)
8485 {
8486 error (0, 0, gettext ("cannot handle segment selector size: %u\n"),
8487 (unsigned int) segment_selector_size);
8488 linep = lineendp;
8489 continue;
8490 }
8491
8492 if (unlikely (linep + opcode_base - 1 >= lineendp))
8493 {
8494 invalid_unit:
8495 error (0, 0,
8496 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
8497 linep - (const unsigned char *) data->d_buf,
8498 elf_ndxscn (scn), section_name (ebl, shdr));
8499 linep = lineendp;
8500 continue;
8501 }
8502 int opcode_base_l10 = 1;
8503 unsigned int tmp = opcode_base;
8504 while (tmp > 10)
8505 {
8506 tmp /= 10;
8507 ++opcode_base_l10;
8508 }
8509 const uint8_t *standard_opcode_lengths = linep - 1;
8510 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8511 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
8512 " [%*" PRIuFAST8 "] %hhu arguments\n",
8513 (int) linep[cnt - 1]),
8514 opcode_base_l10, cnt, linep[cnt - 1]);
8515 linep += opcode_base - 1;
8516
8517 if (unlikely (linep >= lineendp))
8518 goto invalid_unit;
8519
8520 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8521
8522 puts (gettext ("\nDirectory table:"));
8523 if (version > 4)
8524 {
8525 struct encpair { uint16_t desc; uint16_t form; };
8526 struct encpair enc[256];
8527
8528 printf (gettext (" ["));
8529 if ((size_t) (lineendp - linep) < 1)
8530 goto invalid_data;
8531 unsigned char directory_entry_format_count = *linep++;
8532 for (int i = 0; i < directory_entry_format_count; i++)
8533 {
8534 uint16_t desc, form;
8535 if ((size_t) (lineendp - linep) < 1)
8536 goto invalid_data;
8537 get_uleb128 (desc, linep, lineendp);
8538 if ((size_t) (lineendp - linep) < 1)
8539 goto invalid_data;
8540 get_uleb128 (form, linep, lineendp);
8541
8542 enc[i].desc = desc;
8543 enc[i].form = form;
8544
8545 printf ("%s(%s)",
8546 dwarf_line_content_description_name (desc),
8547 dwarf_form_name (form));
8548 if (i + 1 < directory_entry_format_count)
8549 printf (", ");
8550 }
8551 printf ("]\n");
8552
8553 uint64_t directories_count;
8554 if ((size_t) (lineendp - linep) < 1)
8555 goto invalid_data;
8556 get_uleb128 (directories_count, linep, lineendp);
8557
8558 if (directory_entry_format_count == 0
8559 && directories_count != 0)
8560 goto invalid_data;
8561
8562 for (uint64_t i = 0; i < directories_count; i++)
8563 {
8564 printf (" %-5" PRIu64 " ", i);
8565 for (int j = 0; j < directory_entry_format_count; j++)
8566 {
8567 linep = print_form_data (dbg, enc[j].form,
8568 linep, lineendp, length,
8569 str_offsets_base);
8570 if (j + 1 < directory_entry_format_count)
8571 printf (", ");
8572 }
8573 printf ("\n");
8574 if (linep >= lineendp)
8575 goto invalid_unit;
8576 }
8577 }
8578 else
8579 {
8580 while (linep < lineendp && *linep != 0)
8581 {
8582 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8583 if (unlikely (endp == NULL))
8584 goto invalid_unit;
8585
8586 printf (" %s\n", (char *) linep);
8587
8588 linep = endp + 1;
8589 }
8590 if (linep >= lineendp || *linep != 0)
8591 goto invalid_unit;
8592 /* Skip the final NUL byte. */
8593 ++linep;
8594 }
8595
8596 if (unlikely (linep >= lineendp))
8597 goto invalid_unit;
8598
8599 puts (gettext ("\nFile name table:"));
8600 if (version > 4)
8601 {
8602 struct encpair { uint16_t desc; uint16_t form; };
8603 struct encpair enc[256];
8604
8605 printf (gettext (" ["));
8606 if ((size_t) (lineendp - linep) < 1)
8607 goto invalid_data;
8608 unsigned char file_name_format_count = *linep++;
8609 for (int i = 0; i < file_name_format_count; i++)
8610 {
8611 uint64_t desc, form;
8612 if ((size_t) (lineendp - linep) < 1)
8613 goto invalid_data;
8614 get_uleb128 (desc, linep, lineendp);
8615 if ((size_t) (lineendp - linep) < 1)
8616 goto invalid_data;
8617 get_uleb128 (form, linep, lineendp);
8618
8619 if (! libdw_valid_user_form (form))
8620 goto invalid_data;
8621
8622 enc[i].desc = desc;
8623 enc[i].form = form;
8624
8625 printf ("%s(%s)",
8626 dwarf_line_content_description_name (desc),
8627 dwarf_form_name (form));
8628 if (i + 1 < file_name_format_count)
8629 printf (", ");
8630 }
8631 printf ("]\n");
8632
8633 uint64_t file_name_count;
8634 if ((size_t) (lineendp - linep) < 1)
8635 goto invalid_data;
8636 get_uleb128 (file_name_count, linep, lineendp);
8637
8638 if (file_name_format_count == 0
8639 && file_name_count != 0)
8640 goto invalid_data;
8641
8642 for (uint64_t i = 0; i < file_name_count; i++)
8643 {
8644 printf (" %-5" PRIu64 " ", i);
8645 for (int j = 0; j < file_name_format_count; j++)
8646 {
8647 linep = print_form_data (dbg, enc[j].form,
8648 linep, lineendp, length,
8649 str_offsets_base);
8650 if (j + 1 < file_name_format_count)
8651 printf (", ");
8652 }
8653 printf ("\n");
8654 if (linep >= lineendp)
8655 goto invalid_unit;
8656 }
8657 }
8658 else
8659 {
8660 puts (gettext (" Entry Dir Time Size Name"));
8661 for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8662 {
8663 /* First comes the file name. */
8664 char *fname = (char *) linep;
8665 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8666 if (unlikely (endp == NULL))
8667 goto invalid_unit;
8668 linep = endp + 1;
8669
8670 /* Then the index. */
8671 unsigned int diridx;
8672 if (lineendp - linep < 1)
8673 goto invalid_unit;
8674 get_uleb128 (diridx, linep, lineendp);
8675
8676 /* Next comes the modification time. */
8677 unsigned int mtime;
8678 if (lineendp - linep < 1)
8679 goto invalid_unit;
8680 get_uleb128 (mtime, linep, lineendp);
8681
8682 /* Finally the length of the file. */
8683 unsigned int fsize;
8684 if (lineendp - linep < 1)
8685 goto invalid_unit;
8686 get_uleb128 (fsize, linep, lineendp);
8687
8688 printf (" %-5u %-5u %-9u %-9u %s\n",
8689 cnt, diridx, mtime, fsize, fname);
8690 }
8691 if (linep >= lineendp || *linep != '\0')
8692 goto invalid_unit;
8693 /* Skip the final NUL byte. */
8694 ++linep;
8695 }
8696
8697 puts (gettext ("\nLine number statements:"));
8698 Dwarf_Word address = 0;
8699 unsigned int op_index = 0;
8700 size_t line = 1;
8701 uint_fast8_t is_stmt = default_is_stmt;
8702
8703 /* Apply the "operation advance" from a special opcode
8704 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
8705 unsigned int op_addr_advance;
8706 bool show_op_index;
8707 inline void advance_pc (unsigned int op_advance)
8708 {
8709 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8710 / max_ops_per_instr);
8711 address += op_addr_advance;
8712 show_op_index = (op_index > 0 ||
8713 (op_index + op_advance) % max_ops_per_instr > 0);
8714 op_index = (op_index + op_advance) % max_ops_per_instr;
8715 }
8716
8717 if (max_ops_per_instr == 0)
8718 {
8719 error (0, 0,
8720 gettext ("invalid maximum operations per instruction is zero"));
8721 linep = lineendp;
8722 continue;
8723 }
8724
8725 while (linep < lineendp)
8726 {
8727 size_t offset = linep - (const unsigned char *) data->d_buf;
8728 unsigned int u128;
8729 int s128;
8730
8731 /* Read the opcode. */
8732 unsigned int opcode = *linep++;
8733
8734 printf (" [%6" PRIx64 "]", (uint64_t)offset);
8735 /* Is this a special opcode? */
8736 if (likely (opcode >= opcode_base))
8737 {
8738 if (unlikely (line_range == 0))
8739 goto invalid_unit;
8740
8741 /* Yes. Handling this is quite easy since the opcode value
8742 is computed with
8743
8744 opcode = (desired line increment - line_base)
8745 + (line_range * address advance) + opcode_base
8746 */
8747 int line_increment = (line_base
8748 + (opcode - opcode_base) % line_range);
8749
8750 /* Perform the increments. */
8751 line += line_increment;
8752 advance_pc ((opcode - opcode_base) / line_range);
8753
8754 printf (gettext (" special opcode %u: address+%u = "),
8755 opcode, op_addr_advance);
8756 print_dwarf_addr (dwflmod, 0, address, address);
8757 if (show_op_index)
8758 printf (gettext (", op_index = %u, line%+d = %zu\n"),
8759 op_index, line_increment, line);
8760 else
8761 printf (gettext (", line%+d = %zu\n"),
8762 line_increment, line);
8763 }
8764 else if (opcode == 0)
8765 {
8766 /* This an extended opcode. */
8767 if (unlikely (linep + 2 > lineendp))
8768 goto invalid_unit;
8769
8770 /* The length. */
8771 unsigned int len = *linep++;
8772
8773 if (unlikely (linep + len > lineendp))
8774 goto invalid_unit;
8775
8776 /* The sub-opcode. */
8777 opcode = *linep++;
8778
8779 printf (gettext (" extended opcode %u: "), opcode);
8780
8781 switch (opcode)
8782 {
8783 case DW_LNE_end_sequence:
8784 puts (gettext (" end of sequence"));
8785
8786 /* Reset the registers we care about. */
8787 address = 0;
8788 op_index = 0;
8789 line = 1;
8790 is_stmt = default_is_stmt;
8791 break;
8792
8793 case DW_LNE_set_address:
8794 op_index = 0;
8795 if (unlikely ((size_t) (lineendp - linep) < address_size))
8796 goto invalid_unit;
8797 if (address_size == 4)
8798 address = read_4ubyte_unaligned_inc (dbg, linep);
8799 else
8800 address = read_8ubyte_unaligned_inc (dbg, linep);
8801 {
8802 printf (gettext (" set address to "));
8803 print_dwarf_addr (dwflmod, 0, address, address);
8804 printf ("\n");
8805 }
8806 break;
8807
8808 case DW_LNE_define_file:
8809 {
8810 char *fname = (char *) linep;
8811 unsigned char *endp = memchr (linep, '\0',
8812 lineendp - linep);
8813 if (unlikely (endp == NULL))
8814 goto invalid_unit;
8815 linep = endp + 1;
8816
8817 unsigned int diridx;
8818 if (lineendp - linep < 1)
8819 goto invalid_unit;
8820 get_uleb128 (diridx, linep, lineendp);
8821 Dwarf_Word mtime;
8822 if (lineendp - linep < 1)
8823 goto invalid_unit;
8824 get_uleb128 (mtime, linep, lineendp);
8825 Dwarf_Word filelength;
8826 if (lineendp - linep < 1)
8827 goto invalid_unit;
8828 get_uleb128 (filelength, linep, lineendp);
8829
8830 printf (gettext ("\
8831 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8832 diridx, (uint64_t) mtime, (uint64_t) filelength,
8833 fname);
8834 }
8835 break;
8836
8837 case DW_LNE_set_discriminator:
8838 /* Takes one ULEB128 parameter, the discriminator. */
8839 if (unlikely (standard_opcode_lengths[opcode] != 1
8840 || lineendp - linep < 1))
8841 goto invalid_unit;
8842
8843 get_uleb128 (u128, linep, lineendp);
8844 printf (gettext (" set discriminator to %u\n"), u128);
8845 break;
8846
8847 default:
8848 /* Unknown, ignore it. */
8849 puts (gettext (" unknown opcode"));
8850 linep += len - 1;
8851 break;
8852 }
8853 }
8854 else if (opcode <= DW_LNS_set_isa)
8855 {
8856 /* This is a known standard opcode. */
8857 switch (opcode)
8858 {
8859 case DW_LNS_copy:
8860 /* Takes no argument. */
8861 puts (gettext (" copy"));
8862 break;
8863
8864 case DW_LNS_advance_pc:
8865 /* Takes one uleb128 parameter which is added to the
8866 address. */
8867 if (lineendp - linep < 1)
8868 goto invalid_unit;
8869 get_uleb128 (u128, linep, lineendp);
8870 advance_pc (u128);
8871 {
8872 printf (gettext (" advance address by %u to "),
8873 op_addr_advance);
8874 print_dwarf_addr (dwflmod, 0, address, address);
8875 if (show_op_index)
8876 printf (gettext (", op_index to %u"), op_index);
8877 printf ("\n");
8878 }
8879 break;
8880
8881 case DW_LNS_advance_line:
8882 /* Takes one sleb128 parameter which is added to the
8883 line. */
8884 if (lineendp - linep < 1)
8885 goto invalid_unit;
8886 get_sleb128 (s128, linep, lineendp);
8887 line += s128;
8888 printf (gettext ("\
8889 advance line by constant %d to %" PRId64 "\n"),
8890 s128, (int64_t) line);
8891 break;
8892
8893 case DW_LNS_set_file:
8894 /* Takes one uleb128 parameter which is stored in file. */
8895 if (lineendp - linep < 1)
8896 goto invalid_unit;
8897 get_uleb128 (u128, linep, lineendp);
8898 printf (gettext (" set file to %" PRIu64 "\n"),
8899 (uint64_t) u128);
8900 break;
8901
8902 case DW_LNS_set_column:
8903 /* Takes one uleb128 parameter which is stored in column. */
8904 if (unlikely (standard_opcode_lengths[opcode] != 1
8905 || lineendp - linep < 1))
8906 goto invalid_unit;
8907
8908 get_uleb128 (u128, linep, lineendp);
8909 printf (gettext (" set column to %" PRIu64 "\n"),
8910 (uint64_t) u128);
8911 break;
8912
8913 case DW_LNS_negate_stmt:
8914 /* Takes no argument. */
8915 is_stmt = 1 - is_stmt;
8916 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8917 "is_stmt", is_stmt);
8918 break;
8919
8920 case DW_LNS_set_basic_block:
8921 /* Takes no argument. */
8922 puts (gettext (" set basic block flag"));
8923 break;
8924
8925 case DW_LNS_const_add_pc:
8926 /* Takes no argument. */
8927
8928 if (unlikely (line_range == 0))
8929 goto invalid_unit;
8930
8931 advance_pc ((255 - opcode_base) / line_range);
8932 {
8933 printf (gettext (" advance address by constant %u to "),
8934 op_addr_advance);
8935 print_dwarf_addr (dwflmod, 0, address, address);
8936 if (show_op_index)
8937 printf (gettext (", op_index to %u"), op_index);
8938 printf ("\n");
8939 }
8940 break;
8941
8942 case DW_LNS_fixed_advance_pc:
8943 /* Takes one 16 bit parameter which is added to the
8944 address. */
8945 if (unlikely (standard_opcode_lengths[opcode] != 1
8946 || lineendp - linep < 2))
8947 goto invalid_unit;
8948
8949 u128 = read_2ubyte_unaligned_inc (dbg, linep);
8950 address += u128;
8951 op_index = 0;
8952 {
8953 printf (gettext ("\
8954 advance address by fixed value %u to \n"),
8955 u128);
8956 print_dwarf_addr (dwflmod, 0, address, address);
8957 printf ("\n");
8958 }
8959 break;
8960
8961 case DW_LNS_set_prologue_end:
8962 /* Takes no argument. */
8963 puts (gettext (" set prologue end flag"));
8964 break;
8965
8966 case DW_LNS_set_epilogue_begin:
8967 /* Takes no argument. */
8968 puts (gettext (" set epilogue begin flag"));
8969 break;
8970
8971 case DW_LNS_set_isa:
8972 /* Takes one uleb128 parameter which is stored in isa. */
8973 if (unlikely (standard_opcode_lengths[opcode] != 1
8974 || lineendp - linep < 1))
8975 goto invalid_unit;
8976
8977 get_uleb128 (u128, linep, lineendp);
8978 printf (gettext (" set isa to %u\n"), u128);
8979 break;
8980 }
8981 }
8982 else
8983 {
8984 /* This is a new opcode the generator but not we know about.
8985 Read the parameters associated with it but then discard
8986 everything. Read all the parameters for this opcode. */
8987 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8988 " unknown opcode with %" PRIu8 " parameters:",
8989 standard_opcode_lengths[opcode]),
8990 standard_opcode_lengths[opcode]);
8991 for (int n = standard_opcode_lengths[opcode];
8992 n > 0 && linep < lineendp; --n)
8993 {
8994 get_uleb128 (u128, linep, lineendp);
8995 if (n != standard_opcode_lengths[opcode])
8996 putc_unlocked (',', stdout);
8997 printf (" %u", u128);
8998 }
8999
9000 /* Next round, ignore this opcode. */
9001 continue;
9002 }
9003 }
9004 }
9005
9006 /* There must only be one data block. */
9007 assert (elf_getdata (scn, data) == NULL);
9008 }
9009
9010
9011 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9012 print_debug_loclists_section (Dwfl_Module *dwflmod,
9013 Ebl *ebl,
9014 GElf_Ehdr *ehdr __attribute__ ((unused)),
9015 Elf_Scn *scn, GElf_Shdr *shdr,
9016 Dwarf *dbg)
9017 {
9018 printf (gettext ("\
9019 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9020 elf_ndxscn (scn), section_name (ebl, shdr),
9021 (uint64_t) shdr->sh_offset);
9022
9023 Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9024 ?: elf_rawdata (scn, NULL));
9025 if (unlikely (data == NULL))
9026 {
9027 error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
9028 elf_errmsg (-1));
9029 return;
9030 }
9031
9032 /* For the listptr to get the base address/CU. */
9033 sort_listptr (&known_loclistsptr, "loclistsptr");
9034 size_t listptr_idx = 0;
9035
9036 const unsigned char *readp = data->d_buf;
9037 const unsigned char *const dataend = ((unsigned char *) data->d_buf
9038 + data->d_size);
9039 while (readp < dataend)
9040 {
9041 if (unlikely (readp > dataend - 4))
9042 {
9043 invalid_data:
9044 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
9045 elf_ndxscn (scn), section_name (ebl, shdr));
9046 return;
9047 }
9048
9049 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9050 printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
9051 (uint64_t) offset);
9052
9053 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9054 unsigned int offset_size = 4;
9055 if (unlikely (unit_length == 0xffffffff))
9056 {
9057 if (unlikely (readp > dataend - 8))
9058 goto invalid_data;
9059
9060 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9061 offset_size = 8;
9062 }
9063 printf (gettext (" Length: %8" PRIu64 "\n"), unit_length);
9064
9065 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9066 bytes to complete the header. And this unit cannot go beyond
9067 the section data. */
9068 if (readp > dataend - 8
9069 || unit_length < 8
9070 || unit_length > (uint64_t) (dataend - readp))
9071 goto invalid_data;
9072
9073 const unsigned char *nexthdr = readp + unit_length;
9074
9075 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9076 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
9077
9078 if (version != 5)
9079 {
9080 error (0, 0, gettext ("Unknown version"));
9081 goto next_table;
9082 }
9083
9084 uint8_t address_size = *readp++;
9085 printf (gettext (" Address size: %8" PRIu64 "\n"),
9086 (uint64_t) address_size);
9087
9088 if (address_size != 4 && address_size != 8)
9089 {
9090 error (0, 0, gettext ("unsupported address size"));
9091 goto next_table;
9092 }
9093
9094 uint8_t segment_size = *readp++;
9095 printf (gettext (" Segment size: %8" PRIu64 "\n"),
9096 (uint64_t) segment_size);
9097
9098 if (segment_size != 0)
9099 {
9100 error (0, 0, gettext ("unsupported segment size"));
9101 goto next_table;
9102 }
9103
9104 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9105 printf (gettext (" Offset entries: %8" PRIu64 "\n"),
9106 (uint64_t) offset_entry_count);
9107
9108 /* We need the CU that uses this unit to get the initial base address. */
9109 Dwarf_Addr cu_base = 0;
9110 struct Dwarf_CU *cu = NULL;
9111 if (listptr_cu (&known_loclistsptr, &listptr_idx,
9112 (Dwarf_Off) offset,
9113 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9114 &cu_base, &cu)
9115 || split_dwarf_cu_base (dbg, &cu, &cu_base))
9116 {
9117 Dwarf_Die cudie;
9118 if (dwarf_cu_die (cu, &cudie,
9119 NULL, NULL, NULL, NULL,
9120 NULL, NULL) == NULL)
9121 printf (gettext (" Unknown CU base: "));
9122 else
9123 printf (gettext (" CU [%6" PRIx64 "] base: "),
9124 dwarf_dieoffset (&cudie));
9125 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9126 printf ("\n");
9127 }
9128 else
9129 printf (gettext (" Not associated with a CU.\n"));
9130
9131 printf ("\n");
9132
9133 const unsigned char *offset_array_start = readp;
9134 if (offset_entry_count > 0)
9135 {
9136 uint64_t max_entries = (unit_length - 8) / offset_size;
9137 if (offset_entry_count > max_entries)
9138 {
9139 error (0, 0,
9140 gettext ("too many offset entries for unit length"));
9141 offset_entry_count = max_entries;
9142 }
9143
9144 printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),
9145 (uint64_t) (offset_array_start
9146 - (unsigned char *) data->d_buf));
9147 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9148 {
9149 printf (" [%6" PRIu32 "] ", idx);
9150 if (offset_size == 4)
9151 {
9152 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9153 printf ("0x%" PRIx32 "\n", off);
9154 }
9155 else
9156 {
9157 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9158 printf ("0x%" PRIx64 "\n", off);
9159 }
9160 }
9161 printf ("\n");
9162 }
9163
9164 Dwarf_Addr base = cu_base;
9165 bool start_of_list = true;
9166 while (readp < nexthdr)
9167 {
9168 uint8_t kind = *readp++;
9169 uint64_t op1, op2, len;
9170
9171 /* Skip padding. */
9172 if (start_of_list && kind == DW_LLE_end_of_list)
9173 continue;
9174
9175 if (start_of_list)
9176 {
9177 base = cu_base;
9178 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9179 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9180 (uint64_t) (readp - offset_array_start - 1));
9181 start_of_list = false;
9182 }
9183
9184 printf (" %s", dwarf_loc_list_encoding_name (kind));
9185 switch (kind)
9186 {
9187 case DW_LLE_end_of_list:
9188 start_of_list = true;
9189 printf ("\n\n");
9190 break;
9191
9192 case DW_LLE_base_addressx:
9193 if ((uint64_t) (nexthdr - readp) < 1)
9194 {
9195 invalid_entry:
9196 error (0, 0, gettext ("invalid loclists data"));
9197 goto next_table;
9198 }
9199 get_uleb128 (op1, readp, nexthdr);
9200 printf (" %" PRIx64 "\n", op1);
9201 if (! print_unresolved_addresses)
9202 {
9203 Dwarf_Addr addr;
9204 if (get_indexed_addr (cu, op1, &addr) != 0)
9205 printf (" ???\n");
9206 else
9207 {
9208 printf (" ");
9209 print_dwarf_addr (dwflmod, address_size, addr, addr);
9210 printf ("\n");
9211 }
9212 }
9213 break;
9214
9215 case DW_LLE_startx_endx:
9216 if ((uint64_t) (nexthdr - readp) < 1)
9217 goto invalid_entry;
9218 get_uleb128 (op1, readp, nexthdr);
9219 if ((uint64_t) (nexthdr - readp) < 1)
9220 goto invalid_entry;
9221 get_uleb128 (op2, readp, nexthdr);
9222 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9223 if (! print_unresolved_addresses)
9224 {
9225 Dwarf_Addr addr1;
9226 Dwarf_Addr addr2;
9227 if (get_indexed_addr (cu, op1, &addr1) != 0
9228 || get_indexed_addr (cu, op2, &addr2) != 0)
9229 {
9230 printf (" ???..\n");
9231 printf (" ???\n");
9232 }
9233 else
9234 {
9235 printf (" ");
9236 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9237 printf ("..\n ");
9238 print_dwarf_addr (dwflmod, address_size,
9239 addr2 - 1, addr2);
9240 printf ("\n");
9241 }
9242 }
9243 if ((uint64_t) (nexthdr - readp) < 1)
9244 goto invalid_entry;
9245 get_uleb128 (len, readp, nexthdr);
9246 if ((uint64_t) (nexthdr - readp) < len)
9247 goto invalid_entry;
9248 print_ops (dwflmod, dbg, 8, 8, version,
9249 address_size, offset_size, cu, len, readp);
9250 readp += len;
9251 break;
9252
9253 case DW_LLE_startx_length:
9254 if ((uint64_t) (nexthdr - readp) < 1)
9255 goto invalid_entry;
9256 get_uleb128 (op1, readp, nexthdr);
9257 if ((uint64_t) (nexthdr - readp) < 1)
9258 goto invalid_entry;
9259 get_uleb128 (op2, readp, nexthdr);
9260 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9261 if (! print_unresolved_addresses)
9262 {
9263 Dwarf_Addr addr1;
9264 Dwarf_Addr addr2;
9265 if (get_indexed_addr (cu, op1, &addr1) != 0)
9266 {
9267 printf (" ???..\n");
9268 printf (" ???\n");
9269 }
9270 else
9271 {
9272 addr2 = addr1 + op2;
9273 printf (" ");
9274 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9275 printf ("..\n ");
9276 print_dwarf_addr (dwflmod, address_size,
9277 addr2 - 1, addr2);
9278 printf ("\n");
9279 }
9280 }
9281 if ((uint64_t) (nexthdr - readp) < 1)
9282 goto invalid_entry;
9283 get_uleb128 (len, readp, nexthdr);
9284 if ((uint64_t) (nexthdr - readp) < len)
9285 goto invalid_entry;
9286 print_ops (dwflmod, dbg, 8, 8, version,
9287 address_size, offset_size, cu, len, readp);
9288 readp += len;
9289 break;
9290
9291 case DW_LLE_offset_pair:
9292 if ((uint64_t) (nexthdr - readp) < 1)
9293 goto invalid_entry;
9294 get_uleb128 (op1, readp, nexthdr);
9295 if ((uint64_t) (nexthdr - readp) < 1)
9296 goto invalid_entry;
9297 get_uleb128 (op2, readp, nexthdr);
9298 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9299 if (! print_unresolved_addresses)
9300 {
9301 op1 += base;
9302 op2 += base;
9303 printf (" ");
9304 print_dwarf_addr (dwflmod, address_size, op1, op1);
9305 printf ("..\n ");
9306 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9307 printf ("\n");
9308 }
9309 if ((uint64_t) (nexthdr - readp) < 1)
9310 goto invalid_entry;
9311 get_uleb128 (len, readp, nexthdr);
9312 if ((uint64_t) (nexthdr - readp) < len)
9313 goto invalid_entry;
9314 print_ops (dwflmod, dbg, 8, 8, version,
9315 address_size, offset_size, cu, len, readp);
9316 readp += len;
9317 break;
9318
9319 case DW_LLE_default_location:
9320 if ((uint64_t) (nexthdr - readp) < 1)
9321 goto invalid_entry;
9322 get_uleb128 (len, readp, nexthdr);
9323 if ((uint64_t) (nexthdr - readp) < len)
9324 goto invalid_entry;
9325 print_ops (dwflmod, dbg, 8, 8, version,
9326 address_size, offset_size, cu, len, readp);
9327 readp += len;
9328 break;
9329
9330 case DW_LLE_base_address:
9331 if (address_size == 4)
9332 {
9333 if ((uint64_t) (nexthdr - readp) < 4)
9334 goto invalid_entry;
9335 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9336 }
9337 else
9338 {
9339 if ((uint64_t) (nexthdr - readp) < 8)
9340 goto invalid_entry;
9341 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9342 }
9343 base = op1;
9344 printf (" 0x%" PRIx64 "\n", base);
9345 if (! print_unresolved_addresses)
9346 {
9347 printf (" ");
9348 print_dwarf_addr (dwflmod, address_size, base, base);
9349 printf ("\n");
9350 }
9351 break;
9352
9353 case DW_LLE_start_end:
9354 if (address_size == 4)
9355 {
9356 if ((uint64_t) (nexthdr - readp) < 8)
9357 goto invalid_entry;
9358 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9359 op2 = read_4ubyte_unaligned_inc (dbg, readp);
9360 }
9361 else
9362 {
9363 if ((uint64_t) (nexthdr - readp) < 16)
9364 goto invalid_entry;
9365 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9366 op2 = read_8ubyte_unaligned_inc (dbg, readp);
9367 }
9368 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9369 if (! print_unresolved_addresses)
9370 {
9371 printf (" ");
9372 print_dwarf_addr (dwflmod, address_size, op1, op1);
9373 printf ("..\n ");
9374 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9375 printf ("\n");
9376 }
9377 if ((uint64_t) (nexthdr - readp) < 1)
9378 goto invalid_entry;
9379 get_uleb128 (len, readp, nexthdr);
9380 if ((uint64_t) (nexthdr - readp) < len)
9381 goto invalid_entry;
9382 print_ops (dwflmod, dbg, 8, 8, version,
9383 address_size, offset_size, cu, len, readp);
9384 readp += len;
9385 break;
9386
9387 case DW_LLE_start_length:
9388 if (address_size == 4)
9389 {
9390 if ((uint64_t) (nexthdr - readp) < 4)
9391 goto invalid_entry;
9392 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9393 }
9394 else
9395 {
9396 if ((uint64_t) (nexthdr - readp) < 8)
9397 goto invalid_entry;
9398 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9399 }
9400 if ((uint64_t) (nexthdr - readp) < 1)
9401 goto invalid_entry;
9402 get_uleb128 (op2, readp, nexthdr);
9403 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9404 if (! print_unresolved_addresses)
9405 {
9406 op2 = op1 + op2;
9407 printf (" ");
9408 print_dwarf_addr (dwflmod, address_size, op1, op1);
9409 printf ("..\n ");
9410 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9411 printf ("\n");
9412 }
9413 if ((uint64_t) (nexthdr - readp) < 1)
9414 goto invalid_entry;
9415 get_uleb128 (len, readp, nexthdr);
9416 if ((uint64_t) (nexthdr - readp) < len)
9417 goto invalid_entry;
9418 print_ops (dwflmod, dbg, 8, 8, version,
9419 address_size, offset_size, cu, len, readp);
9420 readp += len;
9421 break;
9422
9423 default:
9424 goto invalid_entry;
9425 }
9426 }
9427
9428 next_table:
9429 if (readp != nexthdr)
9430 {
9431 size_t padding = nexthdr - readp;
9432 printf (gettext (" %zu padding bytes\n\n"), padding);
9433 readp = nexthdr;
9434 }
9435 }
9436 }
9437
9438
9439 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9440 print_debug_loc_section (Dwfl_Module *dwflmod,
9441 Ebl *ebl, GElf_Ehdr *ehdr,
9442 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9443 {
9444 Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9445 ?: elf_rawdata (scn, NULL));
9446
9447 if (unlikely (data == NULL))
9448 {
9449 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9450 elf_errmsg (-1));
9451 return;
9452 }
9453
9454 printf (gettext ("\
9455 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9456 elf_ndxscn (scn), section_name (ebl, shdr),
9457 (uint64_t) shdr->sh_offset);
9458
9459 sort_listptr (&known_locsptr, "loclistptr");
9460 size_t listptr_idx = 0;
9461
9462 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9463 uint_fast8_t offset_size = 4;
9464
9465 bool first = true;
9466 Dwarf_Addr base = 0;
9467 unsigned char *readp = data->d_buf;
9468 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9469 Dwarf_CU *last_cu = NULL;
9470 while (readp < endp)
9471 {
9472 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9473 Dwarf_CU *cu = last_cu;
9474 unsigned int attr = 0;
9475
9476 if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9477 &address_size, &offset_size, &base,
9478 &cu, offset, &readp, endp, &attr))
9479 continue;
9480
9481 if (last_cu != cu)
9482 {
9483 Dwarf_Die cudie;
9484 if (dwarf_cu_die (cu, &cudie,
9485 NULL, NULL, NULL, NULL,
9486 NULL, NULL) == NULL)
9487 printf (gettext ("\n Unknown CU base: "));
9488 else
9489 printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9490 dwarf_dieoffset (&cudie));
9491 print_dwarf_addr (dwflmod, address_size, base, base);
9492 printf ("\n");
9493 }
9494 last_cu = cu;
9495
9496 if (attr == DW_AT_GNU_locviews)
9497 {
9498 Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9499 listptr_idx);
9500 const unsigned char *locp = readp;
9501 const unsigned char *locendp;
9502 if (next_off == 0
9503 || next_off > (size_t) (endp
9504 - (const unsigned char *) data->d_buf))
9505 locendp = endp;
9506 else
9507 locendp = (const unsigned char *) data->d_buf + next_off;
9508
9509 while (locp < locendp)
9510 {
9511 uint64_t v1, v2;
9512 get_uleb128 (v1, locp, locendp);
9513 if (locp >= locendp)
9514 {
9515 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
9516 break;
9517 }
9518 get_uleb128 (v2, locp, locendp);
9519 if (first) /* First view pair in a list. */
9520 printf (" [%6tx] ", offset);
9521 else
9522 printf (" ");
9523 printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9524 first = false;
9525 }
9526
9527 first = true;
9528 readp = (unsigned char *) locendp;
9529 continue;
9530 }
9531
9532 /* GNU DebugFission encoded addresses as addrx. */
9533 bool is_debugfission = ((cu != NULL
9534 || split_dwarf_cu_base (dbg, &cu, &base))
9535 && (cu->version < 5
9536 && cu->unit_type == DW_UT_split_compile));
9537 if (!is_debugfission
9538 && unlikely (data->d_size - offset < (size_t) address_size * 2))
9539 {
9540 invalid_data:
9541 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
9542 break;
9543 }
9544
9545 Dwarf_Addr begin;
9546 Dwarf_Addr end;
9547 bool use_base = true;
9548 if (is_debugfission)
9549 {
9550 const unsigned char *locp = readp;
9551 const unsigned char *locendp = readp + data->d_size;
9552 if (locp >= locendp)
9553 goto invalid_data;
9554
9555 Dwarf_Word idx;
9556 unsigned char code = *locp++;
9557 switch (code)
9558 {
9559 case DW_LLE_GNU_end_of_list_entry:
9560 begin = 0;
9561 end = 0;
9562 break;
9563
9564 case DW_LLE_GNU_base_address_selection_entry:
9565 if (locp >= locendp)
9566 goto invalid_data;
9567 begin = (Dwarf_Addr) -1;
9568 get_uleb128 (idx, locp, locendp);
9569 if (get_indexed_addr (cu, idx, &end) != 0)
9570 end = idx; /* ... */
9571 break;
9572
9573 case DW_LLE_GNU_start_end_entry:
9574 if (locp >= locendp)
9575 goto invalid_data;
9576 get_uleb128 (idx, locp, locendp);
9577 if (get_indexed_addr (cu, idx, &begin) != 0)
9578 begin = idx; /* ... */
9579 if (locp >= locendp)
9580 goto invalid_data;
9581 get_uleb128 (idx, locp, locendp);
9582 if (get_indexed_addr (cu, idx, &end) != 0)
9583 end = idx; /* ... */
9584 use_base = false;
9585 break;
9586
9587 case DW_LLE_GNU_start_length_entry:
9588 if (locp >= locendp)
9589 goto invalid_data;
9590 get_uleb128 (idx, locp, locendp);
9591 if (get_indexed_addr (cu, idx, &begin) != 0)
9592 begin = idx; /* ... */
9593 if (locendp - locp < 4)
9594 goto invalid_data;
9595 end = read_4ubyte_unaligned_inc (dbg, locp);
9596 end += begin;
9597 use_base = false;
9598 break;
9599
9600 default:
9601 goto invalid_data;
9602 }
9603
9604 readp = (unsigned char *) locp;
9605 }
9606 else if (address_size == 8)
9607 {
9608 begin = read_8ubyte_unaligned_inc (dbg, readp);
9609 end = read_8ubyte_unaligned_inc (dbg, readp);
9610 }
9611 else
9612 {
9613 begin = read_4ubyte_unaligned_inc (dbg, readp);
9614 end = read_4ubyte_unaligned_inc (dbg, readp);
9615 if (begin == (Dwarf_Addr) (uint32_t) -1)
9616 begin = (Dwarf_Addr) -1l;
9617 }
9618
9619 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
9620 {
9621 printf (gettext (" [%6tx] base address\n "), offset);
9622 print_dwarf_addr (dwflmod, address_size, end, end);
9623 printf ("\n");
9624 base = end;
9625 }
9626 else if (begin == 0 && end == 0) /* End of list entry. */
9627 {
9628 if (first)
9629 printf (gettext (" [%6tx] empty list\n"), offset);
9630 first = true;
9631 }
9632 else
9633 {
9634 /* We have a location expression entry. */
9635 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9636
9637 if (first) /* First entry in a list. */
9638 printf (" [%6tx] ", offset);
9639 else
9640 printf (" ");
9641
9642 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9643 if (! print_unresolved_addresses)
9644 {
9645 Dwarf_Addr dab = use_base ? base + begin : begin;
9646 Dwarf_Addr dae = use_base ? base + end : end;
9647 printf (" ");
9648 print_dwarf_addr (dwflmod, address_size, dab, dab);
9649 printf ("..\n ");
9650 print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9651 printf ("\n");
9652 }
9653
9654 if (endp - readp <= (ptrdiff_t) len)
9655 {
9656 fputs (gettext (" <INVALID DATA>\n"), stdout);
9657 break;
9658 }
9659
9660 print_ops (dwflmod, dbg, 11, 11,
9661 cu != NULL ? cu->version : 3,
9662 address_size, offset_size, cu, len, readp);
9663
9664 first = false;
9665 readp += len;
9666 }
9667 }
9668 }
9669
9670 struct mac_culist
9671 {
9672 Dwarf_Die die;
9673 Dwarf_Off offset;
9674 Dwarf_Files *files;
9675 struct mac_culist *next;
9676 };
9677
9678
9679 static int
mac_compare(const void * p1,const void * p2)9680 mac_compare (const void *p1, const void *p2)
9681 {
9682 struct mac_culist *m1 = (struct mac_culist *) p1;
9683 struct mac_culist *m2 = (struct mac_culist *) p2;
9684
9685 if (m1->offset < m2->offset)
9686 return -1;
9687 if (m1->offset > m2->offset)
9688 return 1;
9689 return 0;
9690 }
9691
9692
9693 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9694 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9695 Ebl *ebl,
9696 GElf_Ehdr *ehdr __attribute__ ((unused)),
9697 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9698 {
9699 printf (gettext ("\
9700 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9701 elf_ndxscn (scn), section_name (ebl, shdr),
9702 (uint64_t) shdr->sh_offset);
9703 putc_unlocked ('\n', stdout);
9704
9705 /* There is no function in libdw to iterate over the raw content of
9706 the section but it is easy enough to do. */
9707 Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9708 ?: elf_rawdata (scn, NULL));
9709 if (unlikely (data == NULL))
9710 {
9711 error (0, 0, gettext ("cannot get macro information section data: %s"),
9712 elf_errmsg (-1));
9713 return;
9714 }
9715
9716 /* Get the source file information for all CUs. */
9717 Dwarf_Off offset;
9718 Dwarf_Off ncu = 0;
9719 size_t hsize;
9720 struct mac_culist *culist = NULL;
9721 size_t nculist = 0;
9722 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9723 {
9724 Dwarf_Die cudie;
9725 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9726 continue;
9727
9728 Dwarf_Attribute attr;
9729 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9730 continue;
9731
9732 Dwarf_Word macoff;
9733 if (dwarf_formudata (&attr, &macoff) != 0)
9734 continue;
9735
9736 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9737 newp->die = cudie;
9738 newp->offset = macoff;
9739 newp->files = NULL;
9740 newp->next = culist;
9741 culist = newp;
9742 ++nculist;
9743 }
9744
9745 /* Convert the list into an array for easier consumption. */
9746 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9747 * sizeof (*cus));
9748 /* Add sentinel. */
9749 cus[nculist].offset = data->d_size;
9750 cus[nculist].files = (Dwarf_Files *) -1l;
9751 if (nculist > 0)
9752 {
9753 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9754 {
9755 assert (cnt < nculist);
9756 cus[cnt] = *culist;
9757 culist = culist->next;
9758 }
9759
9760 /* Sort the array according to the offset in the .debug_macinfo
9761 section. Note we keep the sentinel at the end. */
9762 qsort (cus, nculist, sizeof (*cus), mac_compare);
9763 }
9764
9765 const unsigned char *readp = (const unsigned char *) data->d_buf;
9766 const unsigned char *readendp = readp + data->d_size;
9767 int level = 1;
9768
9769 while (readp < readendp)
9770 {
9771 unsigned int opcode = *readp++;
9772 unsigned int u128;
9773 unsigned int u128_2;
9774 const unsigned char *endp;
9775
9776 switch (opcode)
9777 {
9778 case DW_MACINFO_define:
9779 case DW_MACINFO_undef:
9780 case DW_MACINFO_vendor_ext:
9781 /* For the first two opcodes the parameters are
9782 line, string
9783 For the latter
9784 number, string.
9785 We can treat these cases together. */
9786 get_uleb128 (u128, readp, readendp);
9787
9788 endp = memchr (readp, '\0', readendp - readp);
9789 if (unlikely (endp == NULL))
9790 {
9791 printf (gettext ("\
9792 %*s*** non-terminated string at end of section"),
9793 level, "");
9794 return;
9795 }
9796
9797 if (opcode == DW_MACINFO_define)
9798 printf ("%*s#define %s, line %u\n",
9799 level, "", (char *) readp, u128);
9800 else if (opcode == DW_MACINFO_undef)
9801 printf ("%*s#undef %s, line %u\n",
9802 level, "", (char *) readp, u128);
9803 else
9804 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9805
9806 readp = endp + 1;
9807 break;
9808
9809 case DW_MACINFO_start_file:
9810 /* The two parameters are line and file index, in this order. */
9811 get_uleb128 (u128, readp, readendp);
9812 if (readendp - readp < 1)
9813 {
9814 printf (gettext ("\
9815 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9816 level, "");
9817 return;
9818 }
9819 get_uleb128 (u128_2, readp, readendp);
9820
9821 /* Find the CU DIE for this file. */
9822 size_t macoff = readp - (const unsigned char *) data->d_buf;
9823 const char *fname = "???";
9824 if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
9825 {
9826 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9827 ++cus;
9828
9829 if (cus[0].files == NULL
9830 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9831 cus[0].files = (Dwarf_Files *) -1l;
9832
9833 if (cus[0].files != (Dwarf_Files *) -1l)
9834 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9835 ?: "???");
9836 }
9837
9838 printf ("%*sstart_file %u, [%u] %s\n",
9839 level, "", u128, u128_2, fname);
9840 ++level;
9841 break;
9842
9843 case DW_MACINFO_end_file:
9844 --level;
9845 printf ("%*send_file\n", level, "");
9846 /* Nothing more to do. */
9847 break;
9848
9849 default:
9850 // XXX gcc seems to generate files with a trailing zero.
9851 if (unlikely (opcode != 0 || readp != readendp))
9852 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9853 break;
9854 }
9855 }
9856 }
9857
9858
9859 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9860 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9861 Ebl *ebl,
9862 GElf_Ehdr *ehdr __attribute__ ((unused)),
9863 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9864 {
9865 printf (gettext ("\
9866 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9867 elf_ndxscn (scn), section_name (ebl, shdr),
9868 (uint64_t) shdr->sh_offset);
9869 putc_unlocked ('\n', stdout);
9870
9871 Elf_Data *data = elf_getdata (scn, NULL);
9872 if (unlikely (data == NULL))
9873 {
9874 error (0, 0, gettext ("cannot get macro information section data: %s"),
9875 elf_errmsg (-1));
9876 return;
9877 }
9878
9879 /* Get the source file information for all CUs. Uses same
9880 datastructure as macinfo. But uses offset field to directly
9881 match .debug_line offset. And just stored in a list. */
9882 Dwarf_Off offset;
9883 Dwarf_Off ncu = 0;
9884 size_t hsize;
9885 struct mac_culist *culist = NULL;
9886 size_t nculist = 0;
9887 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9888 {
9889 Dwarf_Die cudie;
9890 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9891 continue;
9892
9893 Dwarf_Attribute attr;
9894 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9895 continue;
9896
9897 Dwarf_Word lineoff;
9898 if (dwarf_formudata (&attr, &lineoff) != 0)
9899 continue;
9900
9901 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9902 newp->die = cudie;
9903 newp->offset = lineoff;
9904 newp->files = NULL;
9905 newp->next = culist;
9906 culist = newp;
9907 ++nculist;
9908 }
9909
9910 const unsigned char *readp = (const unsigned char *) data->d_buf;
9911 const unsigned char *readendp = readp + data->d_size;
9912
9913 while (readp < readendp)
9914 {
9915 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
9916 (uint64_t) (readp - (const unsigned char *) data->d_buf));
9917
9918 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9919 // optional vendor extension macro entry table.
9920 if (readp + 2 > readendp)
9921 {
9922 invalid_data:
9923 error (0, 0, gettext ("invalid data"));
9924 return;
9925 }
9926 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9927 printf (gettext (" Version: %" PRIu16 "\n"), vers);
9928
9929 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
9930 // 5 when it gets standardized.
9931 if (vers != 4 && vers != 5)
9932 {
9933 printf (gettext (" unknown version, cannot parse section\n"));
9934 return;
9935 }
9936
9937 if (readp + 1 > readendp)
9938 goto invalid_data;
9939 const unsigned char flag = *readp++;
9940 printf (gettext (" Flag: 0x%" PRIx8), flag);
9941 if (flag != 0)
9942 {
9943 printf (" (");
9944 if ((flag & 0x01) != 0)
9945 {
9946 printf ("offset_size");
9947 if ((flag & 0xFE) != 0)
9948 printf (", ");
9949 }
9950 if ((flag & 0x02) != 0)
9951 {
9952 printf ("debug_line_offset");
9953 if ((flag & 0xFC) != 0)
9954 printf (", ");
9955 }
9956 if ((flag & 0x04) != 0)
9957 {
9958 printf ("operands_table");
9959 if ((flag & 0xF8) != 0)
9960 printf (", ");
9961 }
9962 if ((flag & 0xF8) != 0)
9963 printf ("unknown");
9964 printf (")");
9965 }
9966 printf ("\n");
9967
9968 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9969 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
9970 Dwarf_Off line_offset = -1;
9971 if (flag & 0x02)
9972 {
9973 if (offset_len == 8)
9974 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9975 else
9976 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9977 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9978 line_offset);
9979 }
9980
9981 struct mac_culist *cu = NULL;
9982 if (line_offset != (Dwarf_Off) -1)
9983 {
9984 cu = culist;
9985 while (cu != NULL && line_offset != cu->offset)
9986 cu = cu->next;
9987 }
9988
9989 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9990 ? cu->die.cu
9991 : NULL));
9992
9993 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9994 memset (vendor, 0, sizeof vendor);
9995 if (flag & 0x04)
9996 {
9997 // 1 byte length, for each item, 1 byte opcode, uleb128 number
9998 // of arguments, for each argument 1 byte form code.
9999 if (readp + 1 > readendp)
10000 goto invalid_data;
10001 unsigned int tlen = *readp++;
10002 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
10003 tlen);
10004 for (unsigned int i = 0; i < tlen; i++)
10005 {
10006 if (readp + 1 > readendp)
10007 goto invalid_data;
10008 unsigned int opcode = *readp++;
10009 printf (gettext (" [%" PRIx8 "]"), opcode);
10010 if (opcode < DW_MACRO_lo_user
10011 || opcode > DW_MACRO_hi_user)
10012 goto invalid_data;
10013 // Record the start of description for this vendor opcode.
10014 // uleb128 nr args, 1 byte per arg form.
10015 vendor[opcode - DW_MACRO_lo_user] = readp;
10016 if (readp + 1 > readendp)
10017 goto invalid_data;
10018 unsigned int args = *readp++;
10019 if (args > 0)
10020 {
10021 printf (gettext (" %" PRIu8 " arguments:"), args);
10022 while (args > 0)
10023 {
10024 if (readp + 1 > readendp)
10025 goto invalid_data;
10026 unsigned int form = *readp++;
10027 printf (" %s", dwarf_form_name (form));
10028 if (! libdw_valid_user_form (form))
10029 goto invalid_data;
10030 args--;
10031 if (args > 0)
10032 putchar_unlocked (',');
10033 }
10034 }
10035 else
10036 printf (gettext (" no arguments."));
10037 putchar_unlocked ('\n');
10038 }
10039 }
10040 putchar_unlocked ('\n');
10041
10042 int level = 1;
10043 if (readp + 1 > readendp)
10044 goto invalid_data;
10045 unsigned int opcode = *readp++;
10046 while (opcode != 0)
10047 {
10048 unsigned int u128;
10049 unsigned int u128_2;
10050 const unsigned char *endp;
10051 uint64_t off;
10052
10053 switch (opcode)
10054 {
10055 case DW_MACRO_start_file:
10056 get_uleb128 (u128, readp, readendp);
10057 if (readp >= readendp)
10058 goto invalid_data;
10059 get_uleb128 (u128_2, readp, readendp);
10060
10061 /* Find the CU DIE that matches this line offset. */
10062 const char *fname = "???";
10063 if (cu != NULL)
10064 {
10065 if (cu->files == NULL
10066 && dwarf_getsrcfiles (&cu->die, &cu->files,
10067 NULL) != 0)
10068 cu->files = (Dwarf_Files *) -1l;
10069
10070 if (cu->files != (Dwarf_Files *) -1l)
10071 fname = (dwarf_filesrc (cu->files, u128_2,
10072 NULL, NULL) ?: "???");
10073 }
10074 printf ("%*sstart_file %u, [%u] %s\n",
10075 level, "", u128, u128_2, fname);
10076 ++level;
10077 break;
10078
10079 case DW_MACRO_end_file:
10080 --level;
10081 printf ("%*send_file\n", level, "");
10082 break;
10083
10084 case DW_MACRO_define:
10085 get_uleb128 (u128, readp, readendp);
10086 endp = memchr (readp, '\0', readendp - readp);
10087 if (endp == NULL)
10088 goto invalid_data;
10089 printf ("%*s#define %s, line %u\n",
10090 level, "", readp, u128);
10091 readp = endp + 1;
10092 break;
10093
10094 case DW_MACRO_undef:
10095 get_uleb128 (u128, readp, readendp);
10096 endp = memchr (readp, '\0', readendp - readp);
10097 if (endp == NULL)
10098 goto invalid_data;
10099 printf ("%*s#undef %s, line %u\n",
10100 level, "", readp, u128);
10101 readp = endp + 1;
10102 break;
10103
10104 case DW_MACRO_define_strp:
10105 get_uleb128 (u128, readp, readendp);
10106 if (readp + offset_len > readendp)
10107 goto invalid_data;
10108 if (offset_len == 8)
10109 off = read_8ubyte_unaligned_inc (dbg, readp);
10110 else
10111 off = read_4ubyte_unaligned_inc (dbg, readp);
10112 printf ("%*s#define %s, line %u (indirect)\n",
10113 level, "", dwarf_getstring (dbg, off, NULL), u128);
10114 break;
10115
10116 case DW_MACRO_undef_strp:
10117 get_uleb128 (u128, readp, readendp);
10118 if (readp + offset_len > readendp)
10119 goto invalid_data;
10120 if (offset_len == 8)
10121 off = read_8ubyte_unaligned_inc (dbg, readp);
10122 else
10123 off = read_4ubyte_unaligned_inc (dbg, readp);
10124 printf ("%*s#undef %s, line %u (indirect)\n",
10125 level, "", dwarf_getstring (dbg, off, NULL), u128);
10126 break;
10127
10128 case DW_MACRO_import:
10129 if (readp + offset_len > readendp)
10130 goto invalid_data;
10131 if (offset_len == 8)
10132 off = read_8ubyte_unaligned_inc (dbg, readp);
10133 else
10134 off = read_4ubyte_unaligned_inc (dbg, readp);
10135 printf ("%*s#include offset 0x%" PRIx64 "\n",
10136 level, "", off);
10137 break;
10138
10139 case DW_MACRO_define_sup:
10140 get_uleb128 (u128, readp, readendp);
10141 if (readp + offset_len > readendp)
10142 goto invalid_data;
10143 printf ("%*s#define ", level, "");
10144 readp = print_form_data (dbg, DW_FORM_strp_sup,
10145 readp, readendp, offset_len,
10146 str_offsets_base);
10147 printf (", line %u (sup)\n", u128);
10148 break;
10149
10150 case DW_MACRO_undef_sup:
10151 get_uleb128 (u128, readp, readendp);
10152 if (readp + offset_len > readendp)
10153 goto invalid_data;
10154 printf ("%*s#undef ", level, "");
10155 readp = print_form_data (dbg, DW_FORM_strp_sup,
10156 readp, readendp, offset_len,
10157 str_offsets_base);
10158 printf (", line %u (sup)\n", u128);
10159 break;
10160
10161 case DW_MACRO_import_sup:
10162 if (readp + offset_len > readendp)
10163 goto invalid_data;
10164 if (offset_len == 8)
10165 off = read_8ubyte_unaligned_inc (dbg, readp);
10166 else
10167 off = read_4ubyte_unaligned_inc (dbg, readp);
10168 // XXX Needs support for reading from supplementary object file.
10169 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10170 level, "", off);
10171 break;
10172
10173 case DW_MACRO_define_strx:
10174 get_uleb128 (u128, readp, readendp);
10175 if (readp + offset_len > readendp)
10176 goto invalid_data;
10177 printf ("%*s#define ", level, "");
10178 readp = print_form_data (dbg, DW_FORM_strx,
10179 readp, readendp, offset_len,
10180 str_offsets_base);
10181 printf (", line %u (strx)\n", u128);
10182 break;
10183
10184 case DW_MACRO_undef_strx:
10185 get_uleb128 (u128, readp, readendp);
10186 if (readp + offset_len > readendp)
10187 goto invalid_data;
10188 printf ("%*s#undef ", level, "");
10189 readp = print_form_data (dbg, DW_FORM_strx,
10190 readp, readendp, offset_len,
10191 str_offsets_base);
10192 printf (", line %u (strx)\n", u128);
10193 break;
10194
10195 default:
10196 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10197 if (opcode < DW_MACRO_lo_user
10198 || opcode > DW_MACRO_lo_user
10199 || vendor[opcode - DW_MACRO_lo_user] == NULL)
10200 goto invalid_data;
10201
10202 const unsigned char *op_desc;
10203 op_desc = vendor[opcode - DW_MACRO_lo_user];
10204
10205 // Just skip the arguments, we cannot really interpret them,
10206 // but print as much as we can.
10207 unsigned int args = *op_desc++;
10208 while (args > 0 && readp < readendp)
10209 {
10210 unsigned int form = *op_desc++;
10211 readp = print_form_data (dbg, form, readp, readendp,
10212 offset_len, str_offsets_base);
10213 args--;
10214 if (args > 0)
10215 printf (", ");
10216 }
10217 putchar_unlocked ('\n');
10218 }
10219
10220 if (readp + 1 > readendp)
10221 goto invalid_data;
10222 opcode = *readp++;
10223 if (opcode == 0)
10224 putchar_unlocked ('\n');
10225 }
10226 }
10227 }
10228
10229
10230 /* Callback for printing global names. */
10231 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10232 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10233 void *arg)
10234 {
10235 int *np = (int *) arg;
10236
10237 printf (gettext (" [%5d] DIE offset: %6" PRId64
10238 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10239 (*np)++, global->die_offset, global->cu_offset, global->name);
10240
10241 return 0;
10242 }
10243
10244
10245 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
10246 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10247 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10248 Ebl *ebl,
10249 GElf_Ehdr *ehdr __attribute__ ((unused)),
10250 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10251 {
10252 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10253 elf_ndxscn (scn), section_name (ebl, shdr),
10254 (uint64_t) shdr->sh_offset);
10255
10256 int n = 0;
10257 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10258 }
10259
10260 /* Print the content of the DWARF string section '.debug_str'. */
10261 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10262 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10263 Ebl *ebl,
10264 GElf_Ehdr *ehdr __attribute__ ((unused)),
10265 Elf_Scn *scn, GElf_Shdr *shdr,
10266 Dwarf *dbg __attribute__ ((unused)))
10267 {
10268 Elf_Data *data = elf_rawdata (scn, NULL);
10269 const size_t sh_size = data ? data->d_size : 0;
10270
10271 /* Compute floor(log16(shdr->sh_size)). */
10272 GElf_Addr tmp = sh_size;
10273 int digits = 1;
10274 while (tmp >= 16)
10275 {
10276 ++digits;
10277 tmp >>= 4;
10278 }
10279 digits = MAX (4, digits);
10280
10281 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10282 " %*s String\n"),
10283 elf_ndxscn (scn),
10284 section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10285 /* TRANS: the debugstr| prefix makes the string unique. */
10286 digits + 2, sgettext ("debugstr|Offset"));
10287
10288 Dwarf_Off offset = 0;
10289 while (offset < sh_size)
10290 {
10291 size_t len;
10292 const char *str = (const char *) data->d_buf + offset;
10293 const char *endp = memchr (str, '\0', sh_size - offset);
10294 if (unlikely (endp == NULL))
10295 {
10296 printf (gettext (" *** error, missing string terminator\n"));
10297 break;
10298 }
10299
10300 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
10301 len = endp - str;
10302 offset += len + 1;
10303 }
10304 }
10305
10306 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10307 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10308 Ebl *ebl,
10309 GElf_Ehdr *ehdr __attribute__ ((unused)),
10310 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10311 {
10312 printf (gettext ("\
10313 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10314 elf_ndxscn (scn), section_name (ebl, shdr),
10315 (uint64_t) shdr->sh_offset);
10316
10317 if (shdr->sh_size == 0)
10318 return;
10319
10320 /* We like to get the section from libdw to make sure they are relocated. */
10321 Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10322 ?: elf_rawdata (scn, NULL));
10323 if (unlikely (data == NULL))
10324 {
10325 error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10326 elf_errmsg (-1));
10327 return;
10328 }
10329
10330 size_t idx = 0;
10331 sort_listptr (&known_stroffbases, "str_offsets");
10332
10333 const unsigned char *start = (const unsigned char *) data->d_buf;
10334 const unsigned char *readp = start;
10335 const unsigned char *readendp = ((const unsigned char *) data->d_buf
10336 + data->d_size);
10337
10338 while (readp < readendp)
10339 {
10340 /* Most string offset tables will have a header. For split
10341 dwarf unit GNU DebugFission didn't add one. But they were
10342 also only defined for split units (main or skeleton units
10343 didn't have indirect strings). So if we don't have a
10344 DW_AT_str_offsets_base at all and this is offset zero, then
10345 just start printing offsets immediately, if this is a .dwo
10346 section. */
10347 Dwarf_Off off = (Dwarf_Off) (readp
10348 - (const unsigned char *) data->d_buf);
10349
10350 printf ("Table at offset %" PRIx64 " ", off);
10351
10352 struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10353 const unsigned char *next_unitp = readendp;
10354 uint8_t offset_size;
10355 bool has_header;
10356 if (listptr == NULL)
10357 {
10358 /* This can happen for .dwo files. There is only an header
10359 in the case this is a version 5 split DWARF file. */
10360 Dwarf_CU *cu;
10361 uint8_t unit_type;
10362 if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10363 NULL, NULL) != 0)
10364 {
10365 error (0, 0, "Warning: Cannot find any DWARF unit.");
10366 /* Just guess some values. */
10367 has_header = false;
10368 offset_size = 4;
10369 }
10370 else if (off == 0
10371 && (unit_type == DW_UT_split_type
10372 || unit_type == DW_UT_split_compile))
10373 {
10374 has_header = cu->version > 4;
10375 offset_size = cu->offset_size;
10376 }
10377 else
10378 {
10379 error (0, 0,
10380 "Warning: No CU references .debug_str_offsets after %"
10381 PRIx64, off);
10382 has_header = cu->version > 4;
10383 offset_size = cu->offset_size;
10384 }
10385 printf ("\n");
10386 }
10387 else
10388 {
10389 /* This must be DWARF5, since GNU DebugFission didn't define
10390 DW_AT_str_offsets_base. */
10391 has_header = true;
10392
10393 Dwarf_Die cudie;
10394 if (dwarf_cu_die (listptr->cu, &cudie,
10395 NULL, NULL, NULL, NULL,
10396 NULL, NULL) == NULL)
10397 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10398 else
10399 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10400 }
10401
10402 if (has_header)
10403 {
10404 uint64_t unit_length;
10405 uint16_t version;
10406 uint16_t padding;
10407
10408 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10409 if (unlikely (unit_length == 0xffffffff))
10410 {
10411 if (unlikely (readp > readendp - 8))
10412 {
10413 invalid_data:
10414 error (0, 0, "Invalid data");
10415 return;
10416 }
10417 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10418 offset_size = 8;
10419 }
10420 else
10421 offset_size = 4;
10422
10423 printf ("\n");
10424 printf (gettext (" Length: %8" PRIu64 "\n"),
10425 unit_length);
10426 printf (gettext (" Offset size: %8" PRIu8 "\n"),
10427 offset_size);
10428
10429 /* We need at least 2-bytes (version) + 2-bytes (padding) =
10430 4 bytes to complete the header. And this unit cannot go
10431 beyond the section data. */
10432 if (readp > readendp - 4
10433 || unit_length < 4
10434 || unit_length > (uint64_t) (readendp - readp))
10435 goto invalid_data;
10436
10437 next_unitp = readp + unit_length;
10438
10439 version = read_2ubyte_unaligned_inc (dbg, readp);
10440 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10441
10442 if (version != 5)
10443 {
10444 error (0, 0, gettext ("Unknown version"));
10445 goto next_unit;
10446 }
10447
10448 padding = read_2ubyte_unaligned_inc (dbg, readp);
10449 printf (gettext (" Padding: %8" PRIx16 "\n"), padding);
10450
10451 if (listptr != NULL
10452 && listptr->offset != (Dwarf_Off) (readp - start))
10453 {
10454 error (0, 0, "String offsets index doesn't start after header");
10455 goto next_unit;
10456 }
10457
10458 printf ("\n");
10459 }
10460
10461 int digits = 1;
10462 size_t offsets = (next_unitp - readp) / offset_size;
10463 while (offsets >= 10)
10464 {
10465 ++digits;
10466 offsets /= 10;
10467 }
10468
10469 unsigned int uidx = 0;
10470 size_t index_offset = readp - (const unsigned char *) data->d_buf;
10471 printf (" Offsets start at 0x%zx:\n", index_offset);
10472 while (readp <= next_unitp - offset_size)
10473 {
10474 Dwarf_Word offset;
10475 if (offset_size == 4)
10476 offset = read_4ubyte_unaligned_inc (dbg, readp);
10477 else
10478 offset = read_8ubyte_unaligned_inc (dbg, readp);
10479 const char *str = dwarf_getstring (dbg, offset, NULL);
10480 printf (" [%*u] [%*" PRIx64 "] \"%s\"\n",
10481 digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10482 }
10483 printf ("\n");
10484
10485 if (readp != next_unitp)
10486 error (0, 0, "extra %zd bytes at end of unit",
10487 (size_t) (next_unitp - readp));
10488
10489 next_unit:
10490 readp = next_unitp;
10491 }
10492 }
10493
10494
10495 /* Print the content of the call frame search table section
10496 '.eh_frame_hdr'. */
10497 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10498 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10499 Ebl *ebl __attribute__ ((unused)),
10500 GElf_Ehdr *ehdr __attribute__ ((unused)),
10501 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10502 {
10503 printf (gettext ("\
10504 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10505 elf_ndxscn (scn));
10506
10507 Elf_Data *data = elf_rawdata (scn, NULL);
10508
10509 if (unlikely (data == NULL))
10510 {
10511 error (0, 0, gettext ("cannot get %s content: %s"),
10512 ".eh_frame_hdr", elf_errmsg (-1));
10513 return;
10514 }
10515
10516 const unsigned char *readp = data->d_buf;
10517 const unsigned char *const dataend = ((unsigned char *) data->d_buf
10518 + data->d_size);
10519
10520 if (unlikely (readp + 4 > dataend))
10521 {
10522 invalid_data:
10523 error (0, 0, gettext ("invalid data"));
10524 return;
10525 }
10526
10527 unsigned int version = *readp++;
10528 unsigned int eh_frame_ptr_enc = *readp++;
10529 unsigned int fde_count_enc = *readp++;
10530 unsigned int table_enc = *readp++;
10531
10532 printf (" version: %u\n"
10533 " eh_frame_ptr_enc: %#x ",
10534 version, eh_frame_ptr_enc);
10535 print_encoding_base ("", eh_frame_ptr_enc);
10536 printf (" fde_count_enc: %#x ", fde_count_enc);
10537 print_encoding_base ("", fde_count_enc);
10538 printf (" table_enc: %#x ", table_enc);
10539 print_encoding_base ("", table_enc);
10540
10541 uint64_t eh_frame_ptr = 0;
10542 if (eh_frame_ptr_enc != DW_EH_PE_omit)
10543 {
10544 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10545 dbg);
10546 if (unlikely (readp == NULL))
10547 goto invalid_data;
10548
10549 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
10550 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10551 printf (" (offset: %#" PRIx64 ")",
10552 /* +4 because of the 4 byte header of the section. */
10553 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10554
10555 putchar_unlocked ('\n');
10556 }
10557
10558 uint64_t fde_count = 0;
10559 if (fde_count_enc != DW_EH_PE_omit)
10560 {
10561 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10562 if (unlikely (readp == NULL))
10563 goto invalid_data;
10564
10565 printf (" fde_count: %" PRIu64 "\n", fde_count);
10566 }
10567
10568 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10569 return;
10570
10571 puts (" Table:");
10572
10573 /* Optimize for the most common case. */
10574 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10575 while (fde_count > 0 && readp + 8 <= dataend)
10576 {
10577 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10578 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10579 + (int64_t) initial_location);
10580 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10581 // XXX Possibly print symbol name or section offset for initial_offset
10582 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10583 " fde=[%6" PRIx64 "]\n",
10584 initial_location, initial_offset,
10585 address, address - (eh_frame_ptr + 4));
10586 }
10587 else
10588 while (0 && readp < dataend)
10589 {
10590
10591 }
10592 }
10593
10594
10595 /* Print the content of the exception handling table section
10596 '.eh_frame_hdr'. */
10597 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10598 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10599 Ebl *ebl __attribute__ ((unused)),
10600 GElf_Ehdr *ehdr __attribute__ ((unused)),
10601 Elf_Scn *scn,
10602 GElf_Shdr *shdr __attribute__ ((unused)),
10603 Dwarf *dbg __attribute__ ((unused)))
10604 {
10605 printf (gettext ("\
10606 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10607 elf_ndxscn (scn));
10608
10609 Elf_Data *data = elf_rawdata (scn, NULL);
10610
10611 if (unlikely (data == NULL))
10612 {
10613 error (0, 0, gettext ("cannot get %s content: %s"),
10614 ".gcc_except_table", elf_errmsg (-1));
10615 return;
10616 }
10617
10618 const unsigned char *readp = data->d_buf;
10619 const unsigned char *const dataend = readp + data->d_size;
10620
10621 if (unlikely (readp + 1 > dataend))
10622 {
10623 invalid_data:
10624 error (0, 0, gettext ("invalid data"));
10625 return;
10626 }
10627 unsigned int lpstart_encoding = *readp++;
10628 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
10629 print_encoding_base ("", lpstart_encoding);
10630 if (lpstart_encoding != DW_EH_PE_omit)
10631 {
10632 uint64_t lpstart;
10633 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10634 printf (" LPStart: %#" PRIx64 "\n", lpstart);
10635 }
10636
10637 if (unlikely (readp + 1 > dataend))
10638 goto invalid_data;
10639 unsigned int ttype_encoding = *readp++;
10640 printf (gettext (" TType encoding: %#x "), ttype_encoding);
10641 print_encoding_base ("", ttype_encoding);
10642 const unsigned char *ttype_base = NULL;
10643 if (ttype_encoding != DW_EH_PE_omit)
10644 {
10645 unsigned int ttype_base_offset;
10646 get_uleb128 (ttype_base_offset, readp, dataend);
10647 printf (" TType base offset: %#x\n", ttype_base_offset);
10648 if ((size_t) (dataend - readp) > ttype_base_offset)
10649 ttype_base = readp + ttype_base_offset;
10650 }
10651
10652 if (unlikely (readp + 1 > dataend))
10653 goto invalid_data;
10654 unsigned int call_site_encoding = *readp++;
10655 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
10656 print_encoding_base ("", call_site_encoding);
10657 unsigned int call_site_table_len;
10658 get_uleb128 (call_site_table_len, readp, dataend);
10659
10660 const unsigned char *const action_table = readp + call_site_table_len;
10661 if (unlikely (action_table > dataend))
10662 goto invalid_data;
10663 unsigned int u = 0;
10664 unsigned int max_action = 0;
10665 while (readp < action_table)
10666 {
10667 if (u == 0)
10668 puts (gettext ("\n Call site table:"));
10669
10670 uint64_t call_site_start;
10671 readp = read_encoded (call_site_encoding, readp, dataend,
10672 &call_site_start, dbg);
10673 uint64_t call_site_length;
10674 readp = read_encoded (call_site_encoding, readp, dataend,
10675 &call_site_length, dbg);
10676 uint64_t landing_pad;
10677 readp = read_encoded (call_site_encoding, readp, dataend,
10678 &landing_pad, dbg);
10679 unsigned int action;
10680 get_uleb128 (action, readp, dataend);
10681 max_action = MAX (action, max_action);
10682 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
10683 " Call site length: %" PRIu64 "\n"
10684 " Landing pad: %#" PRIx64 "\n"
10685 " Action: %u\n"),
10686 u++, call_site_start, call_site_length, landing_pad, action);
10687 }
10688 if (readp != action_table)
10689 goto invalid_data;
10690
10691 unsigned int max_ar_filter = 0;
10692 if (max_action > 0)
10693 {
10694 puts ("\n Action table:");
10695
10696 size_t maxdata = (size_t) (dataend - action_table);
10697 if (max_action > maxdata || maxdata - max_action < 1)
10698 {
10699 invalid_action_table:
10700 fputs (gettext (" <INVALID DATA>\n"), stdout);
10701 return;
10702 }
10703
10704 const unsigned char *const action_table_end
10705 = action_table + max_action + 1;
10706
10707 u = 0;
10708 do
10709 {
10710 int ar_filter;
10711 get_sleb128 (ar_filter, readp, action_table_end);
10712 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10713 max_ar_filter = ar_filter;
10714 int ar_disp;
10715 if (readp >= action_table_end)
10716 goto invalid_action_table;
10717 get_sleb128 (ar_disp, readp, action_table_end);
10718
10719 printf (" [%4u] ar_filter: % d\n"
10720 " ar_disp: % -5d",
10721 u, ar_filter, ar_disp);
10722 if (abs (ar_disp) & 1)
10723 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10724 else if (ar_disp != 0)
10725 puts (" -> ???");
10726 else
10727 putchar_unlocked ('\n');
10728 ++u;
10729 }
10730 while (readp < action_table_end);
10731 }
10732
10733 if (max_ar_filter > 0 && ttype_base != NULL)
10734 {
10735 unsigned char dsize;
10736 puts ("\n TType table:");
10737
10738 // XXX Not *4, size of encoding;
10739 switch (ttype_encoding & 7)
10740 {
10741 case DW_EH_PE_udata2:
10742 case DW_EH_PE_sdata2:
10743 dsize = 2;
10744 break;
10745 case DW_EH_PE_udata4:
10746 case DW_EH_PE_sdata4:
10747 dsize = 4;
10748 break;
10749 case DW_EH_PE_udata8:
10750 case DW_EH_PE_sdata8:
10751 dsize = 8;
10752 break;
10753 default:
10754 dsize = 0;
10755 error (1, 0, gettext ("invalid TType encoding"));
10756 abort();
10757 }
10758
10759 if (max_ar_filter
10760 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10761 goto invalid_data;
10762
10763 readp = ttype_base - max_ar_filter * dsize;
10764 do
10765 {
10766 uint64_t ttype;
10767 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10768 dbg);
10769 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10770 }
10771 while (readp < ttype_base);
10772 }
10773 }
10774
10775 /* Print the content of the '.gdb_index' section.
10776 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10777 */
10778 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10779 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10780 GElf_Ehdr *ehdr __attribute__ ((unused)),
10781 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10782 {
10783 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10784 " contains %" PRId64 " bytes :\n"),
10785 elf_ndxscn (scn), section_name (ebl, shdr),
10786 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10787
10788 Elf_Data *data = elf_rawdata (scn, NULL);
10789
10790 if (unlikely (data == NULL))
10791 {
10792 error (0, 0, gettext ("cannot get %s content: %s"),
10793 ".gdb_index", elf_errmsg (-1));
10794 return;
10795 }
10796
10797 // .gdb_index is always in little endian.
10798 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10799 dbg = &dummy_dbg;
10800
10801 const unsigned char *readp = data->d_buf;
10802 const unsigned char *const dataend = readp + data->d_size;
10803
10804 if (unlikely (readp + 4 > dataend))
10805 {
10806 invalid_data:
10807 error (0, 0, gettext ("invalid data"));
10808 return;
10809 }
10810
10811 int32_t vers = read_4ubyte_unaligned (dbg, readp);
10812 printf (gettext (" Version: %" PRId32 "\n"), vers);
10813
10814 // The only difference between version 4 and version 5 is the
10815 // hash used for generating the table. Version 6 contains symbols
10816 // for inlined functions, older versions didn't. Version 7 adds
10817 // symbol kinds. Version 8 just indicates that it correctly includes
10818 // TUs for symbols.
10819 if (vers < 4 || vers > 8)
10820 {
10821 printf (gettext (" unknown version, cannot parse section\n"));
10822 return;
10823 }
10824
10825 readp += 4;
10826 if (unlikely (readp + 4 > dataend))
10827 goto invalid_data;
10828
10829 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10830 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
10831
10832 readp += 4;
10833 if (unlikely (readp + 4 > dataend))
10834 goto invalid_data;
10835
10836 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10837 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
10838
10839 readp += 4;
10840 if (unlikely (readp + 4 > dataend))
10841 goto invalid_data;
10842
10843 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10844 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
10845
10846 readp += 4;
10847 if (unlikely (readp + 4 > dataend))
10848 goto invalid_data;
10849
10850 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10851 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
10852
10853 readp += 4;
10854 if (unlikely (readp + 4 > dataend))
10855 goto invalid_data;
10856
10857 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10858 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10859
10860 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10861 < const_off))
10862 goto invalid_data;
10863
10864 readp = data->d_buf + cu_off;
10865
10866 const unsigned char *nextp = data->d_buf + tu_off;
10867 if (tu_off >= data->d_size)
10868 goto invalid_data;
10869
10870 size_t cu_nr = (nextp - readp) / 16;
10871
10872 printf (gettext ("\n CU list at offset %#" PRIx32
10873 " contains %zu entries:\n"),
10874 cu_off, cu_nr);
10875
10876 size_t n = 0;
10877 while (dataend - readp >= 16 && n < cu_nr)
10878 {
10879 uint64_t off = read_8ubyte_unaligned (dbg, readp);
10880 readp += 8;
10881
10882 uint64_t len = read_8ubyte_unaligned (dbg, readp);
10883 readp += 8;
10884
10885 printf (" [%4zu] start: %0#8" PRIx64
10886 ", length: %5" PRIu64 "\n", n, off, len);
10887 n++;
10888 }
10889
10890 readp = data->d_buf + tu_off;
10891 nextp = data->d_buf + addr_off;
10892 if (addr_off >= data->d_size)
10893 goto invalid_data;
10894
10895 size_t tu_nr = (nextp - readp) / 24;
10896
10897 printf (gettext ("\n TU list at offset %#" PRIx32
10898 " contains %zu entries:\n"),
10899 tu_off, tu_nr);
10900
10901 n = 0;
10902 while (dataend - readp >= 24 && n < tu_nr)
10903 {
10904 uint64_t off = read_8ubyte_unaligned (dbg, readp);
10905 readp += 8;
10906
10907 uint64_t type = read_8ubyte_unaligned (dbg, readp);
10908 readp += 8;
10909
10910 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10911 readp += 8;
10912
10913 printf (" [%4zu] CU offset: %5" PRId64
10914 ", type offset: %5" PRId64
10915 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10916 n++;
10917 }
10918
10919 readp = data->d_buf + addr_off;
10920 nextp = data->d_buf + sym_off;
10921 if (sym_off >= data->d_size)
10922 goto invalid_data;
10923
10924 size_t addr_nr = (nextp - readp) / 20;
10925
10926 printf (gettext ("\n Address list at offset %#" PRIx32
10927 " contains %zu entries:\n"),
10928 addr_off, addr_nr);
10929
10930 n = 0;
10931 while (dataend - readp >= 20 && n < addr_nr)
10932 {
10933 uint64_t low = read_8ubyte_unaligned (dbg, readp);
10934 readp += 8;
10935
10936 uint64_t high = read_8ubyte_unaligned (dbg, readp);
10937 readp += 8;
10938
10939 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10940 readp += 4;
10941
10942 printf (" [%4zu] ", n);
10943 print_dwarf_addr (dwflmod, 8, low, low);
10944 printf ("..");
10945 print_dwarf_addr (dwflmod, 8, high - 1, high);
10946 printf (", CU index: %5" PRId32 "\n", idx);
10947 n++;
10948 }
10949
10950 const unsigned char *const_start = data->d_buf + const_off;
10951 if (const_off >= data->d_size)
10952 goto invalid_data;
10953
10954 readp = data->d_buf + sym_off;
10955 nextp = const_start;
10956 size_t sym_nr = (nextp - readp) / 8;
10957
10958 printf (gettext ("\n Symbol table at offset %#" PRIx32
10959 " contains %zu slots:\n"),
10960 addr_off, sym_nr);
10961
10962 n = 0;
10963 while (dataend - readp >= 8 && n < sym_nr)
10964 {
10965 uint32_t name = read_4ubyte_unaligned (dbg, readp);
10966 readp += 4;
10967
10968 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10969 readp += 4;
10970
10971 if (name != 0 || vector != 0)
10972 {
10973 const unsigned char *sym = const_start + name;
10974 if (unlikely ((size_t) (dataend - const_start) < name
10975 || memchr (sym, '\0', dataend - sym) == NULL))
10976 goto invalid_data;
10977
10978 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10979
10980 const unsigned char *readcus = const_start + vector;
10981 if (unlikely ((size_t) (dataend - const_start) < vector))
10982 goto invalid_data;
10983 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10984 while (cus--)
10985 {
10986 uint32_t cu_kind, cu, kind;
10987 bool is_static;
10988 readcus += 4;
10989 if (unlikely (readcus + 4 > dataend))
10990 goto invalid_data;
10991 cu_kind = read_4ubyte_unaligned (dbg, readcus);
10992 cu = cu_kind & ((1 << 24) - 1);
10993 kind = (cu_kind >> 28) & 7;
10994 is_static = cu_kind & (1U << 31);
10995 if (cu > cu_nr - 1)
10996 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10997 else
10998 printf ("%" PRId32, cu);
10999 if (kind != 0)
11000 {
11001 printf (" (");
11002 switch (kind)
11003 {
11004 case 1:
11005 printf ("type");
11006 break;
11007 case 2:
11008 printf ("var");
11009 break;
11010 case 3:
11011 printf ("func");
11012 break;
11013 case 4:
11014 printf ("other");
11015 break;
11016 default:
11017 printf ("unknown-0x%" PRIx32, kind);
11018 break;
11019 }
11020 printf (":%c)", (is_static ? 'S' : 'G'));
11021 }
11022 if (cus > 0)
11023 printf (", ");
11024 }
11025 printf ("\n");
11026 }
11027 n++;
11028 }
11029 }
11030
11031 /* Returns true and sets split DWARF CU id if there is a split compile
11032 unit in the given Dwarf, and no non-split units are found (before it). */
11033 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11034 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11035 {
11036 Dwarf_CU *cu = NULL;
11037 while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11038 {
11039 uint8_t unit_type;
11040 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11041 id, NULL, NULL) != 0)
11042 return false;
11043
11044 if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11045 return false;
11046
11047 /* We really only care about the split compile unit, the types
11048 should be fine and self sufficient. Also they don't have an
11049 id that we can match with a skeleton unit. */
11050 if (unit_type == DW_UT_split_compile)
11051 {
11052 *split_cu = cu;
11053 return true;
11054 }
11055 }
11056
11057 return false;
11058 }
11059
11060 /* Check that there is one and only one Dwfl_Module, return in arg. */
11061 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11062 getone_dwflmod (Dwfl_Module *dwflmod,
11063 void **userdata __attribute__ ((unused)),
11064 const char *name __attribute__ ((unused)),
11065 Dwarf_Addr base __attribute__ ((unused)),
11066 void *arg)
11067 {
11068 Dwfl_Module **m = (Dwfl_Module **) arg;
11069 if (*m != NULL)
11070 return DWARF_CB_ABORT;
11071 *m = dwflmod;
11072 return DWARF_CB_OK;
11073 }
11074
11075 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11076 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11077 {
11078 /* Used for skeleton file, if necessary for split DWARF. */
11079 Dwfl *skel_dwfl = NULL;
11080 Dwfl_Module *skel_mod = NULL;
11081 char *skel_name = NULL;
11082 Dwarf *split_dbg = NULL;
11083 Dwarf_CU *split_cu = NULL;
11084
11085 /* Before we start the real work get a debug context descriptor. */
11086 Dwarf_Addr dwbias;
11087 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11088 Dwarf dummy_dbg =
11089 {
11090 .elf = ebl->elf,
11091 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11092 };
11093 if (dbg == NULL)
11094 {
11095 if ((print_debug_sections & ~section_exception) != 0)
11096 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
11097 dwfl_errmsg (-1));
11098 dbg = &dummy_dbg;
11099 }
11100 else
11101 {
11102 /* If we are asked about a split dwarf (.dwo) file, use the user
11103 provided, or find the corresponding skeleton file. If we got
11104 a skeleton file, replace the given dwflmod and dbg, with one
11105 derived from the skeleton file to provide enough context. */
11106 uint64_t split_id;
11107 if (is_split_dwarf (dbg, &split_id, &split_cu))
11108 {
11109 if (dwarf_skeleton != NULL)
11110 skel_name = strdup (dwarf_skeleton);
11111 else
11112 {
11113 /* Replace file.dwo with file.o and see if that matches. */
11114 const char *fname;
11115 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11116 &fname, NULL);
11117 if (fname != NULL)
11118 {
11119 size_t flen = strlen (fname);
11120 if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11121 {
11122 skel_name = strdup (fname);
11123 if (skel_name != NULL)
11124 {
11125 skel_name[flen - 3] = 'o';
11126 skel_name[flen - 2] = '\0';
11127 }
11128 }
11129 }
11130 }
11131
11132 if (skel_name != NULL)
11133 {
11134 int skel_fd = open (skel_name, O_RDONLY);
11135 if (skel_fd == -1)
11136 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11137 " '%s'\n", skel_name);
11138 else
11139 skel_dwfl = create_dwfl (skel_fd, skel_name);
11140
11141 if (skel_dwfl != NULL)
11142 {
11143 if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11144 &skel_mod, 0) != 0)
11145 {
11146 fprintf (stderr, "Warning: Bad DWARF skeleton,"
11147 " multiple modules '%s'\n", skel_name);
11148 dwfl_end (skel_dwfl);
11149 skel_mod = NULL;
11150 }
11151 }
11152 else if (skel_fd != -1)
11153 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11154 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11155
11156 if (skel_mod != NULL)
11157 {
11158 Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11159 if (skel_dbg != NULL)
11160 {
11161 /* First check the skeleton CU DIE, only fetch
11162 the split DIE if we know the id matches to
11163 not unnecessary search for any split DIEs we
11164 don't need. */
11165 Dwarf_CU *cu = NULL;
11166 while (dwarf_get_units (skel_dbg, cu, &cu,
11167 NULL, NULL, NULL, NULL) == 0)
11168 {
11169 uint8_t unit_type;
11170 uint64_t skel_id;
11171 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11172 &skel_id, NULL, NULL) == 0
11173 && unit_type == DW_UT_skeleton
11174 && split_id == skel_id)
11175 {
11176 Dwarf_Die subdie;
11177 if (dwarf_cu_info (cu, NULL, NULL, NULL,
11178 &subdie,
11179 NULL, NULL, NULL) == 0
11180 && dwarf_tag (&subdie) != DW_TAG_invalid)
11181 {
11182 split_dbg = dwarf_cu_getdwarf (subdie.cu);
11183 if (split_dbg == NULL)
11184 fprintf (stderr,
11185 "Warning: Couldn't get split_dbg:"
11186 " %s\n", dwarf_errmsg (-1));
11187 break;
11188 }
11189 else
11190 {
11191 /* Everything matches up, but not
11192 according to libdw. Which means
11193 the user knew better. So...
11194 Terrible hack... We can never
11195 destroy the underlying dwfl
11196 because it would free the wrong
11197 Dwarfs... So we leak memory...*/
11198 if (cu->split == NULL
11199 && dwarf_skeleton != NULL)
11200 {
11201 do_not_close_dwfl = true;
11202 __libdw_link_skel_split (cu, split_cu);
11203 split_dbg = dwarf_cu_getdwarf (split_cu);
11204 break;
11205 }
11206 else
11207 fprintf (stderr, "Warning: Couldn't get"
11208 " skeleton subdie: %s\n",
11209 dwarf_errmsg (-1));
11210 }
11211 }
11212 }
11213 if (split_dbg == NULL)
11214 fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11215 }
11216 else
11217 fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11218 " %s\n", dwfl_errmsg (-1));
11219 }
11220 }
11221
11222 if (split_dbg != NULL)
11223 {
11224 dbg = split_dbg;
11225 dwflmod = skel_mod;
11226 }
11227 else if (skel_name == NULL)
11228 fprintf (stderr,
11229 "Warning: split DWARF file, but no skeleton found.\n");
11230 }
11231 else if (dwarf_skeleton != NULL)
11232 fprintf (stderr, "Warning: DWARF skeleton given,"
11233 " but not a split DWARF file\n");
11234 }
11235
11236 /* Get the section header string table index. */
11237 size_t shstrndx;
11238 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11239 error (EXIT_FAILURE, 0,
11240 gettext ("cannot get section header string table index"));
11241
11242 /* If the .debug_info section is listed as implicitly required then
11243 we must make sure to handle it before handling any other debug
11244 section. Various other sections depend on the CU DIEs being
11245 scanned (silently) first. */
11246 bool implicit_info = (implicit_debug_sections & section_info) != 0;
11247 bool explicit_info = (print_debug_sections & section_info) != 0;
11248 if (implicit_info)
11249 {
11250 Elf_Scn *scn = NULL;
11251 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11252 {
11253 GElf_Shdr shdr_mem;
11254 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11255
11256 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11257 {
11258 const char *name = elf_strptr (ebl->elf, shstrndx,
11259 shdr->sh_name);
11260 if (name == NULL)
11261 continue;
11262
11263 if (strcmp (name, ".debug_info") == 0
11264 || strcmp (name, ".debug_info.dwo") == 0
11265 || strcmp (name, ".zdebug_info") == 0
11266 || strcmp (name, ".zdebug_info.dwo") == 0)
11267 {
11268 print_debug_info_section (dwflmod, ebl, ehdr,
11269 scn, shdr, dbg);
11270 break;
11271 }
11272 }
11273 }
11274 print_debug_sections &= ~section_info;
11275 implicit_debug_sections &= ~section_info;
11276 }
11277
11278 /* Look through all the sections for the debugging sections to print. */
11279 Elf_Scn *scn = NULL;
11280 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11281 {
11282 GElf_Shdr shdr_mem;
11283 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11284
11285 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11286 {
11287 static const struct
11288 {
11289 const char *name;
11290 enum section_e bitmask;
11291 void (*fp) (Dwfl_Module *, Ebl *,
11292 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11293 } debug_sections[] =
11294 {
11295 #define NEW_SECTION(name) \
11296 { ".debug_" #name, section_##name, print_debug_##name##_section }
11297 NEW_SECTION (abbrev),
11298 NEW_SECTION (addr),
11299 NEW_SECTION (aranges),
11300 NEW_SECTION (frame),
11301 NEW_SECTION (info),
11302 NEW_SECTION (types),
11303 NEW_SECTION (line),
11304 NEW_SECTION (loc),
11305 /* loclists is loc for DWARF5. */
11306 { ".debug_loclists", section_loc,
11307 print_debug_loclists_section },
11308 NEW_SECTION (pubnames),
11309 NEW_SECTION (str),
11310 /* A DWARF5 specialised debug string section. */
11311 { ".debug_line_str", section_str,
11312 print_debug_str_section },
11313 /* DWARF5 string offsets table. */
11314 { ".debug_str_offsets", section_str,
11315 print_debug_str_offsets_section },
11316 NEW_SECTION (macinfo),
11317 NEW_SECTION (macro),
11318 NEW_SECTION (ranges),
11319 /* rnglists is ranges for DWARF5. */
11320 { ".debug_rnglists", section_ranges,
11321 print_debug_rnglists_section },
11322 { ".eh_frame", section_frame | section_exception,
11323 print_debug_frame_section },
11324 { ".eh_frame_hdr", section_frame | section_exception,
11325 print_debug_frame_hdr_section },
11326 { ".gcc_except_table", section_frame | section_exception,
11327 print_debug_exception_table },
11328 { ".gdb_index", section_gdb_index, print_gdb_index_section }
11329 };
11330 const int ndebug_sections = (sizeof (debug_sections)
11331 / sizeof (debug_sections[0]));
11332 const char *name = elf_strptr (ebl->elf, shstrndx,
11333 shdr->sh_name);
11334 if (name == NULL)
11335 continue;
11336
11337 int n;
11338 for (n = 0; n < ndebug_sections; ++n)
11339 {
11340 size_t dbglen = strlen (debug_sections[n].name);
11341 size_t scnlen = strlen (name);
11342 if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11343 && (dbglen == scnlen
11344 || (scnlen == dbglen + 4
11345 && strstr (name, ".dwo") == name + dbglen)))
11346 || (name[0] == '.' && name[1] == 'z'
11347 && debug_sections[n].name[1] == 'd'
11348 && strncmp (&name[2], &debug_sections[n].name[1],
11349 dbglen - 1) == 0
11350 && (scnlen == dbglen + 1
11351 || (scnlen == dbglen + 5
11352 && strstr (name, ".dwo") == name + dbglen + 1))))
11353 {
11354 if ((print_debug_sections | implicit_debug_sections)
11355 & debug_sections[n].bitmask)
11356 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11357 break;
11358 }
11359 }
11360 }
11361 }
11362
11363 dwfl_end (skel_dwfl);
11364 free (skel_name);
11365
11366 /* Turn implicit and/or explicit back on in case we go over another file. */
11367 if (implicit_info)
11368 implicit_debug_sections |= section_info;
11369 if (explicit_info)
11370 print_debug_sections |= section_info;
11371
11372 reset_listptr (&known_locsptr);
11373 reset_listptr (&known_loclistsptr);
11374 reset_listptr (&known_rangelistptr);
11375 reset_listptr (&known_rnglistptr);
11376 reset_listptr (&known_addrbases);
11377 reset_listptr (&known_stroffbases);
11378 }
11379
11380
11381 #define ITEM_INDENT 4
11382 #define WRAP_COLUMN 75
11383
11384 /* Print "NAME: FORMAT", wrapping when output text would make the line
11385 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
11386 but this function is also used for registers which should be printed
11387 aligned. Fortunately registers output uses fixed fields width (such
11388 as %11d) for the alignment.
11389
11390 Line breaks should not depend on the particular values although that
11391 may happen in some cases of the core items. */
11392
11393 static unsigned int
11394 __attribute__ ((format (printf, 6, 7)))
print_core_item(unsigned int colno,char sep,unsigned int wrap,size_t name_width,const char * name,const char * format,...)11395 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11396 size_t name_width, const char *name, const char *format, ...)
11397 {
11398 size_t len = strlen (name);
11399 if (name_width < len)
11400 name_width = len;
11401
11402 char *out;
11403 va_list ap;
11404 va_start (ap, format);
11405 int out_len = vasprintf (&out, format, ap);
11406 va_end (ap);
11407 if (out_len == -1)
11408 error (EXIT_FAILURE, 0, _("memory exhausted"));
11409
11410 size_t n = name_width + sizeof ": " - 1 + out_len;
11411
11412 if (colno == 0)
11413 {
11414 printf ("%*s", ITEM_INDENT, "");
11415 colno = ITEM_INDENT + n;
11416 }
11417 else if (colno + 2 + n < wrap)
11418 {
11419 printf ("%c ", sep);
11420 colno += 2 + n;
11421 }
11422 else
11423 {
11424 printf ("\n%*s", ITEM_INDENT, "");
11425 colno = ITEM_INDENT + n;
11426 }
11427
11428 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11429
11430 free (out);
11431
11432 return colno;
11433 }
11434
11435 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11436 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11437 void *value, const void *data, size_t size)
11438 {
11439 Elf_Data valuedata =
11440 {
11441 .d_type = type,
11442 .d_buf = value,
11443 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11444 .d_version = EV_CURRENT,
11445 };
11446 Elf_Data indata =
11447 {
11448 .d_type = type,
11449 .d_buf = (void *) data,
11450 .d_size = valuedata.d_size,
11451 .d_version = EV_CURRENT,
11452 };
11453
11454 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11455 ? elf32_xlatetom : elf64_xlatetom)
11456 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11457 if (d == NULL)
11458 error (EXIT_FAILURE, 0,
11459 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11460
11461 return data + indata.d_size;
11462 }
11463
11464 typedef uint8_t GElf_Byte;
11465
11466 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11467 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11468 unsigned int colno, size_t *repeated_size)
11469 {
11470 uint_fast16_t count = item->count ?: 1;
11471 /* Ebl_Core_Item count is always a small number.
11472 Make sure the backend didn't put in some large bogus value. */
11473 assert (count < 128);
11474
11475 #define TYPES \
11476 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
11477 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
11478 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
11479 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
11480 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
11481 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11482
11483 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11484 typedef union { TYPES; } value_t;
11485 void *data = alloca (count * sizeof (value_t));
11486 #undef DO_TYPE
11487
11488 #define DO_TYPE(NAME, Name, hex, dec) \
11489 GElf_##Name *value_##Name __attribute__((unused)) = data
11490 TYPES;
11491 #undef DO_TYPE
11492
11493 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11494 size_t convsize = size;
11495 if (repeated_size != NULL)
11496 {
11497 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11498 {
11499 data = alloca (*repeated_size);
11500 count *= *repeated_size / size;
11501 convsize = count * size;
11502 *repeated_size -= convsize;
11503 }
11504 else if (item->count != 0 || item->format != '\n')
11505 *repeated_size -= size;
11506 }
11507
11508 convert (core, item->type, count, data, desc + item->offset, convsize);
11509
11510 Elf_Type type = item->type;
11511 if (type == ELF_T_ADDR)
11512 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11513
11514 switch (item->format)
11515 {
11516 case 'd':
11517 assert (count == 1);
11518 switch (type)
11519 {
11520 #define DO_TYPE(NAME, Name, hex, dec) \
11521 case ELF_T_##NAME: \
11522 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11523 0, item->name, dec, value_##Name[0]); \
11524 break
11525 TYPES;
11526 #undef DO_TYPE
11527 default:
11528 abort ();
11529 }
11530 break;
11531
11532 case 'x':
11533 assert (count == 1);
11534 switch (type)
11535 {
11536 #define DO_TYPE(NAME, Name, hex, dec) \
11537 case ELF_T_##NAME: \
11538 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11539 0, item->name, hex, value_##Name[0]); \
11540 break
11541 TYPES;
11542 #undef DO_TYPE
11543 default:
11544 abort ();
11545 }
11546 break;
11547
11548 case 'b':
11549 case 'B':
11550 assert (size % sizeof (unsigned int) == 0);
11551 unsigned int nbits = count * size * 8;
11552 unsigned int pop = 0;
11553 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11554 pop += __builtin_popcount (*i);
11555 bool negate = pop > nbits / 2;
11556 const unsigned int bias = item->format == 'b';
11557
11558 {
11559 char printed[(negate ? nbits - pop : pop) * 16 + 1];
11560 char *p = printed;
11561 *p = '\0';
11562
11563 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11564 {
11565 assert (size == sizeof (unsigned int) * 2);
11566 for (unsigned int *i = data;
11567 (void *) i < data + count * size; i += 2)
11568 {
11569 unsigned int w = i[1];
11570 i[1] = i[0];
11571 i[0] = w;
11572 }
11573 }
11574
11575 unsigned int lastbit = 0;
11576 unsigned int run = 0;
11577 for (const unsigned int *i = data;
11578 (void *) i < data + count * size; ++i)
11579 {
11580 unsigned int bit = ((void *) i - data) * 8;
11581 unsigned int w = negate ? ~*i : *i;
11582 while (w != 0)
11583 {
11584 /* Note that a right shift equal to (or greater than)
11585 the number of bits of w is undefined behaviour. In
11586 particular when the least significant bit is bit 32
11587 (w = 0x8000000) then w >>= n is undefined. So
11588 explicitly handle that case separately. */
11589 unsigned int n = ffs (w);
11590 if (n < sizeof (w) * 8)
11591 w >>= n;
11592 else
11593 w = 0;
11594 bit += n;
11595
11596 if (lastbit != 0 && lastbit + 1 == bit)
11597 ++run;
11598 else
11599 {
11600 if (lastbit == 0)
11601 p += sprintf (p, "%u", bit - bias);
11602 else if (run == 0)
11603 p += sprintf (p, ",%u", bit - bias);
11604 else
11605 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11606 run = 0;
11607 }
11608
11609 lastbit = bit;
11610 }
11611 }
11612 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11613 p += sprintf (p, "-%u", lastbit - bias);
11614
11615 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11616 negate ? "~<%s>" : "<%s>", printed);
11617 }
11618 break;
11619
11620 case 'T':
11621 case (char) ('T'|0x80):
11622 assert (count == 2);
11623 Dwarf_Word sec;
11624 Dwarf_Word usec;
11625 switch (type)
11626 {
11627 #define DO_TYPE(NAME, Name, hex, dec) \
11628 case ELF_T_##NAME: \
11629 sec = value_##Name[0]; \
11630 usec = value_##Name[1]; \
11631 break
11632 TYPES;
11633 #undef DO_TYPE
11634 default:
11635 abort ();
11636 }
11637 if (unlikely (item->format == (char) ('T'|0x80)))
11638 {
11639 /* This is a hack for an ill-considered 64-bit ABI where
11640 tv_usec is actually a 32-bit field with 32 bits of padding
11641 rounding out struct timeval. We've already converted it as
11642 a 64-bit field. For little-endian, this just means the
11643 high half is the padding; it's presumably zero, but should
11644 be ignored anyway. For big-endian, it means the 32-bit
11645 field went into the high half of USEC. */
11646 GElf_Ehdr ehdr_mem;
11647 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11648 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11649 usec >>= 32;
11650 else
11651 usec &= UINT32_MAX;
11652 }
11653 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11654 "%" PRIu64 ".%.6" PRIu64, sec, usec);
11655 break;
11656
11657 case 'c':
11658 assert (count == 1);
11659 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11660 "%c", value_Byte[0]);
11661 break;
11662
11663 case 's':
11664 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11665 "%.*s", (int) count, value_Byte);
11666 break;
11667
11668 case '\n':
11669 /* This is a list of strings separated by '\n'. */
11670 assert (item->count == 0);
11671 assert (repeated_size != NULL);
11672 assert (item->name == NULL);
11673 if (unlikely (item->offset >= *repeated_size))
11674 break;
11675
11676 const char *s = desc + item->offset;
11677 size = *repeated_size - item->offset;
11678 *repeated_size = 0;
11679 while (size > 0)
11680 {
11681 const char *eol = memchr (s, '\n', size);
11682 int len = size;
11683 if (eol != NULL)
11684 len = eol - s;
11685 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11686 if (eol == NULL)
11687 break;
11688 size -= eol + 1 - s;
11689 s = eol + 1;
11690 }
11691
11692 colno = WRAP_COLUMN;
11693 break;
11694
11695 case 'h':
11696 break;
11697
11698 default:
11699 error (0, 0, "XXX not handling format '%c' for %s",
11700 item->format, item->name);
11701 break;
11702 }
11703
11704 #undef TYPES
11705
11706 return colno;
11707 }
11708
11709
11710 /* Sort items by group, and by layout offset within each group. */
11711 static int
compare_core_items(const void * a,const void * b)11712 compare_core_items (const void *a, const void *b)
11713 {
11714 const Ebl_Core_Item *const *p1 = a;
11715 const Ebl_Core_Item *const *p2 = b;
11716 const Ebl_Core_Item *item1 = *p1;
11717 const Ebl_Core_Item *item2 = *p2;
11718
11719 return ((item1->group == item2->group ? 0
11720 : strcmp (item1->group, item2->group))
11721 ?: (int) item1->offset - (int) item2->offset);
11722 }
11723
11724 /* Sort item groups by layout offset of the first item in the group. */
11725 static int
compare_core_item_groups(const void * a,const void * b)11726 compare_core_item_groups (const void *a, const void *b)
11727 {
11728 const Ebl_Core_Item *const *const *p1 = a;
11729 const Ebl_Core_Item *const *const *p2 = b;
11730 const Ebl_Core_Item *const *group1 = *p1;
11731 const Ebl_Core_Item *const *group2 = *p2;
11732 const Ebl_Core_Item *item1 = *group1;
11733 const Ebl_Core_Item *item2 = *group2;
11734
11735 return (int) item1->offset - (int) item2->offset;
11736 }
11737
11738 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11739 handle_core_items (Elf *core, const void *desc, size_t descsz,
11740 const Ebl_Core_Item *items, size_t nitems)
11741 {
11742 if (nitems == 0)
11743 return 0;
11744 unsigned int colno = 0;
11745
11746 /* FORMAT '\n' makes sense to be present only as a single item as it
11747 processes all the data of a note. FORMATs 'b' and 'B' have a special case
11748 if present as a single item but they can be also processed with other
11749 items below. */
11750 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11751 || items[0].format == 'B'))
11752 {
11753 assert (items[0].offset == 0);
11754 size_t size = descsz;
11755 colno = handle_core_item (core, items, desc, colno, &size);
11756 /* If SIZE is not zero here there is some remaining data. But we do not
11757 know how to process it anyway. */
11758 return colno;
11759 }
11760 for (size_t i = 0; i < nitems; ++i)
11761 assert (items[i].format != '\n');
11762
11763 /* Sort to collect the groups together. */
11764 const Ebl_Core_Item *sorted_items[nitems];
11765 for (size_t i = 0; i < nitems; ++i)
11766 sorted_items[i] = &items[i];
11767 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11768
11769 /* Collect the unique groups and sort them. */
11770 const Ebl_Core_Item **groups[nitems];
11771 groups[0] = &sorted_items[0];
11772 size_t ngroups = 1;
11773 for (size_t i = 1; i < nitems; ++i)
11774 if (sorted_items[i]->group != sorted_items[i - 1]->group
11775 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11776 groups[ngroups++] = &sorted_items[i];
11777 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11778
11779 /* Write out all the groups. */
11780 const void *last = desc;
11781 do
11782 {
11783 for (size_t i = 0; i < ngroups; ++i)
11784 {
11785 for (const Ebl_Core_Item **item = groups[i];
11786 (item < &sorted_items[nitems]
11787 && ((*item)->group == groups[i][0]->group
11788 || !strcmp ((*item)->group, groups[i][0]->group)));
11789 ++item)
11790 colno = handle_core_item (core, *item, desc, colno, NULL);
11791
11792 /* Force a line break at the end of the group. */
11793 colno = WRAP_COLUMN;
11794 }
11795
11796 if (descsz == 0)
11797 break;
11798
11799 /* This set of items consumed a certain amount of the note's data.
11800 If there is more data there, we have another unit of the same size.
11801 Loop to print that out too. */
11802 const Ebl_Core_Item *item = &items[nitems - 1];
11803 size_t eltsz = item->offset + gelf_fsize (core, item->type,
11804 item->count ?: 1, EV_CURRENT);
11805
11806 int reps = -1;
11807 do
11808 {
11809 ++reps;
11810 desc += eltsz;
11811 descsz -= eltsz;
11812 }
11813 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11814
11815 if (reps == 1)
11816 {
11817 /* For just one repeat, print it unabridged twice. */
11818 desc -= eltsz;
11819 descsz += eltsz;
11820 }
11821 else if (reps > 1)
11822 printf (gettext ("\n%*s... <repeats %u more times> ..."),
11823 ITEM_INDENT, "", reps);
11824
11825 last = desc;
11826 }
11827 while (descsz > 0);
11828
11829 return colno;
11830 }
11831
11832 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11833 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11834 unsigned int colno)
11835 {
11836 desc += regloc->offset;
11837
11838 abort (); /* XXX */
11839 return colno;
11840 }
11841
11842
11843 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11844 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11845 const Ebl_Register_Location *regloc, const void *desc,
11846 unsigned int colno)
11847 {
11848 if (regloc->bits % 8 != 0)
11849 return handle_bit_registers (regloc, desc, colno);
11850
11851 desc += regloc->offset;
11852
11853 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11854 {
11855 char name[REGNAMESZ];
11856 int bits;
11857 int type;
11858 register_info (ebl, reg, regloc, name, &bits, &type);
11859
11860 #define TYPES \
11861 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
11862 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
11863 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
11864 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
11865
11866 #define BITS(bits, xtype, sfmt, ufmt) \
11867 uint##bits##_t b##bits; int##bits##_t b##bits##s
11868 union { TYPES; uint64_t b128[2]; } value;
11869 #undef BITS
11870
11871 switch (type)
11872 {
11873 case DW_ATE_unsigned:
11874 case DW_ATE_signed:
11875 case DW_ATE_address:
11876 switch (bits)
11877 {
11878 #define BITS(bits, xtype, sfmt, ufmt) \
11879 case bits: \
11880 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
11881 if (type == DW_ATE_signed) \
11882 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
11883 maxregname, name, \
11884 sfmt, value.b##bits##s); \
11885 else \
11886 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
11887 maxregname, name, \
11888 ufmt, value.b##bits); \
11889 break
11890
11891 TYPES;
11892
11893 case 128:
11894 assert (type == DW_ATE_unsigned);
11895 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11896 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11897 colno = print_core_item (colno, ' ', WRAP_COLUMN,
11898 maxregname, name,
11899 "0x%.16" PRIx64 "%.16" PRIx64,
11900 value.b128[!be], value.b128[be]);
11901 break;
11902
11903 default:
11904 abort ();
11905 #undef BITS
11906 }
11907 break;
11908
11909 default:
11910 /* Print each byte in hex, the whole thing in native byte order. */
11911 assert (bits % 8 == 0);
11912 const uint8_t *bytes = desc;
11913 desc += bits / 8;
11914 char hex[bits / 4 + 1];
11915 hex[bits / 4] = '\0';
11916 int incr = 1;
11917 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11918 {
11919 bytes += bits / 8 - 1;
11920 incr = -1;
11921 }
11922 size_t idx = 0;
11923 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11924 {
11925 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11926 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11927 }
11928 colno = print_core_item (colno, ' ', WRAP_COLUMN,
11929 maxregname, name, "0x%s", hex);
11930 break;
11931 }
11932 desc += regloc->pad;
11933
11934 #undef TYPES
11935 }
11936
11937 return colno;
11938 }
11939
11940
11941 struct register_info
11942 {
11943 const Ebl_Register_Location *regloc;
11944 const char *set;
11945 char name[REGNAMESZ];
11946 int regno;
11947 int bits;
11948 int type;
11949 };
11950
11951 static int
register_bitpos(const struct register_info * r)11952 register_bitpos (const struct register_info *r)
11953 {
11954 return (r->regloc->offset * 8
11955 + ((r->regno - r->regloc->regno)
11956 * (r->regloc->bits + r->regloc->pad * 8)));
11957 }
11958
11959 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)11960 compare_sets_by_info (const struct register_info *r1,
11961 const struct register_info *r2)
11962 {
11963 return ((int) r2->bits - (int) r1->bits
11964 ?: register_bitpos (r1) - register_bitpos (r2));
11965 }
11966
11967 /* Sort registers by set, and by size and layout offset within each set. */
11968 static int
compare_registers(const void * a,const void * b)11969 compare_registers (const void *a, const void *b)
11970 {
11971 const struct register_info *r1 = a;
11972 const struct register_info *r2 = b;
11973
11974 /* Unused elements sort last. */
11975 if (r1->regloc == NULL)
11976 return r2->regloc == NULL ? 0 : 1;
11977 if (r2->regloc == NULL)
11978 return -1;
11979
11980 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11981 ?: compare_sets_by_info (r1, r2));
11982 }
11983
11984 /* Sort register sets by layout offset of the first register in the set. */
11985 static int
compare_register_sets(const void * a,const void * b)11986 compare_register_sets (const void *a, const void *b)
11987 {
11988 const struct register_info *const *p1 = a;
11989 const struct register_info *const *p2 = b;
11990 return compare_sets_by_info (*p1, *p2);
11991 }
11992
11993 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)11994 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11995 const Ebl_Register_Location *reglocs, size_t nregloc)
11996 {
11997 if (nregloc == 0)
11998 return 0;
11999
12000 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12001 if (maxnreg <= 0)
12002 {
12003 for (size_t i = 0; i < nregloc; ++i)
12004 if (maxnreg < reglocs[i].regno + reglocs[i].count)
12005 maxnreg = reglocs[i].regno + reglocs[i].count;
12006 assert (maxnreg > 0);
12007 }
12008
12009 struct register_info regs[maxnreg];
12010 memset (regs, 0, sizeof regs);
12011
12012 /* Sort to collect the sets together. */
12013 int maxreg = 0;
12014 for (size_t i = 0; i < nregloc; ++i)
12015 for (int reg = reglocs[i].regno;
12016 reg < reglocs[i].regno + reglocs[i].count;
12017 ++reg)
12018 {
12019 assert (reg < maxnreg);
12020 if (reg > maxreg)
12021 maxreg = reg;
12022 struct register_info *info = ®s[reg];
12023 info->regloc = ®locs[i];
12024 info->regno = reg;
12025 info->set = register_info (ebl, reg, ®locs[i],
12026 info->name, &info->bits, &info->type);
12027 }
12028 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12029
12030 /* Collect the unique sets and sort them. */
12031 inline bool same_set (const struct register_info *a,
12032 const struct register_info *b)
12033 {
12034 return (a < ®s[maxnreg] && a->regloc != NULL
12035 && b < ®s[maxnreg] && b->regloc != NULL
12036 && a->bits == b->bits
12037 && (a->set == b->set || !strcmp (a->set, b->set)));
12038 }
12039 struct register_info *sets[maxreg + 1];
12040 sets[0] = ®s[0];
12041 size_t nsets = 1;
12042 for (int i = 1; i <= maxreg; ++i)
12043 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
12044 sets[nsets++] = ®s[i];
12045 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12046
12047 /* Write out all the sets. */
12048 unsigned int colno = 0;
12049 for (size_t i = 0; i < nsets; ++i)
12050 {
12051 /* Find the longest name of a register in this set. */
12052 size_t maxname = 0;
12053 const struct register_info *end;
12054 for (end = sets[i]; same_set (sets[i], end); ++end)
12055 {
12056 size_t len = strlen (end->name);
12057 if (len > maxname)
12058 maxname = len;
12059 }
12060
12061 for (const struct register_info *reg = sets[i];
12062 reg < end;
12063 reg += reg->regloc->count ?: 1)
12064 colno = handle_core_register (ebl, core, maxname,
12065 reg->regloc, desc, colno);
12066
12067 /* Force a line break at the end of the group. */
12068 colno = WRAP_COLUMN;
12069 }
12070
12071 return colno;
12072 }
12073
12074 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12075 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12076 {
12077 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12078 if (data == NULL)
12079 elf_error:
12080 error (EXIT_FAILURE, 0,
12081 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12082
12083 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12084 for (size_t i = 0; i < nauxv; ++i)
12085 {
12086 GElf_auxv_t av_mem;
12087 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12088 if (av == NULL)
12089 goto elf_error;
12090
12091 const char *name;
12092 const char *fmt;
12093 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12094 {
12095 /* Unknown type. */
12096 if (av->a_un.a_val == 0)
12097 printf (" %" PRIu64 "\n", av->a_type);
12098 else
12099 printf (" %" PRIu64 ": %#" PRIx64 "\n",
12100 av->a_type, av->a_un.a_val);
12101 }
12102 else
12103 switch (fmt[0])
12104 {
12105 case '\0': /* Normally zero. */
12106 if (av->a_un.a_val == 0)
12107 {
12108 printf (" %s\n", name);
12109 break;
12110 }
12111 FALLTHROUGH;
12112 case 'x': /* hex */
12113 case 'p': /* address */
12114 case 's': /* address of string */
12115 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12116 break;
12117 case 'u':
12118 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
12119 break;
12120 case 'd':
12121 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
12122 break;
12123
12124 case 'b':
12125 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
12126 GElf_Xword bit = 1;
12127 const char *pfx = "<";
12128 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12129 {
12130 if (av->a_un.a_val & bit)
12131 {
12132 printf ("%s%s", pfx, p);
12133 pfx = " ";
12134 }
12135 bit <<= 1;
12136 }
12137 printf (">\n");
12138 break;
12139
12140 default:
12141 abort ();
12142 }
12143 }
12144 }
12145
12146 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12147 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12148 {
12149 return ptr < end && (size_t) (end - ptr) >= sz;
12150 }
12151
12152 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12153 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12154 int *retp)
12155 {
12156 if (! buf_has_data (*ptrp, end, 4))
12157 return false;
12158
12159 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12160 return true;
12161 }
12162
12163 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12164 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12165 uint64_t *retp)
12166 {
12167 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12168 if (! buf_has_data (*ptrp, end, sz))
12169 return false;
12170
12171 union
12172 {
12173 uint64_t u64;
12174 uint32_t u32;
12175 } u;
12176
12177 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12178
12179 if (sz == 4)
12180 *retp = u.u32;
12181 else
12182 *retp = u.u64;
12183 return true;
12184 }
12185
12186 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12187 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12188 {
12189 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12190 if (data == NULL)
12191 error (EXIT_FAILURE, 0,
12192 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12193
12194 unsigned char const *ptr = data->d_buf;
12195 unsigned char const *const end = data->d_buf + data->d_size;
12196
12197 /* Siginfo head is three ints: signal number, error number, origin
12198 code. */
12199 int si_signo, si_errno, si_code;
12200 if (! buf_read_int (core, &ptr, end, &si_signo)
12201 || ! buf_read_int (core, &ptr, end, &si_errno)
12202 || ! buf_read_int (core, &ptr, end, &si_code))
12203 {
12204 fail:
12205 printf (" Not enough data in NT_SIGINFO note.\n");
12206 return;
12207 }
12208
12209 /* Next is a pointer-aligned union of structures. On 64-bit
12210 machines, that implies a word of padding. */
12211 if (gelf_getclass (core) == ELFCLASS64)
12212 ptr += 4;
12213
12214 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
12215 si_signo, si_errno, si_code);
12216
12217 if (si_code > 0)
12218 switch (si_signo)
12219 {
12220 case CORE_SIGILL:
12221 case CORE_SIGFPE:
12222 case CORE_SIGSEGV:
12223 case CORE_SIGBUS:
12224 {
12225 uint64_t addr;
12226 if (! buf_read_ulong (core, &ptr, end, &addr))
12227 goto fail;
12228 printf (" fault address: %#" PRIx64 "\n", addr);
12229 break;
12230 }
12231 default:
12232 ;
12233 }
12234 else if (si_code == CORE_SI_USER)
12235 {
12236 int pid, uid;
12237 if (! buf_read_int (core, &ptr, end, &pid)
12238 || ! buf_read_int (core, &ptr, end, &uid))
12239 goto fail;
12240 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
12241 }
12242 }
12243
12244 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12245 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12246 {
12247 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12248 if (data == NULL)
12249 error (EXIT_FAILURE, 0,
12250 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12251
12252 unsigned char const *ptr = data->d_buf;
12253 unsigned char const *const end = data->d_buf + data->d_size;
12254
12255 uint64_t count, page_size;
12256 if (! buf_read_ulong (core, &ptr, end, &count)
12257 || ! buf_read_ulong (core, &ptr, end, &page_size))
12258 {
12259 fail:
12260 printf (" Not enough data in NT_FILE note.\n");
12261 return;
12262 }
12263
12264 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12265 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12266 if (count > maxcount)
12267 goto fail;
12268
12269 /* Where file names are stored. */
12270 unsigned char const *const fstart = ptr + 3 * count * addrsize;
12271 char const *fptr = (char *) fstart;
12272
12273 printf (" %" PRId64 " files:\n", count);
12274 for (uint64_t i = 0; i < count; ++i)
12275 {
12276 uint64_t mstart, mend, moffset;
12277 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12278 || ! buf_read_ulong (core, &ptr, fstart, &mend)
12279 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12280 goto fail;
12281
12282 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12283 if (fnext == NULL)
12284 goto fail;
12285
12286 int ct = printf (" %08" PRIx64 "-%08" PRIx64
12287 " %08" PRIx64 " %" PRId64,
12288 mstart, mend, moffset * page_size, mend - mstart);
12289 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12290
12291 fptr = fnext + 1;
12292 }
12293 }
12294
12295 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12296 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12297 const char *name, const void *desc)
12298 {
12299 GElf_Word regs_offset;
12300 size_t nregloc;
12301 const Ebl_Register_Location *reglocs;
12302 size_t nitems;
12303 const Ebl_Core_Item *items;
12304
12305 if (! ebl_core_note (ebl, nhdr, name, desc,
12306 ®s_offset, &nregloc, ®locs, &nitems, &items))
12307 return;
12308
12309 /* Pass 0 for DESCSZ when there are registers in the note,
12310 so that the ITEMS array does not describe the whole thing.
12311 For non-register notes, the actual descsz might be a multiple
12312 of the unit size, not just exactly the unit size. */
12313 unsigned int colno = handle_core_items (ebl->elf, desc,
12314 nregloc == 0 ? nhdr->n_descsz : 0,
12315 items, nitems);
12316 if (colno != 0)
12317 putchar_unlocked ('\n');
12318
12319 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12320 reglocs, nregloc);
12321 if (colno != 0)
12322 putchar_unlocked ('\n');
12323 }
12324
12325 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12326 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12327 GElf_Off start, Elf_Data *data)
12328 {
12329 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
12330
12331 if (data == NULL)
12332 goto bad_note;
12333
12334 size_t offset = 0;
12335 GElf_Nhdr nhdr;
12336 size_t name_offset;
12337 size_t desc_offset;
12338 while (offset < data->d_size
12339 && (offset = gelf_getnote (data, offset,
12340 &nhdr, &name_offset, &desc_offset)) > 0)
12341 {
12342 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12343 const char *desc = data->d_buf + desc_offset;
12344
12345 /* GNU Build Attributes are weird, they store most of their data
12346 into the owner name field. Extract just the owner name
12347 prefix here, then use the rest later as data. */
12348 bool is_gnu_build_attr
12349 = strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12350 strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12351 const char *print_name = (is_gnu_build_attr
12352 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12353 size_t print_namesz = (is_gnu_build_attr
12354 ? strlen (print_name) : nhdr.n_namesz);
12355
12356 char buf[100];
12357 char buf2[100];
12358 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
12359 (int) print_namesz, print_name, nhdr.n_descsz,
12360 ehdr->e_type == ET_CORE
12361 ? ebl_core_note_type_name (ebl, nhdr.n_type,
12362 buf, sizeof (buf))
12363 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12364 nhdr.n_descsz,
12365 buf2, sizeof (buf2)));
12366
12367 /* Filter out invalid entries. */
12368 if (memchr (name, '\0', nhdr.n_namesz) != NULL
12369 /* XXX For now help broken Linux kernels. */
12370 || 1)
12371 {
12372 if (ehdr->e_type == ET_CORE)
12373 {
12374 if (nhdr.n_type == NT_AUXV
12375 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
12376 || (nhdr.n_namesz == 5 && name[4] == '\0'))
12377 && !memcmp (name, "CORE", 4))
12378 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12379 start + desc_offset);
12380 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12381 switch (nhdr.n_type)
12382 {
12383 case NT_SIGINFO:
12384 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12385 start + desc_offset);
12386 break;
12387
12388 case NT_FILE:
12389 handle_file_note (ebl->elf, nhdr.n_descsz,
12390 start + desc_offset);
12391 break;
12392
12393 default:
12394 handle_core_note (ebl, &nhdr, name, desc);
12395 }
12396 else
12397 handle_core_note (ebl, &nhdr, name, desc);
12398 }
12399 else
12400 ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12401 nhdr.n_descsz, desc);
12402 }
12403 }
12404
12405 if (offset == data->d_size)
12406 return;
12407
12408 bad_note:
12409 error (0, 0,
12410 gettext ("cannot get content of note: %s"),
12411 data != NULL ? "garbage data" : elf_errmsg (-1));
12412 }
12413
12414 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12415 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12416 {
12417 /* If we have section headers, just look for SHT_NOTE sections.
12418 In a debuginfo file, the program headers are not reliable. */
12419 if (shnum != 0)
12420 {
12421 /* Get the section header string table index. */
12422 size_t shstrndx;
12423 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12424 error (EXIT_FAILURE, 0,
12425 gettext ("cannot get section header string table index"));
12426
12427 Elf_Scn *scn = NULL;
12428 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12429 {
12430 GElf_Shdr shdr_mem;
12431 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12432
12433 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12434 /* Not what we are looking for. */
12435 continue;
12436
12437 if (notes_section != NULL)
12438 {
12439 char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12440 if (sname == NULL || strcmp (sname, notes_section) != 0)
12441 continue;
12442 }
12443
12444 printf (gettext ("\
12445 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12446 elf_ndxscn (scn),
12447 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12448 shdr->sh_size, shdr->sh_offset);
12449
12450 handle_notes_data (ebl, ehdr, shdr->sh_offset,
12451 elf_getdata (scn, NULL));
12452 }
12453 return;
12454 }
12455
12456 /* We have to look through the program header to find the note
12457 sections. There can be more than one. */
12458 for (size_t cnt = 0; cnt < phnum; ++cnt)
12459 {
12460 GElf_Phdr mem;
12461 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12462
12463 if (phdr == NULL || phdr->p_type != PT_NOTE)
12464 /* Not what we are looking for. */
12465 continue;
12466
12467 printf (gettext ("\
12468 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12469 phdr->p_filesz, phdr->p_offset);
12470
12471 handle_notes_data (ebl, ehdr, phdr->p_offset,
12472 elf_getdata_rawchunk (ebl->elf,
12473 phdr->p_offset, phdr->p_filesz,
12474 (phdr->p_align == 8
12475 ? ELF_T_NHDR8 : ELF_T_NHDR)));
12476 }
12477 }
12478
12479
12480 static void
hex_dump(const uint8_t * data,size_t len)12481 hex_dump (const uint8_t *data, size_t len)
12482 {
12483 size_t pos = 0;
12484 while (pos < len)
12485 {
12486 printf (" 0x%08zx ", pos);
12487
12488 const size_t chunk = MIN (len - pos, 16);
12489
12490 for (size_t i = 0; i < chunk; ++i)
12491 if (i % 4 == 3)
12492 printf ("%02x ", data[pos + i]);
12493 else
12494 printf ("%02x", data[pos + i]);
12495
12496 if (chunk < 16)
12497 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12498
12499 for (size_t i = 0; i < chunk; ++i)
12500 {
12501 unsigned char b = data[pos + i];
12502 printf ("%c", isprint (b) ? b : '.');
12503 }
12504
12505 putchar ('\n');
12506 pos += chunk;
12507 }
12508 }
12509
12510 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12511 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12512 {
12513 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12514 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12515 elf_ndxscn (scn), name);
12516 else
12517 {
12518 if (print_decompress)
12519 {
12520 /* We try to decompress the section, but keep the old shdr around
12521 so we can show both the original shdr size and the uncompressed
12522 data size. */
12523 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12524 {
12525 if (elf_compress (scn, 0, 0) < 0)
12526 printf ("WARNING: %s [%zd]\n",
12527 gettext ("Couldn't uncompress section"),
12528 elf_ndxscn (scn));
12529 }
12530 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12531 {
12532 if (elf_compress_gnu (scn, 0, 0) < 0)
12533 printf ("WARNING: %s [%zd]\n",
12534 gettext ("Couldn't uncompress section"),
12535 elf_ndxscn (scn));
12536 }
12537 }
12538
12539 Elf_Data *data = elf_rawdata (scn, NULL);
12540 if (data == NULL)
12541 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12542 elf_ndxscn (scn), name, elf_errmsg (-1));
12543 else
12544 {
12545 if (data->d_size == shdr->sh_size)
12546 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12547 " bytes at offset %#0" PRIx64 ":\n"),
12548 elf_ndxscn (scn), name,
12549 shdr->sh_size, shdr->sh_offset);
12550 else
12551 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12552 " bytes (%zd uncompressed) at offset %#0"
12553 PRIx64 ":\n"),
12554 elf_ndxscn (scn), name,
12555 shdr->sh_size, data->d_size, shdr->sh_offset);
12556 hex_dump (data->d_buf, data->d_size);
12557 }
12558 }
12559 }
12560
12561 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12562 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12563 {
12564 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12565 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12566 elf_ndxscn (scn), name);
12567 else
12568 {
12569 if (print_decompress)
12570 {
12571 /* We try to decompress the section, but keep the old shdr around
12572 so we can show both the original shdr size and the uncompressed
12573 data size. */
12574 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12575 {
12576 if (elf_compress (scn, 0, 0) < 0)
12577 printf ("WARNING: %s [%zd]\n",
12578 gettext ("Couldn't uncompress section"),
12579 elf_ndxscn (scn));
12580 }
12581 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12582 {
12583 if (elf_compress_gnu (scn, 0, 0) < 0)
12584 printf ("WARNING: %s [%zd]\n",
12585 gettext ("Couldn't uncompress section"),
12586 elf_ndxscn (scn));
12587 }
12588 }
12589
12590 Elf_Data *data = elf_rawdata (scn, NULL);
12591 if (data == NULL)
12592 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12593 elf_ndxscn (scn), name, elf_errmsg (-1));
12594 else
12595 {
12596 if (data->d_size == shdr->sh_size)
12597 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12598 " bytes at offset %#0" PRIx64 ":\n"),
12599 elf_ndxscn (scn), name,
12600 shdr->sh_size, shdr->sh_offset);
12601 else
12602 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12603 " bytes (%zd uncompressed) at offset %#0"
12604 PRIx64 ":\n"),
12605 elf_ndxscn (scn), name,
12606 shdr->sh_size, data->d_size, shdr->sh_offset);
12607
12608 const char *start = data->d_buf;
12609 const char *const limit = start + data->d_size;
12610 do
12611 {
12612 const char *end = memchr (start, '\0', limit - start);
12613 const size_t pos = start - (const char *) data->d_buf;
12614 if (unlikely (end == NULL))
12615 {
12616 printf (" [%6zx]- %.*s\n",
12617 pos, (int) (limit - start), start);
12618 break;
12619 }
12620 printf (" [%6zx] %s\n", pos, start);
12621 start = end + 1;
12622 } while (start < limit);
12623 }
12624 }
12625 }
12626
12627 static void
for_each_section_argument(Elf * elf,const struct section_argument * list,void (* dump)(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name))12628 for_each_section_argument (Elf *elf, const struct section_argument *list,
12629 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12630 const char *name))
12631 {
12632 /* Get the section header string table index. */
12633 size_t shstrndx;
12634 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12635 error (EXIT_FAILURE, 0,
12636 gettext ("cannot get section header string table index"));
12637
12638 for (const struct section_argument *a = list; a != NULL; a = a->next)
12639 {
12640 Elf_Scn *scn;
12641 GElf_Shdr shdr_mem;
12642 const char *name = NULL;
12643
12644 char *endp = NULL;
12645 unsigned long int shndx = strtoul (a->arg, &endp, 0);
12646 if (endp != a->arg && *endp == '\0')
12647 {
12648 scn = elf_getscn (elf, shndx);
12649 if (scn == NULL)
12650 {
12651 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12652 continue;
12653 }
12654
12655 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12656 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12657 elf_errmsg (-1));
12658 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12659 (*dump) (scn, &shdr_mem, name);
12660 }
12661 else
12662 {
12663 /* Need to look up the section by name. */
12664 scn = NULL;
12665 bool found = false;
12666 while ((scn = elf_nextscn (elf, scn)) != NULL)
12667 {
12668 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12669 continue;
12670 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12671 if (name == NULL)
12672 continue;
12673 if (!strcmp (name, a->arg))
12674 {
12675 found = true;
12676 (*dump) (scn, &shdr_mem, name);
12677 }
12678 }
12679
12680 if (unlikely (!found) && !a->implicit)
12681 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12682 }
12683 }
12684 }
12685
12686 static void
dump_data(Ebl * ebl)12687 dump_data (Ebl *ebl)
12688 {
12689 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12690 }
12691
12692 static void
dump_strings(Ebl * ebl)12693 dump_strings (Ebl *ebl)
12694 {
12695 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12696 }
12697
12698 static void
print_strings(Ebl * ebl)12699 print_strings (Ebl *ebl)
12700 {
12701 /* Get the section header string table index. */
12702 size_t shstrndx;
12703 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12704 error (EXIT_FAILURE, 0,
12705 gettext ("cannot get section header string table index"));
12706
12707 Elf_Scn *scn;
12708 GElf_Shdr shdr_mem;
12709 const char *name;
12710 scn = NULL;
12711 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12712 {
12713 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12714 continue;
12715
12716 if (shdr_mem.sh_type != SHT_PROGBITS
12717 || !(shdr_mem.sh_flags & SHF_STRINGS))
12718 continue;
12719
12720 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12721 if (name == NULL)
12722 continue;
12723
12724 print_string_section (scn, &shdr_mem, name);
12725 }
12726 }
12727
12728 static void
dump_archive_index(Elf * elf,const char * fname)12729 dump_archive_index (Elf *elf, const char *fname)
12730 {
12731 size_t narsym;
12732 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12733 if (arsym == NULL)
12734 {
12735 int result = elf_errno ();
12736 if (unlikely (result != ELF_E_NO_INDEX))
12737 error (EXIT_FAILURE, 0,
12738 gettext ("cannot get symbol index of archive '%s': %s"),
12739 fname, elf_errmsg (result));
12740 else
12741 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12742 return;
12743 }
12744
12745 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12746 fname, narsym);
12747
12748 size_t as_off = 0;
12749 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12750 {
12751 if (s->as_off != as_off)
12752 {
12753 as_off = s->as_off;
12754
12755 Elf *subelf = NULL;
12756 if (unlikely (elf_rand (elf, as_off) == 0)
12757 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12758 == NULL))
12759 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12760 while (1)
12761 #endif
12762 error (EXIT_FAILURE, 0,
12763 gettext ("cannot extract member at offset %zu in '%s': %s"),
12764 as_off, fname, elf_errmsg (-1));
12765
12766 const Elf_Arhdr *h = elf_getarhdr (subelf);
12767
12768 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12769
12770 elf_end (subelf);
12771 }
12772
12773 printf ("\t%s\n", s->as_name);
12774 }
12775 }
12776
12777 #include "debugpred.h"
12778