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 = _("yes");
351 no_str = _("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 static void
add_dump_section(const char * name,int key,bool implicit)385 add_dump_section (const char *name,
386 int key,
387 bool implicit)
388 {
389 struct section_argument *a = xmalloc (sizeof *a);
390 a->arg = name;
391 a->next = NULL;
392 a->implicit = implicit;
393 struct section_argument ***tailp
394 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
395 **tailp = a;
396 *tailp = &a->next;
397 }
398
399 /* Handle program arguments. */
400 static error_t
parse_opt(int key,char * arg,struct argp_state * state)401 parse_opt (int key, char *arg,
402 struct argp_state *state __attribute__ ((unused)))
403 {
404 switch (key)
405 {
406 case 'a':
407 print_file_header = true;
408 print_program_header = true;
409 print_relocations = true;
410 print_section_header = true;
411 print_symbol_table = true;
412 print_version_info = true;
413 print_dynamic_table = true;
414 print_section_groups = true;
415 print_histogram = true;
416 print_arch = true;
417 print_notes = true;
418 implicit_debug_sections |= section_exception;
419 add_dump_section (".strtab", key, true);
420 add_dump_section (".dynstr", key, true);
421 add_dump_section (".comment", key, true);
422 any_control_option = true;
423 break;
424 case 'A':
425 print_arch = true;
426 any_control_option = true;
427 break;
428 case 'd':
429 print_dynamic_table = true;
430 any_control_option = true;
431 break;
432 case 'e':
433 print_debug_sections |= section_exception;
434 any_control_option = true;
435 break;
436 case 'g':
437 print_section_groups = true;
438 any_control_option = true;
439 break;
440 case 'h':
441 print_file_header = true;
442 any_control_option = true;
443 break;
444 case 'I':
445 print_histogram = true;
446 any_control_option = true;
447 break;
448 case 'l':
449 print_program_header = true;
450 any_control_option = true;
451 break;
452 case 'n':
453 print_notes = true;
454 any_control_option = true;
455 notes_section = arg;
456 break;
457 case 'r':
458 print_relocations = true;
459 any_control_option = true;
460 break;
461 case 'S':
462 print_section_header = true;
463 any_control_option = true;
464 break;
465 case 's':
466 print_symbol_table = true;
467 any_control_option = true;
468 symbol_table_section = arg;
469 break;
470 case PRINT_DYNSYM_TABLE:
471 print_dynsym_table = true;
472 any_control_option = true;
473 break;
474 case 'V':
475 print_version_info = true;
476 any_control_option = true;
477 break;
478 case 'c':
479 print_archive_index = true;
480 break;
481 case 'w':
482 if (arg == NULL)
483 {
484 print_debug_sections = section_all;
485 implicit_debug_sections = section_info;
486 show_split_units = true;
487 }
488 else if (strcmp (arg, "abbrev") == 0)
489 print_debug_sections |= section_abbrev;
490 else if (strcmp (arg, "addr") == 0)
491 {
492 print_debug_sections |= section_addr;
493 implicit_debug_sections |= section_info;
494 }
495 else if (strcmp (arg, "aranges") == 0)
496 print_debug_sections |= section_aranges;
497 else if (strcmp (arg, "decodedaranges") == 0)
498 {
499 print_debug_sections |= section_aranges;
500 decodedaranges = true;
501 }
502 else if (strcmp (arg, "ranges") == 0)
503 {
504 print_debug_sections |= section_ranges;
505 implicit_debug_sections |= section_info;
506 }
507 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
508 print_debug_sections |= section_frame;
509 else if (strcmp (arg, "info") == 0)
510 {
511 print_debug_sections |= section_info;
512 print_debug_sections |= section_types;
513 }
514 else if (strcmp (arg, "info+") == 0)
515 {
516 print_debug_sections |= section_info;
517 print_debug_sections |= section_types;
518 show_split_units = true;
519 }
520 else if (strcmp (arg, "loc") == 0)
521 {
522 print_debug_sections |= section_loc;
523 implicit_debug_sections |= section_info;
524 }
525 else if (strcmp (arg, "line") == 0)
526 print_debug_sections |= section_line;
527 else if (strcmp (arg, "decodedline") == 0)
528 {
529 print_debug_sections |= section_line;
530 decodedline = true;
531 }
532 else if (strcmp (arg, "pubnames") == 0)
533 print_debug_sections |= section_pubnames;
534 else if (strcmp (arg, "str") == 0)
535 {
536 print_debug_sections |= section_str;
537 /* For mapping string offset tables to CUs. */
538 implicit_debug_sections |= section_info;
539 }
540 else if (strcmp (arg, "macinfo") == 0)
541 print_debug_sections |= section_macinfo;
542 else if (strcmp (arg, "macro") == 0)
543 print_debug_sections |= section_macro;
544 else if (strcmp (arg, "exception") == 0)
545 print_debug_sections |= section_exception;
546 else if (strcmp (arg, "gdb_index") == 0)
547 print_debug_sections |= section_gdb_index;
548 else
549 {
550 fprintf (stderr, _("Unknown DWARF debug section `%s'.\n"),
551 arg);
552 argp_help (&argp, stderr, ARGP_HELP_SEE,
553 program_invocation_short_name);
554 exit (1);
555 }
556 any_control_option = true;
557 break;
558 case 'p':
559 any_control_option = true;
560 if (arg == NULL)
561 {
562 print_string_sections = true;
563 break;
564 }
565 FALLTHROUGH;
566 case 'x':
567 add_dump_section (arg, key, false);
568 any_control_option = true;
569 break;
570 case 'N':
571 print_address_names = false;
572 break;
573 case 'U':
574 print_unresolved_addresses = true;
575 break;
576 case ARGP_KEY_NO_ARGS:
577 fputs (_("Missing file name.\n"), stderr);
578 goto do_argp_help;
579 case ARGP_KEY_FINI:
580 if (! any_control_option && ! print_archive_index)
581 {
582 fputs (_("No operation specified.\n"), stderr);
583 do_argp_help:
584 argp_help (&argp, stderr, ARGP_HELP_SEE,
585 program_invocation_short_name);
586 exit (EXIT_FAILURE);
587 }
588 break;
589 case 'W': /* Ignored. */
590 break;
591 case 'z':
592 print_decompress = true;
593 break;
594 case ELF_INPUT_SECTION:
595 if (arg == NULL)
596 elf_input_section = ".gnu_debugdata";
597 else
598 elf_input_section = arg;
599 break;
600 case DWARF_SKELETON:
601 dwarf_skeleton = arg;
602 break;
603 default:
604 return ARGP_ERR_UNKNOWN;
605 }
606 return 0;
607 }
608
609
610 /* Create a file descriptor to read the data from the
611 elf_input_section given a file descriptor to an ELF file. */
612 static int
open_input_section(int fd)613 open_input_section (int fd)
614 {
615 size_t shnums;
616 size_t cnt;
617 size_t shstrndx;
618 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
619 if (elf == NULL)
620 {
621 error (0, 0, _("cannot generate Elf descriptor: %s"),
622 elf_errmsg (-1));
623 return -1;
624 }
625
626 if (elf_getshdrnum (elf, &shnums) < 0)
627 {
628 error (0, 0, _("cannot determine number of sections: %s"),
629 elf_errmsg (-1));
630 open_error:
631 elf_end (elf);
632 return -1;
633 }
634
635 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
636 {
637 error (0, 0, _("cannot get section header string table index"));
638 goto open_error;
639 }
640
641 for (cnt = 0; cnt < shnums; ++cnt)
642 {
643 Elf_Scn *scn = elf_getscn (elf, cnt);
644 if (scn == NULL)
645 {
646 error (0, 0, _("cannot get section: %s"),
647 elf_errmsg (-1));
648 goto open_error;
649 }
650
651 GElf_Shdr shdr_mem;
652 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
653 if (unlikely (shdr == NULL))
654 {
655 error (0, 0, _("cannot get section header: %s"),
656 elf_errmsg (-1));
657 goto open_error;
658 }
659
660 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
661 if (sname == NULL)
662 {
663 error (0, 0, _("cannot get section name"));
664 goto open_error;
665 }
666
667 if (strcmp (sname, elf_input_section) == 0)
668 {
669 Elf_Data *data = elf_rawdata (scn, NULL);
670 if (data == NULL)
671 {
672 error (0, 0, _("cannot get %s content: %s"),
673 sname, elf_errmsg (-1));
674 goto open_error;
675 }
676
677 /* Create (and immediately unlink) a temporary file to store
678 section data in to create a file descriptor for it. */
679 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
680 static const char suffix[] = "/readelfXXXXXX";
681 int tmplen = strlen (tmpdir) + sizeof (suffix);
682 char *tempname = alloca (tmplen);
683 sprintf (tempname, "%s%s", tmpdir, suffix);
684
685 int sfd = mkstemp (tempname);
686 if (sfd == -1)
687 {
688 error (0, 0, _("cannot create temp file '%s'"),
689 tempname);
690 goto open_error;
691 }
692 unlink (tempname);
693
694 ssize_t size = data->d_size;
695 if (write_retry (sfd, data->d_buf, size) != size)
696 {
697 error (0, 0, _("cannot write section data"));
698 goto open_error;
699 }
700
701 if (elf_end (elf) != 0)
702 {
703 error (0, 0, _("error while closing Elf descriptor: %s"),
704 elf_errmsg (-1));
705 return -1;
706 }
707
708 if (lseek (sfd, 0, SEEK_SET) == -1)
709 {
710 error (0, 0, _("error while rewinding file descriptor"));
711 return -1;
712 }
713
714 return sfd;
715 }
716 }
717
718 /* Named section not found. */
719 if (elf_end (elf) != 0)
720 error (0, 0, _("error while closing Elf descriptor: %s"),
721 elf_errmsg (-1));
722 return -1;
723 }
724
725 /* Check if the file is an archive, and if so dump its index. */
726 static void
check_archive_index(int fd,const char * fname,bool only_one)727 check_archive_index (int fd, const char *fname, bool only_one)
728 {
729 /* Create an `Elf' descriptor. */
730 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
731 if (elf == NULL)
732 error (0, 0, _("cannot generate Elf descriptor: %s"),
733 elf_errmsg (-1));
734 else
735 {
736 if (elf_kind (elf) == ELF_K_AR)
737 {
738 if (!only_one)
739 printf ("\n%s:\n\n", fname);
740 dump_archive_index (elf, fname);
741 }
742 else
743 error (0, 0,
744 _("'%s' is not an archive, cannot print archive index"),
745 fname);
746
747 /* Now we can close the descriptor. */
748 if (elf_end (elf) != 0)
749 error (0, 0, _("error while closing Elf descriptor: %s"),
750 elf_errmsg (-1));
751 }
752 }
753
754 /* Trivial callback used for checking if we opened an archive. */
755 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)756 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
757 void **userdata __attribute__ ((unused)),
758 const char *name __attribute__ ((unused)),
759 Dwarf_Addr base __attribute__ ((unused)),
760 void *arg)
761 {
762 if (*(bool *) arg)
763 return DWARF_CB_ABORT;
764 *(bool *) arg = true;
765 return DWARF_CB_OK;
766 }
767
768 struct process_dwflmod_args
769 {
770 int fd;
771 bool only_one;
772 };
773
774 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)775 process_dwflmod (Dwfl_Module *dwflmod,
776 void **userdata __attribute__ ((unused)),
777 const char *name __attribute__ ((unused)),
778 Dwarf_Addr base __attribute__ ((unused)),
779 void *arg)
780 {
781 const struct process_dwflmod_args *a = arg;
782
783 /* Print the file name. */
784 if (!a->only_one)
785 {
786 const char *fname;
787 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
788
789 printf ("\n%s:\n\n", fname);
790 }
791
792 process_elf_file (dwflmod, a->fd);
793
794 return DWARF_CB_OK;
795 }
796
797 /* Stub libdwfl callback, only the ELF handle already open is ever used.
798 Only used for finding the alternate debug file if the Dwarf comes from
799 the main file. We are not interested in separate debuginfo. */
800 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)801 find_no_debuginfo (Dwfl_Module *mod,
802 void **userdata,
803 const char *modname,
804 Dwarf_Addr base,
805 const char *file_name,
806 const char *debuglink_file,
807 GElf_Word debuglink_crc,
808 char **debuginfo_file_name)
809 {
810 Dwarf_Addr dwbias;
811 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
812
813 /* We are only interested if the Dwarf has been setup on the main
814 elf file but is only missing the alternate debug link. If dwbias
815 hasn't even been setup, this is searching for separate debuginfo
816 for the main elf. We don't care in that case. */
817 if (dwbias == (Dwarf_Addr) -1)
818 return -1;
819
820 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
821 file_name, debuglink_file,
822 debuglink_crc, debuginfo_file_name);
823 }
824
825 static Dwfl *
create_dwfl(int fd,const char * fname)826 create_dwfl (int fd, const char *fname)
827 {
828 /* Duplicate an fd for dwfl_report_offline to swallow. */
829 int dwfl_fd = dup (fd);
830 if (unlikely (dwfl_fd < 0))
831 error (EXIT_FAILURE, errno, "dup");
832
833 /* Use libdwfl in a trivial way to open the libdw handle for us.
834 This takes care of applying relocations to DWARF data in ET_REL files. */
835 static const Dwfl_Callbacks callbacks =
836 {
837 .section_address = dwfl_offline_section_address,
838 .find_debuginfo = find_no_debuginfo
839 };
840 Dwfl *dwfl = dwfl_begin (&callbacks);
841 if (likely (dwfl != NULL))
842 /* Let 0 be the logical address of the file (or first in archive). */
843 dwfl->offline_next_address = 0;
844 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
845 {
846 struct stat st;
847 if (fstat (dwfl_fd, &st) != 0)
848 error (0, errno, _("cannot stat input file"));
849 else if (unlikely (st.st_size == 0))
850 error (0, 0, _("input file is empty"));
851 else
852 error (0, 0, _("failed reading '%s': %s"),
853 fname, dwfl_errmsg (-1));
854 close (dwfl_fd); /* Consumed on success, not on failure. */
855 dwfl = NULL;
856 }
857 else
858 dwfl_report_end (dwfl, NULL, NULL);
859
860 return dwfl;
861 }
862
863 /* Process one input file. */
864 static void
process_file(int fd,const char * fname,bool only_one)865 process_file (int fd, const char *fname, bool only_one)
866 {
867 if (print_archive_index)
868 check_archive_index (fd, fname, only_one);
869
870 if (!any_control_option)
871 return;
872
873 if (elf_input_section != NULL)
874 {
875 /* Replace fname and fd with section content. */
876 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
877 sprintf (fnname, "%s:%s", fname, elf_input_section);
878 fd = open_input_section (fd);
879 if (fd == -1)
880 {
881 error (0, 0, _("No such section '%s' in '%s'"),
882 elf_input_section, fname);
883 return;
884 }
885 fname = fnname;
886 }
887
888 Dwfl *dwfl = create_dwfl (fd, fname);
889 if (dwfl != NULL)
890 {
891 if (only_one)
892 {
893 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
894 bool seen = false;
895 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
896 }
897
898 /* Process the one or more modules gleaned from this file. */
899 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
900 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
901 }
902 /* Terrible hack for hooking unrelated skeleton/split compile units,
903 see __libdw_link_skel_split in print_debug. */
904 if (! do_not_close_dwfl)
905 dwfl_end (dwfl);
906
907 /* Need to close the replaced fd if we created it. Caller takes
908 care of original. */
909 if (elf_input_section != NULL)
910 close (fd);
911 }
912
913 /* Check whether there are any compressed sections in the ELF file. */
914 static bool
elf_contains_chdrs(Elf * elf)915 elf_contains_chdrs (Elf *elf)
916 {
917 Elf_Scn *scn = NULL;
918 while ((scn = elf_nextscn (elf, scn)) != NULL)
919 {
920 GElf_Shdr shdr_mem;
921 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
922 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
923 return true;
924 }
925 return false;
926 }
927
928 /* Process one ELF file. */
929 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)930 process_elf_file (Dwfl_Module *dwflmod, int fd)
931 {
932 GElf_Addr dwflbias;
933 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
934
935 GElf_Ehdr ehdr_mem;
936 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
937
938 if (ehdr == NULL)
939 {
940 error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1));
941 return;
942 }
943
944 Ebl *ebl = ebl_openbackend (elf);
945 if (unlikely (ebl == NULL))
946 {
947 ebl_error:
948 error (0, errno, _("cannot create EBL handle"));
949 return;
950 }
951
952 /* Determine the number of sections. */
953 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
954 error (EXIT_FAILURE, 0,
955 _("cannot determine number of sections: %s"),
956 elf_errmsg (-1));
957
958 /* Determine the number of phdrs. */
959 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
960 error (EXIT_FAILURE, 0,
961 _("cannot determine number of program headers: %s"),
962 elf_errmsg (-1));
963
964 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
965 may have applied relocation to some sections. If there are any
966 compressed sections, any pass (or libdw/libdwfl) might have
967 uncompressed them. So we need to get a fresh Elf handle on the
968 file to display those. */
969 bool print_unchanged = ((print_section_header
970 || print_relocations
971 || dump_data_sections != NULL
972 || print_notes)
973 && (ehdr->e_type == ET_REL
974 || elf_contains_chdrs (ebl->elf)));
975
976 Elf *pure_elf = NULL;
977 Ebl *pure_ebl = ebl;
978 if (print_unchanged)
979 {
980 /* Read the file afresh. */
981 off_t aroff = elf_getaroff (elf);
982 pure_elf = dwelf_elf_begin (fd);
983 if (aroff > 0)
984 {
985 /* Archive member. */
986 (void) elf_rand (pure_elf, aroff);
987 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
988 elf_end (pure_elf);
989 pure_elf = armem;
990 }
991 if (pure_elf == NULL)
992 {
993 error (0, 0, _("cannot read ELF: %s"), elf_errmsg (-1));
994 return;
995 }
996 pure_ebl = ebl_openbackend (pure_elf);
997 if (pure_ebl == NULL)
998 goto ebl_error;
999 }
1000
1001 if (print_file_header)
1002 print_ehdr (ebl, ehdr);
1003 if (print_section_header)
1004 print_shdr (pure_ebl, ehdr);
1005 if (print_program_header)
1006 print_phdr (ebl, ehdr);
1007 if (print_section_groups)
1008 print_scngrp (ebl);
1009 if (print_dynamic_table)
1010 print_dynamic (ebl);
1011 if (print_relocations)
1012 print_relocs (pure_ebl, ehdr);
1013 if (print_histogram)
1014 handle_hash (ebl);
1015 if (print_symbol_table || print_dynsym_table)
1016 print_symtab (ebl, SHT_DYNSYM);
1017 if (print_version_info)
1018 print_verinfo (ebl);
1019 if (print_symbol_table)
1020 print_symtab (ebl, SHT_SYMTAB);
1021 if (print_arch)
1022 print_liblist (ebl);
1023 if (print_arch)
1024 print_attributes (ebl, ehdr);
1025 if (dump_data_sections != NULL)
1026 dump_data (pure_ebl);
1027 if (string_sections != NULL)
1028 dump_strings (ebl);
1029 if ((print_debug_sections | implicit_debug_sections) != 0)
1030 print_debug (dwflmod, ebl, ehdr);
1031 if (print_notes)
1032 handle_notes (pure_ebl, ehdr);
1033 if (print_string_sections)
1034 print_strings (ebl);
1035
1036 ebl_closebackend (ebl);
1037
1038 if (pure_ebl != ebl)
1039 {
1040 ebl_closebackend (pure_ebl);
1041 elf_end (pure_elf);
1042 }
1043 }
1044
1045
1046 /* Print file type. */
1047 static void
print_file_type(unsigned short int e_type)1048 print_file_type (unsigned short int e_type)
1049 {
1050 if (likely (e_type <= ET_CORE))
1051 {
1052 static const char *const knowntypes[] =
1053 {
1054 N_("NONE (None)"),
1055 N_("REL (Relocatable file)"),
1056 N_("EXEC (Executable file)"),
1057 N_("DYN (Shared object file)"),
1058 N_("CORE (Core file)")
1059 };
1060 puts (_(knowntypes[e_type]));
1061 }
1062 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1063 printf (_("OS Specific: (%x)\n"), e_type);
1064 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1065 printf (_("Processor Specific: (%x)\n"), e_type);
1066 else
1067 puts ("???");
1068 }
1069
1070
1071 /* Print ELF header. */
1072 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1073 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1074 {
1075 fputs_unlocked (_("ELF Header:\n Magic: "), stdout);
1076 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1077 printf (" %02hhx", ehdr->e_ident[cnt]);
1078
1079 printf (_("\n Class: %s\n"),
1080 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1081 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1082 : "\?\?\?");
1083
1084 printf (_(" Data: %s\n"),
1085 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1086 ? "2's complement, little endian"
1087 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1088 ? "2's complement, big endian" : "\?\?\?");
1089
1090 printf (_(" Ident Version: %hhd %s\n"),
1091 ehdr->e_ident[EI_VERSION],
1092 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)")
1093 : "(\?\?\?)");
1094
1095 char buf[512];
1096 printf (_(" OS/ABI: %s\n"),
1097 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1098
1099 printf (_(" ABI Version: %hhd\n"),
1100 ehdr->e_ident[EI_ABIVERSION]);
1101
1102 fputs_unlocked (_(" Type: "), stdout);
1103 print_file_type (ehdr->e_type);
1104
1105 const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1106 if (machine != NULL)
1107 printf (_(" Machine: %s\n"), machine);
1108 else
1109 printf (_(" Machine: <unknown>: 0x%x\n"),
1110 ehdr->e_machine);
1111
1112 printf (_(" Version: %d %s\n"),
1113 ehdr->e_version,
1114 ehdr->e_version == EV_CURRENT ? _("(current)") : "(\?\?\?)");
1115
1116 printf (_(" Entry point address: %#" PRIx64 "\n"),
1117 ehdr->e_entry);
1118
1119 printf (_(" Start of program headers: %" PRId64 " %s\n"),
1120 ehdr->e_phoff, _("(bytes into file)"));
1121
1122 printf (_(" Start of section headers: %" PRId64 " %s\n"),
1123 ehdr->e_shoff, _("(bytes into file)"));
1124
1125 printf (_(" Flags: %s\n"),
1126 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1127
1128 printf (_(" Size of this header: %" PRId16 " %s\n"),
1129 ehdr->e_ehsize, _("(bytes)"));
1130
1131 printf (_(" Size of program header entries: %" PRId16 " %s\n"),
1132 ehdr->e_phentsize, _("(bytes)"));
1133
1134 printf (_(" Number of program headers entries: %" PRId16),
1135 ehdr->e_phnum);
1136 if (ehdr->e_phnum == PN_XNUM)
1137 {
1138 GElf_Shdr shdr_mem;
1139 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1140 if (shdr != NULL)
1141 printf (_(" (%" PRIu32 " in [0].sh_info)"),
1142 (uint32_t) shdr->sh_info);
1143 else
1144 fputs_unlocked (_(" ([0] not available)"), stdout);
1145 }
1146 fputc_unlocked ('\n', stdout);
1147
1148 printf (_(" Size of section header entries: %" PRId16 " %s\n"),
1149 ehdr->e_shentsize, _("(bytes)"));
1150
1151 printf (_(" Number of section headers entries: %" PRId16),
1152 ehdr->e_shnum);
1153 if (ehdr->e_shnum == 0)
1154 {
1155 GElf_Shdr shdr_mem;
1156 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1157 if (shdr != NULL)
1158 printf (_(" (%" PRIu32 " in [0].sh_size)"),
1159 (uint32_t) shdr->sh_size);
1160 else
1161 fputs_unlocked (_(" ([0] not available)"), stdout);
1162 }
1163 fputc_unlocked ('\n', stdout);
1164
1165 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1166 {
1167 GElf_Shdr shdr_mem;
1168 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1169 if (shdr != NULL)
1170 /* We managed to get the zeroth section. */
1171 snprintf (buf, sizeof (buf), _(" (%" PRIu32 " in [0].sh_link)"),
1172 (uint32_t) shdr->sh_link);
1173 else
1174 {
1175 strncpy (buf, _(" ([0] not available)"), sizeof (buf));
1176 buf[sizeof (buf) - 1] = '\0';
1177 }
1178
1179 printf (_(" Section header string table index: XINDEX%s\n\n"),
1180 buf);
1181 }
1182 else
1183 printf (_(" Section header string table index: %" PRId16 "\n\n"),
1184 ehdr->e_shstrndx);
1185 }
1186
1187
1188 static const char *
get_visibility_type(int value)1189 get_visibility_type (int value)
1190 {
1191 switch (value)
1192 {
1193 case STV_DEFAULT:
1194 return "DEFAULT";
1195 case STV_INTERNAL:
1196 return "INTERNAL";
1197 case STV_HIDDEN:
1198 return "HIDDEN";
1199 case STV_PROTECTED:
1200 return "PROTECTED";
1201 default:
1202 return "???";
1203 }
1204 }
1205
1206 static const char *
elf_ch_type_name(unsigned int code)1207 elf_ch_type_name (unsigned int code)
1208 {
1209 if (code == 0)
1210 return "NONE";
1211
1212 if (code == ELFCOMPRESS_ZLIB)
1213 return "ZLIB";
1214
1215 return "UNKNOWN";
1216 }
1217
1218 /* Print the section headers. */
1219 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1220 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1221 {
1222 size_t cnt;
1223 size_t shstrndx;
1224
1225 if (! print_file_header)
1226 {
1227 size_t sections;
1228 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1229 error (EXIT_FAILURE, 0,
1230 _("cannot get number of sections: %s"),
1231 elf_errmsg (-1));
1232
1233 printf (_("\
1234 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1235 \n"),
1236 sections, ehdr->e_shoff);
1237 }
1238
1239 /* Get the section header string table index. */
1240 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1241 error (EXIT_FAILURE, 0,
1242 _("cannot get section header string table index: %s"),
1243 elf_errmsg (-1));
1244
1245 puts (_("Section Headers:"));
1246
1247 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1248 puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1249 else
1250 puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1251
1252 if (print_decompress)
1253 {
1254 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1255 puts (_(" [Compression Size Al]"));
1256 else
1257 puts (_(" [Compression Size Al]"));
1258 }
1259
1260 for (cnt = 0; cnt < shnum; ++cnt)
1261 {
1262 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1263
1264 if (unlikely (scn == NULL))
1265 error (EXIT_FAILURE, 0, _("cannot get section: %s"),
1266 elf_errmsg (-1));
1267
1268 /* Get the section header. */
1269 GElf_Shdr shdr_mem;
1270 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1271 if (unlikely (shdr == NULL))
1272 error (EXIT_FAILURE, 0, _("cannot get section header: %s"),
1273 elf_errmsg (-1));
1274
1275 char flagbuf[20];
1276 char *cp = flagbuf;
1277 if (shdr->sh_flags & SHF_WRITE)
1278 *cp++ = 'W';
1279 if (shdr->sh_flags & SHF_ALLOC)
1280 *cp++ = 'A';
1281 if (shdr->sh_flags & SHF_EXECINSTR)
1282 *cp++ = 'X';
1283 if (shdr->sh_flags & SHF_MERGE)
1284 *cp++ = 'M';
1285 if (shdr->sh_flags & SHF_STRINGS)
1286 *cp++ = 'S';
1287 if (shdr->sh_flags & SHF_INFO_LINK)
1288 *cp++ = 'I';
1289 if (shdr->sh_flags & SHF_LINK_ORDER)
1290 *cp++ = 'L';
1291 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1292 *cp++ = 'N';
1293 if (shdr->sh_flags & SHF_GROUP)
1294 *cp++ = 'G';
1295 if (shdr->sh_flags & SHF_TLS)
1296 *cp++ = 'T';
1297 if (shdr->sh_flags & SHF_COMPRESSED)
1298 *cp++ = 'C';
1299 if (shdr->sh_flags & SHF_ORDERED)
1300 *cp++ = 'O';
1301 if (shdr->sh_flags & SHF_EXCLUDE)
1302 *cp++ = 'E';
1303 if (shdr->sh_flags & SHF_GNU_RETAIN)
1304 *cp++ = 'R';
1305 *cp = '\0';
1306
1307 const char *sname;
1308 char buf[128];
1309 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1310 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1311 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1312 " %2" PRId64 "\n",
1313 cnt, sname,
1314 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1315 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1316 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1317 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1318 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1319 shdr->sh_addralign);
1320
1321 if (print_decompress)
1322 {
1323 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1324 {
1325 GElf_Chdr chdr;
1326 if (gelf_getchdr (scn, &chdr) != NULL)
1327 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1328 " %2" PRId64 "]\n",
1329 elf_ch_type_name (chdr.ch_type),
1330 chdr.ch_type,
1331 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1332 chdr.ch_size, chdr.ch_addralign);
1333 else
1334 error (0, 0,
1335 _("bad compression header for section %zd: %s"),
1336 elf_ndxscn (scn), elf_errmsg (-1));
1337 }
1338 else if (startswith (sname, ".zdebug"))
1339 {
1340 ssize_t size;
1341 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1342 printf (" [GNU ZLIB %0*zx ]\n",
1343 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1344 else
1345 error (0, 0,
1346 _("bad gnu compressed size for section %zd: %s"),
1347 elf_ndxscn (scn), elf_errmsg (-1));
1348 }
1349 }
1350 }
1351
1352 fputc_unlocked ('\n', stdout);
1353 }
1354
1355
1356 /* Print the program header. */
1357 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1358 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1359 {
1360 if (phnum == 0)
1361 /* No program header, this is OK in relocatable objects. */
1362 return;
1363
1364 puts (_("Program Headers:"));
1365 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1366 puts (_("\
1367 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1368 else
1369 puts (_("\
1370 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1371
1372 /* Process all program headers. */
1373 bool has_relro = false;
1374 GElf_Addr relro_from = 0;
1375 GElf_Addr relro_to = 0;
1376 for (size_t cnt = 0; cnt < phnum; ++cnt)
1377 {
1378 char buf[128];
1379 GElf_Phdr mem;
1380 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1381
1382 /* If for some reason the header cannot be returned show this. */
1383 if (unlikely (phdr == NULL))
1384 {
1385 puts (" ???");
1386 continue;
1387 }
1388
1389 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1390 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1391 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1392 phdr->p_offset,
1393 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1394 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1395 phdr->p_filesz,
1396 phdr->p_memsz,
1397 phdr->p_flags & PF_R ? 'R' : ' ',
1398 phdr->p_flags & PF_W ? 'W' : ' ',
1399 phdr->p_flags & PF_X ? 'E' : ' ',
1400 phdr->p_align);
1401
1402 if (phdr->p_type == PT_INTERP)
1403 {
1404 /* If we are sure the file offset is valid then we can show
1405 the user the name of the interpreter. We check whether
1406 there is a section at the file offset. Normally there
1407 would be a section called ".interp". But in separate
1408 .debug files it is a NOBITS section (and so doesn't match
1409 with gelf_offscn). Which probably means the offset is
1410 not valid another reason could be because the ELF file
1411 just doesn't contain any section headers, in that case
1412 just play it safe and don't display anything. */
1413
1414 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1415 GElf_Shdr shdr_mem;
1416 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1417
1418 size_t maxsize;
1419 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1420
1421 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1422 && filedata != NULL && phdr->p_offset < maxsize
1423 && phdr->p_filesz <= maxsize - phdr->p_offset
1424 && memchr (filedata + phdr->p_offset, '\0',
1425 phdr->p_filesz) != NULL)
1426 printf (_("\t[Requesting program interpreter: %s]\n"),
1427 filedata + phdr->p_offset);
1428 }
1429 else if (phdr->p_type == PT_GNU_RELRO)
1430 {
1431 has_relro = true;
1432 relro_from = phdr->p_vaddr;
1433 relro_to = relro_from + phdr->p_memsz;
1434 }
1435 }
1436
1437 size_t sections;
1438 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1439 error (EXIT_FAILURE, 0,
1440 _("cannot get number of sections: %s"),
1441 elf_errmsg (-1));
1442
1443 if (sections == 0)
1444 /* No sections in the file. Punt. */
1445 return;
1446
1447 /* Get the section header string table index. */
1448 size_t shstrndx;
1449 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1450 error (EXIT_FAILURE, 0,
1451 _("cannot get section header string table index"));
1452
1453 puts (_("\n Section to Segment mapping:\n Segment Sections..."));
1454
1455 for (size_t cnt = 0; cnt < phnum; ++cnt)
1456 {
1457 /* Print the segment number. */
1458 printf (" %2.2zu ", cnt);
1459
1460 GElf_Phdr phdr_mem;
1461 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1462 /* This must not happen. */
1463 if (unlikely (phdr == NULL))
1464 error (EXIT_FAILURE, 0, _("cannot get program header: %s"),
1465 elf_errmsg (-1));
1466
1467 /* Iterate over the sections. */
1468 bool in_relro = false;
1469 bool in_ro = false;
1470 for (size_t inner = 1; inner < shnum; ++inner)
1471 {
1472 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1473 /* This should not happen. */
1474 if (unlikely (scn == NULL))
1475 error (EXIT_FAILURE, 0, _("cannot get section: %s"),
1476 elf_errmsg (-1));
1477
1478 /* Get the section header. */
1479 GElf_Shdr shdr_mem;
1480 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1481 if (unlikely (shdr == NULL))
1482 error (EXIT_FAILURE, 0,
1483 _("cannot get section header: %s"),
1484 elf_errmsg (-1));
1485
1486 if (shdr->sh_size > 0
1487 /* Compare allocated sections by VMA, unallocated
1488 sections by file offset. */
1489 && (shdr->sh_flags & SHF_ALLOC
1490 ? (shdr->sh_addr >= phdr->p_vaddr
1491 && (shdr->sh_addr + shdr->sh_size
1492 <= phdr->p_vaddr + phdr->p_memsz))
1493 : (shdr->sh_offset >= phdr->p_offset
1494 && (shdr->sh_offset + shdr->sh_size
1495 <= phdr->p_offset + phdr->p_filesz))))
1496 {
1497 if (has_relro && !in_relro
1498 && shdr->sh_addr >= relro_from
1499 && shdr->sh_addr + shdr->sh_size <= relro_to)
1500 {
1501 fputs_unlocked (" [RELRO:", stdout);
1502 in_relro = true;
1503 }
1504 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1505 {
1506 fputs_unlocked ("]", stdout);
1507 in_relro = false;
1508 }
1509 else if (has_relro && in_relro
1510 && shdr->sh_addr + shdr->sh_size > relro_to)
1511 fputs_unlocked ("] <RELRO:", stdout);
1512 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1513 {
1514 if (!in_ro)
1515 {
1516 fputs_unlocked (" [RO:", stdout);
1517 in_ro = true;
1518 }
1519 }
1520 else
1521 {
1522 /* Determine the segment this section is part of. */
1523 size_t cnt2;
1524 GElf_Phdr phdr2_mem;
1525 GElf_Phdr *phdr2 = NULL;
1526 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1527 {
1528 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1529
1530 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1531 && shdr->sh_addr >= phdr2->p_vaddr
1532 && (shdr->sh_addr + shdr->sh_size
1533 <= phdr2->p_vaddr + phdr2->p_memsz))
1534 break;
1535 }
1536
1537 if (cnt2 < phnum)
1538 {
1539 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1540 {
1541 fputs_unlocked (" [RO:", stdout);
1542 in_ro = true;
1543 }
1544 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1545 {
1546 fputs_unlocked ("]", stdout);
1547 in_ro = false;
1548 }
1549 }
1550 }
1551
1552 printf (" %s",
1553 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1554
1555 /* Signal that this section is only partially covered. */
1556 if (has_relro && in_relro
1557 && shdr->sh_addr + shdr->sh_size > relro_to)
1558 {
1559 fputs_unlocked (">", stdout);
1560 in_relro = false;
1561 }
1562 }
1563 }
1564 if (in_relro || in_ro)
1565 fputs_unlocked ("]", stdout);
1566
1567 /* Finish the line. */
1568 fputc_unlocked ('\n', stdout);
1569 }
1570 }
1571
1572
1573 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1574 section_name (Ebl *ebl, GElf_Shdr *shdr)
1575 {
1576 size_t shstrndx;
1577 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1578 return "???";
1579 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1580 }
1581
1582
1583 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1584 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1585 {
1586 /* Get the data of the section. */
1587 Elf_Data *data = elf_getdata (scn, NULL);
1588
1589 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1590 GElf_Shdr symshdr_mem;
1591 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1592 Elf_Data *symdata = elf_getdata (symscn, NULL);
1593
1594 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1595 || symdata == NULL)
1596 return;
1597
1598 /* Get the section header string table index. */
1599 size_t shstrndx;
1600 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1601 error (EXIT_FAILURE, 0,
1602 _("cannot get section header string table index"));
1603
1604 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1605
1606 GElf_Sym sym_mem;
1607 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1608
1609 printf ((grpref[0] & GRP_COMDAT)
1610 ? ngettext ("\
1611 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1612 "\
1613 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1614 data->d_size / sizeof (Elf32_Word) - 1)
1615 : ngettext ("\
1616 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1617 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1618 data->d_size / sizeof (Elf32_Word) - 1),
1619 elf_ndxscn (scn),
1620 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1621 (sym == NULL ? NULL
1622 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1623 ?: _("<INVALID SYMBOL>"),
1624 data->d_size / sizeof (Elf32_Word) - 1);
1625
1626 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1627 {
1628 GElf_Shdr grpshdr_mem;
1629 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1630 &grpshdr_mem);
1631
1632 const char *str;
1633 printf (" [%2u] %s\n",
1634 grpref[cnt],
1635 grpshdr != NULL
1636 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1637 ? str : _("<INVALID SECTION>"));
1638 }
1639 }
1640
1641
1642 static void
print_scngrp(Ebl * ebl)1643 print_scngrp (Ebl *ebl)
1644 {
1645 /* Find all relocation sections and handle them. */
1646 Elf_Scn *scn = NULL;
1647
1648 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1649 {
1650 /* Handle the section if it is a symbol table. */
1651 GElf_Shdr shdr_mem;
1652 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1653
1654 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1655 {
1656 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1657 {
1658 if (elf_compress (scn, 0, 0) < 0)
1659 printf ("WARNING: %s [%zd]\n",
1660 _("Couldn't uncompress section"),
1661 elf_ndxscn (scn));
1662 shdr = gelf_getshdr (scn, &shdr_mem);
1663 if (unlikely (shdr == NULL))
1664 error (EXIT_FAILURE, 0,
1665 _("cannot get section [%zd] header: %s"),
1666 elf_ndxscn (scn),
1667 elf_errmsg (-1));
1668 }
1669 handle_scngrp (ebl, scn, shdr);
1670 }
1671 }
1672 }
1673
1674
1675 static const struct flags
1676 {
1677 int mask;
1678 const char *str;
1679 } dt_flags[] =
1680 {
1681 { DF_ORIGIN, "ORIGIN" },
1682 { DF_SYMBOLIC, "SYMBOLIC" },
1683 { DF_TEXTREL, "TEXTREL" },
1684 { DF_BIND_NOW, "BIND_NOW" },
1685 { DF_STATIC_TLS, "STATIC_TLS" }
1686 };
1687 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1688
1689 static const struct flags dt_flags_1[] =
1690 {
1691 { DF_1_NOW, "NOW" },
1692 { DF_1_GLOBAL, "GLOBAL" },
1693 { DF_1_GROUP, "GROUP" },
1694 { DF_1_NODELETE, "NODELETE" },
1695 { DF_1_LOADFLTR, "LOADFLTR" },
1696 { DF_1_INITFIRST, "INITFIRST" },
1697 { DF_1_NOOPEN, "NOOPEN" },
1698 { DF_1_ORIGIN, "ORIGIN" },
1699 { DF_1_DIRECT, "DIRECT" },
1700 { DF_1_TRANS, "TRANS" },
1701 { DF_1_INTERPOSE, "INTERPOSE" },
1702 { DF_1_NODEFLIB, "NODEFLIB" },
1703 { DF_1_NODUMP, "NODUMP" },
1704 { DF_1_CONFALT, "CONFALT" },
1705 { DF_1_ENDFILTEE, "ENDFILTEE" },
1706 { DF_1_DISPRELDNE, "DISPRELDNE" },
1707 { DF_1_DISPRELPND, "DISPRELPND" },
1708 };
1709 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1710
1711 static const struct flags dt_feature_1[] =
1712 {
1713 { DTF_1_PARINIT, "PARINIT" },
1714 { DTF_1_CONFEXP, "CONFEXP" }
1715 };
1716 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1717 / sizeof (dt_feature_1[0]));
1718
1719 static const struct flags dt_posflag_1[] =
1720 {
1721 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1722 { DF_P1_GROUPPERM, "GROUPPERM" }
1723 };
1724 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1725 / sizeof (dt_posflag_1[0]));
1726
1727
1728 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1729 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1730 int nflags)
1731 {
1732 bool first = true;
1733 int cnt;
1734
1735 for (cnt = 0; cnt < nflags; ++cnt)
1736 if (d_val & flags[cnt].mask)
1737 {
1738 if (!first)
1739 putchar_unlocked (' ');
1740 fputs_unlocked (flags[cnt].str, stdout);
1741 d_val &= ~flags[cnt].mask;
1742 first = false;
1743 }
1744
1745 if (d_val != 0)
1746 {
1747 if (!first)
1748 putchar_unlocked (' ');
1749 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1750 }
1751
1752 putchar_unlocked ('\n');
1753 }
1754
1755
1756 static void
print_dt_flags(int class,GElf_Xword d_val)1757 print_dt_flags (int class, GElf_Xword d_val)
1758 {
1759 print_flags (class, d_val, dt_flags, ndt_flags);
1760 }
1761
1762
1763 static void
print_dt_flags_1(int class,GElf_Xword d_val)1764 print_dt_flags_1 (int class, GElf_Xword d_val)
1765 {
1766 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1767 }
1768
1769
1770 static void
print_dt_feature_1(int class,GElf_Xword d_val)1771 print_dt_feature_1 (int class, GElf_Xword d_val)
1772 {
1773 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1774 }
1775
1776
1777 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1778 print_dt_posflag_1 (int class, GElf_Xword d_val)
1779 {
1780 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1781 }
1782
1783
1784 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1785 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1786 {
1787 int class = gelf_getclass (ebl->elf);
1788 GElf_Shdr glink_mem;
1789 GElf_Shdr *glink;
1790 Elf_Data *data;
1791 size_t cnt;
1792 size_t shstrndx;
1793 size_t sh_entsize;
1794
1795 /* Get the data of the section. */
1796 data = elf_getdata (scn, NULL);
1797 if (data == NULL)
1798 return;
1799
1800 /* Get the section header string table index. */
1801 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1802 error (EXIT_FAILURE, 0,
1803 _("cannot get section header string table index"));
1804
1805 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1806
1807 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1808 if (glink == NULL)
1809 error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
1810 elf_ndxscn (scn));
1811
1812 printf (ngettext ("\
1813 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1814 "\
1815 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1816 shdr->sh_size / sh_entsize),
1817 (unsigned long int) (shdr->sh_size / sh_entsize),
1818 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1819 shdr->sh_offset,
1820 (int) shdr->sh_link,
1821 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1822 fputs_unlocked (_(" Type Value\n"), stdout);
1823
1824 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1825 {
1826 GElf_Dyn dynmem;
1827 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1828 if (dyn == NULL)
1829 break;
1830
1831 char buf[64];
1832 printf (" %-17s ",
1833 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1834
1835 switch (dyn->d_tag)
1836 {
1837 case DT_NULL:
1838 case DT_DEBUG:
1839 case DT_BIND_NOW:
1840 case DT_TEXTREL:
1841 /* No further output. */
1842 fputc_unlocked ('\n', stdout);
1843 break;
1844
1845 case DT_NEEDED:
1846 printf (_("Shared library: [%s]\n"),
1847 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1848 break;
1849
1850 case DT_SONAME:
1851 printf (_("Library soname: [%s]\n"),
1852 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1853 break;
1854
1855 case DT_RPATH:
1856 printf (_("Library rpath: [%s]\n"),
1857 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1858 break;
1859
1860 case DT_RUNPATH:
1861 printf (_("Library runpath: [%s]\n"),
1862 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1863 break;
1864
1865 case DT_PLTRELSZ:
1866 case DT_RELASZ:
1867 case DT_STRSZ:
1868 case DT_RELSZ:
1869 case DT_RELAENT:
1870 case DT_SYMENT:
1871 case DT_RELENT:
1872 case DT_PLTPADSZ:
1873 case DT_MOVEENT:
1874 case DT_MOVESZ:
1875 case DT_INIT_ARRAYSZ:
1876 case DT_FINI_ARRAYSZ:
1877 case DT_SYMINSZ:
1878 case DT_SYMINENT:
1879 case DT_GNU_CONFLICTSZ:
1880 case DT_GNU_LIBLISTSZ:
1881 printf (_("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1882 break;
1883
1884 case DT_VERDEFNUM:
1885 case DT_VERNEEDNUM:
1886 case DT_RELACOUNT:
1887 case DT_RELCOUNT:
1888 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1889 break;
1890
1891 case DT_PLTREL:;
1892 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1893 NULL, 0);
1894 puts (tagname ?: "???");
1895 break;
1896
1897 case DT_FLAGS:
1898 print_dt_flags (class, dyn->d_un.d_val);
1899 break;
1900
1901 case DT_FLAGS_1:
1902 print_dt_flags_1 (class, dyn->d_un.d_val);
1903 break;
1904
1905 case DT_FEATURE_1:
1906 print_dt_feature_1 (class, dyn->d_un.d_val);
1907 break;
1908
1909 case DT_POSFLAG_1:
1910 print_dt_posflag_1 (class, dyn->d_un.d_val);
1911 break;
1912
1913 default:
1914 printf ("%#0*" PRIx64 "\n",
1915 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1916 break;
1917 }
1918 }
1919 }
1920
1921
1922 /* Print the dynamic segment. */
1923 static void
print_dynamic(Ebl * ebl)1924 print_dynamic (Ebl *ebl)
1925 {
1926 for (size_t i = 0; i < phnum; ++i)
1927 {
1928 GElf_Phdr phdr_mem;
1929 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1930
1931 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1932 {
1933 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1934 GElf_Shdr shdr_mem;
1935 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1936 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1937 handle_dynamic (ebl, scn, shdr);
1938 break;
1939 }
1940 }
1941 }
1942
1943
1944 /* Print relocations. */
1945 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1946 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1947 {
1948 /* Find all relocation sections and handle them. */
1949 Elf_Scn *scn = NULL;
1950
1951 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1952 {
1953 /* Handle the section if it is a symbol table. */
1954 GElf_Shdr shdr_mem;
1955 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1956
1957 if (likely (shdr != NULL))
1958 {
1959 if (shdr->sh_type == SHT_REL)
1960 handle_relocs_rel (ebl, ehdr, scn, shdr);
1961 else if (shdr->sh_type == SHT_RELA)
1962 handle_relocs_rela (ebl, ehdr, scn, shdr);
1963 }
1964 }
1965 }
1966
1967
1968 /* Handle a relocation section. */
1969 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1970 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1971 {
1972 int class = gelf_getclass (ebl->elf);
1973 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1974 int nentries = shdr->sh_size / sh_entsize;
1975
1976 /* Get the data of the section. */
1977 Elf_Data *data = elf_getdata (scn, NULL);
1978 if (data == NULL)
1979 return;
1980
1981 /* Get the symbol table information. */
1982 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1983 GElf_Shdr symshdr_mem;
1984 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1985 Elf_Data *symdata = elf_getdata (symscn, NULL);
1986
1987 /* Get the section header of the section the relocations are for. */
1988 GElf_Shdr destshdr_mem;
1989 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1990 &destshdr_mem);
1991
1992 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1993 {
1994 printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1995 shdr->sh_offset);
1996 return;
1997 }
1998
1999 /* Search for the optional extended section index table. */
2000 Elf_Data *xndxdata = NULL;
2001 int xndxscnidx = elf_scnshndx (scn);
2002 if (unlikely (xndxscnidx > 0))
2003 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2004
2005 /* Get the section header string table index. */
2006 size_t shstrndx;
2007 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2008 error (EXIT_FAILURE, 0,
2009 _("cannot get section header string table index"));
2010
2011 if (shdr->sh_info != 0)
2012 printf (ngettext ("\
2013 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2014 "\
2015 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2016 nentries),
2017 elf_ndxscn (scn),
2018 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2019 (unsigned int) shdr->sh_info,
2020 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2021 shdr->sh_offset,
2022 nentries);
2023 else
2024 /* The .rel.dyn section does not refer to a specific section but
2025 instead of section index zero. Do not try to print a section
2026 name. */
2027 printf (ngettext ("\
2028 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2029 "\
2030 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2031 nentries),
2032 (unsigned int) elf_ndxscn (scn),
2033 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2034 shdr->sh_offset,
2035 nentries);
2036 fputs_unlocked (class == ELFCLASS32
2037 ? _("\
2038 Offset Type Value Name\n")
2039 : _("\
2040 Offset Type Value Name\n"),
2041 stdout);
2042
2043 int is_statically_linked = 0;
2044 for (int cnt = 0; cnt < nentries; ++cnt)
2045 {
2046 GElf_Rel relmem;
2047 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2048 if (likely (rel != NULL))
2049 {
2050 char buf[128];
2051 GElf_Sym symmem;
2052 Elf32_Word xndx;
2053 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2054 GELF_R_SYM (rel->r_info),
2055 &symmem, &xndx);
2056 if (unlikely (sym == NULL))
2057 {
2058 /* As a special case we have to handle relocations in static
2059 executables. This only happens for IRELATIVE relocations
2060 (so far). There is no symbol table. */
2061 if (is_statically_linked == 0)
2062 {
2063 /* Find the program header and look for a PT_INTERP entry. */
2064 is_statically_linked = -1;
2065 if (ehdr->e_type == ET_EXEC)
2066 {
2067 is_statically_linked = 1;
2068
2069 for (size_t inner = 0; inner < phnum; ++inner)
2070 {
2071 GElf_Phdr phdr_mem;
2072 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2073 &phdr_mem);
2074 if (phdr != NULL && phdr->p_type == PT_INTERP)
2075 {
2076 is_statically_linked = -1;
2077 break;
2078 }
2079 }
2080 }
2081 }
2082
2083 if (is_statically_linked > 0 && shdr->sh_link == 0)
2084 printf ("\
2085 %#0*" PRIx64 " %-20s %*s %s\n",
2086 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2087 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2088 /* Avoid the leading R_ which isn't carrying any
2089 information. */
2090 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2091 buf, sizeof (buf)) + 2
2092 : _("<INVALID RELOC>"),
2093 class == ELFCLASS32 ? 10 : 18, "",
2094 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2095 else
2096 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2097 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2098 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2099 /* Avoid the leading R_ which isn't carrying any
2100 information. */
2101 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2102 buf, sizeof (buf)) + 2
2103 : _("<INVALID RELOC>"),
2104 _("INVALID SYMBOL"),
2105 (long int) GELF_R_SYM (rel->r_info));
2106 }
2107 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2108 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2109 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2110 likely (ebl_reloc_type_check (ebl,
2111 GELF_R_TYPE (rel->r_info)))
2112 /* Avoid the leading R_ which isn't carrying any
2113 information. */
2114 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2115 buf, sizeof (buf)) + 2
2116 : _("<INVALID RELOC>"),
2117 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2118 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2119 else
2120 {
2121 /* This is a relocation against a STT_SECTION symbol. */
2122 GElf_Shdr secshdr_mem;
2123 GElf_Shdr *secshdr;
2124 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2125 sym->st_shndx == SHN_XINDEX
2126 ? xndx : sym->st_shndx),
2127 &secshdr_mem);
2128
2129 if (unlikely (secshdr == NULL))
2130 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2131 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2132 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2133 /* Avoid the leading R_ which isn't carrying any
2134 information. */
2135 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2136 buf, sizeof (buf)) + 2
2137 : _("<INVALID RELOC>"),
2138 _("INVALID SECTION"),
2139 (long int) (sym->st_shndx == SHN_XINDEX
2140 ? xndx : sym->st_shndx));
2141 else
2142 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2143 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2144 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2145 /* Avoid the leading R_ which isn't carrying any
2146 information. */
2147 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2148 buf, sizeof (buf)) + 2
2149 : _("<INVALID RELOC>"),
2150 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2151 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2152 }
2153 }
2154 }
2155 }
2156
2157
2158 /* Handle a relocation section. */
2159 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2160 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2161 {
2162 int class = gelf_getclass (ebl->elf);
2163 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2164 int nentries = shdr->sh_size / sh_entsize;
2165
2166 /* Get the data of the section. */
2167 Elf_Data *data = elf_getdata (scn, NULL);
2168 if (data == NULL)
2169 return;
2170
2171 /* Get the symbol table information. */
2172 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2173 GElf_Shdr symshdr_mem;
2174 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2175 Elf_Data *symdata = elf_getdata (symscn, NULL);
2176
2177 /* Get the section header of the section the relocations are for. */
2178 GElf_Shdr destshdr_mem;
2179 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2180 &destshdr_mem);
2181
2182 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2183 {
2184 printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2185 shdr->sh_offset);
2186 return;
2187 }
2188
2189 /* Search for the optional extended section index table. */
2190 Elf_Data *xndxdata = NULL;
2191 int xndxscnidx = elf_scnshndx (scn);
2192 if (unlikely (xndxscnidx > 0))
2193 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2194
2195 /* Get the section header string table index. */
2196 size_t shstrndx;
2197 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2198 error (EXIT_FAILURE, 0,
2199 _("cannot get section header string table index"));
2200
2201 if (shdr->sh_info != 0)
2202 printf (ngettext ("\
2203 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2204 "\
2205 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2206 nentries),
2207 elf_ndxscn (scn),
2208 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2209 (unsigned int) shdr->sh_info,
2210 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2211 shdr->sh_offset,
2212 nentries);
2213 else
2214 /* The .rela.dyn section does not refer to a specific section but
2215 instead of section index zero. Do not try to print a section
2216 name. */
2217 printf (ngettext ("\
2218 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2219 "\
2220 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2221 nentries),
2222 (unsigned int) elf_ndxscn (scn),
2223 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2224 shdr->sh_offset,
2225 nentries);
2226 fputs_unlocked (class == ELFCLASS32
2227 ? _("\
2228 Offset Type Value Addend Name\n")
2229 : _("\
2230 Offset Type Value Addend Name\n"),
2231 stdout);
2232
2233 int is_statically_linked = 0;
2234 for (int cnt = 0; cnt < nentries; ++cnt)
2235 {
2236 GElf_Rela relmem;
2237 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2238 if (likely (rel != NULL))
2239 {
2240 char buf[64];
2241 GElf_Sym symmem;
2242 Elf32_Word xndx;
2243 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2244 GELF_R_SYM (rel->r_info),
2245 &symmem, &xndx);
2246
2247 if (unlikely (sym == NULL))
2248 {
2249 /* As a special case we have to handle relocations in static
2250 executables. This only happens for IRELATIVE relocations
2251 (so far). There is no symbol table. */
2252 if (is_statically_linked == 0)
2253 {
2254 /* Find the program header and look for a PT_INTERP entry. */
2255 is_statically_linked = -1;
2256 if (ehdr->e_type == ET_EXEC)
2257 {
2258 is_statically_linked = 1;
2259
2260 for (size_t inner = 0; inner < phnum; ++inner)
2261 {
2262 GElf_Phdr phdr_mem;
2263 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2264 &phdr_mem);
2265 if (phdr != NULL && phdr->p_type == PT_INTERP)
2266 {
2267 is_statically_linked = -1;
2268 break;
2269 }
2270 }
2271 }
2272 }
2273
2274 if (is_statically_linked > 0 && shdr->sh_link == 0)
2275 printf ("\
2276 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2277 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2278 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2279 /* Avoid the leading R_ which isn't carrying any
2280 information. */
2281 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2282 buf, sizeof (buf)) + 2
2283 : _("<INVALID RELOC>"),
2284 class == ELFCLASS32 ? 10 : 18, "",
2285 rel->r_addend,
2286 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2287 else
2288 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2289 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2290 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2291 /* Avoid the leading R_ which isn't carrying any
2292 information. */
2293 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2294 buf, sizeof (buf)) + 2
2295 : _("<INVALID RELOC>"),
2296 _("INVALID SYMBOL"),
2297 (long int) GELF_R_SYM (rel->r_info));
2298 }
2299 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2300 printf ("\
2301 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2302 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2303 likely (ebl_reloc_type_check (ebl,
2304 GELF_R_TYPE (rel->r_info)))
2305 /* Avoid the leading R_ which isn't carrying any
2306 information. */
2307 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2308 buf, sizeof (buf)) + 2
2309 : _("<INVALID RELOC>"),
2310 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2311 rel->r_addend,
2312 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2313 else
2314 {
2315 /* This is a relocation against a STT_SECTION symbol. */
2316 GElf_Shdr secshdr_mem;
2317 GElf_Shdr *secshdr;
2318 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2319 sym->st_shndx == SHN_XINDEX
2320 ? xndx : sym->st_shndx),
2321 &secshdr_mem);
2322
2323 if (unlikely (secshdr == NULL))
2324 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2325 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2326 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2327 /* Avoid the leading R_ which isn't carrying any
2328 information. */
2329 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2330 buf, sizeof (buf)) + 2
2331 : _("<INVALID RELOC>"),
2332 _("INVALID SECTION"),
2333 (long int) (sym->st_shndx == SHN_XINDEX
2334 ? xndx : sym->st_shndx));
2335 else
2336 printf ("\
2337 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2338 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2339 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2340 /* Avoid the leading R_ which isn't carrying any
2341 information. */
2342 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2343 buf, sizeof (buf)) + 2
2344 : _("<INVALID RELOC>"),
2345 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2346 rel->r_addend,
2347 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2348 }
2349 }
2350 }
2351 }
2352
2353
2354 /* Print the program header. */
2355 static void
print_symtab(Ebl * ebl,int type)2356 print_symtab (Ebl *ebl, int type)
2357 {
2358 /* Find the symbol table(s). For this we have to search through the
2359 section table. */
2360 Elf_Scn *scn = NULL;
2361
2362 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2363 {
2364 /* Handle the section if it is a symbol table. */
2365 GElf_Shdr shdr_mem;
2366 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2367
2368 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2369 {
2370 if (symbol_table_section != NULL)
2371 {
2372 /* Get the section header string table index. */
2373 size_t shstrndx;
2374 const char *sname;
2375 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2376 error (EXIT_FAILURE, 0,
2377 _("cannot get section header string table index"));
2378 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2379 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2380 continue;
2381 }
2382
2383 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2384 {
2385 if (elf_compress (scn, 0, 0) < 0)
2386 printf ("WARNING: %s [%zd]\n",
2387 _("Couldn't uncompress section"),
2388 elf_ndxscn (scn));
2389 shdr = gelf_getshdr (scn, &shdr_mem);
2390 if (unlikely (shdr == NULL))
2391 error (EXIT_FAILURE, 0,
2392 _("cannot get section [%zd] header: %s"),
2393 elf_ndxscn (scn), elf_errmsg (-1));
2394 }
2395 handle_symtab (ebl, scn, shdr);
2396 }
2397 }
2398 }
2399
2400
2401 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2402 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2403 {
2404 Elf_Data *versym_data = NULL;
2405 Elf_Data *verneed_data = NULL;
2406 Elf_Data *verdef_data = NULL;
2407 Elf_Data *xndx_data = NULL;
2408 int class = gelf_getclass (ebl->elf);
2409 Elf32_Word verneed_stridx = 0;
2410 Elf32_Word verdef_stridx = 0;
2411
2412 /* Get the data of the section. */
2413 Elf_Data *data = elf_getdata (scn, NULL);
2414 if (data == NULL)
2415 return;
2416
2417 /* Find out whether we have other sections we might need. */
2418 Elf_Scn *runscn = NULL;
2419 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2420 {
2421 GElf_Shdr runshdr_mem;
2422 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2423
2424 if (likely (runshdr != NULL))
2425 {
2426 if (runshdr->sh_type == SHT_GNU_versym
2427 && runshdr->sh_link == elf_ndxscn (scn))
2428 /* Bingo, found the version information. Now get the data. */
2429 versym_data = elf_getdata (runscn, NULL);
2430 else if (runshdr->sh_type == SHT_GNU_verneed)
2431 {
2432 /* This is the information about the needed versions. */
2433 verneed_data = elf_getdata (runscn, NULL);
2434 verneed_stridx = runshdr->sh_link;
2435 }
2436 else if (runshdr->sh_type == SHT_GNU_verdef)
2437 {
2438 /* This is the information about the defined versions. */
2439 verdef_data = elf_getdata (runscn, NULL);
2440 verdef_stridx = runshdr->sh_link;
2441 }
2442 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2443 && runshdr->sh_link == elf_ndxscn (scn))
2444 /* Extended section index. */
2445 xndx_data = elf_getdata (runscn, NULL);
2446 }
2447 }
2448
2449 /* Get the section header string table index. */
2450 size_t shstrndx;
2451 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2452 error (EXIT_FAILURE, 0,
2453 _("cannot get section header string table index"));
2454
2455 GElf_Shdr glink_mem;
2456 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2457 &glink_mem);
2458 if (glink == NULL)
2459 error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
2460 elf_ndxscn (scn));
2461
2462 /* Now we can compute the number of entries in the section. */
2463 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2464 ? sizeof (Elf32_Sym)
2465 : sizeof (Elf64_Sym));
2466
2467 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2468 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2469 nsyms),
2470 (unsigned int) elf_ndxscn (scn),
2471 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2472 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2473 " %lu local symbols String table: [%2u] '%s'\n",
2474 shdr->sh_info),
2475 (unsigned long int) shdr->sh_info,
2476 (unsigned int) shdr->sh_link,
2477 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2478
2479 fputs_unlocked (class == ELFCLASS32
2480 ? _("\
2481 Num: Value Size Type Bind Vis Ndx Name\n")
2482 : _("\
2483 Num: Value Size Type Bind Vis Ndx Name\n"),
2484 stdout);
2485
2486 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2487 {
2488 char typebuf[64];
2489 char bindbuf[64];
2490 char scnbuf[64];
2491 Elf32_Word xndx;
2492 GElf_Sym sym_mem;
2493 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2494
2495 if (unlikely (sym == NULL))
2496 continue;
2497
2498 /* Determine the real section index. */
2499 if (likely (sym->st_shndx != SHN_XINDEX))
2500 xndx = sym->st_shndx;
2501
2502 printf (_("\
2503 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2504 cnt,
2505 class == ELFCLASS32 ? 8 : 16,
2506 sym->st_value,
2507 sym->st_size,
2508 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2509 typebuf, sizeof (typebuf)),
2510 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2511 bindbuf, sizeof (bindbuf)),
2512 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2513 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2514 sizeof (scnbuf), NULL, shnum),
2515 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2516
2517 if (versym_data != NULL)
2518 {
2519 /* Get the version information. */
2520 GElf_Versym versym_mem;
2521 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2522
2523 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2524 {
2525 bool is_nobits = false;
2526 bool check_def = xndx != SHN_UNDEF;
2527
2528 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2529 {
2530 GElf_Shdr symshdr_mem;
2531 GElf_Shdr *symshdr =
2532 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2533
2534 is_nobits = (symshdr != NULL
2535 && symshdr->sh_type == SHT_NOBITS);
2536 }
2537
2538 if (is_nobits || ! check_def)
2539 {
2540 /* We must test both. */
2541 GElf_Vernaux vernaux_mem;
2542 GElf_Vernaux *vernaux = NULL;
2543 size_t vn_offset = 0;
2544
2545 GElf_Verneed verneed_mem;
2546 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2547 &verneed_mem);
2548 while (verneed != NULL)
2549 {
2550 size_t vna_offset = vn_offset;
2551
2552 vernaux = gelf_getvernaux (verneed_data,
2553 vna_offset += verneed->vn_aux,
2554 &vernaux_mem);
2555 while (vernaux != NULL
2556 && vernaux->vna_other != *versym
2557 && vernaux->vna_next != 0
2558 && (verneed_data->d_size - vna_offset
2559 >= vernaux->vna_next))
2560 {
2561 /* Update the offset. */
2562 vna_offset += vernaux->vna_next;
2563
2564 vernaux = (vernaux->vna_next == 0
2565 ? NULL
2566 : gelf_getvernaux (verneed_data,
2567 vna_offset,
2568 &vernaux_mem));
2569 }
2570
2571 /* Check whether we found the version. */
2572 if (vernaux != NULL && vernaux->vna_other == *versym)
2573 /* Found it. */
2574 break;
2575
2576 if (verneed_data->d_size - vn_offset < verneed->vn_next)
2577 break;
2578
2579 vn_offset += verneed->vn_next;
2580 verneed = (verneed->vn_next == 0
2581 ? NULL
2582 : gelf_getverneed (verneed_data, vn_offset,
2583 &verneed_mem));
2584 }
2585
2586 if (vernaux != NULL && vernaux->vna_other == *versym)
2587 {
2588 printf ("@%s (%u)",
2589 elf_strptr (ebl->elf, verneed_stridx,
2590 vernaux->vna_name),
2591 (unsigned int) vernaux->vna_other);
2592 check_def = 0;
2593 }
2594 else if (unlikely (! is_nobits))
2595 error (0, 0, _("bad dynamic symbol"));
2596 else
2597 check_def = 1;
2598 }
2599
2600 if (check_def && *versym != 0x8001)
2601 {
2602 /* We must test both. */
2603 size_t vd_offset = 0;
2604
2605 GElf_Verdef verdef_mem;
2606 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2607 &verdef_mem);
2608 while (verdef != NULL)
2609 {
2610 if (verdef->vd_ndx == (*versym & 0x7fff))
2611 /* Found the definition. */
2612 break;
2613
2614 if (verdef_data->d_size - vd_offset < verdef->vd_next)
2615 break;
2616
2617 vd_offset += verdef->vd_next;
2618 verdef = (verdef->vd_next == 0
2619 ? NULL
2620 : gelf_getverdef (verdef_data, vd_offset,
2621 &verdef_mem));
2622 }
2623
2624 if (verdef != NULL)
2625 {
2626 GElf_Verdaux verdaux_mem;
2627 GElf_Verdaux *verdaux
2628 = gelf_getverdaux (verdef_data,
2629 vd_offset + verdef->vd_aux,
2630 &verdaux_mem);
2631
2632 if (verdaux != NULL)
2633 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2634 elf_strptr (ebl->elf, verdef_stridx,
2635 verdaux->vda_name));
2636 }
2637 }
2638 }
2639 }
2640
2641 putchar_unlocked ('\n');
2642 }
2643 }
2644
2645
2646 /* Print version information. */
2647 static void
print_verinfo(Ebl * ebl)2648 print_verinfo (Ebl *ebl)
2649 {
2650 /* Find the version information sections. For this we have to
2651 search through the section table. */
2652 Elf_Scn *scn = NULL;
2653
2654 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2655 {
2656 /* Handle the section if it is part of the versioning handling. */
2657 GElf_Shdr shdr_mem;
2658 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2659
2660 if (likely (shdr != NULL))
2661 {
2662 if (shdr->sh_type == SHT_GNU_verneed)
2663 handle_verneed (ebl, scn, shdr);
2664 else if (shdr->sh_type == SHT_GNU_verdef)
2665 handle_verdef (ebl, scn, shdr);
2666 else if (shdr->sh_type == SHT_GNU_versym)
2667 handle_versym (ebl, scn, shdr);
2668 }
2669 }
2670 }
2671
2672
2673 static const char *
get_ver_flags(unsigned int flags)2674 get_ver_flags (unsigned int flags)
2675 {
2676 static char buf[32];
2677 char *endp;
2678
2679 if (flags == 0)
2680 return _("none");
2681
2682 if (flags & VER_FLG_BASE)
2683 endp = stpcpy (buf, "BASE ");
2684 else
2685 endp = buf;
2686
2687 if (flags & VER_FLG_WEAK)
2688 {
2689 if (endp != buf)
2690 endp = stpcpy (endp, "| ");
2691
2692 endp = stpcpy (endp, "WEAK ");
2693 }
2694
2695 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2696 {
2697 strncpy (endp, _("| <unknown>"), buf + sizeof (buf) - endp);
2698 buf[sizeof (buf) - 1] = '\0';
2699 }
2700
2701 return buf;
2702 }
2703
2704
2705 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2706 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2707 {
2708 int class = gelf_getclass (ebl->elf);
2709
2710 /* Get the data of the section. */
2711 Elf_Data *data = elf_getdata (scn, NULL);
2712 if (data == NULL)
2713 return;
2714
2715 /* Get the section header string table index. */
2716 size_t shstrndx;
2717 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2718 error (EXIT_FAILURE, 0,
2719 _("cannot get section header string table index"));
2720
2721 GElf_Shdr glink_mem;
2722 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2723 &glink_mem);
2724 if (glink == NULL)
2725 error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
2726 elf_ndxscn (scn));
2727
2728 printf (ngettext ("\
2729 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2730 "\
2731 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2732 shdr->sh_info),
2733 (unsigned int) elf_ndxscn (scn),
2734 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2735 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2736 shdr->sh_offset,
2737 (unsigned int) shdr->sh_link,
2738 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2739
2740 unsigned int offset = 0;
2741 for (int cnt = shdr->sh_info; --cnt >= 0; )
2742 {
2743 /* Get the data at the next offset. */
2744 GElf_Verneed needmem;
2745 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2746 if (unlikely (need == NULL))
2747 break;
2748
2749 printf (_(" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2750 offset, (unsigned short int) need->vn_version,
2751 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2752 (unsigned short int) need->vn_cnt);
2753
2754 unsigned int auxoffset = offset + need->vn_aux;
2755 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2756 {
2757 GElf_Vernaux auxmem;
2758 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2759 if (unlikely (aux == NULL))
2760 break;
2761
2762 printf (_(" %#06x: Name: %s Flags: %s Version: %hu\n"),
2763 auxoffset,
2764 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2765 get_ver_flags (aux->vna_flags),
2766 (unsigned short int) aux->vna_other);
2767
2768 if (aux->vna_next == 0)
2769 break;
2770
2771 auxoffset += aux->vna_next;
2772 }
2773
2774 /* Find the next offset. */
2775 if (need->vn_next == 0)
2776 break;
2777
2778 offset += need->vn_next;
2779 }
2780 }
2781
2782
2783 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2784 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2785 {
2786 /* Get the data of the section. */
2787 Elf_Data *data = elf_getdata (scn, NULL);
2788 if (data == NULL)
2789 return;
2790
2791 /* Get the section header string table index. */
2792 size_t shstrndx;
2793 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2794 error (EXIT_FAILURE, 0,
2795 _("cannot get section header string table index"));
2796
2797 GElf_Shdr glink_mem;
2798 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2799 &glink_mem);
2800 if (glink == NULL)
2801 error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
2802 elf_ndxscn (scn));
2803
2804 int class = gelf_getclass (ebl->elf);
2805 printf (ngettext ("\
2806 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2807 "\
2808 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2809 shdr->sh_info),
2810 (unsigned int) elf_ndxscn (scn),
2811 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2812 shdr->sh_info,
2813 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2814 shdr->sh_offset,
2815 (unsigned int) shdr->sh_link,
2816 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2817
2818 unsigned int offset = 0;
2819 for (int cnt = shdr->sh_info; --cnt >= 0; )
2820 {
2821 /* Get the data at the next offset. */
2822 GElf_Verdef defmem;
2823 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2824 if (unlikely (def == NULL))
2825 break;
2826
2827 unsigned int auxoffset = offset + def->vd_aux;
2828 GElf_Verdaux auxmem;
2829 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2830 if (unlikely (aux == NULL))
2831 break;
2832
2833 printf (_("\
2834 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2835 offset, def->vd_version,
2836 get_ver_flags (def->vd_flags),
2837 def->vd_ndx,
2838 def->vd_cnt,
2839 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2840
2841 auxoffset += aux->vda_next;
2842 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2843 {
2844 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2845 if (unlikely (aux == NULL))
2846 break;
2847
2848 printf (_(" %#06x: Parent %d: %s\n"),
2849 auxoffset, cnt2,
2850 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2851
2852 if (aux->vda_next == 0)
2853 break;
2854
2855 auxoffset += aux->vda_next;
2856 }
2857
2858 /* Find the next offset. */
2859 if (def->vd_next == 0)
2860 break;
2861 offset += def->vd_next;
2862 }
2863 }
2864
2865
2866 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2867 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2868 {
2869 int class = gelf_getclass (ebl->elf);
2870 const char **vername;
2871 const char **filename;
2872
2873 /* Get the data of the section. */
2874 Elf_Data *data = elf_getdata (scn, NULL);
2875 if (data == NULL)
2876 return;
2877
2878 /* Get the section header string table index. */
2879 size_t shstrndx;
2880 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2881 error (EXIT_FAILURE, 0,
2882 _("cannot get section header string table index"));
2883
2884 /* We have to find the version definition section and extract the
2885 version names. */
2886 Elf_Scn *defscn = NULL;
2887 Elf_Scn *needscn = NULL;
2888
2889 Elf_Scn *verscn = NULL;
2890 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2891 {
2892 GElf_Shdr vershdr_mem;
2893 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2894
2895 if (likely (vershdr != NULL))
2896 {
2897 if (vershdr->sh_type == SHT_GNU_verdef)
2898 defscn = verscn;
2899 else if (vershdr->sh_type == SHT_GNU_verneed)
2900 needscn = verscn;
2901 }
2902 }
2903
2904 size_t nvername;
2905 if (defscn != NULL || needscn != NULL)
2906 {
2907 /* We have a version information (better should have). Now get
2908 the version names. First find the maximum version number. */
2909 nvername = 0;
2910 if (defscn != NULL)
2911 {
2912 /* Run through the version definitions and find the highest
2913 index. */
2914 unsigned int offset = 0;
2915 Elf_Data *defdata;
2916 GElf_Shdr defshdrmem;
2917 GElf_Shdr *defshdr;
2918
2919 defdata = elf_getdata (defscn, NULL);
2920 if (unlikely (defdata == NULL))
2921 return;
2922
2923 defshdr = gelf_getshdr (defscn, &defshdrmem);
2924 if (unlikely (defshdr == NULL))
2925 return;
2926
2927 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2928 {
2929 GElf_Verdef defmem;
2930 GElf_Verdef *def;
2931
2932 /* Get the data at the next offset. */
2933 def = gelf_getverdef (defdata, offset, &defmem);
2934 if (unlikely (def == NULL))
2935 break;
2936
2937 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2938
2939 if (def->vd_next == 0)
2940 break;
2941 offset += def->vd_next;
2942 }
2943 }
2944 if (needscn != NULL)
2945 {
2946 unsigned int offset = 0;
2947 Elf_Data *needdata;
2948 GElf_Shdr needshdrmem;
2949 GElf_Shdr *needshdr;
2950
2951 needdata = elf_getdata (needscn, NULL);
2952 if (unlikely (needdata == NULL))
2953 return;
2954
2955 needshdr = gelf_getshdr (needscn, &needshdrmem);
2956 if (unlikely (needshdr == NULL))
2957 return;
2958
2959 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2960 {
2961 GElf_Verneed needmem;
2962 GElf_Verneed *need;
2963 unsigned int auxoffset;
2964 int cnt2;
2965
2966 /* Get the data at the next offset. */
2967 need = gelf_getverneed (needdata, offset, &needmem);
2968 if (unlikely (need == NULL))
2969 break;
2970
2971 /* Run through the auxiliary entries. */
2972 auxoffset = offset + need->vn_aux;
2973 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2974 {
2975 GElf_Vernaux auxmem;
2976 GElf_Vernaux *aux;
2977
2978 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2979 if (unlikely (aux == NULL))
2980 break;
2981
2982 nvername = MAX (nvername,
2983 (size_t) (aux->vna_other & 0x7fff));
2984
2985 if (aux->vna_next == 0)
2986 break;
2987 auxoffset += aux->vna_next;
2988 }
2989
2990 if (need->vn_next == 0)
2991 break;
2992 offset += need->vn_next;
2993 }
2994 }
2995
2996 /* This is the number of versions we know about. */
2997 ++nvername;
2998
2999 /* Allocate the array. */
3000 vername = (const char **) alloca (nvername * sizeof (const char *));
3001 memset(vername, 0, nvername * sizeof (const char *));
3002 filename = (const char **) alloca (nvername * sizeof (const char *));
3003 memset(filename, 0, nvername * sizeof (const char *));
3004
3005 /* Run through the data structures again and collect the strings. */
3006 if (defscn != NULL)
3007 {
3008 /* Run through the version definitions and find the highest
3009 index. */
3010 unsigned int offset = 0;
3011 Elf_Data *defdata;
3012 GElf_Shdr defshdrmem;
3013 GElf_Shdr *defshdr;
3014
3015 defdata = elf_getdata (defscn, NULL);
3016 if (unlikely (defdata == NULL))
3017 return;
3018
3019 defshdr = gelf_getshdr (defscn, &defshdrmem);
3020 if (unlikely (defshdr == NULL))
3021 return;
3022
3023 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3024 {
3025
3026 /* Get the data at the next offset. */
3027 GElf_Verdef defmem;
3028 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3029 if (unlikely (def == NULL))
3030 break;
3031
3032 GElf_Verdaux auxmem;
3033 GElf_Verdaux *aux = gelf_getverdaux (defdata,
3034 offset + def->vd_aux,
3035 &auxmem);
3036 if (unlikely (aux == NULL))
3037 break;
3038
3039 vername[def->vd_ndx & 0x7fff]
3040 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3041 filename[def->vd_ndx & 0x7fff] = NULL;
3042
3043 if (def->vd_next == 0)
3044 break;
3045 offset += def->vd_next;
3046 }
3047 }
3048 if (needscn != NULL)
3049 {
3050 unsigned int offset = 0;
3051
3052 Elf_Data *needdata = elf_getdata (needscn, NULL);
3053 GElf_Shdr needshdrmem;
3054 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3055 if (unlikely (needdata == NULL || needshdr == NULL))
3056 return;
3057
3058 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3059 {
3060 /* Get the data at the next offset. */
3061 GElf_Verneed needmem;
3062 GElf_Verneed *need = gelf_getverneed (needdata, offset,
3063 &needmem);
3064 if (unlikely (need == NULL))
3065 break;
3066
3067 /* Run through the auxiliary entries. */
3068 unsigned int auxoffset = offset + need->vn_aux;
3069 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3070 {
3071 GElf_Vernaux auxmem;
3072 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3073 &auxmem);
3074 if (unlikely (aux == NULL))
3075 break;
3076
3077 vername[aux->vna_other & 0x7fff]
3078 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3079 filename[aux->vna_other & 0x7fff]
3080 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3081
3082 if (aux->vna_next == 0)
3083 break;
3084 auxoffset += aux->vna_next;
3085 }
3086
3087 if (need->vn_next == 0)
3088 break;
3089 offset += need->vn_next;
3090 }
3091 }
3092 }
3093 else
3094 {
3095 vername = NULL;
3096 nvername = 1;
3097 filename = NULL;
3098 }
3099
3100 GElf_Shdr glink_mem;
3101 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3102 &glink_mem);
3103 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3104 if (glink == NULL)
3105 error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
3106 elf_ndxscn (scn));
3107
3108 /* Print the header. */
3109 printf (ngettext ("\
3110 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3111 "\
3112 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3113 shdr->sh_size / sh_entsize),
3114 (unsigned int) elf_ndxscn (scn),
3115 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3116 (int) (shdr->sh_size / sh_entsize),
3117 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3118 shdr->sh_offset,
3119 (unsigned int) shdr->sh_link,
3120 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3121
3122 /* Now we can finally look at the actual contents of this section. */
3123 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3124 {
3125 if (cnt % 2 == 0)
3126 printf ("\n %4d:", cnt);
3127
3128 GElf_Versym symmem;
3129 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3130 if (sym == NULL)
3131 break;
3132
3133 switch (*sym)
3134 {
3135 ssize_t n;
3136 case 0:
3137 fputs_unlocked (_(" 0 *local* "),
3138 stdout);
3139 break;
3140
3141 case 1:
3142 fputs_unlocked (_(" 1 *global* "),
3143 stdout);
3144 break;
3145
3146 default:
3147 n = printf ("%4d%c%s",
3148 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3149 (vername != NULL
3150 && (unsigned int) (*sym & 0x7fff) < nvername)
3151 ? vername[*sym & 0x7fff] : "???");
3152 if ((unsigned int) (*sym & 0x7fff) < nvername
3153 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3154 n += printf ("(%s)", filename[*sym & 0x7fff]);
3155 printf ("%*s", MAX (0, 33 - (int) n), " ");
3156 break;
3157 }
3158 }
3159 putchar_unlocked ('\n');
3160 }
3161
3162
3163 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)3164 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3165 uint_fast32_t maxlength, Elf32_Word nbucket,
3166 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3167 {
3168 uint32_t *counts = xcalloc (maxlength + 1, sizeof (uint32_t));
3169
3170 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3171 ++counts[lengths[cnt]];
3172
3173 GElf_Shdr glink_mem;
3174 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3175 shdr->sh_link),
3176 &glink_mem);
3177 if (glink == NULL)
3178 {
3179 error (0, 0, _("invalid sh_link value in section %zu"),
3180 elf_ndxscn (scn));
3181 return;
3182 }
3183
3184 printf (ngettext ("\
3185 \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",
3186 "\
3187 \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",
3188 nbucket),
3189 (unsigned int) elf_ndxscn (scn),
3190 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3191 (int) nbucket,
3192 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3193 shdr->sh_addr,
3194 shdr->sh_offset,
3195 (unsigned int) shdr->sh_link,
3196 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3197
3198 if (extrastr != NULL)
3199 fputs (extrastr, stdout);
3200
3201 if (likely (nbucket > 0))
3202 {
3203 uint64_t success = 0;
3204
3205 /* xgettext:no-c-format */
3206 fputs_unlocked (_("\
3207 Length Number % of total Coverage\n"), stdout);
3208 printf (_(" 0 %6" PRIu32 " %5.1f%%\n"),
3209 counts[0], (counts[0] * 100.0) / nbucket);
3210
3211 uint64_t nzero_counts = 0;
3212 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3213 {
3214 nzero_counts += counts[cnt] * cnt;
3215 printf (_("\
3216 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3217 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3218 (nzero_counts * 100.0) / nsyms);
3219 }
3220
3221 Elf32_Word acc = 0;
3222 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3223 {
3224 acc += cnt;
3225 success += counts[cnt] * acc;
3226 }
3227
3228 printf (_("\
3229 Average number of tests: successful lookup: %f\n\
3230 unsuccessful lookup: %f\n"),
3231 (double) success / (double) nzero_counts,
3232 (double) nzero_counts / (double) nbucket);
3233 }
3234
3235 free (counts);
3236 }
3237
3238
3239 /* This function handles the traditional System V-style hash table format. */
3240 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3241 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3242 {
3243 Elf_Data *data = elf_getdata (scn, NULL);
3244 if (unlikely (data == NULL))
3245 {
3246 error (0, 0, _("cannot get data for section %d: %s"),
3247 (int) elf_ndxscn (scn), elf_errmsg (-1));
3248 return;
3249 }
3250
3251 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3252 {
3253 invalid_data:
3254 error (0, 0, _("invalid data in sysv.hash section %d"),
3255 (int) elf_ndxscn (scn));
3256 return;
3257 }
3258
3259 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3260 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3261
3262 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3263 if (used_buf > data->d_size)
3264 goto invalid_data;
3265
3266 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3267 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3268
3269 uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3270
3271 uint_fast32_t maxlength = 0;
3272 uint_fast32_t nsyms = 0;
3273 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3274 {
3275 Elf32_Word inner = bucket[cnt];
3276 Elf32_Word chain_len = 0;
3277 while (inner > 0 && inner < nchain)
3278 {
3279 ++nsyms;
3280 ++chain_len;
3281 if (chain_len > nchain)
3282 {
3283 error (0, 0, _("invalid chain in sysv.hash section %d"),
3284 (int) elf_ndxscn (scn));
3285 free (lengths);
3286 return;
3287 }
3288 if (maxlength < ++lengths[cnt])
3289 ++maxlength;
3290
3291 inner = chain[inner];
3292 }
3293 }
3294
3295 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3296 lengths, NULL);
3297
3298 free (lengths);
3299 }
3300
3301
3302 /* This function handles the incorrect, System V-style hash table
3303 format some 64-bit architectures use. */
3304 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3305 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3306 {
3307 Elf_Data *data = elf_getdata (scn, NULL);
3308 if (unlikely (data == NULL))
3309 {
3310 error (0, 0, _("cannot get data for section %d: %s"),
3311 (int) elf_ndxscn (scn), elf_errmsg (-1));
3312 return;
3313 }
3314
3315 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3316 {
3317 invalid_data:
3318 error (0, 0, _("invalid data in sysv.hash64 section %d"),
3319 (int) elf_ndxscn (scn));
3320 return;
3321 }
3322
3323 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3324 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3325
3326 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3327 if (maxwords < 2
3328 || maxwords - 2 < nbucket
3329 || maxwords - 2 - nbucket < nchain)
3330 goto invalid_data;
3331
3332 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3333 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3334
3335 uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3336
3337 uint_fast32_t maxlength = 0;
3338 uint_fast32_t nsyms = 0;
3339 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3340 {
3341 Elf64_Xword inner = bucket[cnt];
3342 Elf64_Xword chain_len = 0;
3343 while (inner > 0 && inner < nchain)
3344 {
3345 ++nsyms;
3346 ++chain_len;
3347 if (chain_len > nchain)
3348 {
3349 error (0, 0, _("invalid chain in sysv.hash64 section %d"),
3350 (int) elf_ndxscn (scn));
3351 free (lengths);
3352 return;
3353 }
3354 if (maxlength < ++lengths[cnt])
3355 ++maxlength;
3356
3357 inner = chain[inner];
3358 }
3359 }
3360
3361 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3362 lengths, NULL);
3363
3364 free (lengths);
3365 }
3366
3367
3368 /* This function handles the GNU-style hash table format. */
3369 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3370 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3371 {
3372 uint32_t *lengths = NULL;
3373 Elf_Data *data = elf_getdata (scn, NULL);
3374 if (unlikely (data == NULL))
3375 {
3376 error (0, 0, _("cannot get data for section %d: %s"),
3377 (int) elf_ndxscn (scn), elf_errmsg (-1));
3378 return;
3379 }
3380
3381 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3382 {
3383 invalid_data:
3384 free (lengths);
3385 error (0, 0, _("invalid data in gnu.hash section %d"),
3386 (int) elf_ndxscn (scn));
3387 return;
3388 }
3389
3390 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3391 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3392
3393 /* Next comes the size of the bitmap. It's measured in words for
3394 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3395 64 bit archs. There is always a bloom filter present, so zero is
3396 an invalid value. */
3397 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3398 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3399 bitmask_words *= 2;
3400
3401 if (bitmask_words == 0)
3402 goto invalid_data;
3403
3404 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3405
3406 /* Is there still room for the sym chain?
3407 Use uint64_t calculation to prevent 32bit overflow. */
3408 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3409 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3410 if (used_buf > data->d_size)
3411 goto invalid_data;
3412
3413 lengths = xcalloc (nbucket, sizeof (uint32_t));
3414
3415 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3416 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3417 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3418 + nbucket];
3419
3420 /* Compute distribution of chain lengths. */
3421 uint_fast32_t maxlength = 0;
3422 uint_fast32_t nsyms = 0;
3423 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3424 if (bucket[cnt] != 0)
3425 {
3426 Elf32_Word inner = bucket[cnt] - symbias;
3427 do
3428 {
3429 ++nsyms;
3430 if (maxlength < ++lengths[cnt])
3431 ++maxlength;
3432 if (inner >= max_nsyms)
3433 goto invalid_data;
3434 }
3435 while ((chain[inner++] & 1) == 0);
3436 }
3437
3438 /* Count bits in bitmask. */
3439 uint_fast32_t nbits = 0;
3440 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3441 {
3442 uint_fast32_t word = bitmask[cnt];
3443
3444 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3445 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3446 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3447 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3448 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3449 }
3450
3451 char *str = xasprintf (_("\
3452 Symbol Bias: %u\n\
3453 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3454 (unsigned int) symbias,
3455 bitmask_words * sizeof (Elf32_Word),
3456 ((nbits * 100 + 50)
3457 / (uint_fast32_t) (bitmask_words
3458 * sizeof (Elf32_Word) * 8)),
3459 (unsigned int) shift);
3460
3461 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3462 lengths, str);
3463
3464 free (str);
3465 free (lengths);
3466 }
3467
3468
3469 /* Find the symbol table(s). For this we have to search through the
3470 section table. */
3471 static void
handle_hash(Ebl * ebl)3472 handle_hash (Ebl *ebl)
3473 {
3474 /* Get the section header string table index. */
3475 size_t shstrndx;
3476 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3477 error (EXIT_FAILURE, 0,
3478 _("cannot get section header string table index"));
3479
3480 Elf_Scn *scn = NULL;
3481 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3482 {
3483 /* Handle the section if it is a symbol table. */
3484 GElf_Shdr shdr_mem;
3485 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3486
3487 if (likely (shdr != NULL))
3488 {
3489 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3490 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3491 {
3492 if (elf_compress (scn, 0, 0) < 0)
3493 printf ("WARNING: %s [%zd]\n",
3494 _("Couldn't uncompress section"),
3495 elf_ndxscn (scn));
3496 shdr = gelf_getshdr (scn, &shdr_mem);
3497 if (unlikely (shdr == NULL))
3498 error (EXIT_FAILURE, 0,
3499 _("cannot get section [%zd] header: %s"),
3500 elf_ndxscn (scn), elf_errmsg (-1));
3501 }
3502
3503 if (shdr->sh_type == SHT_HASH)
3504 {
3505 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3506 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3507 else
3508 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3509 }
3510 else if (shdr->sh_type == SHT_GNU_HASH)
3511 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3512 }
3513 }
3514 }
3515
3516
3517 static void
print_liblist(Ebl * ebl)3518 print_liblist (Ebl *ebl)
3519 {
3520 /* Find the library list sections. For this we have to search
3521 through the section table. */
3522 Elf_Scn *scn = NULL;
3523
3524 /* Get the section header string table index. */
3525 size_t shstrndx;
3526 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3527 error (EXIT_FAILURE, 0,
3528 _("cannot get section header string table index"));
3529
3530 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3531 {
3532 GElf_Shdr shdr_mem;
3533 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3534
3535 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3536 {
3537 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3538 int nentries = shdr->sh_size / sh_entsize;
3539 printf (ngettext ("\
3540 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3541 "\
3542 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3543 nentries),
3544 elf_ndxscn (scn),
3545 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3546 shdr->sh_offset,
3547 nentries);
3548
3549 Elf_Data *data = elf_getdata (scn, NULL);
3550 if (data == NULL)
3551 return;
3552
3553 puts (_("\
3554 Library Time Stamp Checksum Version Flags"));
3555
3556 for (int cnt = 0; cnt < nentries; ++cnt)
3557 {
3558 GElf_Lib lib_mem;
3559 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3560 if (unlikely (lib == NULL))
3561 continue;
3562
3563 time_t t = (time_t) lib->l_time_stamp;
3564 struct tm *tm = gmtime (&t);
3565 if (unlikely (tm == NULL))
3566 continue;
3567
3568 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3569 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3570 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3571 tm->tm_hour, tm->tm_min, tm->tm_sec,
3572 (unsigned int) lib->l_checksum,
3573 (unsigned int) lib->l_version,
3574 (unsigned int) lib->l_flags);
3575 }
3576 }
3577 }
3578 }
3579
3580 static inline size_t
left(Elf_Data * data,const unsigned char * p)3581 left (Elf_Data *data,
3582 const unsigned char *p)
3583 {
3584 return (const unsigned char *) data->d_buf + data->d_size - p;
3585 }
3586
3587 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3588 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3589 {
3590 /* Find the object attributes sections. For this we have to search
3591 through the section table. */
3592 Elf_Scn *scn = NULL;
3593
3594 /* Get the section header string table index. */
3595 size_t shstrndx;
3596 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3597 error (EXIT_FAILURE, 0,
3598 _("cannot get section header string table index"));
3599
3600 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3601 {
3602 GElf_Shdr shdr_mem;
3603 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3604
3605 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3606 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3607 || ehdr->e_machine != EM_ARM)
3608 && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
3609 || ehdr->e_machine != EM_CSKY)))
3610 continue;
3611
3612 printf (_("\
3613 \nObject attributes section [%2zu] '%s' of %" PRIu64
3614 " bytes at offset %#0" PRIx64 ":\n"),
3615 elf_ndxscn (scn),
3616 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3617 shdr->sh_size, shdr->sh_offset);
3618
3619 Elf_Data *data = elf_rawdata (scn, NULL);
3620 if (unlikely (data == NULL || data->d_size == 0))
3621 return;
3622
3623 const unsigned char *p = data->d_buf;
3624
3625 /* There is only one 'version', A. */
3626 if (unlikely (*p++ != 'A'))
3627 return;
3628
3629 fputs_unlocked (_(" Owner Size\n"), stdout);
3630
3631 /* Loop over the sections. */
3632 while (left (data, p) >= 4)
3633 {
3634 /* Section length. */
3635 uint32_t len;
3636 memcpy (&len, p, sizeof len);
3637
3638 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3639 CONVERT (len);
3640
3641 if (unlikely (len > left (data, p)))
3642 break;
3643
3644 /* Section vendor name. */
3645 const unsigned char *name = p + sizeof len;
3646 p += len;
3647
3648 unsigned const char *q = memchr (name, '\0', len);
3649 if (unlikely (q == NULL))
3650 break;
3651 ++q;
3652
3653 printf (_(" %-13s %4" PRIu32 "\n"), name, len);
3654
3655 bool gnu_vendor = (q - name == sizeof "gnu"
3656 && !memcmp (name, "gnu", sizeof "gnu"));
3657
3658 /* Loop over subsections. */
3659 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3660 || gnu_vendor)
3661 while (q < p)
3662 {
3663 const unsigned char *const sub = q;
3664
3665 unsigned int subsection_tag;
3666 get_uleb128 (subsection_tag, q, p);
3667 if (unlikely (q >= p))
3668 break;
3669
3670 uint32_t subsection_len;
3671 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3672 break;
3673
3674 memcpy (&subsection_len, q, sizeof subsection_len);
3675
3676 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3677 CONVERT (subsection_len);
3678
3679 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3680 if (unlikely (subsection_len == 0
3681 || subsection_len >= (uint32_t) PTRDIFF_MAX
3682 || p - sub < (ptrdiff_t) subsection_len))
3683 break;
3684
3685 const unsigned char *r = q + sizeof subsection_len;
3686 q = sub + subsection_len;
3687
3688 switch (subsection_tag)
3689 {
3690 default:
3691 /* Unknown subsection, print and skip. */
3692 printf (_(" %-4u %12" PRIu32 "\n"),
3693 subsection_tag, subsection_len);
3694 break;
3695
3696 case 1: /* Tag_File */
3697 printf (_(" File: %11" PRIu32 "\n"),
3698 subsection_len);
3699
3700 while (r < q)
3701 {
3702 unsigned int tag;
3703 get_uleb128 (tag, r, q);
3704 if (unlikely (r >= q))
3705 break;
3706
3707 /* GNU style tags have either a uleb128 value,
3708 when lowest bit is not set, or a string
3709 when the lowest bit is set.
3710 "compatibility" (32) is special. It has
3711 both a string and a uleb128 value. For
3712 non-gnu we assume 6 till 31 only take ints.
3713 XXX see arm backend, do we need a separate
3714 hook? */
3715 uint64_t value = 0;
3716 const char *string = NULL;
3717 if (tag == 32 || (tag & 1) == 0
3718 || (! gnu_vendor && (tag > 5 && tag < 32)))
3719 {
3720 get_uleb128 (value, r, q);
3721 if (r > q)
3722 break;
3723 }
3724 if (tag == 32
3725 || ((tag & 1) != 0
3726 && (gnu_vendor
3727 || (! gnu_vendor && tag > 32)))
3728 || (! gnu_vendor && tag > 3 && tag < 6))
3729 {
3730 string = (const char *) r;
3731 r = memchr (r, '\0', q - r);
3732 if (r == NULL)
3733 break;
3734 ++r;
3735 }
3736
3737 const char *tag_name = NULL;
3738 const char *value_name = NULL;
3739 ebl_check_object_attribute (ebl, (const char *) name,
3740 tag, value,
3741 &tag_name, &value_name);
3742
3743 if (tag_name != NULL)
3744 {
3745 if (tag == 32)
3746 printf (_(" %s: %" PRId64 ", %s\n"),
3747 tag_name, value, string);
3748 else if (string == NULL && value_name == NULL)
3749 printf (_(" %s: %" PRId64 "\n"),
3750 tag_name, value);
3751 else
3752 printf (_(" %s: %s\n"),
3753 tag_name, string ?: value_name);
3754 }
3755 else
3756 {
3757 /* For "gnu" vendor 32 "compatibility" has
3758 already been handled above. */
3759 assert (tag != 32
3760 || strcmp ((const char *) name, "gnu"));
3761 if (string == NULL)
3762 printf (_(" %u: %" PRId64 "\n"),
3763 tag, value);
3764 else
3765 printf (_(" %u: %s\n"),
3766 tag, string);
3767 }
3768 }
3769 }
3770 }
3771 }
3772 }
3773 }
3774
3775
3776 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3777 print_dwarf_addr (Dwfl_Module *dwflmod,
3778 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3779 {
3780 /* See if there is a name we can give for this address. */
3781 GElf_Sym sym;
3782 GElf_Off off = 0;
3783 const char *name = (print_address_names && ! print_unresolved_addresses)
3784 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3785 : NULL;
3786
3787 const char *scn;
3788 if (print_unresolved_addresses)
3789 {
3790 address = raw;
3791 scn = NULL;
3792 }
3793 else
3794 {
3795 /* Relativize the address. */
3796 int n = dwfl_module_relocations (dwflmod);
3797 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3798
3799 /* In an ET_REL file there is a section name to refer to. */
3800 scn = (i < 0 ? NULL
3801 : dwfl_module_relocation_info (dwflmod, i, NULL));
3802 }
3803
3804 if ((name != NULL
3805 ? (off != 0
3806 ? (scn != NULL
3807 ? (address_size == 0
3808 ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3809 scn, address, name, off)
3810 : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3811 scn, 2 + address_size * 2, address,
3812 name, off))
3813 : (address_size == 0
3814 ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3815 address, name, off)
3816 : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3817 2 + address_size * 2, address,
3818 name, off)))
3819 : (scn != NULL
3820 ? (address_size == 0
3821 ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3822 : printf ("%s+%#0*" PRIx64 " <%s>",
3823 scn, 2 + address_size * 2, address, name))
3824 : (address_size == 0
3825 ? printf ("%#" PRIx64 " <%s>", address, name)
3826 : printf ("%#0*" PRIx64 " <%s>",
3827 2 + address_size * 2, address, name))))
3828 : (scn != NULL
3829 ? (address_size == 0
3830 ? printf ("%s+%#" PRIx64, scn, address)
3831 : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3832 : (address_size == 0
3833 ? printf ("%#" PRIx64, address)
3834 : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3835 error (EXIT_FAILURE, 0, _("sprintf failure"));
3836 }
3837
3838
3839 static const char *
dwarf_tag_string(unsigned int tag)3840 dwarf_tag_string (unsigned int tag)
3841 {
3842 switch (tag)
3843 {
3844 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3845 DWARF_ALL_KNOWN_DW_TAG
3846 #undef DWARF_ONE_KNOWN_DW_TAG
3847 default:
3848 return NULL;
3849 }
3850 }
3851
3852
3853 static const char *
dwarf_attr_string(unsigned int attrnum)3854 dwarf_attr_string (unsigned int attrnum)
3855 {
3856 switch (attrnum)
3857 {
3858 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3859 DWARF_ALL_KNOWN_DW_AT
3860 #undef DWARF_ONE_KNOWN_DW_AT
3861 default:
3862 return NULL;
3863 }
3864 }
3865
3866
3867 static const char *
dwarf_form_string(unsigned int form)3868 dwarf_form_string (unsigned int form)
3869 {
3870 switch (form)
3871 {
3872 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3873 DWARF_ALL_KNOWN_DW_FORM
3874 #undef DWARF_ONE_KNOWN_DW_FORM
3875 default:
3876 return NULL;
3877 }
3878 }
3879
3880
3881 static const char *
dwarf_lang_string(unsigned int lang)3882 dwarf_lang_string (unsigned int lang)
3883 {
3884 switch (lang)
3885 {
3886 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3887 DWARF_ALL_KNOWN_DW_LANG
3888 #undef DWARF_ONE_KNOWN_DW_LANG
3889 default:
3890 return NULL;
3891 }
3892 }
3893
3894
3895 static const char *
dwarf_inline_string(unsigned int code)3896 dwarf_inline_string (unsigned int code)
3897 {
3898 static const char *const known[] =
3899 {
3900 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3901 DWARF_ALL_KNOWN_DW_INL
3902 #undef DWARF_ONE_KNOWN_DW_INL
3903 };
3904
3905 if (likely (code < sizeof (known) / sizeof (known[0])))
3906 return known[code];
3907
3908 return NULL;
3909 }
3910
3911
3912 static const char *
dwarf_encoding_string(unsigned int code)3913 dwarf_encoding_string (unsigned int code)
3914 {
3915 static const char *const known[] =
3916 {
3917 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3918 DWARF_ALL_KNOWN_DW_ATE
3919 #undef DWARF_ONE_KNOWN_DW_ATE
3920 };
3921
3922 if (likely (code < sizeof (known) / sizeof (known[0])))
3923 return known[code];
3924
3925 return NULL;
3926 }
3927
3928
3929 static const char *
dwarf_access_string(unsigned int code)3930 dwarf_access_string (unsigned int code)
3931 {
3932 static const char *const known[] =
3933 {
3934 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3935 DWARF_ALL_KNOWN_DW_ACCESS
3936 #undef DWARF_ONE_KNOWN_DW_ACCESS
3937 };
3938
3939 if (likely (code < sizeof (known) / sizeof (known[0])))
3940 return known[code];
3941
3942 return NULL;
3943 }
3944
3945
3946 static const char *
dwarf_defaulted_string(unsigned int code)3947 dwarf_defaulted_string (unsigned int code)
3948 {
3949 static const char *const known[] =
3950 {
3951 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3952 DWARF_ALL_KNOWN_DW_DEFAULTED
3953 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3954 };
3955
3956 if (likely (code < sizeof (known) / sizeof (known[0])))
3957 return known[code];
3958
3959 return NULL;
3960 }
3961
3962
3963 static const char *
dwarf_visibility_string(unsigned int code)3964 dwarf_visibility_string (unsigned int code)
3965 {
3966 static const char *const known[] =
3967 {
3968 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3969 DWARF_ALL_KNOWN_DW_VIS
3970 #undef DWARF_ONE_KNOWN_DW_VIS
3971 };
3972
3973 if (likely (code < sizeof (known) / sizeof (known[0])))
3974 return known[code];
3975
3976 return NULL;
3977 }
3978
3979
3980 static const char *
dwarf_virtuality_string(unsigned int code)3981 dwarf_virtuality_string (unsigned int code)
3982 {
3983 static const char *const known[] =
3984 {
3985 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3986 DWARF_ALL_KNOWN_DW_VIRTUALITY
3987 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3988 };
3989
3990 if (likely (code < sizeof (known) / sizeof (known[0])))
3991 return known[code];
3992
3993 return NULL;
3994 }
3995
3996
3997 static const char *
dwarf_identifier_case_string(unsigned int code)3998 dwarf_identifier_case_string (unsigned int code)
3999 {
4000 static const char *const known[] =
4001 {
4002 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
4003 DWARF_ALL_KNOWN_DW_ID
4004 #undef DWARF_ONE_KNOWN_DW_ID
4005 };
4006
4007 if (likely (code < sizeof (known) / sizeof (known[0])))
4008 return known[code];
4009
4010 return NULL;
4011 }
4012
4013
4014 static const char *
dwarf_calling_convention_string(unsigned int code)4015 dwarf_calling_convention_string (unsigned int code)
4016 {
4017 static const char *const known[] =
4018 {
4019 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4020 DWARF_ALL_KNOWN_DW_CC
4021 #undef DWARF_ONE_KNOWN_DW_CC
4022 };
4023
4024 if (likely (code < sizeof (known) / sizeof (known[0])))
4025 return known[code];
4026
4027 return NULL;
4028 }
4029
4030
4031 static const char *
dwarf_ordering_string(unsigned int code)4032 dwarf_ordering_string (unsigned int code)
4033 {
4034 static const char *const known[] =
4035 {
4036 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4037 DWARF_ALL_KNOWN_DW_ORD
4038 #undef DWARF_ONE_KNOWN_DW_ORD
4039 };
4040
4041 if (likely (code < sizeof (known) / sizeof (known[0])))
4042 return known[code];
4043
4044 return NULL;
4045 }
4046
4047
4048 static const char *
dwarf_discr_list_string(unsigned int code)4049 dwarf_discr_list_string (unsigned int code)
4050 {
4051 static const char *const known[] =
4052 {
4053 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4054 DWARF_ALL_KNOWN_DW_DSC
4055 #undef DWARF_ONE_KNOWN_DW_DSC
4056 };
4057
4058 if (likely (code < sizeof (known) / sizeof (known[0])))
4059 return known[code];
4060
4061 return NULL;
4062 }
4063
4064
4065 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4066 dwarf_locexpr_opcode_string (unsigned int code)
4067 {
4068 static const char *const known[] =
4069 {
4070 /* Normally we can't afford building huge table of 64K entries,
4071 most of them zero, just because there are a couple defined
4072 values at the far end. In case of opcodes, it's OK. */
4073 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4074 DWARF_ALL_KNOWN_DW_OP
4075 #undef DWARF_ONE_KNOWN_DW_OP
4076 };
4077
4078 if (likely (code < sizeof (known) / sizeof (known[0])))
4079 return known[code];
4080
4081 return NULL;
4082 }
4083
4084
4085 static const char *
dwarf_unit_string(unsigned int type)4086 dwarf_unit_string (unsigned int type)
4087 {
4088 switch (type)
4089 {
4090 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4091 DWARF_ALL_KNOWN_DW_UT
4092 #undef DWARF_ONE_KNOWN_DW_UT
4093 default:
4094 return NULL;
4095 }
4096 }
4097
4098
4099 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4100 dwarf_range_list_encoding_string (unsigned int kind)
4101 {
4102 switch (kind)
4103 {
4104 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4105 DWARF_ALL_KNOWN_DW_RLE
4106 #undef DWARF_ONE_KNOWN_DW_RLE
4107 default:
4108 return NULL;
4109 }
4110 }
4111
4112
4113 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4114 dwarf_loc_list_encoding_string (unsigned int kind)
4115 {
4116 switch (kind)
4117 {
4118 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4119 DWARF_ALL_KNOWN_DW_LLE
4120 #undef DWARF_ONE_KNOWN_DW_LLE
4121 default:
4122 return NULL;
4123 }
4124 }
4125
4126
4127 static const char *
dwarf_line_content_description_string(unsigned int kind)4128 dwarf_line_content_description_string (unsigned int kind)
4129 {
4130 switch (kind)
4131 {
4132 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4133 DWARF_ALL_KNOWN_DW_LNCT
4134 #undef DWARF_ONE_KNOWN_DW_LNCT
4135 default:
4136 return NULL;
4137 }
4138 }
4139
4140
4141 /* Used by all dwarf_foo_name functions. */
4142 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4143 string_or_unknown (const char *known, unsigned int code,
4144 unsigned int lo_user, unsigned int hi_user,
4145 bool print_unknown_num)
4146 {
4147 static char unknown_buf[20];
4148
4149 if (likely (known != NULL))
4150 return known;
4151
4152 if (lo_user != 0 && code >= lo_user && code <= hi_user)
4153 {
4154 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4155 code - lo_user);
4156 return unknown_buf;
4157 }
4158
4159 if (print_unknown_num)
4160 {
4161 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4162 return unknown_buf;
4163 }
4164
4165 return "???";
4166 }
4167
4168
4169 static const char *
dwarf_tag_name(unsigned int tag)4170 dwarf_tag_name (unsigned int tag)
4171 {
4172 const char *ret = dwarf_tag_string (tag);
4173 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4174 }
4175
4176 static const char *
dwarf_attr_name(unsigned int attr)4177 dwarf_attr_name (unsigned int attr)
4178 {
4179 const char *ret = dwarf_attr_string (attr);
4180 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4181 }
4182
4183
4184 static const char *
dwarf_form_name(unsigned int form)4185 dwarf_form_name (unsigned int form)
4186 {
4187 const char *ret = dwarf_form_string (form);
4188 return string_or_unknown (ret, form, 0, 0, true);
4189 }
4190
4191
4192 static const char *
dwarf_lang_name(unsigned int lang)4193 dwarf_lang_name (unsigned int lang)
4194 {
4195 const char *ret = dwarf_lang_string (lang);
4196 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4197 }
4198
4199
4200 static const char *
dwarf_inline_name(unsigned int code)4201 dwarf_inline_name (unsigned int code)
4202 {
4203 const char *ret = dwarf_inline_string (code);
4204 return string_or_unknown (ret, code, 0, 0, false);
4205 }
4206
4207
4208 static const char *
dwarf_encoding_name(unsigned int code)4209 dwarf_encoding_name (unsigned int code)
4210 {
4211 const char *ret = dwarf_encoding_string (code);
4212 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4213 }
4214
4215
4216 static const char *
dwarf_access_name(unsigned int code)4217 dwarf_access_name (unsigned int code)
4218 {
4219 const char *ret = dwarf_access_string (code);
4220 return string_or_unknown (ret, code, 0, 0, false);
4221 }
4222
4223
4224 static const char *
dwarf_defaulted_name(unsigned int code)4225 dwarf_defaulted_name (unsigned int code)
4226 {
4227 const char *ret = dwarf_defaulted_string (code);
4228 return string_or_unknown (ret, code, 0, 0, false);
4229 }
4230
4231
4232 static const char *
dwarf_visibility_name(unsigned int code)4233 dwarf_visibility_name (unsigned int code)
4234 {
4235 const char *ret = dwarf_visibility_string (code);
4236 return string_or_unknown (ret, code, 0, 0, false);
4237 }
4238
4239
4240 static const char *
dwarf_virtuality_name(unsigned int code)4241 dwarf_virtuality_name (unsigned int code)
4242 {
4243 const char *ret = dwarf_virtuality_string (code);
4244 return string_or_unknown (ret, code, 0, 0, false);
4245 }
4246
4247
4248 static const char *
dwarf_identifier_case_name(unsigned int code)4249 dwarf_identifier_case_name (unsigned int code)
4250 {
4251 const char *ret = dwarf_identifier_case_string (code);
4252 return string_or_unknown (ret, code, 0, 0, false);
4253 }
4254
4255
4256 static const char *
dwarf_calling_convention_name(unsigned int code)4257 dwarf_calling_convention_name (unsigned int code)
4258 {
4259 const char *ret = dwarf_calling_convention_string (code);
4260 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4261 }
4262
4263
4264 static const char *
dwarf_ordering_name(unsigned int code)4265 dwarf_ordering_name (unsigned int code)
4266 {
4267 const char *ret = dwarf_ordering_string (code);
4268 return string_or_unknown (ret, code, 0, 0, false);
4269 }
4270
4271
4272 static const char *
dwarf_discr_list_name(unsigned int code)4273 dwarf_discr_list_name (unsigned int code)
4274 {
4275 const char *ret = dwarf_discr_list_string (code);
4276 return string_or_unknown (ret, code, 0, 0, false);
4277 }
4278
4279
4280 static const char *
dwarf_unit_name(unsigned int type)4281 dwarf_unit_name (unsigned int type)
4282 {
4283 const char *ret = dwarf_unit_string (type);
4284 return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4285 }
4286
4287
4288 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4289 dwarf_range_list_encoding_name (unsigned int kind)
4290 {
4291 const char *ret = dwarf_range_list_encoding_string (kind);
4292 return string_or_unknown (ret, kind, 0, 0, false);
4293 }
4294
4295
4296 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4297 dwarf_loc_list_encoding_name (unsigned int kind)
4298 {
4299 const char *ret = dwarf_loc_list_encoding_string (kind);
4300 return string_or_unknown (ret, kind, 0, 0, false);
4301 }
4302
4303
4304 static const char *
dwarf_line_content_description_name(unsigned int kind)4305 dwarf_line_content_description_name (unsigned int kind)
4306 {
4307 const char *ret = dwarf_line_content_description_string (kind);
4308 return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4309 false);
4310 }
4311
4312
4313 static void
print_block(size_t n,const void * block)4314 print_block (size_t n, const void *block)
4315 {
4316 if (n == 0)
4317 puts (_("empty block"));
4318 else
4319 {
4320 printf (_("%zu byte block:"), n);
4321 const unsigned char *data = block;
4322 do
4323 printf (" %02x", *data++);
4324 while (--n > 0);
4325 putchar ('\n');
4326 }
4327 }
4328
4329 static void
print_bytes(size_t n,const unsigned char * bytes)4330 print_bytes (size_t n, const unsigned char *bytes)
4331 {
4332 while (n-- > 0)
4333 {
4334 printf ("%02x", *bytes++);
4335 if (n > 0)
4336 printf (" ");
4337 }
4338 }
4339
4340 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4341 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4342 {
4343 if (cu == NULL)
4344 return -1;
4345
4346 Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4347 if (debug_addr == NULL)
4348 return -1;
4349
4350 Dwarf_Off base = __libdw_cu_addr_base (cu);
4351 Dwarf_Word off = idx * cu->address_size;
4352 if (base > debug_addr->d_size
4353 || off > debug_addr->d_size - base
4354 || cu->address_size > debug_addr->d_size - base - off)
4355 return -1;
4356
4357 const unsigned char *addrp = debug_addr->d_buf + base + off;
4358 if (cu->address_size == 4)
4359 *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4360 else
4361 *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4362
4363 return 0;
4364 }
4365
4366 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)4367 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4368 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4369 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4370 {
4371 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4372
4373 if (len == 0)
4374 {
4375 printf ("%*s(empty)\n", indent, "");
4376 return;
4377 }
4378
4379 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4380 #define CONSUME(n) NEED (n); else len -= (n)
4381
4382 Dwarf_Word offset = 0;
4383 while (len-- > 0)
4384 {
4385 uint_fast8_t op = *data++;
4386
4387 const char *op_name = dwarf_locexpr_opcode_string (op);
4388 if (unlikely (op_name == NULL))
4389 {
4390 static char buf[20];
4391 if (op >= DW_OP_lo_user)
4392 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4393 else
4394 snprintf (buf, sizeof buf, "??? (%#x)", op);
4395 op_name = buf;
4396 }
4397
4398 switch (op)
4399 {
4400 case DW_OP_addr:;
4401 /* Address operand. */
4402 Dwarf_Word addr;
4403 NEED (addrsize);
4404 if (addrsize == 4)
4405 addr = read_4ubyte_unaligned (dbg, data);
4406 else if (addrsize == 8)
4407 addr = read_8ubyte_unaligned (dbg, data);
4408 else
4409 goto invalid;
4410 data += addrsize;
4411 CONSUME (addrsize);
4412
4413 printf ("%*s[%2" PRIuMAX "] %s ",
4414 indent, "", (uintmax_t) offset, op_name);
4415 print_dwarf_addr (dwflmod, 0, addr, addr);
4416 printf ("\n");
4417
4418 offset += 1 + addrsize;
4419 break;
4420
4421 case DW_OP_call_ref:
4422 case DW_OP_GNU_variable_value:
4423 /* Offset operand. */
4424 if (ref_size != 4 && ref_size != 8)
4425 goto invalid; /* Cannot be used in CFA. */
4426 NEED (ref_size);
4427 if (ref_size == 4)
4428 addr = read_4ubyte_unaligned (dbg, data);
4429 else
4430 addr = read_8ubyte_unaligned (dbg, data);
4431 data += ref_size;
4432 CONSUME (ref_size);
4433 /* addr is a DIE offset, so format it as one. */
4434 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4435 indent, "", (uintmax_t) offset,
4436 op_name, (uintmax_t) addr);
4437 offset += 1 + ref_size;
4438 break;
4439
4440 case DW_OP_deref_size:
4441 case DW_OP_xderef_size:
4442 case DW_OP_pick:
4443 case DW_OP_const1u:
4444 // XXX value might be modified by relocation
4445 NEED (1);
4446 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4447 indent, "", (uintmax_t) offset,
4448 op_name, *((uint8_t *) data));
4449 ++data;
4450 --len;
4451 offset += 2;
4452 break;
4453
4454 case DW_OP_const2u:
4455 NEED (2);
4456 // XXX value might be modified by relocation
4457 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4458 indent, "", (uintmax_t) offset,
4459 op_name, read_2ubyte_unaligned (dbg, data));
4460 CONSUME (2);
4461 data += 2;
4462 offset += 3;
4463 break;
4464
4465 case DW_OP_const4u:
4466 NEED (4);
4467 // XXX value might be modified by relocation
4468 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4469 indent, "", (uintmax_t) offset,
4470 op_name, read_4ubyte_unaligned (dbg, data));
4471 CONSUME (4);
4472 data += 4;
4473 offset += 5;
4474 break;
4475
4476 case DW_OP_const8u:
4477 NEED (8);
4478 // XXX value might be modified by relocation
4479 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4480 indent, "", (uintmax_t) offset,
4481 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4482 CONSUME (8);
4483 data += 8;
4484 offset += 9;
4485 break;
4486
4487 case DW_OP_const1s:
4488 NEED (1);
4489 // XXX value might be modified by relocation
4490 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4491 indent, "", (uintmax_t) offset,
4492 op_name, *((int8_t *) data));
4493 ++data;
4494 --len;
4495 offset += 2;
4496 break;
4497
4498 case DW_OP_const2s:
4499 NEED (2);
4500 // XXX value might be modified by relocation
4501 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4502 indent, "", (uintmax_t) offset,
4503 op_name, read_2sbyte_unaligned (dbg, data));
4504 CONSUME (2);
4505 data += 2;
4506 offset += 3;
4507 break;
4508
4509 case DW_OP_const4s:
4510 NEED (4);
4511 // XXX value might be modified by relocation
4512 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4513 indent, "", (uintmax_t) offset,
4514 op_name, read_4sbyte_unaligned (dbg, data));
4515 CONSUME (4);
4516 data += 4;
4517 offset += 5;
4518 break;
4519
4520 case DW_OP_const8s:
4521 NEED (8);
4522 // XXX value might be modified by relocation
4523 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4524 indent, "", (uintmax_t) offset,
4525 op_name, read_8sbyte_unaligned (dbg, data));
4526 CONSUME (8);
4527 data += 8;
4528 offset += 9;
4529 break;
4530
4531 case DW_OP_piece:
4532 case DW_OP_regx:
4533 case DW_OP_plus_uconst:
4534 case DW_OP_constu:;
4535 const unsigned char *start = data;
4536 uint64_t uleb;
4537 NEED (1);
4538 get_uleb128 (uleb, data, data + len);
4539 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4540 indent, "", (uintmax_t) offset, op_name, uleb);
4541 CONSUME (data - start);
4542 offset += 1 + (data - start);
4543 break;
4544
4545 case DW_OP_addrx:
4546 case DW_OP_GNU_addr_index:
4547 case DW_OP_constx:
4548 case DW_OP_GNU_const_index:;
4549 start = data;
4550 NEED (1);
4551 get_uleb128 (uleb, data, data + len);
4552 printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4553 indent, "", (uintmax_t) offset, op_name, uleb);
4554 CONSUME (data - start);
4555 offset += 1 + (data - start);
4556 if (get_indexed_addr (cu, uleb, &addr) != 0)
4557 printf ("???\n");
4558 else
4559 {
4560 print_dwarf_addr (dwflmod, 0, addr, addr);
4561 printf ("\n");
4562 }
4563 break;
4564
4565 case DW_OP_bit_piece:
4566 start = data;
4567 uint64_t uleb2;
4568 NEED (1);
4569 get_uleb128 (uleb, data, data + len);
4570 NEED (1);
4571 get_uleb128 (uleb2, data, data + len);
4572 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4573 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4574 CONSUME (data - start);
4575 offset += 1 + (data - start);
4576 break;
4577
4578 case DW_OP_fbreg:
4579 case DW_OP_breg0 ... DW_OP_breg31:
4580 case DW_OP_consts:
4581 start = data;
4582 int64_t sleb;
4583 NEED (1);
4584 get_sleb128 (sleb, data, data + len);
4585 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4586 indent, "", (uintmax_t) offset, op_name, sleb);
4587 CONSUME (data - start);
4588 offset += 1 + (data - start);
4589 break;
4590
4591 case DW_OP_bregx:
4592 start = data;
4593 NEED (1);
4594 get_uleb128 (uleb, data, data + len);
4595 NEED (1);
4596 get_sleb128 (sleb, data, data + len);
4597 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4598 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4599 CONSUME (data - start);
4600 offset += 1 + (data - start);
4601 break;
4602
4603 case DW_OP_call2:
4604 NEED (2);
4605 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4606 indent, "", (uintmax_t) offset, op_name,
4607 read_2ubyte_unaligned (dbg, data));
4608 CONSUME (2);
4609 data += 2;
4610 offset += 3;
4611 break;
4612
4613 case DW_OP_call4:
4614 NEED (4);
4615 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4616 indent, "", (uintmax_t) offset, op_name,
4617 read_4ubyte_unaligned (dbg, data));
4618 CONSUME (4);
4619 data += 4;
4620 offset += 5;
4621 break;
4622
4623 case DW_OP_skip:
4624 case DW_OP_bra:
4625 NEED (2);
4626 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4627 indent, "", (uintmax_t) offset, op_name,
4628 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4629 CONSUME (2);
4630 data += 2;
4631 offset += 3;
4632 break;
4633
4634 case DW_OP_implicit_value:
4635 start = data;
4636 NEED (1);
4637 get_uleb128 (uleb, data, data + len);
4638 printf ("%*s[%2" PRIuMAX "] %s: ",
4639 indent, "", (uintmax_t) offset, op_name);
4640 NEED (uleb);
4641 print_block (uleb, data);
4642 data += uleb;
4643 CONSUME (data - start);
4644 offset += 1 + (data - start);
4645 break;
4646
4647 case DW_OP_implicit_pointer:
4648 case DW_OP_GNU_implicit_pointer:
4649 /* DIE offset operand. */
4650 start = data;
4651 NEED (ref_size);
4652 if (ref_size != 4 && ref_size != 8)
4653 goto invalid; /* Cannot be used in CFA. */
4654 if (ref_size == 4)
4655 addr = read_4ubyte_unaligned (dbg, data);
4656 else
4657 addr = read_8ubyte_unaligned (dbg, data);
4658 data += ref_size;
4659 /* Byte offset operand. */
4660 NEED (1);
4661 get_sleb128 (sleb, data, data + len);
4662
4663 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4664 indent, "", (intmax_t) offset,
4665 op_name, (uintmax_t) addr, sleb);
4666 CONSUME (data - start);
4667 offset += 1 + (data - start);
4668 break;
4669
4670 case DW_OP_entry_value:
4671 case DW_OP_GNU_entry_value:
4672 /* Size plus expression block. */
4673 start = data;
4674 NEED (1);
4675 get_uleb128 (uleb, data, data + len);
4676 printf ("%*s[%2" PRIuMAX "] %s:\n",
4677 indent, "", (uintmax_t) offset, op_name);
4678 NEED (uleb);
4679 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4680 addrsize, offset_size, cu, uleb, data);
4681 data += uleb;
4682 CONSUME (data - start);
4683 offset += 1 + (data - start);
4684 break;
4685
4686 case DW_OP_const_type:
4687 case DW_OP_GNU_const_type:
4688 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4689 unsigned size plus block. */
4690 start = data;
4691 NEED (1);
4692 get_uleb128 (uleb, data, data + len);
4693 if (! print_unresolved_addresses && cu != NULL)
4694 uleb += cu->start;
4695 NEED (1);
4696 uint8_t usize = *(uint8_t *) data++;
4697 NEED (usize);
4698 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4699 indent, "", (uintmax_t) offset, op_name, uleb);
4700 print_block (usize, data);
4701 data += usize;
4702 CONSUME (data - start);
4703 offset += 1 + (data - start);
4704 break;
4705
4706 case DW_OP_regval_type:
4707 case DW_OP_GNU_regval_type:
4708 /* uleb128 register number, uleb128 CU relative
4709 DW_TAG_base_type DIE offset. */
4710 start = data;
4711 NEED (1);
4712 get_uleb128 (uleb, data, data + len);
4713 NEED (1);
4714 get_uleb128 (uleb2, data, data + len);
4715 if (! print_unresolved_addresses && cu != NULL)
4716 uleb2 += cu->start;
4717 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4718 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4719 CONSUME (data - start);
4720 offset += 1 + (data - start);
4721 break;
4722
4723 case DW_OP_deref_type:
4724 case DW_OP_GNU_deref_type:
4725 /* 1-byte unsigned size of value, uleb128 CU relative
4726 DW_TAG_base_type DIE offset. */
4727 start = data;
4728 NEED (1);
4729 usize = *(uint8_t *) data++;
4730 NEED (1);
4731 get_uleb128 (uleb, data, data + len);
4732 if (! print_unresolved_addresses && cu != NULL)
4733 uleb += cu->start;
4734 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4735 indent, "", (uintmax_t) offset,
4736 op_name, usize, uleb);
4737 CONSUME (data - start);
4738 offset += 1 + (data - start);
4739 break;
4740
4741 case DW_OP_xderef_type:
4742 /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */
4743 start = data;
4744 NEED (1);
4745 usize = *(uint8_t *) data++;
4746 NEED (1);
4747 get_uleb128 (uleb, data, data + len);
4748 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4749 indent, "", (uintmax_t) offset,
4750 op_name, usize, uleb);
4751 CONSUME (data - start);
4752 offset += 1 + (data - start);
4753 break;
4754
4755 case DW_OP_convert:
4756 case DW_OP_GNU_convert:
4757 case DW_OP_reinterpret:
4758 case DW_OP_GNU_reinterpret:
4759 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4760 for conversion to untyped. */
4761 start = data;
4762 NEED (1);
4763 get_uleb128 (uleb, data, data + len);
4764 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4765 uleb += cu->start;
4766 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4767 indent, "", (uintmax_t) offset, op_name, uleb);
4768 CONSUME (data - start);
4769 offset += 1 + (data - start);
4770 break;
4771
4772 case DW_OP_GNU_parameter_ref:
4773 /* 4 byte CU relative reference to the abstract optimized away
4774 DW_TAG_formal_parameter. */
4775 NEED (4);
4776 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4777 if (! print_unresolved_addresses && cu != NULL)
4778 param_off += cu->start;
4779 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4780 indent, "", (uintmax_t) offset, op_name, param_off);
4781 CONSUME (4);
4782 data += 4;
4783 offset += 5;
4784 break;
4785
4786 default:
4787 /* No Operand. */
4788 printf ("%*s[%2" PRIuMAX "] %s\n",
4789 indent, "", (uintmax_t) offset, op_name);
4790 ++offset;
4791 break;
4792 }
4793
4794 indent = indentrest;
4795 continue;
4796
4797 invalid:
4798 printf (_("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
4799 indent, "", (uintmax_t) offset, op_name);
4800 break;
4801 }
4802 }
4803
4804
4805 struct listptr
4806 {
4807 Dwarf_Off offset:(64 - 3);
4808 bool addr64:1;
4809 bool dwarf64:1;
4810 bool warned:1;
4811 struct Dwarf_CU *cu;
4812 unsigned int attr;
4813 };
4814
4815 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4816 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4817
4818 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4819 cudie_base (Dwarf_Die *cudie)
4820 {
4821 Dwarf_Addr base;
4822 /* Find the base address of the compilation unit. It will normally
4823 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4824 address could be overridden by DW_AT_entry_pc. It's been
4825 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4826 compilation units with discontinuous ranges. */
4827 if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4828 {
4829 Dwarf_Attribute attr_mem;
4830 if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4831 &base) != 0)
4832 base = 0;
4833 }
4834 return base;
4835 }
4836
4837 static Dwarf_Addr
listptr_base(struct listptr * p)4838 listptr_base (struct listptr *p)
4839 {
4840 Dwarf_Die cu = CUDIE (p->cu);
4841 return cudie_base (&cu);
4842 }
4843
4844 /* To store the name used in compare_listptr */
4845 static const char *sort_listptr_name;
4846
4847 static int
compare_listptr(const void * a,const void * b)4848 compare_listptr (const void *a, const void *b)
4849 {
4850 const char *name = sort_listptr_name;
4851 struct listptr *p1 = (void *) a;
4852 struct listptr *p2 = (void *) b;
4853
4854 if (p1->offset < p2->offset)
4855 return -1;
4856 if (p1->offset > p2->offset)
4857 return 1;
4858
4859 if (!p1->warned && !p2->warned)
4860 {
4861 if (p1->addr64 != p2->addr64)
4862 {
4863 p1->warned = p2->warned = true;
4864 error (0, 0,
4865 _("%s %#" PRIx64 " used with different address sizes"),
4866 name, (uint64_t) p1->offset);
4867 }
4868 if (p1->dwarf64 != p2->dwarf64)
4869 {
4870 p1->warned = p2->warned = true;
4871 error (0, 0,
4872 _("%s %#" PRIx64 " used with different offset sizes"),
4873 name, (uint64_t) p1->offset);
4874 }
4875 if (listptr_base (p1) != listptr_base (p2))
4876 {
4877 p1->warned = p2->warned = true;
4878 error (0, 0,
4879 _("%s %#" PRIx64 " used with different base addresses"),
4880 name, (uint64_t) p1->offset);
4881 }
4882 if (p1->attr != p2 ->attr)
4883 {
4884 p1->warned = p2->warned = true;
4885 error (0, 0,
4886 _("%s %#" PRIx64
4887 " used with different attribute %s and %s"),
4888 name, (uint64_t) p1->offset, dwarf_attr_name (p1->attr),
4889 dwarf_attr_name (p2->attr));
4890 }
4891 }
4892
4893 return 0;
4894 }
4895
4896 struct listptr_table
4897 {
4898 size_t n;
4899 size_t alloc;
4900 struct listptr *table;
4901 };
4902
4903 static struct listptr_table known_locsptr;
4904 static struct listptr_table known_loclistsptr;
4905 static struct listptr_table known_rangelistptr;
4906 static struct listptr_table known_rnglistptr;
4907 static struct listptr_table known_addrbases;
4908 static struct listptr_table known_stroffbases;
4909
4910 static void
reset_listptr(struct listptr_table * table)4911 reset_listptr (struct listptr_table *table)
4912 {
4913 free (table->table);
4914 table->table = NULL;
4915 table->n = table->alloc = 0;
4916 }
4917
4918 /* Returns false if offset doesn't fit. See struct listptr. */
4919 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)4920 notice_listptr (enum section_e section, struct listptr_table *table,
4921 uint_fast8_t address_size, uint_fast8_t offset_size,
4922 struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4923 {
4924 if (print_debug_sections & section)
4925 {
4926 if (table->n == table->alloc)
4927 {
4928 if (table->alloc == 0)
4929 table->alloc = 128;
4930 else
4931 table->alloc *= 2;
4932 table->table = xrealloc (table->table,
4933 table->alloc * sizeof table->table[0]);
4934 }
4935
4936 struct listptr *p = &table->table[table->n++];
4937
4938 *p = (struct listptr)
4939 {
4940 .addr64 = address_size == 8,
4941 .dwarf64 = offset_size == 8,
4942 .offset = offset,
4943 .cu = cu,
4944 .attr = attr
4945 };
4946
4947 if (p->offset != offset)
4948 {
4949 table->n--;
4950 return false;
4951 }
4952 }
4953 return true;
4954 }
4955
4956 static void
sort_listptr(struct listptr_table * table,const char * name)4957 sort_listptr (struct listptr_table *table, const char *name)
4958 {
4959 if (table->n > 0)
4960 {
4961 sort_listptr_name = name;
4962 qsort (table->table, table->n, sizeof table->table[0],
4963 &compare_listptr);
4964 }
4965 }
4966
4967 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)4968 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4969 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4970 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4971 unsigned char **readp, unsigned char *endp,
4972 unsigned int *attr)
4973 {
4974 if (table->n == 0)
4975 return false;
4976
4977 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4978 ++*idxp;
4979
4980 struct listptr *p = &table->table[*idxp];
4981
4982 if (*idxp == table->n
4983 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4984 {
4985 *readp = endp;
4986 printf (_(" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4987 offset);
4988 return true;
4989 }
4990
4991 if (p->offset != (Dwarf_Off) offset)
4992 {
4993 *readp += p->offset - offset;
4994 printf (_(" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4995 offset, (Dwarf_Off) p->offset - offset);
4996 return true;
4997 }
4998
4999 if (address_sizep != NULL)
5000 *address_sizep = listptr_address_size (p);
5001 if (offset_sizep != NULL)
5002 *offset_sizep = listptr_offset_size (p);
5003 if (base != NULL)
5004 *base = listptr_base (p);
5005 if (cu != NULL)
5006 *cu = p->cu;
5007 if (attr != NULL)
5008 *attr = p->attr;
5009
5010 return false;
5011 }
5012
5013 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t * idxp,Dwarf_Off off)5014 next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off)
5015 {
5016 /* Note that multiple attributes could in theory point to the same loclist
5017 offset, so make sure we pick one that is bigger than the current one.
5018 The table is sorted on offset. */
5019 if (*idxp < table->n)
5020 {
5021 while (++*idxp < table->n)
5022 {
5023 Dwarf_Off next = table->table[*idxp].offset;
5024 if (next > off)
5025 return next;
5026 }
5027 }
5028 return 0;
5029 }
5030
5031 /* Returns the listptr associated with the given index, or NULL. */
5032 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5033 get_listptr (struct listptr_table *table, size_t idx)
5034 {
5035 if (idx >= table->n)
5036 return NULL;
5037 return &table->table[idx];
5038 }
5039
5040 /* Returns the next index, base address and CU associated with the
5041 list unit offsets. If there is none false is returned, otherwise
5042 true. Assumes the table has been sorted. */
5043 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5044 listptr_cu (struct listptr_table *table, size_t *idxp,
5045 Dwarf_Off start, Dwarf_Off end,
5046 Dwarf_Addr *base, struct Dwarf_CU **cu)
5047 {
5048 while (*idxp < table->n
5049 && table->table[*idxp].offset < start)
5050 ++*idxp;
5051
5052 if (*idxp < table->n
5053 && table->table[*idxp].offset >= start
5054 && table->table[*idxp].offset < end)
5055 {
5056 struct listptr *p = &table->table[*idxp];
5057 *base = listptr_base (p);
5058 *cu = p->cu;
5059 return true;
5060 }
5061
5062 return false;
5063 }
5064
5065 /* Returns the next index with the current CU for the given attribute.
5066 If there is none false is returned, otherwise true. Assumes the
5067 table has been sorted. */
5068 static bool
listptr_attr(struct listptr_table * table,size_t idxp,Dwarf_Off offset,unsigned int attr)5069 listptr_attr (struct listptr_table *table, size_t idxp,
5070 Dwarf_Off offset, unsigned int attr)
5071 {
5072 struct listptr *listptr;
5073 do
5074 {
5075 listptr = get_listptr (table, idxp);
5076 if (listptr == NULL)
5077 return false;
5078
5079 if (listptr->offset == offset && listptr->attr == attr)
5080 return true;
5081
5082 idxp++;
5083 }
5084 while (listptr->offset <= offset);
5085
5086 return false;
5087 }
5088
5089 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5090 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5091 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5092 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5093 {
5094 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5095 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5096
5097 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5098 " [ Code]\n"),
5099 elf_ndxscn (scn), section_name (ebl, shdr),
5100 (uint64_t) shdr->sh_offset);
5101
5102 Dwarf_Off offset = 0;
5103 while (offset < sh_size)
5104 {
5105 printf (_("\nAbbreviation section at offset %" PRIu64 ":\n"),
5106 offset);
5107
5108 while (1)
5109 {
5110 size_t length;
5111 Dwarf_Abbrev abbrev;
5112
5113 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5114 if (res != 0)
5115 {
5116 if (unlikely (res < 0))
5117 {
5118 printf (_("\
5119 *** error while reading abbreviation: %s\n"),
5120 dwarf_errmsg (-1));
5121 return;
5122 }
5123
5124 /* This is the NUL byte at the end of the section. */
5125 ++offset;
5126 break;
5127 }
5128
5129 /* We know these calls can never fail. */
5130 unsigned int code = dwarf_getabbrevcode (&abbrev);
5131 unsigned int tag = dwarf_getabbrevtag (&abbrev);
5132 int has_children = dwarf_abbrevhaschildren (&abbrev);
5133
5134 printf (_(" [%5u] offset: %" PRId64
5135 ", children: %s, tag: %s\n"),
5136 code, (int64_t) offset,
5137 has_children ? yes_str : no_str,
5138 dwarf_tag_name (tag));
5139
5140 size_t cnt = 0;
5141 unsigned int name;
5142 unsigned int form;
5143 Dwarf_Sword data;
5144 Dwarf_Off enoffset;
5145 while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5146 &data, &enoffset) == 0)
5147 {
5148 printf (" attr: %s, form: %s",
5149 dwarf_attr_name (name), dwarf_form_name (form));
5150 if (form == DW_FORM_implicit_const)
5151 printf (" (%" PRId64 ")", data);
5152 printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5153 ++cnt;
5154 }
5155
5156 offset += length;
5157 }
5158 }
5159 }
5160
5161
5162 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5163 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5164 Ebl *ebl, GElf_Ehdr *ehdr,
5165 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5166 {
5167 printf (_("\
5168 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5169 elf_ndxscn (scn), section_name (ebl, shdr),
5170 (uint64_t) shdr->sh_offset);
5171
5172 if (shdr->sh_size == 0)
5173 return;
5174
5175 /* We like to get the section from libdw to make sure they are relocated. */
5176 Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5177 ?: elf_rawdata (scn, NULL));
5178 if (unlikely (data == NULL))
5179 {
5180 error (0, 0, _("cannot get .debug_addr section data: %s"),
5181 elf_errmsg (-1));
5182 return;
5183 }
5184
5185 size_t idx = 0;
5186 sort_listptr (&known_addrbases, "addr_base");
5187
5188 const unsigned char *start = (const unsigned char *) data->d_buf;
5189 const unsigned char *readp = start;
5190 const unsigned char *readendp = ((const unsigned char *) data->d_buf
5191 + data->d_size);
5192
5193 while (readp < readendp)
5194 {
5195 /* We cannot really know whether or not there is an header. The
5196 DebugFission extension to DWARF4 doesn't add one. The DWARF5
5197 .debug_addr variant does. Whether or not we have an header,
5198 DW_AT_[GNU_]addr_base points at "index 0". So if the current
5199 offset equals the CU addr_base then we can just start
5200 printing addresses. If there is no CU with an exact match
5201 then we'll try to parse the header first. */
5202 Dwarf_Off off = (Dwarf_Off) (readp
5203 - (const unsigned char *) data->d_buf);
5204
5205 printf ("Table at offset %" PRIx64 " ", off);
5206
5207 struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5208 const unsigned char *next_unitp;
5209
5210 uint64_t unit_length;
5211 uint16_t version;
5212 uint8_t address_size;
5213 uint8_t segment_size;
5214 if (listptr == NULL)
5215 {
5216 error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5217 off);
5218
5219 /* We will have to assume it is just addresses to the end... */
5220 address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5221 next_unitp = readendp;
5222 printf ("Unknown CU:\n");
5223 }
5224 else
5225 {
5226 Dwarf_Die cudie;
5227 if (dwarf_cu_die (listptr->cu, &cudie,
5228 NULL, NULL, NULL, NULL,
5229 NULL, NULL) == NULL)
5230 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5231 else
5232 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5233
5234 if (listptr->offset == off)
5235 {
5236 address_size = listptr_address_size (listptr);
5237 segment_size = 0;
5238 version = 4;
5239
5240 /* The addresses start here, but where do they end? */
5241 listptr = get_listptr (&known_addrbases, idx);
5242 if (listptr == NULL)
5243 next_unitp = readendp;
5244 else if (listptr->cu->version < 5)
5245 {
5246 next_unitp = start + listptr->offset;
5247 if (listptr->offset < off || listptr->offset > data->d_size)
5248 {
5249 error (0, 0,
5250 "Warning: Bad address base for next unit at %"
5251 PRIx64, off);
5252 next_unitp = readendp;
5253 }
5254 }
5255 else
5256 {
5257 /* Tricky, we don't have a header for this unit, but
5258 there is one for the next. We will have to
5259 "guess" how big it is and subtract it from the
5260 offset (because that points after the header). */
5261 unsigned int offset_size = listptr_offset_size (listptr);
5262 Dwarf_Off next_off = (listptr->offset
5263 - (offset_size == 4 ? 4 : 12) /* len */
5264 - 2 /* version */
5265 - 1 /* address size */
5266 - 1); /* segment selector size */
5267 next_unitp = start + next_off;
5268 if (next_off < off || next_off > data->d_size)
5269 {
5270 error (0, 0,
5271 "Warning: Couldn't calculate .debug_addr "
5272 " unit length at %" PRIx64, off);
5273 next_unitp = readendp;
5274 }
5275 }
5276 unit_length = (uint64_t) (next_unitp - readp);
5277
5278 /* Pretend we have a header. */
5279 printf ("\n");
5280 printf (_(" Length: %8" PRIu64 "\n"),
5281 unit_length);
5282 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5283 printf (_(" Address size: %8" PRIu64 "\n"),
5284 (uint64_t) address_size);
5285 printf (_(" Segment size: %8" PRIu64 "\n"),
5286 (uint64_t) segment_size);
5287 printf ("\n");
5288 }
5289 else
5290 {
5291 /* OK, we have to parse an header first. */
5292 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5293 if (unlikely (unit_length == 0xffffffff))
5294 {
5295 if (unlikely (readp > readendp - 8))
5296 {
5297 invalid_data:
5298 error (0, 0, "Invalid data");
5299 return;
5300 }
5301 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5302 }
5303 printf ("\n");
5304 printf (_(" Length: %8" PRIu64 "\n"),
5305 unit_length);
5306
5307 /* We need at least 2-bytes (version) + 1-byte
5308 (addr_size) + 1-byte (segment_size) = 4 bytes to
5309 complete the header. And this unit cannot go beyond
5310 the section data. */
5311 if (readp > readendp - 4
5312 || unit_length < 4
5313 || unit_length > (uint64_t) (readendp - readp))
5314 goto invalid_data;
5315
5316 next_unitp = readp + unit_length;
5317
5318 version = read_2ubyte_unaligned_inc (dbg, readp);
5319 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5320
5321 if (version != 5)
5322 {
5323 error (0, 0, _("Unknown version"));
5324 goto next_unit;
5325 }
5326
5327 address_size = *readp++;
5328 printf (_(" Address size: %8" PRIu64 "\n"),
5329 (uint64_t) address_size);
5330
5331 if (address_size != 4 && address_size != 8)
5332 {
5333 error (0, 0, _("unsupported address size"));
5334 goto next_unit;
5335 }
5336
5337 segment_size = *readp++;
5338 printf (_(" Segment size: %8" PRIu64 "\n"),
5339 (uint64_t) segment_size);
5340 printf ("\n");
5341
5342 if (segment_size != 0)
5343 {
5344 error (0, 0, _("unsupported segment size"));
5345 goto next_unit;
5346 }
5347
5348 if (listptr->offset != (Dwarf_Off) (readp - start))
5349 {
5350 error (0, 0, "Address index doesn't start after header");
5351 goto next_unit;
5352 }
5353 }
5354 }
5355
5356 int digits = 1;
5357 size_t addresses = (next_unitp - readp) / address_size;
5358 while (addresses >= 10)
5359 {
5360 ++digits;
5361 addresses /= 10;
5362 }
5363
5364 unsigned int uidx = 0;
5365 size_t index_offset = readp - (const unsigned char *) data->d_buf;
5366 printf (" Addresses start at offset 0x%zx:\n", index_offset);
5367 while (readp <= next_unitp - address_size)
5368 {
5369 Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5370 readp);
5371 printf (" [%*u] ", digits, uidx++);
5372 print_dwarf_addr (dwflmod, address_size, addr, addr);
5373 printf ("\n");
5374 }
5375 printf ("\n");
5376
5377 if (readp != next_unitp)
5378 error (0, 0, "extra %zd bytes at end of unit",
5379 (size_t) (next_unitp - readp));
5380
5381 next_unit:
5382 readp = next_unitp;
5383 }
5384 }
5385
5386 /* Print content of DWARF .debug_aranges section. We fortunately do
5387 not have to know a bit about the structure of the section, libdwarf
5388 takes care of it. */
5389 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5390 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5391 GElf_Shdr *shdr, Dwarf *dbg)
5392 {
5393 Dwarf_Aranges *aranges;
5394 size_t cnt;
5395 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5396 {
5397 error (0, 0, _("cannot get .debug_aranges content: %s"),
5398 dwarf_errmsg (-1));
5399 return;
5400 }
5401
5402 GElf_Shdr glink_mem;
5403 GElf_Shdr *glink;
5404 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5405 if (glink == NULL)
5406 {
5407 error (0, 0, _("invalid sh_link value in section %zu"),
5408 elf_ndxscn (scn));
5409 return;
5410 }
5411
5412 printf (ngettext ("\
5413 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5414 "\
5415 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5416 cnt),
5417 elf_ndxscn (scn), section_name (ebl, shdr),
5418 (uint64_t) shdr->sh_offset, cnt);
5419
5420 /* Compute floor(log16(cnt)). */
5421 size_t tmp = cnt;
5422 int digits = 1;
5423 while (tmp >= 16)
5424 {
5425 ++digits;
5426 tmp >>= 4;
5427 }
5428
5429 for (size_t n = 0; n < cnt; ++n)
5430 {
5431 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5432 if (unlikely (runp == NULL))
5433 {
5434 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5435 return;
5436 }
5437
5438 Dwarf_Addr start;
5439 Dwarf_Word length;
5440 Dwarf_Off offset;
5441
5442 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5443 printf (_(" [%*zu] ???\n"), digits, n);
5444 else
5445 printf (_(" [%*zu] start: %0#*" PRIx64
5446 ", length: %5" PRIu64 ", CU DIE offset: %6"
5447 PRId64 "\n"),
5448 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5449 (uint64_t) start, (uint64_t) length, (int64_t) offset);
5450 }
5451 }
5452
5453
5454 /* Print content of DWARF .debug_aranges section. */
5455 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5456 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5457 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5458 GElf_Shdr *shdr, Dwarf *dbg)
5459 {
5460 if (decodedaranges)
5461 {
5462 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5463 return;
5464 }
5465
5466 Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5467 ?: elf_rawdata (scn, NULL));
5468
5469 if (unlikely (data == NULL))
5470 {
5471 error (0, 0, _("cannot get .debug_aranges content: %s"),
5472 elf_errmsg (-1));
5473 return;
5474 }
5475
5476 printf (_("\
5477 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5478 elf_ndxscn (scn), section_name (ebl, shdr),
5479 (uint64_t) shdr->sh_offset);
5480
5481 const unsigned char *readp = data->d_buf;
5482 const unsigned char *readendp = readp + data->d_size;
5483
5484 while (readp < readendp)
5485 {
5486 const unsigned char *hdrstart = readp;
5487 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5488
5489 printf (_("\nTable at offset %zu:\n"), start_offset);
5490 if (readp + 4 > readendp)
5491 {
5492 invalid_data:
5493 error (0, 0, _("invalid data in section [%zu] '%s'"),
5494 elf_ndxscn (scn), section_name (ebl, shdr));
5495 return;
5496 }
5497
5498 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5499 unsigned int length_bytes = 4;
5500 if (length == DWARF3_LENGTH_64_BIT)
5501 {
5502 if (readp + 8 > readendp)
5503 goto invalid_data;
5504 length = read_8ubyte_unaligned_inc (dbg, readp);
5505 length_bytes = 8;
5506 }
5507
5508 const unsigned char *nexthdr = readp + length;
5509 printf (_("\n Length: %6" PRIu64 "\n"),
5510 (uint64_t) length);
5511
5512 if (unlikely (length > (size_t) (readendp - readp)))
5513 goto invalid_data;
5514
5515 if (length == 0)
5516 continue;
5517
5518 if (readp + 2 > readendp)
5519 goto invalid_data;
5520 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5521 printf (_(" DWARF version: %6" PRIuFAST16 "\n"),
5522 version);
5523 if (version != 2)
5524 {
5525 error (0, 0, _("unsupported aranges version"));
5526 goto next_table;
5527 }
5528
5529 Dwarf_Word offset;
5530 if (readp + length_bytes > readendp)
5531 goto invalid_data;
5532 if (length_bytes == 8)
5533 offset = read_8ubyte_unaligned_inc (dbg, readp);
5534 else
5535 offset = read_4ubyte_unaligned_inc (dbg, readp);
5536 printf (_(" CU offset: %6" PRIx64 "\n"),
5537 (uint64_t) offset);
5538
5539 if (readp + 1 > readendp)
5540 goto invalid_data;
5541 unsigned int address_size = *readp++;
5542 printf (_(" Address size: %6" PRIu64 "\n"),
5543 (uint64_t) address_size);
5544 if (address_size != 4 && address_size != 8)
5545 {
5546 error (0, 0, _("unsupported address size"));
5547 goto next_table;
5548 }
5549
5550 if (readp + 1 > readendp)
5551 goto invalid_data;
5552 unsigned int segment_size = *readp++;
5553 printf (_(" Segment size: %6" PRIu64 "\n\n"),
5554 (uint64_t) segment_size);
5555 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5556 {
5557 error (0, 0, _("unsupported segment size"));
5558 goto next_table;
5559 }
5560
5561 /* Round the address to the next multiple of 2*address_size. */
5562 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5563 % (2 * address_size));
5564
5565 while (readp < nexthdr)
5566 {
5567 Dwarf_Word range_address;
5568 Dwarf_Word range_length;
5569 Dwarf_Word segment = 0;
5570 if (readp + 2 * address_size + segment_size > readendp)
5571 goto invalid_data;
5572 if (address_size == 4)
5573 {
5574 range_address = read_4ubyte_unaligned_inc (dbg, readp);
5575 range_length = read_4ubyte_unaligned_inc (dbg, readp);
5576 }
5577 else
5578 {
5579 range_address = read_8ubyte_unaligned_inc (dbg, readp);
5580 range_length = read_8ubyte_unaligned_inc (dbg, readp);
5581 }
5582
5583 if (segment_size == 4)
5584 segment = read_4ubyte_unaligned_inc (dbg, readp);
5585 else if (segment_size == 8)
5586 segment = read_8ubyte_unaligned_inc (dbg, readp);
5587
5588 if (range_address == 0 && range_length == 0 && segment == 0)
5589 break;
5590
5591 printf (" ");
5592 print_dwarf_addr (dwflmod, address_size, range_address,
5593 range_address);
5594 printf ("..");
5595 print_dwarf_addr (dwflmod, address_size,
5596 range_address + range_length - 1,
5597 range_length);
5598 if (segment_size != 0)
5599 printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5600 else
5601 printf ("\n");
5602 }
5603
5604 next_table:
5605 if (readp != nexthdr)
5606 {
5607 size_t padding = nexthdr - readp;
5608 printf (_(" %zu padding bytes\n"), padding);
5609 readp = nexthdr;
5610 }
5611 }
5612 }
5613
5614
5615 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5616
5617 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5618 DWARF (.dwo) file. */
5619 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5620 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5621 {
5622 uint64_t id;
5623 if (is_split_dwarf (dbg, &id, cu))
5624 {
5625 Dwarf_Die cudie;
5626 if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5627 {
5628 *cu_base = cudie_base (&cudie);
5629 return true;
5630 }
5631 }
5632 return false;
5633 }
5634
5635 /* Print content of DWARF .debug_rnglists section. */
5636 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5637 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5638 Ebl *ebl,
5639 GElf_Ehdr *ehdr __attribute__ ((unused)),
5640 Elf_Scn *scn, GElf_Shdr *shdr,
5641 Dwarf *dbg __attribute__((unused)))
5642 {
5643 printf (_("\
5644 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5645 elf_ndxscn (scn), section_name (ebl, shdr),
5646 (uint64_t) shdr->sh_offset);
5647
5648 Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5649 ?: elf_rawdata (scn, NULL));
5650 if (unlikely (data == NULL))
5651 {
5652 error (0, 0, _("cannot get .debug_rnglists content: %s"),
5653 elf_errmsg (-1));
5654 return;
5655 }
5656
5657 /* For the listptr to get the base address/CU. */
5658 sort_listptr (&known_rnglistptr, "rnglistptr");
5659 size_t listptr_idx = 0;
5660
5661 const unsigned char *readp = data->d_buf;
5662 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5663 + data->d_size);
5664 while (readp < dataend)
5665 {
5666 if (unlikely (readp > dataend - 4))
5667 {
5668 invalid_data:
5669 error (0, 0, _("invalid data in section [%zu] '%s'"),
5670 elf_ndxscn (scn), section_name (ebl, shdr));
5671 return;
5672 }
5673
5674 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5675 printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
5676 (uint64_t) offset);
5677
5678 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5679 unsigned int offset_size = 4;
5680 if (unlikely (unit_length == 0xffffffff))
5681 {
5682 if (unlikely (readp > dataend - 8))
5683 goto invalid_data;
5684
5685 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5686 offset_size = 8;
5687 }
5688 printf (_(" Length: %8" PRIu64 "\n"), unit_length);
5689
5690 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5691 bytes to complete the header. And this unit cannot go beyond
5692 the section data. */
5693 if (readp > dataend - 8
5694 || unit_length < 8
5695 || unit_length > (uint64_t) (dataend - readp))
5696 goto invalid_data;
5697
5698 const unsigned char *nexthdr = readp + unit_length;
5699
5700 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5701 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5702
5703 if (version != 5)
5704 {
5705 error (0, 0, _("Unknown version"));
5706 goto next_table;
5707 }
5708
5709 uint8_t address_size = *readp++;
5710 printf (_(" Address size: %8" PRIu64 "\n"),
5711 (uint64_t) address_size);
5712
5713 if (address_size != 4 && address_size != 8)
5714 {
5715 error (0, 0, _("unsupported address size"));
5716 goto next_table;
5717 }
5718
5719 uint8_t segment_size = *readp++;
5720 printf (_(" Segment size: %8" PRIu64 "\n"),
5721 (uint64_t) segment_size);
5722
5723 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5724 {
5725 error (0, 0, _("unsupported segment size"));
5726 goto next_table;
5727 }
5728
5729 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5730 printf (_(" Offset entries: %8" PRIu64 "\n"),
5731 (uint64_t) offset_entry_count);
5732
5733 /* We need the CU that uses this unit to get the initial base address. */
5734 Dwarf_Addr cu_base = 0;
5735 struct Dwarf_CU *cu = NULL;
5736 if (listptr_cu (&known_rnglistptr, &listptr_idx,
5737 (Dwarf_Off) offset,
5738 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5739 &cu_base, &cu)
5740 || split_dwarf_cu_base (dbg, &cu, &cu_base))
5741 {
5742 Dwarf_Die cudie;
5743 if (dwarf_cu_die (cu, &cudie,
5744 NULL, NULL, NULL, NULL,
5745 NULL, NULL) == NULL)
5746 printf (_(" Unknown CU base: "));
5747 else
5748 printf (_(" CU [%6" PRIx64 "] base: "),
5749 dwarf_dieoffset (&cudie));
5750 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5751 printf ("\n");
5752 }
5753 else
5754 printf (_(" Not associated with a CU.\n"));
5755
5756 printf ("\n");
5757
5758 const unsigned char *offset_array_start = readp;
5759 if (offset_entry_count > 0)
5760 {
5761 uint64_t max_entries = (unit_length - 8) / offset_size;
5762 if (offset_entry_count > max_entries)
5763 {
5764 error (0, 0,
5765 _("too many offset entries for unit length"));
5766 offset_entry_count = max_entries;
5767 }
5768
5769 printf (_(" Offsets starting at 0x%" PRIx64 ":\n"),
5770 (uint64_t) (offset_array_start
5771 - (unsigned char *) data->d_buf));
5772 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5773 {
5774 printf (" [%6" PRIu32 "] ", idx);
5775 if (offset_size == 4)
5776 {
5777 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5778 printf ("0x%" PRIx32 "\n", off);
5779 }
5780 else
5781 {
5782 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5783 printf ("0x%" PRIx64 "\n", off);
5784 }
5785 }
5786 printf ("\n");
5787 }
5788
5789 Dwarf_Addr base = cu_base;
5790 bool start_of_list = true;
5791 while (readp < nexthdr)
5792 {
5793 uint8_t kind = *readp++;
5794 uint64_t op1, op2;
5795
5796 /* Skip padding. */
5797 if (start_of_list && kind == DW_RLE_end_of_list)
5798 continue;
5799
5800 if (start_of_list)
5801 {
5802 base = cu_base;
5803 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5804 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5805 (uint64_t) (readp - offset_array_start - 1));
5806 start_of_list = false;
5807 }
5808
5809 printf (" %s", dwarf_range_list_encoding_name (kind));
5810 switch (kind)
5811 {
5812 case DW_RLE_end_of_list:
5813 start_of_list = true;
5814 printf ("\n\n");
5815 break;
5816
5817 case DW_RLE_base_addressx:
5818 if ((uint64_t) (nexthdr - readp) < 1)
5819 {
5820 invalid_range:
5821 error (0, 0, _("invalid range list data"));
5822 goto next_table;
5823 }
5824 get_uleb128 (op1, readp, nexthdr);
5825 printf (" %" PRIx64 "\n", op1);
5826 if (! print_unresolved_addresses)
5827 {
5828 Dwarf_Addr addr;
5829 if (get_indexed_addr (cu, op1, &addr) != 0)
5830 printf (" ???\n");
5831 else
5832 {
5833 printf (" ");
5834 print_dwarf_addr (dwflmod, address_size, addr, addr);
5835 printf ("\n");
5836 }
5837 }
5838 break;
5839
5840 case DW_RLE_startx_endx:
5841 if ((uint64_t) (nexthdr - readp) < 1)
5842 goto invalid_range;
5843 get_uleb128 (op1, readp, nexthdr);
5844 if ((uint64_t) (nexthdr - readp) < 1)
5845 goto invalid_range;
5846 get_uleb128 (op2, readp, nexthdr);
5847 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5848 if (! print_unresolved_addresses)
5849 {
5850 Dwarf_Addr addr1;
5851 Dwarf_Addr addr2;
5852 if (get_indexed_addr (cu, op1, &addr1) != 0
5853 || get_indexed_addr (cu, op2, &addr2) != 0)
5854 {
5855 printf (" ???..\n");
5856 printf (" ???\n");
5857 }
5858 else
5859 {
5860 printf (" ");
5861 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5862 printf ("..\n ");
5863 print_dwarf_addr (dwflmod, address_size,
5864 addr2 - 1, addr2);
5865 printf ("\n");
5866 }
5867 }
5868 break;
5869
5870 case DW_RLE_startx_length:
5871 if ((uint64_t) (nexthdr - readp) < 1)
5872 goto invalid_range;
5873 get_uleb128 (op1, readp, nexthdr);
5874 if ((uint64_t) (nexthdr - readp) < 1)
5875 goto invalid_range;
5876 get_uleb128 (op2, readp, nexthdr);
5877 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5878 if (! print_unresolved_addresses)
5879 {
5880 Dwarf_Addr addr1;
5881 Dwarf_Addr addr2;
5882 if (get_indexed_addr (cu, op1, &addr1) != 0)
5883 {
5884 printf (" ???..\n");
5885 printf (" ???\n");
5886 }
5887 else
5888 {
5889 addr2 = addr1 + op2;
5890 printf (" ");
5891 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5892 printf ("..\n ");
5893 print_dwarf_addr (dwflmod, address_size,
5894 addr2 - 1, addr2);
5895 printf ("\n");
5896 }
5897 }
5898 break;
5899
5900 case DW_RLE_offset_pair:
5901 if ((uint64_t) (nexthdr - readp) < 1)
5902 goto invalid_range;
5903 get_uleb128 (op1, readp, nexthdr);
5904 if ((uint64_t) (nexthdr - readp) < 1)
5905 goto invalid_range;
5906 get_uleb128 (op2, readp, nexthdr);
5907 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5908 if (! print_unresolved_addresses)
5909 {
5910 op1 += base;
5911 op2 += base;
5912 printf (" ");
5913 print_dwarf_addr (dwflmod, address_size, op1, op1);
5914 printf ("..\n ");
5915 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5916 printf ("\n");
5917 }
5918 break;
5919
5920 case DW_RLE_base_address:
5921 if (address_size == 4)
5922 {
5923 if ((uint64_t) (nexthdr - readp) < 4)
5924 goto invalid_range;
5925 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5926 }
5927 else
5928 {
5929 if ((uint64_t) (nexthdr - readp) < 8)
5930 goto invalid_range;
5931 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5932 }
5933 base = op1;
5934 printf (" 0x%" PRIx64 "\n", base);
5935 if (! print_unresolved_addresses)
5936 {
5937 printf (" ");
5938 print_dwarf_addr (dwflmod, address_size, base, base);
5939 printf ("\n");
5940 }
5941 break;
5942
5943 case DW_RLE_start_end:
5944 if (address_size == 4)
5945 {
5946 if ((uint64_t) (nexthdr - readp) < 8)
5947 goto invalid_range;
5948 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5949 op2 = read_4ubyte_unaligned_inc (dbg, readp);
5950 }
5951 else
5952 {
5953 if ((uint64_t) (nexthdr - readp) < 16)
5954 goto invalid_range;
5955 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5956 op2 = read_8ubyte_unaligned_inc (dbg, readp);
5957 }
5958 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5959 if (! print_unresolved_addresses)
5960 {
5961 printf (" ");
5962 print_dwarf_addr (dwflmod, address_size, op1, op1);
5963 printf ("..\n ");
5964 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5965 printf ("\n");
5966 }
5967 break;
5968
5969 case DW_RLE_start_length:
5970 if (address_size == 4)
5971 {
5972 if ((uint64_t) (nexthdr - readp) < 4)
5973 goto invalid_range;
5974 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5975 }
5976 else
5977 {
5978 if ((uint64_t) (nexthdr - readp) < 8)
5979 goto invalid_range;
5980 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5981 }
5982 if ((uint64_t) (nexthdr - readp) < 1)
5983 goto invalid_range;
5984 get_uleb128 (op2, readp, nexthdr);
5985 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5986 if (! print_unresolved_addresses)
5987 {
5988 op2 = op1 + op2;
5989 printf (" ");
5990 print_dwarf_addr (dwflmod, address_size, op1, op1);
5991 printf ("..\n ");
5992 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5993 printf ("\n");
5994 }
5995 break;
5996
5997 default:
5998 goto invalid_range;
5999 }
6000 }
6001
6002 next_table:
6003 if (readp != nexthdr)
6004 {
6005 size_t padding = nexthdr - readp;
6006 printf (_(" %zu padding bytes\n\n"), padding);
6007 readp = nexthdr;
6008 }
6009 }
6010 }
6011
6012 /* Print content of DWARF .debug_ranges section. */
6013 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6014 print_debug_ranges_section (Dwfl_Module *dwflmod,
6015 Ebl *ebl, GElf_Ehdr *ehdr,
6016 Elf_Scn *scn, GElf_Shdr *shdr,
6017 Dwarf *dbg)
6018 {
6019 Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
6020 ?: elf_rawdata (scn, NULL));
6021 if (unlikely (data == NULL))
6022 {
6023 error (0, 0, _("cannot get .debug_ranges content: %s"),
6024 elf_errmsg (-1));
6025 return;
6026 }
6027
6028 printf (_("\
6029 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6030 elf_ndxscn (scn), section_name (ebl, shdr),
6031 (uint64_t) shdr->sh_offset);
6032
6033 sort_listptr (&known_rangelistptr, "rangelistptr");
6034 size_t listptr_idx = 0;
6035
6036 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6037
6038 bool first = true;
6039 Dwarf_Addr base = 0;
6040 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6041 unsigned char *readp = data->d_buf;
6042 Dwarf_CU *last_cu = NULL;
6043 while (readp < endp)
6044 {
6045 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6046 Dwarf_CU *cu = last_cu;
6047
6048 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6049 &address_size, NULL, &base, &cu,
6050 offset, &readp, endp, NULL))
6051 continue;
6052
6053 if (last_cu != cu)
6054 {
6055 Dwarf_Die cudie;
6056 if (dwarf_cu_die (cu, &cudie,
6057 NULL, NULL, NULL, NULL,
6058 NULL, NULL) == NULL)
6059 printf (_("\n Unknown CU base: "));
6060 else
6061 printf (_("\n CU [%6" PRIx64 "] base: "),
6062 dwarf_dieoffset (&cudie));
6063 print_dwarf_addr (dwflmod, address_size, base, base);
6064 printf ("\n");
6065 }
6066 last_cu = cu;
6067
6068 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6069 {
6070 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
6071 break;
6072 }
6073
6074 Dwarf_Addr begin;
6075 Dwarf_Addr end;
6076 if (address_size == 8)
6077 {
6078 begin = read_8ubyte_unaligned_inc (dbg, readp);
6079 end = read_8ubyte_unaligned_inc (dbg, readp);
6080 }
6081 else
6082 {
6083 begin = read_4ubyte_unaligned_inc (dbg, readp);
6084 end = read_4ubyte_unaligned_inc (dbg, readp);
6085 if (begin == (Dwarf_Addr) (uint32_t) -1)
6086 begin = (Dwarf_Addr) -1l;
6087 }
6088
6089 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6090 {
6091 if (first)
6092 printf (" [%6tx] ", offset);
6093 else
6094 printf (" ");
6095 puts (_("base address"));
6096 printf (" ");
6097 print_dwarf_addr (dwflmod, address_size, end, end);
6098 printf ("\n");
6099 base = end;
6100 first = false;
6101 }
6102 else if (begin == 0 && end == 0) /* End of list entry. */
6103 {
6104 if (first)
6105 printf (_(" [%6tx] empty list\n"), offset);
6106 first = true;
6107 }
6108 else
6109 {
6110 /* We have an address range entry. */
6111 if (first) /* First address range entry in a list. */
6112 printf (" [%6tx] ", offset);
6113 else
6114 printf (" ");
6115
6116 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6117 if (! print_unresolved_addresses)
6118 {
6119 printf (" ");
6120 print_dwarf_addr (dwflmod, address_size, base + begin,
6121 base + begin);
6122 printf ("..\n ");
6123 print_dwarf_addr (dwflmod, address_size,
6124 base + end - 1, base + end);
6125 printf ("\n");
6126 }
6127
6128 first = false;
6129 }
6130 }
6131 }
6132
6133 #define REGNAMESZ 16
6134 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6135 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6136 char name[REGNAMESZ], int *bits, int *type)
6137 {
6138 const char *set;
6139 const char *pfx;
6140 int ignore;
6141 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6142 bits ?: &ignore, type ?: &ignore);
6143 if (n <= 0)
6144 {
6145 if (loc != NULL)
6146 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6147 else
6148 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6149 if (bits != NULL)
6150 *bits = loc != NULL ? loc->bits : 0;
6151 if (type != NULL)
6152 *type = DW_ATE_unsigned;
6153 set = "??? unrecognized";
6154 }
6155 else
6156 {
6157 if (bits != NULL && *bits <= 0)
6158 *bits = loc != NULL ? loc->bits : 0;
6159 if (type != NULL && *type == DW_ATE_void)
6160 *type = DW_ATE_unsigned;
6161
6162 }
6163 return set;
6164 }
6165
6166 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6167 read_encoded (unsigned int encoding, const unsigned char *readp,
6168 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6169 {
6170 if ((encoding & 0xf) == DW_EH_PE_absptr)
6171 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6172 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6173
6174 switch (encoding & 0xf)
6175 {
6176 case DW_EH_PE_uleb128:
6177 get_uleb128 (*res, readp, endp);
6178 break;
6179 case DW_EH_PE_sleb128:
6180 get_sleb128 (*res, readp, endp);
6181 break;
6182 case DW_EH_PE_udata2:
6183 if (readp + 2 > endp)
6184 goto invalid;
6185 *res = read_2ubyte_unaligned_inc (dbg, readp);
6186 break;
6187 case DW_EH_PE_udata4:
6188 if (readp + 4 > endp)
6189 goto invalid;
6190 *res = read_4ubyte_unaligned_inc (dbg, readp);
6191 break;
6192 case DW_EH_PE_udata8:
6193 if (readp + 8 > endp)
6194 goto invalid;
6195 *res = read_8ubyte_unaligned_inc (dbg, readp);
6196 break;
6197 case DW_EH_PE_sdata2:
6198 if (readp + 2 > endp)
6199 goto invalid;
6200 *res = read_2sbyte_unaligned_inc (dbg, readp);
6201 break;
6202 case DW_EH_PE_sdata4:
6203 if (readp + 4 > endp)
6204 goto invalid;
6205 *res = read_4sbyte_unaligned_inc (dbg, readp);
6206 break;
6207 case DW_EH_PE_sdata8:
6208 if (readp + 8 > endp)
6209 goto invalid;
6210 *res = read_8sbyte_unaligned_inc (dbg, readp);
6211 break;
6212 default:
6213 invalid:
6214 error (1, 0,
6215 _("invalid encoding"));
6216 }
6217
6218 return readp;
6219 }
6220
6221 static const char *
regname(Ebl * ebl,unsigned int regno,char * regnamebuf)6222 regname (Ebl *ebl, unsigned int regno, char *regnamebuf)
6223 {
6224 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6225
6226 return regnamebuf;
6227 }
6228
6229 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Dwarf * dbg)6230 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6231 Dwarf_Word vma_base, unsigned int code_align,
6232 int data_align,
6233 unsigned int version, unsigned int ptr_size,
6234 unsigned int encoding,
6235 Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
6236 {
6237 char regnamebuf[REGNAMESZ];
6238
6239 puts ("\n Program:");
6240 Dwarf_Word pc = vma_base;
6241 while (readp < endp)
6242 {
6243 unsigned int opcode = *readp++;
6244
6245 if (opcode < DW_CFA_advance_loc)
6246 /* Extended opcode. */
6247 switch (opcode)
6248 {
6249 uint64_t op1;
6250 int64_t sop1;
6251 uint64_t op2;
6252 int64_t sop2;
6253
6254 case DW_CFA_nop:
6255 puts (" nop");
6256 break;
6257 case DW_CFA_set_loc:
6258 if ((uint64_t) (endp - readp) < 1)
6259 goto invalid;
6260 readp = read_encoded (encoding, readp, endp, &op1, dbg);
6261 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6262 op1, pc = vma_base + op1);
6263 break;
6264 case DW_CFA_advance_loc1:
6265 if ((uint64_t) (endp - readp) < 1)
6266 goto invalid;
6267 printf (" advance_loc1 %u to %#" PRIx64 "\n",
6268 *readp, pc += *readp * code_align);
6269 ++readp;
6270 break;
6271 case DW_CFA_advance_loc2:
6272 if ((uint64_t) (endp - readp) < 2)
6273 goto invalid;
6274 op1 = read_2ubyte_unaligned_inc (dbg, readp);
6275 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6276 op1, pc += op1 * code_align);
6277 break;
6278 case DW_CFA_advance_loc4:
6279 if ((uint64_t) (endp - readp) < 4)
6280 goto invalid;
6281 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6282 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6283 op1, pc += op1 * code_align);
6284 break;
6285 case DW_CFA_offset_extended:
6286 if ((uint64_t) (endp - readp) < 1)
6287 goto invalid;
6288 get_uleb128 (op1, readp, endp);
6289 if ((uint64_t) (endp - readp) < 1)
6290 goto invalid;
6291 get_uleb128 (op2, readp, endp);
6292 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6293 "\n",
6294 op1, regname (ebl, op1, regnamebuf), op2 * data_align);
6295 break;
6296 case DW_CFA_restore_extended:
6297 if ((uint64_t) (endp - readp) < 1)
6298 goto invalid;
6299 get_uleb128 (op1, readp, endp);
6300 printf (" restore_extended r%" PRIu64 " (%s)\n",
6301 op1, regname (ebl, op1, regnamebuf));
6302 break;
6303 case DW_CFA_undefined:
6304 if ((uint64_t) (endp - readp) < 1)
6305 goto invalid;
6306 get_uleb128 (op1, readp, endp);
6307 printf (" undefined r%" PRIu64 " (%s)\n", op1,
6308 regname (ebl, op1, regnamebuf));
6309 break;
6310 case DW_CFA_same_value:
6311 if ((uint64_t) (endp - readp) < 1)
6312 goto invalid;
6313 get_uleb128 (op1, readp, endp);
6314 printf (" same_value r%" PRIu64 " (%s)\n", op1,
6315 regname (ebl, op1, regnamebuf));
6316 break;
6317 case DW_CFA_register:
6318 if ((uint64_t) (endp - readp) < 1)
6319 goto invalid;
6320 get_uleb128 (op1, readp, endp);
6321 if ((uint64_t) (endp - readp) < 1)
6322 goto invalid;
6323 get_uleb128 (op2, readp, endp);
6324 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6325 op1, regname (ebl, op1, regnamebuf), op2,
6326 regname (ebl, op2, regnamebuf));
6327 break;
6328 case DW_CFA_remember_state:
6329 puts (" remember_state");
6330 break;
6331 case DW_CFA_restore_state:
6332 puts (" restore_state");
6333 break;
6334 case DW_CFA_def_cfa:
6335 if ((uint64_t) (endp - readp) < 1)
6336 goto invalid;
6337 get_uleb128 (op1, readp, endp);
6338 if ((uint64_t) (endp - readp) < 1)
6339 goto invalid;
6340 get_uleb128 (op2, readp, endp);
6341 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6342 op1, regname (ebl, op1, regnamebuf), op2);
6343 break;
6344 case DW_CFA_def_cfa_register:
6345 if ((uint64_t) (endp - readp) < 1)
6346 goto invalid;
6347 get_uleb128 (op1, readp, endp);
6348 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
6349 op1, regname (ebl, op1, regnamebuf));
6350 break;
6351 case DW_CFA_def_cfa_offset:
6352 if ((uint64_t) (endp - readp) < 1)
6353 goto invalid;
6354 get_uleb128 (op1, readp, endp);
6355 printf (" def_cfa_offset %" PRIu64 "\n", op1);
6356 break;
6357 case DW_CFA_def_cfa_expression:
6358 if ((uint64_t) (endp - readp) < 1)
6359 goto invalid;
6360 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
6361 printf (" def_cfa_expression %" PRIu64 "\n", op1);
6362 if ((uint64_t) (endp - readp) < op1)
6363 {
6364 invalid:
6365 fputs (_(" <INVALID DATA>\n"), stdout);
6366 return;
6367 }
6368 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6369 op1, readp);
6370 readp += op1;
6371 break;
6372 case DW_CFA_expression:
6373 if ((uint64_t) (endp - readp) < 1)
6374 goto invalid;
6375 get_uleb128 (op1, readp, endp);
6376 if ((uint64_t) (endp - readp) < 1)
6377 goto invalid;
6378 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6379 printf (" expression r%" PRIu64 " (%s) \n",
6380 op1, regname (ebl, op1, regnamebuf));
6381 if ((uint64_t) (endp - readp) < op2)
6382 goto invalid;
6383 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6384 op2, readp);
6385 readp += op2;
6386 break;
6387 case DW_CFA_offset_extended_sf:
6388 if ((uint64_t) (endp - readp) < 1)
6389 goto invalid;
6390 get_uleb128 (op1, readp, endp);
6391 if ((uint64_t) (endp - readp) < 1)
6392 goto invalid;
6393 get_sleb128 (sop2, readp, endp);
6394 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6395 PRId64 "\n",
6396 op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6397 break;
6398 case DW_CFA_def_cfa_sf:
6399 if ((uint64_t) (endp - readp) < 1)
6400 goto invalid;
6401 get_uleb128 (op1, readp, endp);
6402 if ((uint64_t) (endp - readp) < 1)
6403 goto invalid;
6404 get_sleb128 (sop2, readp, endp);
6405 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6406 op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6407 break;
6408 case DW_CFA_def_cfa_offset_sf:
6409 if ((uint64_t) (endp - readp) < 1)
6410 goto invalid;
6411 get_sleb128 (sop1, readp, endp);
6412 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6413 break;
6414 case DW_CFA_val_offset:
6415 if ((uint64_t) (endp - readp) < 1)
6416 goto invalid;
6417 get_uleb128 (op1, readp, endp);
6418 if ((uint64_t) (endp - readp) < 1)
6419 goto invalid;
6420 get_uleb128 (op2, readp, endp);
6421 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6422 op1, op2 * data_align);
6423 break;
6424 case DW_CFA_val_offset_sf:
6425 if ((uint64_t) (endp - readp) < 1)
6426 goto invalid;
6427 get_uleb128 (op1, readp, endp);
6428 if ((uint64_t) (endp - readp) < 1)
6429 goto invalid;
6430 get_sleb128 (sop2, readp, endp);
6431 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6432 op1, sop2 * data_align);
6433 break;
6434 case DW_CFA_val_expression:
6435 if ((uint64_t) (endp - readp) < 1)
6436 goto invalid;
6437 get_uleb128 (op1, readp, endp);
6438 if ((uint64_t) (endp - readp) < 1)
6439 goto invalid;
6440 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6441 printf (" val_expression r%" PRIu64 " (%s)\n",
6442 op1, regname (ebl, op1, regnamebuf));
6443 if ((uint64_t) (endp - readp) < op2)
6444 goto invalid;
6445 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6446 NULL, op2, readp);
6447 readp += op2;
6448 break;
6449 case DW_CFA_MIPS_advance_loc8:
6450 if ((uint64_t) (endp - readp) < 8)
6451 goto invalid;
6452 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6453 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6454 op1, pc += op1 * code_align);
6455 break;
6456 case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
6457 if (ehdr->e_machine == EM_AARCH64)
6458 puts (" AARCH64_negate_ra_state");
6459 else
6460 puts (" GNU_window_save");
6461 break;
6462 case DW_CFA_GNU_args_size:
6463 if ((uint64_t) (endp - readp) < 1)
6464 goto invalid;
6465 get_uleb128 (op1, readp, endp);
6466 printf (" args_size %" PRIu64 "\n", op1);
6467 break;
6468 default:
6469 printf (" ??? (%u)\n", opcode);
6470 break;
6471 }
6472 else if (opcode < DW_CFA_offset)
6473 printf (" advance_loc %u to %#" PRIx64 "\n",
6474 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6475 else if (opcode < DW_CFA_restore)
6476 {
6477 uint64_t offset;
6478 if ((uint64_t) (endp - readp) < 1)
6479 goto invalid;
6480 get_uleb128 (offset, readp, endp);
6481 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
6482 opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf),
6483 offset * data_align);
6484 }
6485 else
6486 printf (" restore r%u (%s)\n",
6487 opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf));
6488 }
6489 }
6490
6491
6492 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6493 encoded_ptr_size (int encoding, unsigned int ptr_size)
6494 {
6495 switch (encoding & 7)
6496 {
6497 case DW_EH_PE_udata4:
6498 return 4;
6499 case DW_EH_PE_udata8:
6500 return 8;
6501 case 0:
6502 return ptr_size;
6503 }
6504
6505 fprintf (stderr, "Unsupported pointer encoding: %#x, "
6506 "assuming pointer size of %d.\n", encoding, ptr_size);
6507 return ptr_size;
6508 }
6509
6510
6511 static unsigned int
print_encoding(unsigned int val)6512 print_encoding (unsigned int val)
6513 {
6514 switch (val & 0xf)
6515 {
6516 case DW_EH_PE_absptr:
6517 fputs ("absptr", stdout);
6518 break;
6519 case DW_EH_PE_uleb128:
6520 fputs ("uleb128", stdout);
6521 break;
6522 case DW_EH_PE_udata2:
6523 fputs ("udata2", stdout);
6524 break;
6525 case DW_EH_PE_udata4:
6526 fputs ("udata4", stdout);
6527 break;
6528 case DW_EH_PE_udata8:
6529 fputs ("udata8", stdout);
6530 break;
6531 case DW_EH_PE_sleb128:
6532 fputs ("sleb128", stdout);
6533 break;
6534 case DW_EH_PE_sdata2:
6535 fputs ("sdata2", stdout);
6536 break;
6537 case DW_EH_PE_sdata4:
6538 fputs ("sdata4", stdout);
6539 break;
6540 case DW_EH_PE_sdata8:
6541 fputs ("sdata8", stdout);
6542 break;
6543 default:
6544 /* We did not use any of the bits after all. */
6545 return val;
6546 }
6547
6548 return val & ~0xf;
6549 }
6550
6551
6552 static unsigned int
print_relinfo(unsigned int val)6553 print_relinfo (unsigned int val)
6554 {
6555 switch (val & 0x70)
6556 {
6557 case DW_EH_PE_pcrel:
6558 fputs ("pcrel", stdout);
6559 break;
6560 case DW_EH_PE_textrel:
6561 fputs ("textrel", stdout);
6562 break;
6563 case DW_EH_PE_datarel:
6564 fputs ("datarel", stdout);
6565 break;
6566 case DW_EH_PE_funcrel:
6567 fputs ("funcrel", stdout);
6568 break;
6569 case DW_EH_PE_aligned:
6570 fputs ("aligned", stdout);
6571 break;
6572 default:
6573 return val;
6574 }
6575
6576 return val & ~0x70;
6577 }
6578
6579
6580 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6581 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6582 {
6583 printf ("(%s", pfx);
6584
6585 if (fde_encoding == DW_EH_PE_omit)
6586 puts ("omit)");
6587 else
6588 {
6589 unsigned int w = fde_encoding;
6590
6591 w = print_encoding (w);
6592
6593 if (w & 0x70)
6594 {
6595 if (w != fde_encoding)
6596 fputc_unlocked (' ', stdout);
6597
6598 w = print_relinfo (w);
6599 }
6600
6601 if (w != 0)
6602 printf ("%s%x", w != fde_encoding ? " " : "", w);
6603
6604 puts (")");
6605 }
6606 }
6607
6608
6609 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6610 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6611 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6612 {
6613 size_t shstrndx;
6614 /* We know this call will succeed since it did in the caller. */
6615 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6616 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6617
6618 /* Needed if we find PC-relative addresses. */
6619 GElf_Addr bias;
6620 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6621 {
6622 error (0, 0, _("cannot get ELF: %s"), dwfl_errmsg (-1));
6623 return;
6624 }
6625
6626 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6627 Elf_Data *data = (is_eh_frame
6628 ? elf_rawdata (scn, NULL)
6629 : (dbg->sectiondata[IDX_debug_frame]
6630 ?: elf_rawdata (scn, NULL)));
6631
6632 if (unlikely (data == NULL))
6633 {
6634 error (0, 0, _("cannot get %s content: %s"),
6635 scnname, elf_errmsg (-1));
6636 return;
6637 }
6638
6639 if (is_eh_frame)
6640 printf (_("\
6641 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6642 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6643 else
6644 printf (_("\
6645 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6646 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6647
6648 struct cieinfo
6649 {
6650 ptrdiff_t cie_offset;
6651 const char *augmentation;
6652 unsigned int code_alignment_factor;
6653 unsigned int data_alignment_factor;
6654 uint8_t address_size;
6655 uint8_t fde_encoding;
6656 uint8_t lsda_encoding;
6657 struct cieinfo *next;
6658 } *cies = NULL;
6659
6660 const unsigned char *readp = data->d_buf;
6661 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6662 + data->d_size);
6663 while (readp < dataend)
6664 {
6665 if (unlikely (readp + 4 > dataend))
6666 {
6667 invalid_data:
6668 error (0, 0, _("invalid data in section [%zu] '%s'"),
6669 elf_ndxscn (scn), scnname);
6670 return;
6671 }
6672
6673 /* At the beginning there must be a CIE. There can be multiple,
6674 hence we test tis in a loop. */
6675 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6676
6677 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6678 unsigned int length = 4;
6679 if (unlikely (unit_length == 0xffffffff))
6680 {
6681 if (unlikely (readp + 8 > dataend))
6682 goto invalid_data;
6683
6684 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6685 length = 8;
6686 }
6687
6688 if (unlikely (unit_length == 0))
6689 {
6690 printf (_("\n [%6tx] Zero terminator\n"), offset);
6691 continue;
6692 }
6693
6694 Dwarf_Word maxsize = dataend - readp;
6695 if (unlikely (unit_length > maxsize))
6696 goto invalid_data;
6697
6698 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6699
6700 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6701 const unsigned char *const cieend = readp + unit_length;
6702 if (unlikely (cieend > dataend))
6703 goto invalid_data;
6704
6705 Dwarf_Off cie_id;
6706 if (length == 4)
6707 {
6708 if (unlikely (cieend - readp < 4))
6709 goto invalid_data;
6710 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6711 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6712 cie_id = DW_CIE_ID_64;
6713 }
6714 else
6715 {
6716 if (unlikely (cieend - readp < 8))
6717 goto invalid_data;
6718 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6719 }
6720
6721 uint_fast8_t version = 2;
6722 unsigned int code_alignment_factor;
6723 int data_alignment_factor;
6724 unsigned int fde_encoding = 0;
6725 unsigned int lsda_encoding = 0;
6726 Dwarf_Word initial_location = 0;
6727 Dwarf_Word vma_base = 0;
6728
6729 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6730 {
6731 if (unlikely (cieend - readp < 2))
6732 goto invalid_data;
6733 version = *readp++;
6734 const char *const augmentation = (const char *) readp;
6735 readp = memchr (readp, '\0', cieend - readp);
6736 if (unlikely (readp == NULL))
6737 goto invalid_data;
6738 ++readp;
6739
6740 uint_fast8_t segment_size = 0;
6741 if (version >= 4)
6742 {
6743 if (cieend - readp < 5)
6744 goto invalid_data;
6745 ptr_size = *readp++;
6746 segment_size = *readp++;
6747 }
6748
6749 if (cieend - readp < 1)
6750 goto invalid_data;
6751 get_uleb128 (code_alignment_factor, readp, cieend);
6752 if (cieend - readp < 1)
6753 goto invalid_data;
6754 get_sleb128 (data_alignment_factor, readp, cieend);
6755
6756 /* In some variant for unwind data there is another field. */
6757 if (strcmp (augmentation, "eh") == 0)
6758 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6759
6760 unsigned int return_address_register;
6761 if (cieend - readp < 1)
6762 goto invalid_data;
6763 if (unlikely (version == 1))
6764 return_address_register = *readp++;
6765 else
6766 get_uleb128 (return_address_register, readp, cieend);
6767
6768 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6769 " CIE_id: %" PRIu64 "\n"
6770 " version: %u\n"
6771 " augmentation: \"%s\"\n",
6772 offset, (uint64_t) unit_length, (uint64_t) cie_id,
6773 version, augmentation);
6774 if (version >= 4)
6775 printf (" address_size: %u\n"
6776 " segment_size: %u\n",
6777 ptr_size, segment_size);
6778 printf (" code_alignment_factor: %u\n"
6779 " data_alignment_factor: %d\n"
6780 " return_address_register: %u\n",
6781 code_alignment_factor,
6782 data_alignment_factor, return_address_register);
6783
6784 if (augmentation[0] == 'z')
6785 {
6786 unsigned int augmentationlen;
6787 get_uleb128 (augmentationlen, readp, cieend);
6788
6789 if (augmentationlen > (size_t) (cieend - readp))
6790 {
6791 error (0, 0, _("invalid augmentation length"));
6792 readp = cieend;
6793 continue;
6794 }
6795
6796 const char *hdr = "Augmentation data:";
6797 const char *cp = augmentation + 1;
6798 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6799 {
6800 printf (" %-26s%#x ", hdr, *readp);
6801 hdr = "";
6802
6803 if (*cp == 'R')
6804 {
6805 fde_encoding = *readp++;
6806 print_encoding_base (_("FDE address encoding: "),
6807 fde_encoding);
6808 }
6809 else if (*cp == 'L')
6810 {
6811 lsda_encoding = *readp++;
6812 print_encoding_base (_("LSDA pointer encoding: "),
6813 lsda_encoding);
6814 }
6815 else if (*cp == 'P')
6816 {
6817 /* Personality. This field usually has a relocation
6818 attached pointing to __gcc_personality_v0. */
6819 const unsigned char *startp = readp;
6820 unsigned int encoding = *readp++;
6821 uint64_t val = 0;
6822 readp = read_encoded (encoding, readp,
6823 readp - 1 + augmentationlen,
6824 &val, dbg);
6825
6826 while (++startp < readp)
6827 printf ("%#x ", *startp);
6828
6829 putchar ('(');
6830 print_encoding (encoding);
6831 putchar (' ');
6832 switch (encoding & 0xf)
6833 {
6834 case DW_EH_PE_sleb128:
6835 case DW_EH_PE_sdata2:
6836 case DW_EH_PE_sdata4:
6837 printf ("%" PRId64 ")\n", val);
6838 break;
6839 default:
6840 printf ("%#" PRIx64 ")\n", val);
6841 break;
6842 }
6843 }
6844 else
6845 printf ("(%x)\n", *readp++);
6846
6847 ++cp;
6848 }
6849 }
6850
6851 if (likely (ptr_size == 4 || ptr_size == 8))
6852 {
6853 struct cieinfo *newp = alloca (sizeof (*newp));
6854 newp->cie_offset = offset;
6855 newp->augmentation = augmentation;
6856 newp->fde_encoding = fde_encoding;
6857 newp->lsda_encoding = lsda_encoding;
6858 newp->address_size = ptr_size;
6859 newp->code_alignment_factor = code_alignment_factor;
6860 newp->data_alignment_factor = data_alignment_factor;
6861 newp->next = cies;
6862 cies = newp;
6863 }
6864 }
6865 else
6866 {
6867 struct cieinfo *cie = cies;
6868 while (cie != NULL)
6869 if (is_eh_frame
6870 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6871 : cie_id == (Dwarf_Off) cie->cie_offset)
6872 break;
6873 else
6874 cie = cie->next;
6875 if (unlikely (cie == NULL))
6876 {
6877 puts ("invalid CIE reference in FDE");
6878 return;
6879 }
6880
6881 /* Initialize from CIE data. */
6882 fde_encoding = cie->fde_encoding;
6883 lsda_encoding = cie->lsda_encoding;
6884 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6885 code_alignment_factor = cie->code_alignment_factor;
6886 data_alignment_factor = cie->data_alignment_factor;
6887
6888 const unsigned char *base = readp;
6889 // XXX There are sometimes relocations for this value
6890 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6891 Dwarf_Word address_range
6892 = read_addr_unaligned_inc (ptr_size, dbg, readp);
6893
6894 /* pcrel for an FDE address is relative to the runtime
6895 address of the start_address field itself. Sign extend
6896 if necessary to make sure the calculation is done on the
6897 full 64 bit address even when initial_location only holds
6898 the lower 32 bits. */
6899 Dwarf_Addr pc_start = initial_location;
6900 if (ptr_size == 4)
6901 pc_start = (uint64_t) (int32_t) pc_start;
6902 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6903 pc_start += ((uint64_t) shdr->sh_addr
6904 + (base - (const unsigned char *) data->d_buf)
6905 - bias);
6906
6907 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6908 " CIE_pointer: %" PRIu64 "\n"
6909 " initial_location: ",
6910 offset, (uint64_t) unit_length,
6911 cie->cie_offset, (uint64_t) cie_id);
6912 print_dwarf_addr (dwflmod, cie->address_size,
6913 pc_start, initial_location);
6914 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6915 {
6916 vma_base = (((uint64_t) shdr->sh_offset
6917 + (base - (const unsigned char *) data->d_buf)
6918 + (uint64_t) initial_location)
6919 & (ptr_size == 4
6920 ? UINT64_C (0xffffffff)
6921 : UINT64_C (0xffffffffffffffff)));
6922 printf (_(" (offset: %#" PRIx64 ")"),
6923 (uint64_t) vma_base);
6924 }
6925
6926 printf ("\n address_range: %#" PRIx64,
6927 (uint64_t) address_range);
6928 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6929 printf (_(" (end offset: %#" PRIx64 ")"),
6930 ((uint64_t) vma_base + (uint64_t) address_range)
6931 & (ptr_size == 4
6932 ? UINT64_C (0xffffffff)
6933 : UINT64_C (0xffffffffffffffff)));
6934 putchar ('\n');
6935
6936 if (cie->augmentation[0] == 'z')
6937 {
6938 unsigned int augmentationlen;
6939 if (cieend - readp < 1)
6940 goto invalid_data;
6941 get_uleb128 (augmentationlen, readp, cieend);
6942
6943 if (augmentationlen > (size_t) (cieend - readp))
6944 {
6945 error (0, 0, _("invalid augmentation length"));
6946 readp = cieend;
6947 continue;
6948 }
6949
6950 if (augmentationlen > 0)
6951 {
6952 const char *hdr = "Augmentation data:";
6953 const char *cp = cie->augmentation + 1;
6954 unsigned int u = 0;
6955 while (*cp != '\0'
6956 && cp < cie->augmentation + augmentationlen + 1)
6957 {
6958 if (*cp == 'L')
6959 {
6960 uint64_t lsda_pointer;
6961 const unsigned char *p
6962 = read_encoded (lsda_encoding, &readp[u],
6963 &readp[augmentationlen],
6964 &lsda_pointer, dbg);
6965 u = p - readp;
6966 printf (_("\
6967 %-26sLSDA pointer: %#" PRIx64 "\n"),
6968 hdr, lsda_pointer);
6969 hdr = "";
6970 }
6971 ++cp;
6972 }
6973
6974 while (u < augmentationlen)
6975 {
6976 printf (" %-26s%#x\n", hdr, readp[u++]);
6977 hdr = "";
6978 }
6979 }
6980
6981 readp += augmentationlen;
6982 }
6983 }
6984
6985 /* Handle the initialization instructions. */
6986 if (ptr_size != 4 && ptr_size !=8)
6987 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6988 else
6989 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6990 data_alignment_factor, version, ptr_size,
6991 fde_encoding, dwflmod, ebl, ehdr, dbg);
6992 readp = cieend;
6993 }
6994 }
6995
6996
6997 /* Returns the signedness (or false if it cannot be determined) and
6998 the byte size (or zero if it cannot be gotten) of the given DIE
6999 DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */
7000 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)7001 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
7002 {
7003 Dwarf_Attribute attr;
7004 Dwarf_Die type;
7005
7006 *bytes = 0;
7007 *is_signed = false;
7008
7009 if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
7010 DW_AT_type,
7011 &attr), &type),
7012 &type) == 0)
7013 {
7014 Dwarf_Word val;
7015 *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
7016 &attr), &val) == 0
7017 && (val == DW_ATE_signed || val == DW_ATE_signed_char));
7018
7019 if (dwarf_aggregate_size (&type, &val) == 0)
7020 *bytes = val;
7021 }
7022 }
7023
7024 struct attrcb_args
7025 {
7026 Dwfl_Module *dwflmod;
7027 Dwarf *dbg;
7028 Dwarf_Die *dies;
7029 int level;
7030 bool silent;
7031 bool is_split;
7032 unsigned int version;
7033 unsigned int addrsize;
7034 unsigned int offset_size;
7035 struct Dwarf_CU *cu;
7036 };
7037
7038
7039 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)7040 attr_callback (Dwarf_Attribute *attrp, void *arg)
7041 {
7042 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
7043 const int level = cbargs->level;
7044 Dwarf_Die *die = &cbargs->dies[level];
7045 bool is_split = cbargs->is_split;
7046
7047 unsigned int attr = dwarf_whatattr (attrp);
7048 if (unlikely (attr == 0))
7049 {
7050 if (!cbargs->silent)
7051 error (0, 0, _("DIE [%" PRIx64 "] "
7052 "cannot get attribute code: %s"),
7053 dwarf_dieoffset (die), dwarf_errmsg (-1));
7054 return DWARF_CB_ABORT;
7055 }
7056
7057 unsigned int form = dwarf_whatform (attrp);
7058 if (unlikely (form == 0))
7059 {
7060 if (!cbargs->silent)
7061 error (0, 0, _("DIE [%" PRIx64 "] "
7062 "cannot get attribute form: %s"),
7063 dwarf_dieoffset (die), dwarf_errmsg (-1));
7064 return DWARF_CB_ABORT;
7065 }
7066
7067 switch (form)
7068 {
7069 case DW_FORM_addr:
7070 case DW_FORM_addrx:
7071 case DW_FORM_addrx1:
7072 case DW_FORM_addrx2:
7073 case DW_FORM_addrx3:
7074 case DW_FORM_addrx4:
7075 case DW_FORM_GNU_addr_index:
7076 if (!cbargs->silent)
7077 {
7078 Dwarf_Addr addr;
7079 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7080 {
7081 attrval_out:
7082 if (!cbargs->silent)
7083 error (0, 0, _("DIE [%" PRIx64 "] "
7084 "cannot get attribute '%s' (%s) value: "
7085 "%s"),
7086 dwarf_dieoffset (die),
7087 dwarf_attr_name (attr),
7088 dwarf_form_name (form),
7089 dwarf_errmsg (-1));
7090 /* Don't ABORT, it might be other attributes can be resolved. */
7091 return DWARF_CB_OK;
7092 }
7093 if (form != DW_FORM_addr )
7094 {
7095 Dwarf_Word word;
7096 if (dwarf_formudata (attrp, &word) != 0)
7097 goto attrval_out;
7098 printf (" %*s%-20s (%s) [%" PRIx64 "] ",
7099 (int) (level * 2), "", dwarf_attr_name (attr),
7100 dwarf_form_name (form), word);
7101 }
7102 else
7103 printf (" %*s%-20s (%s) ",
7104 (int) (level * 2), "", dwarf_attr_name (attr),
7105 dwarf_form_name (form));
7106 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7107 printf ("\n");
7108 }
7109 break;
7110
7111 case DW_FORM_indirect:
7112 case DW_FORM_strp:
7113 case DW_FORM_line_strp:
7114 case DW_FORM_strx:
7115 case DW_FORM_strx1:
7116 case DW_FORM_strx2:
7117 case DW_FORM_strx3:
7118 case DW_FORM_strx4:
7119 case DW_FORM_string:
7120 case DW_FORM_GNU_strp_alt:
7121 case DW_FORM_GNU_str_index:
7122 if (cbargs->silent)
7123 break;
7124 const char *str = dwarf_formstring (attrp);
7125 if (unlikely (str == NULL))
7126 goto attrval_out;
7127 printf (" %*s%-20s (%s) \"%s\"\n",
7128 (int) (level * 2), "", dwarf_attr_name (attr),
7129 dwarf_form_name (form), str);
7130 break;
7131
7132 case DW_FORM_ref_addr:
7133 case DW_FORM_ref_udata:
7134 case DW_FORM_ref8:
7135 case DW_FORM_ref4:
7136 case DW_FORM_ref2:
7137 case DW_FORM_ref1:
7138 case DW_FORM_GNU_ref_alt:
7139 case DW_FORM_ref_sup4:
7140 case DW_FORM_ref_sup8:
7141 if (cbargs->silent)
7142 break;
7143 Dwarf_Die ref;
7144 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7145 goto attrval_out;
7146
7147 printf (" %*s%-20s (%s) ",
7148 (int) (level * 2), "", dwarf_attr_name (attr),
7149 dwarf_form_name (form));
7150 if (is_split)
7151 printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7152 else
7153 printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7154 break;
7155
7156 case DW_FORM_ref_sig8:
7157 if (cbargs->silent)
7158 break;
7159 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
7160 (int) (level * 2), "", dwarf_attr_name (attr),
7161 dwarf_form_name (form),
7162 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7163 break;
7164
7165 case DW_FORM_sec_offset:
7166 case DW_FORM_rnglistx:
7167 case DW_FORM_loclistx:
7168 case DW_FORM_implicit_const:
7169 case DW_FORM_udata:
7170 case DW_FORM_sdata:
7171 case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7172 case DW_FORM_data4:
7173 case DW_FORM_data2:
7174 case DW_FORM_data1:;
7175 Dwarf_Word num;
7176 if (unlikely (dwarf_formudata (attrp, &num) != 0))
7177 goto attrval_out;
7178
7179 const char *valuestr = NULL;
7180 bool as_hex_id = false;
7181 switch (attr)
7182 {
7183 /* This case can take either a constant or a loclistptr. */
7184 case DW_AT_data_member_location:
7185 if (form != DW_FORM_sec_offset
7186 && (cbargs->version >= 4
7187 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7188 {
7189 if (!cbargs->silent)
7190 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
7191 (int) (level * 2), "", dwarf_attr_name (attr),
7192 dwarf_form_name (form), (uintmax_t) num);
7193 return DWARF_CB_OK;
7194 }
7195 FALLTHROUGH;
7196
7197 /* These cases always take a loclist[ptr] and no constant. */
7198 case DW_AT_location:
7199 case DW_AT_data_location:
7200 case DW_AT_vtable_elem_location:
7201 case DW_AT_string_length:
7202 case DW_AT_use_location:
7203 case DW_AT_frame_base:
7204 case DW_AT_return_addr:
7205 case DW_AT_static_link:
7206 case DW_AT_segment:
7207 case DW_AT_GNU_call_site_value:
7208 case DW_AT_GNU_call_site_data_value:
7209 case DW_AT_GNU_call_site_target:
7210 case DW_AT_GNU_call_site_target_clobbered:
7211 case DW_AT_GNU_locviews:
7212 {
7213 bool nlpt;
7214 if (cbargs->cu->version < 5)
7215 {
7216 if (! cbargs->is_split)
7217 {
7218 nlpt = notice_listptr (section_loc, &known_locsptr,
7219 cbargs->addrsize,
7220 cbargs->offset_size,
7221 cbargs->cu, num, attr);
7222 }
7223 else
7224 nlpt = true;
7225 }
7226 else
7227 {
7228 /* Only register for a real section offset. Otherwise
7229 it is a DW_FORM_loclistx which is just an index
7230 number and we should already have registered the
7231 section offset for the index when we saw the
7232 DW_AT_loclists_base CU attribute. */
7233 if (form == DW_FORM_sec_offset)
7234 nlpt = notice_listptr (section_loc, &known_loclistsptr,
7235 cbargs->addrsize, cbargs->offset_size,
7236 cbargs->cu, num, attr);
7237 else
7238 nlpt = true;
7239
7240 }
7241
7242 if (!cbargs->silent)
7243 {
7244 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7245 printf (" %*s%-20s (%s) location list [%6"
7246 PRIxMAX "]%s\n",
7247 (int) (level * 2), "", dwarf_attr_name (attr),
7248 dwarf_form_name (form), (uintmax_t) num,
7249 nlpt ? "" : " <WARNING offset too big>");
7250 else
7251 printf (" %*s%-20s (%s) location index [%6"
7252 PRIxMAX "]\n",
7253 (int) (level * 2), "", dwarf_attr_name (attr),
7254 dwarf_form_name (form), (uintmax_t) num);
7255 }
7256 }
7257 return DWARF_CB_OK;
7258
7259 case DW_AT_loclists_base:
7260 {
7261 bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7262 cbargs->addrsize, cbargs->offset_size,
7263 cbargs->cu, num, attr);
7264
7265 if (!cbargs->silent)
7266 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7267 (int) (level * 2), "", dwarf_attr_name (attr),
7268 dwarf_form_name (form), (uintmax_t) num,
7269 nlpt ? "" : " <WARNING offset too big>");
7270 }
7271 return DWARF_CB_OK;
7272
7273 case DW_AT_ranges:
7274 case DW_AT_start_scope:
7275 {
7276 bool nlpt;
7277 if (cbargs->cu->version < 5)
7278 nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7279 cbargs->addrsize, cbargs->offset_size,
7280 cbargs->cu, num, attr);
7281 else
7282 {
7283 /* Only register for a real section offset. Otherwise
7284 it is a DW_FORM_rangelistx which is just an index
7285 number and we should already have registered the
7286 section offset for the index when we saw the
7287 DW_AT_rnglists_base CU attribute. */
7288 if (form == DW_FORM_sec_offset)
7289 nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7290 cbargs->addrsize, cbargs->offset_size,
7291 cbargs->cu, num, attr);
7292 else
7293 nlpt = true;
7294 }
7295
7296 if (!cbargs->silent)
7297 {
7298 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7299 printf (" %*s%-20s (%s) range list [%6"
7300 PRIxMAX "]%s\n",
7301 (int) (level * 2), "", dwarf_attr_name (attr),
7302 dwarf_form_name (form), (uintmax_t) num,
7303 nlpt ? "" : " <WARNING offset too big>");
7304 else
7305 printf (" %*s%-20s (%s) range index [%6"
7306 PRIxMAX "]\n",
7307 (int) (level * 2), "", dwarf_attr_name (attr),
7308 dwarf_form_name (form), (uintmax_t) num);
7309 }
7310 }
7311 return DWARF_CB_OK;
7312
7313 case DW_AT_rnglists_base:
7314 {
7315 bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7316 cbargs->addrsize, cbargs->offset_size,
7317 cbargs->cu, num, attr);
7318 if (!cbargs->silent)
7319 printf (" %*s%-20s (%s) range list [%6"
7320 PRIxMAX "]%s\n",
7321 (int) (level * 2), "", dwarf_attr_name (attr),
7322 dwarf_form_name (form), (uintmax_t) num,
7323 nlpt ? "" : " <WARNING offset too big>");
7324 }
7325 return DWARF_CB_OK;
7326
7327 case DW_AT_addr_base:
7328 case DW_AT_GNU_addr_base:
7329 {
7330 bool addrbase = notice_listptr (section_addr, &known_addrbases,
7331 cbargs->addrsize,
7332 cbargs->offset_size,
7333 cbargs->cu, num, attr);
7334 if (!cbargs->silent)
7335 printf (" %*s%-20s (%s) address base [%6"
7336 PRIxMAX "]%s\n",
7337 (int) (level * 2), "", dwarf_attr_name (attr),
7338 dwarf_form_name (form), (uintmax_t) num,
7339 addrbase ? "" : " <WARNING offset too big>");
7340 }
7341 return DWARF_CB_OK;
7342
7343 case DW_AT_str_offsets_base:
7344 {
7345 bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7346 cbargs->addrsize,
7347 cbargs->offset_size,
7348 cbargs->cu, num, attr);
7349 if (!cbargs->silent)
7350 printf (" %*s%-20s (%s) str offsets base [%6"
7351 PRIxMAX "]%s\n",
7352 (int) (level * 2), "", dwarf_attr_name (attr),
7353 dwarf_form_name (form), (uintmax_t) num,
7354 stroffbase ? "" : " <WARNING offset too big>");
7355 }
7356 return DWARF_CB_OK;
7357
7358 case DW_AT_language:
7359 valuestr = dwarf_lang_name (num);
7360 break;
7361 case DW_AT_encoding:
7362 valuestr = dwarf_encoding_name (num);
7363 break;
7364 case DW_AT_accessibility:
7365 valuestr = dwarf_access_name (num);
7366 break;
7367 case DW_AT_defaulted:
7368 valuestr = dwarf_defaulted_name (num);
7369 break;
7370 case DW_AT_visibility:
7371 valuestr = dwarf_visibility_name (num);
7372 break;
7373 case DW_AT_virtuality:
7374 valuestr = dwarf_virtuality_name (num);
7375 break;
7376 case DW_AT_identifier_case:
7377 valuestr = dwarf_identifier_case_name (num);
7378 break;
7379 case DW_AT_calling_convention:
7380 valuestr = dwarf_calling_convention_name (num);
7381 break;
7382 case DW_AT_inline:
7383 valuestr = dwarf_inline_name (num);
7384 break;
7385 case DW_AT_ordering:
7386 valuestr = dwarf_ordering_name (num);
7387 break;
7388 case DW_AT_decl_file:
7389 case DW_AT_call_file:
7390 {
7391 if (cbargs->silent)
7392 break;
7393
7394 /* Try to get the actual file, the current interface only
7395 gives us full paths, but we only want to show the file
7396 name for now. */
7397 Dwarf_Die cudie;
7398 if (dwarf_cu_die (cbargs->cu, &cudie,
7399 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7400 {
7401 Dwarf_Files *files;
7402 size_t nfiles;
7403 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7404 {
7405 valuestr = dwarf_filesrc (files, num, NULL, NULL);
7406 if (valuestr != NULL)
7407 {
7408 char *filename = strrchr (valuestr, '/');
7409 if (filename != NULL)
7410 valuestr = filename + 1;
7411 }
7412 else
7413 error (0, 0, _("invalid file (%" PRId64 "): %s"),
7414 num, dwarf_errmsg (-1));
7415 }
7416 else
7417 error (0, 0, _("no srcfiles for CU [%" PRIx64 "]"),
7418 dwarf_dieoffset (&cudie));
7419 }
7420 else
7421 error (0, 0, _("couldn't get DWARF CU: %s"),
7422 dwarf_errmsg (-1));
7423 if (valuestr == NULL)
7424 valuestr = "???";
7425 }
7426 break;
7427 case DW_AT_GNU_dwo_id:
7428 as_hex_id = true;
7429 break;
7430
7431 default:
7432 /* Nothing. */
7433 break;
7434 }
7435
7436 if (cbargs->silent)
7437 break;
7438
7439 /* When highpc is in constant form it is relative to lowpc.
7440 In that case also show the address. */
7441 Dwarf_Addr highpc;
7442 if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7443 {
7444 printf (" %*s%-20s (%s) %" PRIuMAX " (",
7445 (int) (level * 2), "", dwarf_attr_name (attr),
7446 dwarf_form_name (form), (uintmax_t) num);
7447 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7448 printf (")\n");
7449 }
7450 else
7451 {
7452 if (as_hex_id)
7453 {
7454 printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7455 (int) (level * 2), "", dwarf_attr_name (attr),
7456 dwarf_form_name (form), num);
7457 }
7458 else
7459 {
7460 Dwarf_Sword snum = 0;
7461 bool is_signed;
7462 int bytes = 0;
7463 if (attr == DW_AT_const_value)
7464 die_type_sign_bytes (die, &is_signed, &bytes);
7465 else
7466 is_signed = (form == DW_FORM_sdata
7467 || form == DW_FORM_implicit_const);
7468
7469 if (is_signed)
7470 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7471 goto attrval_out;
7472
7473 if (valuestr == NULL)
7474 {
7475 printf (" %*s%-20s (%s) ",
7476 (int) (level * 2), "", dwarf_attr_name (attr),
7477 dwarf_form_name (form));
7478 }
7479 else
7480 {
7481 printf (" %*s%-20s (%s) %s (",
7482 (int) (level * 2), "", dwarf_attr_name (attr),
7483 dwarf_form_name (form), valuestr);
7484 }
7485
7486 switch (bytes)
7487 {
7488 case 1:
7489 if (is_signed)
7490 printf ("%" PRId8, (int8_t) snum);
7491 else
7492 printf ("%" PRIu8, (uint8_t) num);
7493 break;
7494
7495 case 2:
7496 if (is_signed)
7497 printf ("%" PRId16, (int16_t) snum);
7498 else
7499 printf ("%" PRIu16, (uint16_t) num);
7500 break;
7501
7502 case 4:
7503 if (is_signed)
7504 printf ("%" PRId32, (int32_t) snum);
7505 else
7506 printf ("%" PRIu32, (uint32_t) num);
7507 break;
7508
7509 case 8:
7510 if (is_signed)
7511 printf ("%" PRId64, (int64_t) snum);
7512 else
7513 printf ("%" PRIu64, (uint64_t) num);
7514 break;
7515
7516 default:
7517 if (is_signed)
7518 printf ("%" PRIdMAX, (intmax_t) snum);
7519 else
7520 printf ("%" PRIuMAX, (uintmax_t) num);
7521 break;
7522 }
7523
7524 /* Make clear if we switched from a signed encoding to
7525 an unsigned value. */
7526 if (attr == DW_AT_const_value
7527 && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7528 && !is_signed)
7529 printf (" (%" PRIdMAX ")", (intmax_t) num);
7530
7531 if (valuestr == NULL)
7532 printf ("\n");
7533 else
7534 printf (")\n");
7535 }
7536 }
7537 break;
7538
7539 case DW_FORM_flag:
7540 if (cbargs->silent)
7541 break;
7542 bool flag;
7543 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7544 goto attrval_out;
7545
7546 printf (" %*s%-20s (%s) %s\n",
7547 (int) (level * 2), "", dwarf_attr_name (attr),
7548 dwarf_form_name (form), flag ? yes_str : no_str);
7549 break;
7550
7551 case DW_FORM_flag_present:
7552 if (cbargs->silent)
7553 break;
7554 printf (" %*s%-20s (%s) %s\n",
7555 (int) (level * 2), "", dwarf_attr_name (attr),
7556 dwarf_form_name (form), yes_str);
7557 break;
7558
7559 case DW_FORM_exprloc:
7560 case DW_FORM_block4:
7561 case DW_FORM_block2:
7562 case DW_FORM_block1:
7563 case DW_FORM_block:
7564 case DW_FORM_data16: /* DWARF5 calls this a constant class. */
7565 if (cbargs->silent)
7566 break;
7567 Dwarf_Block block;
7568 if (unlikely (dwarf_formblock (attrp, &block) != 0))
7569 goto attrval_out;
7570
7571 printf (" %*s%-20s (%s) ",
7572 (int) (level * 2), "", dwarf_attr_name (attr),
7573 dwarf_form_name (form));
7574
7575 switch (attr)
7576 {
7577 default:
7578 if (form != DW_FORM_exprloc)
7579 {
7580 print_block (block.length, block.data);
7581 break;
7582 }
7583 FALLTHROUGH;
7584
7585 case DW_AT_location:
7586 case DW_AT_data_location:
7587 case DW_AT_data_member_location:
7588 case DW_AT_vtable_elem_location:
7589 case DW_AT_string_length:
7590 case DW_AT_use_location:
7591 case DW_AT_frame_base:
7592 case DW_AT_return_addr:
7593 case DW_AT_static_link:
7594 case DW_AT_allocated:
7595 case DW_AT_associated:
7596 case DW_AT_bit_size:
7597 case DW_AT_bit_offset:
7598 case DW_AT_bit_stride:
7599 case DW_AT_byte_size:
7600 case DW_AT_byte_stride:
7601 case DW_AT_count:
7602 case DW_AT_lower_bound:
7603 case DW_AT_upper_bound:
7604 case DW_AT_GNU_call_site_value:
7605 case DW_AT_GNU_call_site_data_value:
7606 case DW_AT_GNU_call_site_target:
7607 case DW_AT_GNU_call_site_target_clobbered:
7608 if (form == DW_FORM_exprloc
7609 || (form != DW_FORM_data16
7610 && attrp->cu->version < 4)) /* blocks were expressions. */
7611 {
7612 putchar ('\n');
7613 print_ops (cbargs->dwflmod, cbargs->dbg,
7614 12 + level * 2, 12 + level * 2,
7615 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7616 attrp->cu, block.length, block.data);
7617 }
7618 else
7619 print_block (block.length, block.data);
7620 break;
7621
7622 case DW_AT_discr_list:
7623 if (block.length == 0)
7624 puts ("<default>");
7625 else if (form != DW_FORM_data16)
7626 {
7627 const unsigned char *readp = block.data;
7628 const unsigned char *readendp = readp + block.length;
7629
7630 /* See if we are dealing with a signed or unsigned
7631 values. If the parent of this variant DIE is a
7632 variant_part then it will either have a discriminant
7633 which points to the member which type is the
7634 discriminant type. Or the variant_part itself has a
7635 type representing the discriminant. */
7636 bool is_signed = false;
7637 if (level > 0)
7638 {
7639 Dwarf_Die *parent = &cbargs->dies[level - 1];
7640 if (dwarf_tag (die) == DW_TAG_variant
7641 && dwarf_tag (parent) == DW_TAG_variant_part)
7642 {
7643 Dwarf_Die member;
7644 Dwarf_Attribute discr_attr;
7645 int bytes;
7646 if (dwarf_formref_die (dwarf_attr (parent,
7647 DW_AT_discr,
7648 &discr_attr),
7649 &member) != NULL)
7650 die_type_sign_bytes (&member, &is_signed, &bytes);
7651 else
7652 die_type_sign_bytes (parent, &is_signed, &bytes);
7653 }
7654 }
7655 while (readp < readendp)
7656 {
7657 int d = (int) *readp++;
7658 printf ("%s ", dwarf_discr_list_name (d));
7659 if (readp >= readendp)
7660 goto attrval_out;
7661
7662 Dwarf_Word val;
7663 Dwarf_Sword sval;
7664 if (d == DW_DSC_label)
7665 {
7666 if (is_signed)
7667 {
7668 get_sleb128 (sval, readp, readendp);
7669 printf ("%" PRId64 "", sval);
7670 }
7671 else
7672 {
7673 get_uleb128 (val, readp, readendp);
7674 printf ("%" PRIu64 "", val);
7675 }
7676 }
7677 else if (d == DW_DSC_range)
7678 {
7679 if (is_signed)
7680 {
7681 get_sleb128 (sval, readp, readendp);
7682 printf ("%" PRId64 "..", sval);
7683 if (readp >= readendp)
7684 goto attrval_out;
7685 get_sleb128 (sval, readp, readendp);
7686 printf ("%" PRId64 "", sval);
7687 }
7688 else
7689 {
7690 get_uleb128 (val, readp, readendp);
7691 printf ("%" PRIu64 "..", val);
7692 if (readp >= readendp)
7693 goto attrval_out;
7694 get_uleb128 (val, readp, readendp);
7695 printf ("%" PRIu64 "", val);
7696 }
7697 }
7698 else
7699 {
7700 print_block (readendp - readp, readp);
7701 break;
7702 }
7703 if (readp < readendp)
7704 printf (", ");
7705 }
7706 putchar ('\n');
7707 }
7708 else
7709 print_block (block.length, block.data);
7710 break;
7711 }
7712 break;
7713
7714 default:
7715 if (cbargs->silent)
7716 break;
7717 printf (" %*s%-20s (%s) ???\n",
7718 (int) (level * 2), "", dwarf_attr_name (attr),
7719 dwarf_form_name (form));
7720 break;
7721 }
7722
7723 return DWARF_CB_OK;
7724 }
7725
7726 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7727 print_debug_units (Dwfl_Module *dwflmod,
7728 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7729 Elf_Scn *scn, GElf_Shdr *shdr,
7730 Dwarf *dbg, bool debug_types)
7731 {
7732 const bool silent = !(print_debug_sections & section_info) && !debug_types;
7733 const char *secname = section_name (ebl, shdr);
7734
7735 if (!silent)
7736 printf (_("\
7737 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7738 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7739
7740 /* If the section is empty we don't have to do anything. */
7741 if (!silent && shdr->sh_size == 0)
7742 return;
7743
7744 int maxdies = 20;
7745 Dwarf_Die *dies = xmalloc (maxdies * sizeof (Dwarf_Die));
7746
7747 /* New compilation unit. */
7748 Dwarf_Half version;
7749
7750 Dwarf_Die result;
7751 Dwarf_Off abbroffset;
7752 uint8_t addrsize;
7753 uint8_t offsize;
7754 uint64_t unit_id;
7755 Dwarf_Off subdie_off;
7756
7757 int unit_res;
7758 Dwarf_CU *cu;
7759 Dwarf_CU cu_mem;
7760 uint8_t unit_type;
7761 Dwarf_Die cudie;
7762
7763 /* We cheat a little because we want to see only the CUs from .debug_info
7764 or .debug_types. We know the Dwarf_CU struct layout. Set it up at
7765 the end of .debug_info if we want .debug_types only. Check the returned
7766 Dwarf_CU is still in the expected section. */
7767 if (debug_types)
7768 {
7769 cu_mem.dbg = dbg;
7770 cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7771 cu_mem.sec_idx = IDX_debug_info;
7772 cu = &cu_mem;
7773 }
7774 else
7775 cu = NULL;
7776
7777 next_cu:
7778 unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7779 &cudie, NULL);
7780 if (unit_res == 1)
7781 goto do_return;
7782
7783 if (unit_res == -1)
7784 {
7785 if (!silent)
7786 error (0, 0, _("cannot get next unit: %s"), dwarf_errmsg (-1));
7787 goto do_return;
7788 }
7789
7790 if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7791 goto do_return;
7792
7793 dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7794 &unit_id, &subdie_off);
7795
7796 if (!silent)
7797 {
7798 Dwarf_Off offset = cu->start;
7799 if (debug_types && version < 5)
7800 {
7801 Dwarf_Die typedie;
7802 Dwarf_Off dieoffset;
7803 dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, cu->start
7804 + subdie_off,
7805 &typedie));
7806 printf (_(" Type unit at offset %" PRIu64 ":\n"
7807 " Version: %" PRIu16
7808 ", Abbreviation section offset: %" PRIu64
7809 ", Address size: %" PRIu8
7810 ", Offset size: %" PRIu8
7811 "\n Type signature: %#" PRIx64
7812 ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7813 (uint64_t) offset, version, abbroffset, addrsize, offsize,
7814 unit_id, (uint64_t) subdie_off, dieoffset);
7815 }
7816 else
7817 {
7818 printf (_(" Compilation unit at offset %" PRIu64 ":\n"
7819 " Version: %" PRIu16
7820 ", Abbreviation section offset: %" PRIu64
7821 ", Address size: %" PRIu8
7822 ", Offset size: %" PRIu8 "\n"),
7823 (uint64_t) offset, version, abbroffset, addrsize, offsize);
7824
7825 if (version >= 5 || (unit_type != DW_UT_compile
7826 && unit_type != DW_UT_partial))
7827 {
7828 printf (_(" Unit type: %s (%" PRIu8 ")"),
7829 dwarf_unit_name (unit_type), unit_type);
7830 if (unit_type == DW_UT_type
7831 || unit_type == DW_UT_skeleton
7832 || unit_type == DW_UT_split_compile
7833 || unit_type == DW_UT_split_type)
7834 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7835 if (unit_type == DW_UT_type
7836 || unit_type == DW_UT_split_type)
7837 {
7838 Dwarf_Die typedie;
7839 Dwarf_Off dieoffset;
7840 dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7841 NULL, NULL, NULL);
7842 dieoffset = dwarf_dieoffset (&typedie);
7843 printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7844 subdie_off, dieoffset);
7845 }
7846 printf ("\n");
7847 }
7848 }
7849 }
7850
7851 if (version < 2 || version > 5
7852 || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7853 {
7854 if (!silent)
7855 error (0, 0, _("unknown version (%d) or unit type (%d)"),
7856 version, unit_type);
7857 goto next_cu;
7858 }
7859
7860 struct attrcb_args args =
7861 {
7862 .dwflmod = dwflmod,
7863 .silent = silent,
7864 .version = version,
7865 .addrsize = addrsize,
7866 .offset_size = offsize
7867 };
7868
7869 bool is_split = false;
7870 int level = 0;
7871 dies[0] = cudie;
7872 args.cu = dies[0].cu;
7873 args.dbg = dbg;
7874 args.is_split = is_split;
7875
7876 /* We might return here again for the split CU subdie. */
7877 do_cu:
7878 do
7879 {
7880 Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7881 if (unlikely (offset == (Dwarf_Off) -1))
7882 {
7883 if (!silent)
7884 error (0, 0, _("cannot get DIE offset: %s"),
7885 dwarf_errmsg (-1));
7886 goto do_return;
7887 }
7888
7889 int tag = dwarf_tag (&dies[level]);
7890 if (unlikely (tag == DW_TAG_invalid))
7891 {
7892 if (!silent)
7893 error (0, 0, _("cannot get tag of DIE at offset [%" PRIx64
7894 "] in section '%s': %s"),
7895 (uint64_t) offset, secname, dwarf_errmsg (-1));
7896 goto do_return;
7897 }
7898
7899 if (!silent)
7900 {
7901 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7902 if (is_split)
7903 printf (" {%6" PRIx64 "} ", (uint64_t) offset);
7904 else
7905 printf (" [%6" PRIx64 "] ", (uint64_t) offset);
7906 printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7907 dwarf_tag_name (tag), code);
7908 }
7909
7910 /* Print the attribute values. */
7911 args.level = level;
7912 args.dies = dies;
7913 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7914
7915 /* Make room for the next level's DIE. */
7916 if (level + 1 == maxdies)
7917 dies = xrealloc (dies, (maxdies += 10) * sizeof (Dwarf_Die));
7918
7919 int res = dwarf_child (&dies[level], &dies[level + 1]);
7920 if (res > 0)
7921 {
7922 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7923 if (level-- == 0)
7924 break;
7925
7926 if (unlikely (res == -1))
7927 {
7928 if (!silent)
7929 error (0, 0, _("cannot get next DIE: %s\n"),
7930 dwarf_errmsg (-1));
7931 goto do_return;
7932 }
7933 }
7934 else if (unlikely (res < 0))
7935 {
7936 if (!silent)
7937 error (0, 0, _("cannot get next DIE: %s"),
7938 dwarf_errmsg (-1));
7939 goto do_return;
7940 }
7941 else
7942 ++level;
7943 }
7944 while (level >= 0);
7945
7946 /* We might want to show the split compile unit if this was a skeleton.
7947 We need to scan it if we are requesting printing .debug_ranges for
7948 DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7949 section. */
7950 if (unit_type == DW_UT_skeleton
7951 && ((!silent && show_split_units)
7952 || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7953 {
7954 Dwarf_Die subdie;
7955 if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7956 || dwarf_tag (&subdie) == DW_TAG_invalid)
7957 {
7958 if (!silent)
7959 {
7960 Dwarf_Attribute dwo_at;
7961 const char *dwo_name =
7962 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7963 &dwo_at))
7964 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7965 &dwo_at))
7966 ?: "<unknown>"));
7967 fprintf (stderr,
7968 "Could not find split unit '%s', id: %" PRIx64 "\n",
7969 dwo_name, unit_id);
7970 }
7971 }
7972 else
7973 {
7974 Dwarf_CU *split_cu = subdie.cu;
7975 dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7976 &addrsize, &offsize, &unit_id, &subdie_off);
7977 Dwarf_Off offset = cu->start;
7978
7979 if (!silent)
7980 {
7981 printf (_(" Split compilation unit at offset %"
7982 PRIu64 ":\n"
7983 " Version: %" PRIu16
7984 ", Abbreviation section offset: %" PRIu64
7985 ", Address size: %" PRIu8
7986 ", Offset size: %" PRIu8 "\n"),
7987 (uint64_t) offset, version, abbroffset,
7988 addrsize, offsize);
7989 printf (_(" Unit type: %s (%" PRIu8 ")"),
7990 dwarf_unit_name (unit_type), unit_type);
7991 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7992 printf ("\n");
7993 }
7994
7995 unit_type = DW_UT_split_compile;
7996 is_split = true;
7997 level = 0;
7998 dies[0] = subdie;
7999 args.cu = dies[0].cu;
8000 args.dbg = split_cu->dbg;
8001 args.is_split = is_split;
8002 goto do_cu;
8003 }
8004 }
8005
8006 /* And again... */
8007 goto next_cu;
8008
8009 do_return:
8010 free (dies);
8011 }
8012
8013 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8014 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8015 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8016 {
8017 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
8018 }
8019
8020 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8021 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8022 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8023 {
8024 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
8025 }
8026
8027
8028 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8029 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
8030 GElf_Ehdr *ehdr __attribute__ ((unused)),
8031 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8032 {
8033 printf (_("\
8034 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
8035 elf_ndxscn (scn), section_name (ebl, shdr),
8036 (uint64_t) shdr->sh_offset);
8037
8038 size_t address_size
8039 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8040
8041 Dwarf_Lines *lines;
8042 size_t nlines;
8043 Dwarf_Off off, next_off = 0;
8044 Dwarf_CU *cu = NULL;
8045 while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
8046 &lines, &nlines) == 0)
8047 {
8048 Dwarf_Die cudie;
8049 if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8050 NULL, NULL, NULL, NULL) == 0)
8051 printf (" CU [%" PRIx64 "] %s\n",
8052 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8053 else
8054 {
8055 /* DWARF5 lines can be independent of any CU, but they probably
8056 are used by some CU. Determine the CU this block is for. */
8057 Dwarf_Off cuoffset;
8058 Dwarf_Off ncuoffset = 0;
8059 size_t hsize;
8060 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8061 NULL, NULL, NULL) == 0)
8062 {
8063 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8064 continue;
8065 Dwarf_Attribute stmt_list;
8066 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8067 continue;
8068 Dwarf_Word lineoff;
8069 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8070 continue;
8071 if (lineoff == off)
8072 {
8073 /* Found the CU. */
8074 cu = cudie.cu;
8075 break;
8076 }
8077 }
8078
8079 if (cu != NULL)
8080 printf (" CU [%" PRIx64 "] %s\n",
8081 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8082 else
8083 printf (" No CU\n");
8084 }
8085
8086 printf (" line:col SBPE* disc isa op address"
8087 " (Statement Block Prologue Epilogue *End)\n");
8088 const char *last_file = "";
8089 for (size_t n = 0; n < nlines; n++)
8090 {
8091 Dwarf_Line *line = dwarf_onesrcline (lines, n);
8092 if (line == NULL)
8093 {
8094 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8095 continue;
8096 }
8097 Dwarf_Word mtime, length;
8098 const char *file = dwarf_linesrc (line, &mtime, &length);
8099 if (file == NULL)
8100 {
8101 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8102 last_file = "";
8103 }
8104 else if (strcmp (last_file, file) != 0)
8105 {
8106 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8107 file, mtime, length);
8108 last_file = file;
8109 }
8110
8111 int lineno, colno;
8112 bool statement, endseq, block, prologue_end, epilogue_begin;
8113 unsigned int lineop, isa, disc;
8114 Dwarf_Addr address;
8115 dwarf_lineaddr (line, &address);
8116 dwarf_lineno (line, &lineno);
8117 dwarf_linecol (line, &colno);
8118 dwarf_lineop_index (line, &lineop);
8119 dwarf_linebeginstatement (line, &statement);
8120 dwarf_lineendsequence (line, &endseq);
8121 dwarf_lineblock (line, &block);
8122 dwarf_lineprologueend (line, &prologue_end);
8123 dwarf_lineepiloguebegin (line, &epilogue_begin);
8124 dwarf_lineisa (line, &isa);
8125 dwarf_linediscriminator (line, &disc);
8126
8127 /* End sequence is special, it is one byte past. */
8128 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8129 lineno, colno,
8130 (statement ? 'S' : ' '),
8131 (block ? 'B' : ' '),
8132 (prologue_end ? 'P' : ' '),
8133 (epilogue_begin ? 'E' : ' '),
8134 (endseq ? '*' : ' '),
8135 disc, isa, lineop);
8136 print_dwarf_addr (dwflmod, address_size,
8137 address - (endseq ? 1 : 0), address);
8138 printf ("\n");
8139
8140 if (endseq)
8141 printf("\n");
8142 }
8143 }
8144 }
8145
8146
8147 /* Print the value of a form.
8148 Returns new value of readp, or readendp on failure. */
8149 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)8150 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8151 const unsigned char *readendp, unsigned int offset_len,
8152 Dwarf_Off str_offsets_base)
8153 {
8154 Dwarf_Word val;
8155 unsigned char *endp;
8156 Elf_Data *data;
8157 char *str;
8158 switch (form)
8159 {
8160 case DW_FORM_data1:
8161 if (readendp - readp < 1)
8162 {
8163 invalid_data:
8164 error (0, 0, "invalid data");
8165 return readendp;
8166 }
8167 val = *readp++;
8168 printf (" %" PRIx8, (unsigned int) val);
8169 break;
8170
8171 case DW_FORM_data2:
8172 if (readendp - readp < 2)
8173 goto invalid_data;
8174 val = read_2ubyte_unaligned_inc (dbg, readp);
8175 printf(" %" PRIx16, (unsigned int) val);
8176 break;
8177
8178 case DW_FORM_data4:
8179 if (readendp - readp < 4)
8180 goto invalid_data;
8181 val = read_4ubyte_unaligned_inc (dbg, readp);
8182 printf (" %" PRIx32, (unsigned int) val);
8183 break;
8184
8185 case DW_FORM_data8:
8186 if (readendp - readp < 8)
8187 goto invalid_data;
8188 val = read_8ubyte_unaligned_inc (dbg, readp);
8189 printf (" %" PRIx64, val);
8190 break;
8191
8192 case DW_FORM_sdata:
8193 if (readendp - readp < 1)
8194 goto invalid_data;
8195 get_sleb128 (val, readp, readendp);
8196 printf (" %" PRIx64, val);
8197 break;
8198
8199 case DW_FORM_udata:
8200 if (readendp - readp < 1)
8201 goto invalid_data;
8202 get_uleb128 (val, readp, readendp);
8203 printf (" %" PRIx64, val);
8204 break;
8205
8206 case DW_FORM_block:
8207 if (readendp - readp < 1)
8208 goto invalid_data;
8209 get_uleb128 (val, readp, readendp);
8210 if ((size_t) (readendp - readp) < val)
8211 goto invalid_data;
8212 print_bytes (val, readp);
8213 readp += val;
8214 break;
8215
8216 case DW_FORM_block1:
8217 if (readendp - readp < 1)
8218 goto invalid_data;
8219 val = *readp++;
8220 if ((size_t) (readendp - readp) < val)
8221 goto invalid_data;
8222 print_bytes (val, readp);
8223 readp += val;
8224 break;
8225
8226 case DW_FORM_block2:
8227 if (readendp - readp < 2)
8228 goto invalid_data;
8229 val = read_2ubyte_unaligned_inc (dbg, readp);
8230 if ((size_t) (readendp - readp) < val)
8231 goto invalid_data;
8232 print_bytes (val, readp);
8233 readp += val;
8234 break;
8235
8236 case DW_FORM_block4:
8237 if (readendp - readp < 4)
8238 goto invalid_data;
8239 val = read_4ubyte_unaligned_inc (dbg, readp);
8240 if ((size_t) (readendp - readp) < val)
8241 goto invalid_data;
8242 print_bytes (val, readp);
8243 readp += val;
8244 break;
8245
8246 case DW_FORM_data16:
8247 if (readendp - readp < 16)
8248 goto invalid_data;
8249 print_bytes (16, readp);
8250 readp += 16;
8251 break;
8252
8253 case DW_FORM_flag:
8254 if (readendp - readp < 1)
8255 goto invalid_data;
8256 val = *readp++;
8257 printf ("%s", val != 0 ? yes_str : no_str);
8258 break;
8259
8260 case DW_FORM_string:
8261 endp = memchr (readp, '\0', readendp - readp);
8262 if (endp == NULL)
8263 goto invalid_data;
8264 printf ("%s", readp);
8265 readp = endp + 1;
8266 break;
8267
8268 case DW_FORM_strp:
8269 case DW_FORM_line_strp:
8270 case DW_FORM_strp_sup:
8271 if ((size_t) (readendp - readp) < offset_len)
8272 goto invalid_data;
8273 if (offset_len == 8)
8274 val = read_8ubyte_unaligned_inc (dbg, readp);
8275 else
8276 val = read_4ubyte_unaligned_inc (dbg, readp);
8277 if (form == DW_FORM_strp)
8278 data = dbg->sectiondata[IDX_debug_str];
8279 else if (form == DW_FORM_line_strp)
8280 data = dbg->sectiondata[IDX_debug_line_str];
8281 else /* form == DW_FORM_strp_sup */
8282 {
8283 Dwarf *alt = dwarf_getalt (dbg);
8284 data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8285 }
8286 if (data == NULL || val >= data->d_size
8287 || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8288 str = "???";
8289 else
8290 str = (char *) data->d_buf + val;
8291 printf ("%s (%" PRIu64 ")", str, val);
8292 break;
8293
8294 case DW_FORM_sec_offset:
8295 if ((size_t) (readendp - readp) < offset_len)
8296 goto invalid_data;
8297 if (offset_len == 8)
8298 val = read_8ubyte_unaligned_inc (dbg, readp);
8299 else
8300 val = read_4ubyte_unaligned_inc (dbg, readp);
8301 printf ("[%" PRIx64 "]", val);
8302 break;
8303
8304 case DW_FORM_strx:
8305 case DW_FORM_GNU_str_index:
8306 if (readendp - readp < 1)
8307 goto invalid_data;
8308 get_uleb128 (val, readp, readendp);
8309 strx_val:
8310 data = dbg->sectiondata[IDX_debug_str_offsets];
8311 if (data == NULL
8312 || data->d_size - str_offsets_base < val)
8313 str = "???";
8314 else
8315 {
8316 const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8317 const unsigned char *strreadendp = data->d_buf + data->d_size;
8318 if ((size_t) (strreadendp - strreadp) < offset_len)
8319 str = "???";
8320 else
8321 {
8322 Dwarf_Off idx;
8323 if (offset_len == 8)
8324 idx = read_8ubyte_unaligned (dbg, strreadp);
8325 else
8326 idx = read_4ubyte_unaligned (dbg, strreadp);
8327
8328 data = dbg->sectiondata[IDX_debug_str];
8329 if (data == NULL || idx >= data->d_size
8330 || memchr (data->d_buf + idx, '\0',
8331 data->d_size - idx) == NULL)
8332 str = "???";
8333 else
8334 str = (char *) data->d_buf + idx;
8335 }
8336 }
8337 printf ("%s (%" PRIu64 ")", str, val);
8338 break;
8339
8340 case DW_FORM_strx1:
8341 if (readendp - readp < 1)
8342 goto invalid_data;
8343 val = *readp++;
8344 goto strx_val;
8345
8346 case DW_FORM_strx2:
8347 if (readendp - readp < 2)
8348 goto invalid_data;
8349 val = read_2ubyte_unaligned_inc (dbg, readp);
8350 goto strx_val;
8351
8352 case DW_FORM_strx3:
8353 if (readendp - readp < 3)
8354 goto invalid_data;
8355 val = read_3ubyte_unaligned_inc (dbg, readp);
8356 goto strx_val;
8357
8358 case DW_FORM_strx4:
8359 if (readendp - readp < 4)
8360 goto invalid_data;
8361 val = read_4ubyte_unaligned_inc (dbg, readp);
8362 goto strx_val;
8363
8364 default:
8365 error (0, 0, _("unknown form: %s"), dwarf_form_name (form));
8366 return readendp;
8367 }
8368
8369 return readp;
8370 }
8371
8372 /* Only used via run_advance_pc() macro */
8373 static inline void
run_advance_pc(unsigned int op_advance,unsigned int minimum_instr_len,unsigned int max_ops_per_instr,unsigned int * op_addr_advance,Dwarf_Word * address,unsigned int * op_index)8374 run_advance_pc (unsigned int op_advance,
8375 unsigned int minimum_instr_len,
8376 unsigned int max_ops_per_instr,
8377 unsigned int *op_addr_advance,
8378 Dwarf_Word *address,
8379 unsigned int *op_index)
8380 {
8381 const unsigned int advanced_op_index = (*op_index) + op_advance;
8382
8383 *op_addr_advance = minimum_instr_len * (advanced_op_index
8384 / max_ops_per_instr);
8385 *address = *address + *op_addr_advance;
8386 *op_index = advanced_op_index % max_ops_per_instr;
8387 }
8388
8389 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8390 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8391 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8392 {
8393 if (decodedline)
8394 {
8395 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8396 return;
8397 }
8398
8399 printf (_("\
8400 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8401 elf_ndxscn (scn), section_name (ebl, shdr),
8402 (uint64_t) shdr->sh_offset);
8403
8404 if (shdr->sh_size == 0)
8405 return;
8406
8407 /* There is no functionality in libdw to read the information in the
8408 way it is represented here. Hardcode the decoder. */
8409 Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8410 ?: elf_rawdata (scn, NULL));
8411 if (unlikely (data == NULL))
8412 {
8413 error (0, 0, _("cannot get line data section data: %s"),
8414 elf_errmsg (-1));
8415 return;
8416 }
8417
8418 const unsigned char *linep = (const unsigned char *) data->d_buf;
8419 const unsigned char *lineendp;
8420
8421 while (linep
8422 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8423 {
8424 size_t start_offset = linep - (const unsigned char *) data->d_buf;
8425
8426 printf (_("\nTable at offset %zu:\n"), start_offset);
8427
8428 if (unlikely (linep + 4 > lineendp))
8429 goto invalid_data;
8430 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8431 unsigned int length = 4;
8432 if (unlikely (unit_length == 0xffffffff))
8433 {
8434 if (unlikely (linep + 8 > lineendp))
8435 {
8436 invalid_data:
8437 error (0, 0, _("invalid data in section [%zu] '%s'"),
8438 elf_ndxscn (scn), section_name (ebl, shdr));
8439 return;
8440 }
8441 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8442 length = 8;
8443 }
8444
8445 /* Check whether we have enough room in the section. */
8446 if (unlikely (unit_length > (size_t) (lineendp - linep)))
8447 goto invalid_data;
8448 lineendp = linep + unit_length;
8449
8450 /* The next element of the header is the version identifier. */
8451 if ((size_t) (lineendp - linep) < 2)
8452 goto invalid_data;
8453 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8454
8455 size_t address_size
8456 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8457 unsigned char segment_selector_size = 0;
8458 if (version > 4)
8459 {
8460 if ((size_t) (lineendp - linep) < 2)
8461 goto invalid_data;
8462 address_size = *linep++;
8463 segment_selector_size = *linep++;
8464 }
8465
8466 /* Next comes the header length. */
8467 Dwarf_Word header_length;
8468 if (length == 4)
8469 {
8470 if ((size_t) (lineendp - linep) < 4)
8471 goto invalid_data;
8472 header_length = read_4ubyte_unaligned_inc (dbg, linep);
8473 }
8474 else
8475 {
8476 if ((size_t) (lineendp - linep) < 8)
8477 goto invalid_data;
8478 header_length = read_8ubyte_unaligned_inc (dbg, linep);
8479 }
8480
8481 const unsigned char *header_start = linep;
8482
8483 /* Next the minimum instruction length. */
8484 if ((size_t) (lineendp - linep) < 1)
8485 goto invalid_data;
8486 uint_fast8_t minimum_instr_len = *linep++;
8487
8488 /* Next the maximum operations per instruction, in version 4 format. */
8489 uint_fast8_t max_ops_per_instr;
8490 if (version < 4)
8491 max_ops_per_instr = 1;
8492 else
8493 {
8494 if ((size_t) (lineendp - linep) < 1)
8495 goto invalid_data;
8496 max_ops_per_instr = *linep++;
8497 }
8498
8499 /* We need at least 4 more bytes. */
8500 if ((size_t) (lineendp - linep) < 4)
8501 goto invalid_data;
8502
8503 /* Then the flag determining the default value of the is_stmt
8504 register. */
8505 uint_fast8_t default_is_stmt = *linep++;
8506
8507 /* Now the line base. */
8508 int_fast8_t line_base = *linep++;
8509
8510 /* And the line range. */
8511 uint_fast8_t line_range = *linep++;
8512
8513 /* The opcode base. */
8514 uint_fast8_t opcode_base = *linep++;
8515
8516 /* Print what we got so far. */
8517 printf (_("\n"
8518 " Length: %" PRIu64 "\n"
8519 " DWARF version: %" PRIuFAST16 "\n"
8520 " Prologue length: %" PRIu64 "\n"
8521 " Address size: %zd\n"
8522 " Segment selector size: %zd\n"
8523 " Min instruction length: %" PRIuFAST8 "\n"
8524 " Max operations per instruction: %" PRIuFAST8 "\n"
8525 " Initial value if 'is_stmt': %" PRIuFAST8 "\n"
8526 " Line base: %" PRIdFAST8 "\n"
8527 " Line range: %" PRIuFAST8 "\n"
8528 " Opcode base: %" PRIuFAST8 "\n"
8529 "\n"
8530 "Opcodes:\n"),
8531 (uint64_t) unit_length, version, (uint64_t) header_length,
8532 address_size, (size_t) segment_selector_size,
8533 minimum_instr_len, max_ops_per_instr,
8534 default_is_stmt, line_base,
8535 line_range, opcode_base);
8536
8537 if (version < 2 || version > 5)
8538 {
8539 error (0, 0, _("cannot handle .debug_line version: %u\n"),
8540 (unsigned int) version);
8541 linep = lineendp;
8542 continue;
8543 }
8544
8545 if (address_size != 4 && address_size != 8)
8546 {
8547 error (0, 0, _("cannot handle address size: %u\n"),
8548 (unsigned int) address_size);
8549 linep = lineendp;
8550 continue;
8551 }
8552
8553 if (segment_selector_size != 0)
8554 {
8555 error (0, 0, _("cannot handle segment selector size: %u\n"),
8556 (unsigned int) segment_selector_size);
8557 linep = lineendp;
8558 continue;
8559 }
8560
8561 if (unlikely (linep + opcode_base - 1 >= lineendp))
8562 {
8563 invalid_unit:
8564 error (0, 0,
8565 _("invalid data at offset %tu in section [%zu] '%s'"),
8566 linep - (const unsigned char *) data->d_buf,
8567 elf_ndxscn (scn), section_name (ebl, shdr));
8568 linep = lineendp;
8569 continue;
8570 }
8571 int opcode_base_l10 = 1;
8572 unsigned int tmp = opcode_base;
8573 while (tmp > 10)
8574 {
8575 tmp /= 10;
8576 ++opcode_base_l10;
8577 }
8578 const uint8_t *standard_opcode_lengths = linep - 1;
8579 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8580 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
8581 " [%*" PRIuFAST8 "] %hhu arguments\n",
8582 (int) linep[cnt - 1]),
8583 opcode_base_l10, cnt, linep[cnt - 1]);
8584 linep += opcode_base - 1;
8585
8586 if (unlikely (linep >= lineendp))
8587 goto invalid_unit;
8588
8589 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8590
8591 puts (_("\nDirectory table:"));
8592 if (version > 4)
8593 {
8594 struct encpair { uint16_t desc; uint16_t form; };
8595 struct encpair enc[256];
8596
8597 printf (_(" ["));
8598 if ((size_t) (lineendp - linep) < 1)
8599 goto invalid_data;
8600 unsigned char directory_entry_format_count = *linep++;
8601 for (int i = 0; i < directory_entry_format_count; i++)
8602 {
8603 uint16_t desc, form;
8604 if ((size_t) (lineendp - linep) < 1)
8605 goto invalid_data;
8606 get_uleb128 (desc, linep, lineendp);
8607 if ((size_t) (lineendp - linep) < 1)
8608 goto invalid_data;
8609 get_uleb128 (form, linep, lineendp);
8610
8611 enc[i].desc = desc;
8612 enc[i].form = form;
8613
8614 printf ("%s(%s)",
8615 dwarf_line_content_description_name (desc),
8616 dwarf_form_name (form));
8617 if (i + 1 < directory_entry_format_count)
8618 printf (", ");
8619 }
8620 printf ("]\n");
8621
8622 uint64_t directories_count;
8623 if ((size_t) (lineendp - linep) < 1)
8624 goto invalid_data;
8625 get_uleb128 (directories_count, linep, lineendp);
8626
8627 if (directory_entry_format_count == 0
8628 && directories_count != 0)
8629 goto invalid_data;
8630
8631 for (uint64_t i = 0; i < directories_count; i++)
8632 {
8633 printf (" %-5" PRIu64 " ", i);
8634 for (int j = 0; j < directory_entry_format_count; j++)
8635 {
8636 linep = print_form_data (dbg, enc[j].form,
8637 linep, lineendp, length,
8638 str_offsets_base);
8639 if (j + 1 < directory_entry_format_count)
8640 printf (", ");
8641 }
8642 printf ("\n");
8643 if (linep >= lineendp)
8644 goto invalid_unit;
8645 }
8646 }
8647 else
8648 {
8649 while (linep < lineendp && *linep != 0)
8650 {
8651 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8652 if (unlikely (endp == NULL))
8653 goto invalid_unit;
8654
8655 printf (" %s\n", (char *) linep);
8656
8657 linep = endp + 1;
8658 }
8659 if (linep >= lineendp || *linep != 0)
8660 goto invalid_unit;
8661 /* Skip the final NUL byte. */
8662 ++linep;
8663 }
8664
8665 if (unlikely (linep >= lineendp))
8666 goto invalid_unit;
8667
8668 puts (_("\nFile name table:"));
8669 if (version > 4)
8670 {
8671 struct encpair { uint16_t desc; uint16_t form; };
8672 struct encpair enc[256];
8673
8674 printf (_(" ["));
8675 if ((size_t) (lineendp - linep) < 1)
8676 goto invalid_data;
8677 unsigned char file_name_format_count = *linep++;
8678 for (int i = 0; i < file_name_format_count; i++)
8679 {
8680 uint64_t desc, form;
8681 if ((size_t) (lineendp - linep) < 1)
8682 goto invalid_data;
8683 get_uleb128 (desc, linep, lineendp);
8684 if ((size_t) (lineendp - linep) < 1)
8685 goto invalid_data;
8686 get_uleb128 (form, linep, lineendp);
8687
8688 if (! libdw_valid_user_form (form))
8689 goto invalid_data;
8690
8691 enc[i].desc = desc;
8692 enc[i].form = form;
8693
8694 printf ("%s(%s)",
8695 dwarf_line_content_description_name (desc),
8696 dwarf_form_name (form));
8697 if (i + 1 < file_name_format_count)
8698 printf (", ");
8699 }
8700 printf ("]\n");
8701
8702 uint64_t file_name_count;
8703 if ((size_t) (lineendp - linep) < 1)
8704 goto invalid_data;
8705 get_uleb128 (file_name_count, linep, lineendp);
8706
8707 if (file_name_format_count == 0
8708 && file_name_count != 0)
8709 goto invalid_data;
8710
8711 for (uint64_t i = 0; i < file_name_count; i++)
8712 {
8713 printf (" %-5" PRIu64 " ", i);
8714 for (int j = 0; j < file_name_format_count; j++)
8715 {
8716 linep = print_form_data (dbg, enc[j].form,
8717 linep, lineendp, length,
8718 str_offsets_base);
8719 if (j + 1 < file_name_format_count)
8720 printf (", ");
8721 }
8722 printf ("\n");
8723 if (linep > lineendp)
8724 goto invalid_unit;
8725 }
8726 }
8727 else
8728 {
8729 puts (_(" Entry Dir Time Size Name"));
8730 for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8731 {
8732 /* First comes the file name. */
8733 char *fname = (char *) linep;
8734 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8735 if (unlikely (endp == NULL))
8736 goto invalid_unit;
8737 linep = endp + 1;
8738
8739 /* Then the index. */
8740 unsigned int diridx;
8741 if (lineendp - linep < 1)
8742 goto invalid_unit;
8743 get_uleb128 (diridx, linep, lineendp);
8744
8745 /* Next comes the modification time. */
8746 unsigned int mtime;
8747 if (lineendp - linep < 1)
8748 goto invalid_unit;
8749 get_uleb128 (mtime, linep, lineendp);
8750
8751 /* Finally the length of the file. */
8752 unsigned int fsize;
8753 if (lineendp - linep < 1)
8754 goto invalid_unit;
8755 get_uleb128 (fsize, linep, lineendp);
8756
8757 printf (" %-5u %-5u %-9u %-9u %s\n",
8758 cnt, diridx, mtime, fsize, fname);
8759 }
8760 if (linep >= lineendp || *linep != '\0')
8761 goto invalid_unit;
8762 /* Skip the final NUL byte. */
8763 ++linep;
8764 }
8765
8766 unsigned int debug_str_offset = 0;
8767 if (unlikely (linep == header_start + header_length - 4))
8768 {
8769 /* CUBINs contain an unsigned 4-byte offset */
8770 debug_str_offset = read_4ubyte_unaligned_inc (dbg, linep);
8771 }
8772
8773 if (linep == lineendp)
8774 {
8775 puts (_("\nNo line number statements."));
8776 continue;
8777 }
8778
8779 puts (_("\nLine number statements:"));
8780 Dwarf_Word address = 0;
8781 unsigned int op_index = 0;
8782 size_t line = 1;
8783 uint_fast8_t is_stmt = default_is_stmt;
8784
8785 /* Apply the "operation advance" from a special opcode
8786 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
8787 unsigned int op_addr_advance;
8788 #define advance_pc(op_advance) run_advance_pc(op_advance, minimum_instr_len, \
8789 max_ops_per_instr, &op_addr_advance, &address, &op_index)
8790
8791 if (max_ops_per_instr == 0)
8792 {
8793 error (0, 0,
8794 _("invalid maximum operations per instruction is zero"));
8795 linep = lineendp;
8796 continue;
8797 }
8798
8799 while (linep < lineendp)
8800 {
8801 size_t offset = linep - (const unsigned char *) data->d_buf;
8802 unsigned int u128;
8803 int s128;
8804
8805 /* Read the opcode. */
8806 unsigned int opcode = *linep++;
8807
8808 printf (" [%6" PRIx64 "]", (uint64_t)offset);
8809 /* Is this a special opcode? */
8810 if (likely (opcode >= opcode_base))
8811 {
8812 if (unlikely (line_range == 0))
8813 goto invalid_unit;
8814
8815 /* Yes. Handling this is quite easy since the opcode value
8816 is computed with
8817
8818 opcode = (desired line increment - line_base)
8819 + (line_range * address advance) + opcode_base
8820 */
8821 int line_increment = (line_base
8822 + (opcode - opcode_base) % line_range);
8823
8824 /* Perform the increments. */
8825 line += line_increment;
8826 advance_pc ((opcode - opcode_base) / line_range);
8827
8828 printf (_(" special opcode %u: address+%u = "),
8829 opcode, op_addr_advance);
8830 print_dwarf_addr (dwflmod, 0, address, address);
8831 if (op_index > 0)
8832 printf (_(", op_index = %u, line%+d = %zu\n"),
8833 op_index, line_increment, line);
8834 else
8835 printf (_(", line%+d = %zu\n"),
8836 line_increment, line);
8837 }
8838 else if (opcode == 0)
8839 {
8840 /* This an extended opcode. */
8841 if (unlikely (linep + 2 > lineendp))
8842 goto invalid_unit;
8843
8844 /* The length. */
8845 unsigned int len = *linep++;
8846
8847 if (unlikely (linep + len > lineendp))
8848 goto invalid_unit;
8849
8850 /* The sub-opcode. */
8851 opcode = *linep++;
8852
8853 printf (_(" extended opcode %u: "), opcode);
8854
8855 switch (opcode)
8856 {
8857 case DW_LNE_end_sequence:
8858 puts (_(" end of sequence"));
8859
8860 /* Reset the registers we care about. */
8861 address = 0;
8862 op_index = 0;
8863 line = 1;
8864 is_stmt = default_is_stmt;
8865 break;
8866
8867 case DW_LNE_set_address:
8868 op_index = 0;
8869 if (unlikely ((size_t) (lineendp - linep) < address_size))
8870 goto invalid_unit;
8871 if (address_size == 4)
8872 address = read_4ubyte_unaligned_inc (dbg, linep);
8873 else
8874 address = read_8ubyte_unaligned_inc (dbg, linep);
8875 {
8876 printf (_(" set address to "));
8877 print_dwarf_addr (dwflmod, 0, address, address);
8878 printf ("\n");
8879 }
8880 break;
8881
8882 case DW_LNE_define_file:
8883 {
8884 char *fname = (char *) linep;
8885 unsigned char *endp = memchr (linep, '\0',
8886 lineendp - linep);
8887 if (unlikely (endp == NULL))
8888 goto invalid_unit;
8889 linep = endp + 1;
8890
8891 unsigned int diridx;
8892 if (lineendp - linep < 1)
8893 goto invalid_unit;
8894 get_uleb128 (diridx, linep, lineendp);
8895 Dwarf_Word mtime;
8896 if (lineendp - linep < 1)
8897 goto invalid_unit;
8898 get_uleb128 (mtime, linep, lineendp);
8899 Dwarf_Word filelength;
8900 if (lineendp - linep < 1)
8901 goto invalid_unit;
8902 get_uleb128 (filelength, linep, lineendp);
8903
8904 printf (_("\
8905 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8906 diridx, (uint64_t) mtime, (uint64_t) filelength,
8907 fname);
8908 }
8909 break;
8910
8911 case DW_LNE_set_discriminator:
8912 /* Takes one ULEB128 parameter, the discriminator. */
8913 if (unlikely (standard_opcode_lengths[opcode] != 1
8914 || lineendp - linep < 1))
8915 goto invalid_unit;
8916
8917 get_uleb128 (u128, linep, lineendp);
8918 printf (_(" set discriminator to %u\n"), u128);
8919 break;
8920
8921 case DW_LNE_NVIDIA_inlined_call:
8922 {
8923 if (unlikely (linep >= lineendp))
8924 goto invalid_data;
8925
8926 unsigned int context;
8927 get_uleb128 (context, linep, lineendp);
8928
8929 if (unlikely (linep >= lineendp))
8930 goto invalid_data;
8931
8932 unsigned int function_name;
8933 get_uleb128 (function_name, linep, lineendp);
8934 function_name += debug_str_offset;
8935
8936 Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
8937 char *function_str;
8938 if (str_data == NULL || function_name >= str_data->d_size
8939 || memchr (str_data->d_buf + function_name, '\0',
8940 str_data->d_size - function_name) == NULL)
8941 function_str = "???";
8942 else
8943 function_str = (char *) str_data->d_buf + function_name;
8944
8945 printf (_(" set inlined context %u,"
8946 " function name %s (0x%x)\n"),
8947 context, function_str, function_name);
8948 break;
8949 }
8950
8951 case DW_LNE_NVIDIA_set_function_name:
8952 {
8953 if (unlikely (linep >= lineendp))
8954 goto invalid_data;
8955
8956 unsigned int function_name;
8957 get_uleb128 (function_name, linep, lineendp);
8958 function_name += debug_str_offset;
8959
8960 Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
8961 char *function_str;
8962 if (str_data == NULL || function_name >= str_data->d_size
8963 || memchr (str_data->d_buf + function_name, '\0',
8964 str_data->d_size - function_name) == NULL)
8965 function_str = "???";
8966 else
8967 function_str = (char *) str_data->d_buf + function_name;
8968
8969 printf (_(" set function name %s (0x%x)\n"),
8970 function_str, function_name);
8971 }
8972 break;
8973
8974 default:
8975 /* Unknown, ignore it. */
8976 puts (_(" unknown opcode"));
8977 linep += len - 1;
8978 break;
8979 }
8980 }
8981 else if (opcode <= DW_LNS_set_isa)
8982 {
8983 /* This is a known standard opcode. */
8984 switch (opcode)
8985 {
8986 case DW_LNS_copy:
8987 /* Takes no argument. */
8988 puts (_(" copy"));
8989 break;
8990
8991 case DW_LNS_advance_pc:
8992 /* Takes one uleb128 parameter which is added to the
8993 address. */
8994 if (lineendp - linep < 1)
8995 goto invalid_unit;
8996 get_uleb128 (u128, linep, lineendp);
8997 advance_pc (u128);
8998 {
8999 printf (_(" advance address by %u to "),
9000 op_addr_advance);
9001 print_dwarf_addr (dwflmod, 0, address, address);
9002 if (op_index > 0)
9003 printf (_(", op_index to %u"), op_index);
9004 printf ("\n");
9005 }
9006 break;
9007
9008 case DW_LNS_advance_line:
9009 /* Takes one sleb128 parameter which is added to the
9010 line. */
9011 if (lineendp - linep < 1)
9012 goto invalid_unit;
9013 get_sleb128 (s128, linep, lineendp);
9014 line += s128;
9015 printf (_("\
9016 advance line by constant %d to %" PRId64 "\n"),
9017 s128, (int64_t) line);
9018 break;
9019
9020 case DW_LNS_set_file:
9021 /* Takes one uleb128 parameter which is stored in file. */
9022 if (lineendp - linep < 1)
9023 goto invalid_unit;
9024 get_uleb128 (u128, linep, lineendp);
9025 printf (_(" set file to %" PRIu64 "\n"),
9026 (uint64_t) u128);
9027 break;
9028
9029 case DW_LNS_set_column:
9030 /* Takes one uleb128 parameter which is stored in column. */
9031 if (unlikely (standard_opcode_lengths[opcode] != 1
9032 || lineendp - linep < 1))
9033 goto invalid_unit;
9034
9035 get_uleb128 (u128, linep, lineendp);
9036 printf (_(" set column to %" PRIu64 "\n"),
9037 (uint64_t) u128);
9038 break;
9039
9040 case DW_LNS_negate_stmt:
9041 /* Takes no argument. */
9042 is_stmt = 1 - is_stmt;
9043 printf (_(" set '%s' to %" PRIuFAST8 "\n"),
9044 "is_stmt", is_stmt);
9045 break;
9046
9047 case DW_LNS_set_basic_block:
9048 /* Takes no argument. */
9049 puts (_(" set basic block flag"));
9050 break;
9051
9052 case DW_LNS_const_add_pc:
9053 /* Takes no argument. */
9054
9055 if (unlikely (line_range == 0))
9056 goto invalid_unit;
9057
9058 advance_pc ((255 - opcode_base) / line_range);
9059 {
9060 printf (_(" advance address by constant %u to "),
9061 op_addr_advance);
9062 print_dwarf_addr (dwflmod, 0, address, address);
9063 if (op_index > 0)
9064 printf (_(", op_index to %u"), op_index);
9065 printf ("\n");
9066 }
9067 break;
9068
9069 case DW_LNS_fixed_advance_pc:
9070 /* Takes one 16 bit parameter which is added to the
9071 address. */
9072 if (unlikely (standard_opcode_lengths[opcode] != 1
9073 || lineendp - linep < 2))
9074 goto invalid_unit;
9075
9076 u128 = read_2ubyte_unaligned_inc (dbg, linep);
9077 address += u128;
9078 op_index = 0;
9079 {
9080 printf (_("\
9081 advance address by fixed value %u to \n"),
9082 u128);
9083 print_dwarf_addr (dwflmod, 0, address, address);
9084 printf ("\n");
9085 }
9086 break;
9087
9088 case DW_LNS_set_prologue_end:
9089 /* Takes no argument. */
9090 puts (_(" set prologue end flag"));
9091 break;
9092
9093 case DW_LNS_set_epilogue_begin:
9094 /* Takes no argument. */
9095 puts (_(" set epilogue begin flag"));
9096 break;
9097
9098 case DW_LNS_set_isa:
9099 /* Takes one uleb128 parameter which is stored in isa. */
9100 if (unlikely (standard_opcode_lengths[opcode] != 1
9101 || lineendp - linep < 1))
9102 goto invalid_unit;
9103
9104 get_uleb128 (u128, linep, lineendp);
9105 printf (_(" set isa to %u\n"), u128);
9106 break;
9107 }
9108 }
9109 else
9110 {
9111 /* This is a new opcode the generator but not we know about.
9112 Read the parameters associated with it but then discard
9113 everything. Read all the parameters for this opcode. */
9114 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
9115 " unknown opcode with %" PRIu8 " parameters:",
9116 standard_opcode_lengths[opcode]),
9117 standard_opcode_lengths[opcode]);
9118 for (int n = standard_opcode_lengths[opcode];
9119 n > 0 && linep < lineendp; --n)
9120 {
9121 get_uleb128 (u128, linep, lineendp);
9122 if (n != standard_opcode_lengths[opcode])
9123 putc_unlocked (',', stdout);
9124 printf (" %u", u128);
9125 }
9126
9127 /* Next round, ignore this opcode. */
9128 continue;
9129 }
9130 }
9131 }
9132
9133 /* There must only be one data block. */
9134 assert (elf_getdata (scn, data) == NULL);
9135 }
9136
9137
9138 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9139 print_debug_loclists_section (Dwfl_Module *dwflmod,
9140 Ebl *ebl,
9141 GElf_Ehdr *ehdr __attribute__ ((unused)),
9142 Elf_Scn *scn, GElf_Shdr *shdr,
9143 Dwarf *dbg)
9144 {
9145 printf (_("\
9146 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9147 elf_ndxscn (scn), section_name (ebl, shdr),
9148 (uint64_t) shdr->sh_offset);
9149
9150 Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9151 ?: elf_rawdata (scn, NULL));
9152 if (unlikely (data == NULL))
9153 {
9154 error (0, 0, _("cannot get .debug_loclists content: %s"),
9155 elf_errmsg (-1));
9156 return;
9157 }
9158
9159 /* For the listptr to get the base address/CU. */
9160 sort_listptr (&known_loclistsptr, "loclistsptr");
9161 size_t listptr_idx = 0;
9162
9163 const unsigned char *readp = data->d_buf;
9164 const unsigned char *const dataend = ((unsigned char *) data->d_buf
9165 + data->d_size);
9166 while (readp < dataend)
9167 {
9168 if (unlikely (readp > dataend - 4))
9169 {
9170 invalid_data:
9171 error (0, 0, _("invalid data in section [%zu] '%s'"),
9172 elf_ndxscn (scn), section_name (ebl, shdr));
9173 return;
9174 }
9175
9176 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9177 printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
9178 (uint64_t) offset);
9179
9180 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9181 unsigned int offset_size = 4;
9182 if (unlikely (unit_length == 0xffffffff))
9183 {
9184 if (unlikely (readp > dataend - 8))
9185 goto invalid_data;
9186
9187 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9188 offset_size = 8;
9189 }
9190 printf (_(" Length: %8" PRIu64 "\n"), unit_length);
9191
9192 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9193 bytes to complete the header. And this unit cannot go beyond
9194 the section data. */
9195 if (readp > dataend - 8
9196 || unit_length < 8
9197 || unit_length > (uint64_t) (dataend - readp))
9198 goto invalid_data;
9199
9200 const unsigned char *nexthdr = readp + unit_length;
9201
9202 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9203 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
9204
9205 if (version != 5)
9206 {
9207 error (0, 0, _("Unknown version"));
9208 goto next_table;
9209 }
9210
9211 uint8_t address_size = *readp++;
9212 printf (_(" Address size: %8" PRIu64 "\n"),
9213 (uint64_t) address_size);
9214
9215 if (address_size != 4 && address_size != 8)
9216 {
9217 error (0, 0, _("unsupported address size"));
9218 goto next_table;
9219 }
9220
9221 uint8_t segment_size = *readp++;
9222 printf (_(" Segment size: %8" PRIu64 "\n"),
9223 (uint64_t) segment_size);
9224
9225 if (segment_size != 0)
9226 {
9227 error (0, 0, _("unsupported segment size"));
9228 goto next_table;
9229 }
9230
9231 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9232 printf (_(" Offset entries: %8" PRIu64 "\n"),
9233 (uint64_t) offset_entry_count);
9234
9235 /* We need the CU that uses this unit to get the initial base address. */
9236 Dwarf_Addr cu_base = 0;
9237 struct Dwarf_CU *cu = NULL;
9238 if (listptr_cu (&known_loclistsptr, &listptr_idx,
9239 (Dwarf_Off) offset,
9240 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9241 &cu_base, &cu)
9242 || split_dwarf_cu_base (dbg, &cu, &cu_base))
9243 {
9244 Dwarf_Die cudie;
9245 if (dwarf_cu_die (cu, &cudie,
9246 NULL, NULL, NULL, NULL,
9247 NULL, NULL) == NULL)
9248 printf (_(" Unknown CU base: "));
9249 else
9250 printf (_(" CU [%6" PRIx64 "] base: "),
9251 dwarf_dieoffset (&cudie));
9252 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9253 printf ("\n");
9254 }
9255 else
9256 printf (_(" Not associated with a CU.\n"));
9257
9258 printf ("\n");
9259
9260 const unsigned char *offset_array_start = readp;
9261 if (offset_entry_count > 0)
9262 {
9263 uint64_t max_entries = (unit_length - 8) / offset_size;
9264 if (offset_entry_count > max_entries)
9265 {
9266 error (0, 0,
9267 _("too many offset entries for unit length"));
9268 offset_entry_count = max_entries;
9269 }
9270
9271 printf (_(" Offsets starting at 0x%" PRIx64 ":\n"),
9272 (uint64_t) (offset_array_start
9273 - (unsigned char *) data->d_buf));
9274 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9275 {
9276 printf (" [%6" PRIu32 "] ", idx);
9277 if (offset_size == 4)
9278 {
9279 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9280 printf ("0x%" PRIx32 "\n", off);
9281 }
9282 else
9283 {
9284 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9285 printf ("0x%" PRIx64 "\n", off);
9286 }
9287 }
9288 printf ("\n");
9289 }
9290
9291 Dwarf_Addr base = cu_base;
9292 bool start_of_list = true;
9293 while (readp < nexthdr)
9294 {
9295 Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf);
9296 if (listptr_attr (&known_loclistsptr, listptr_idx, off,
9297 DW_AT_GNU_locviews))
9298 {
9299 Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
9300 &listptr_idx, off);
9301 const unsigned char *locp = readp;
9302 const unsigned char *locendp;
9303 if (next_off == 0
9304 || next_off > (size_t) (nexthdr - ((const unsigned char *)
9305 data->d_buf)))
9306 locendp = nexthdr;
9307 else
9308 locendp = (const unsigned char *) data->d_buf + next_off;
9309
9310 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9311 (uint64_t) (readp - (unsigned char *) data->d_buf),
9312 (uint64_t) (readp - offset_array_start));
9313
9314 while (locp < locendp)
9315 {
9316 uint64_t v1, v2;
9317 get_uleb128 (v1, locp, locendp);
9318 if (locp >= locendp)
9319 {
9320 printf (_(" <INVALID DATA>\n"));
9321 break;
9322 }
9323 get_uleb128 (v2, locp, locendp);
9324 printf (" view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9325 }
9326
9327 printf ("\n");
9328 readp = (unsigned char *) locendp;
9329 continue;
9330 }
9331
9332 uint8_t kind = *readp++;
9333 uint64_t op1, op2, len;
9334
9335 /* Skip padding. */
9336 if (start_of_list && kind == DW_LLE_end_of_list)
9337 continue;
9338
9339 if (start_of_list)
9340 {
9341 base = cu_base;
9342 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9343 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9344 (uint64_t) (readp - offset_array_start - 1));
9345 start_of_list = false;
9346 }
9347
9348 printf (" %s", dwarf_loc_list_encoding_name (kind));
9349 switch (kind)
9350 {
9351 case DW_LLE_end_of_list:
9352 start_of_list = true;
9353 printf ("\n\n");
9354 break;
9355
9356 case DW_LLE_base_addressx:
9357 if ((uint64_t) (nexthdr - readp) < 1)
9358 {
9359 invalid_entry:
9360 error (0, 0, _("invalid loclists data"));
9361 goto next_table;
9362 }
9363 get_uleb128 (op1, readp, nexthdr);
9364 printf (" %" PRIx64 "\n", op1);
9365 if (! print_unresolved_addresses)
9366 {
9367 Dwarf_Addr addr;
9368 if (get_indexed_addr (cu, op1, &addr) != 0)
9369 printf (" ???\n");
9370 else
9371 {
9372 printf (" ");
9373 print_dwarf_addr (dwflmod, address_size, addr, addr);
9374 printf ("\n");
9375 }
9376 }
9377 break;
9378
9379 case DW_LLE_startx_endx:
9380 if ((uint64_t) (nexthdr - readp) < 1)
9381 goto invalid_entry;
9382 get_uleb128 (op1, readp, nexthdr);
9383 if ((uint64_t) (nexthdr - readp) < 1)
9384 goto invalid_entry;
9385 get_uleb128 (op2, readp, nexthdr);
9386 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9387 if (! print_unresolved_addresses)
9388 {
9389 Dwarf_Addr addr1;
9390 Dwarf_Addr addr2;
9391 if (get_indexed_addr (cu, op1, &addr1) != 0
9392 || get_indexed_addr (cu, op2, &addr2) != 0)
9393 {
9394 printf (" ???..\n");
9395 printf (" ???\n");
9396 }
9397 else
9398 {
9399 printf (" ");
9400 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9401 printf ("..\n ");
9402 print_dwarf_addr (dwflmod, address_size,
9403 addr2 - 1, addr2);
9404 printf ("\n");
9405 }
9406 }
9407 if ((uint64_t) (nexthdr - readp) < 1)
9408 goto invalid_entry;
9409 get_uleb128 (len, readp, nexthdr);
9410 if ((uint64_t) (nexthdr - readp) < len)
9411 goto invalid_entry;
9412 print_ops (dwflmod, dbg, 8, 8, version,
9413 address_size, offset_size, cu, len, readp);
9414 readp += len;
9415 break;
9416
9417 case DW_LLE_startx_length:
9418 if ((uint64_t) (nexthdr - readp) < 1)
9419 goto invalid_entry;
9420 get_uleb128 (op1, readp, nexthdr);
9421 if ((uint64_t) (nexthdr - readp) < 1)
9422 goto invalid_entry;
9423 get_uleb128 (op2, readp, nexthdr);
9424 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9425 if (! print_unresolved_addresses)
9426 {
9427 Dwarf_Addr addr1;
9428 Dwarf_Addr addr2;
9429 if (get_indexed_addr (cu, op1, &addr1) != 0)
9430 {
9431 printf (" ???..\n");
9432 printf (" ???\n");
9433 }
9434 else
9435 {
9436 addr2 = addr1 + op2;
9437 printf (" ");
9438 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9439 printf ("..\n ");
9440 print_dwarf_addr (dwflmod, address_size,
9441 addr2 - 1, addr2);
9442 printf ("\n");
9443 }
9444 }
9445 if ((uint64_t) (nexthdr - readp) < 1)
9446 goto invalid_entry;
9447 get_uleb128 (len, readp, nexthdr);
9448 if ((uint64_t) (nexthdr - readp) < len)
9449 goto invalid_entry;
9450 print_ops (dwflmod, dbg, 8, 8, version,
9451 address_size, offset_size, cu, len, readp);
9452 readp += len;
9453 break;
9454
9455 case DW_LLE_offset_pair:
9456 if ((uint64_t) (nexthdr - readp) < 1)
9457 goto invalid_entry;
9458 get_uleb128 (op1, readp, nexthdr);
9459 if ((uint64_t) (nexthdr - readp) < 1)
9460 goto invalid_entry;
9461 get_uleb128 (op2, readp, nexthdr);
9462 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9463 if (! print_unresolved_addresses)
9464 {
9465 op1 += base;
9466 op2 += base;
9467 printf (" ");
9468 print_dwarf_addr (dwflmod, address_size, op1, op1);
9469 printf ("..\n ");
9470 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9471 printf ("\n");
9472 }
9473 if ((uint64_t) (nexthdr - readp) < 1)
9474 goto invalid_entry;
9475 get_uleb128 (len, readp, nexthdr);
9476 if ((uint64_t) (nexthdr - readp) < len)
9477 goto invalid_entry;
9478 print_ops (dwflmod, dbg, 8, 8, version,
9479 address_size, offset_size, cu, len, readp);
9480 readp += len;
9481 break;
9482
9483 case DW_LLE_default_location:
9484 if ((uint64_t) (nexthdr - readp) < 1)
9485 goto invalid_entry;
9486 get_uleb128 (len, readp, nexthdr);
9487 if ((uint64_t) (nexthdr - readp) < len)
9488 goto invalid_entry;
9489 print_ops (dwflmod, dbg, 8, 8, version,
9490 address_size, offset_size, cu, len, readp);
9491 readp += len;
9492 break;
9493
9494 case DW_LLE_base_address:
9495 if (address_size == 4)
9496 {
9497 if ((uint64_t) (nexthdr - readp) < 4)
9498 goto invalid_entry;
9499 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9500 }
9501 else
9502 {
9503 if ((uint64_t) (nexthdr - readp) < 8)
9504 goto invalid_entry;
9505 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9506 }
9507 base = op1;
9508 printf (" 0x%" PRIx64 "\n", base);
9509 if (! print_unresolved_addresses)
9510 {
9511 printf (" ");
9512 print_dwarf_addr (dwflmod, address_size, base, base);
9513 printf ("\n");
9514 }
9515 break;
9516
9517 case DW_LLE_start_end:
9518 if (address_size == 4)
9519 {
9520 if ((uint64_t) (nexthdr - readp) < 8)
9521 goto invalid_entry;
9522 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9523 op2 = read_4ubyte_unaligned_inc (dbg, readp);
9524 }
9525 else
9526 {
9527 if ((uint64_t) (nexthdr - readp) < 16)
9528 goto invalid_entry;
9529 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9530 op2 = read_8ubyte_unaligned_inc (dbg, readp);
9531 }
9532 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9533 if (! print_unresolved_addresses)
9534 {
9535 printf (" ");
9536 print_dwarf_addr (dwflmod, address_size, op1, op1);
9537 printf ("..\n ");
9538 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9539 printf ("\n");
9540 }
9541 if ((uint64_t) (nexthdr - readp) < 1)
9542 goto invalid_entry;
9543 get_uleb128 (len, readp, nexthdr);
9544 if ((uint64_t) (nexthdr - readp) < len)
9545 goto invalid_entry;
9546 print_ops (dwflmod, dbg, 8, 8, version,
9547 address_size, offset_size, cu, len, readp);
9548 readp += len;
9549 break;
9550
9551 case DW_LLE_start_length:
9552 if (address_size == 4)
9553 {
9554 if ((uint64_t) (nexthdr - readp) < 4)
9555 goto invalid_entry;
9556 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9557 }
9558 else
9559 {
9560 if ((uint64_t) (nexthdr - readp) < 8)
9561 goto invalid_entry;
9562 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9563 }
9564 if ((uint64_t) (nexthdr - readp) < 1)
9565 goto invalid_entry;
9566 get_uleb128 (op2, readp, nexthdr);
9567 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9568 if (! print_unresolved_addresses)
9569 {
9570 op2 = op1 + op2;
9571 printf (" ");
9572 print_dwarf_addr (dwflmod, address_size, op1, op1);
9573 printf ("..\n ");
9574 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9575 printf ("\n");
9576 }
9577 if ((uint64_t) (nexthdr - readp) < 1)
9578 goto invalid_entry;
9579 get_uleb128 (len, readp, nexthdr);
9580 if ((uint64_t) (nexthdr - readp) < len)
9581 goto invalid_entry;
9582 print_ops (dwflmod, dbg, 8, 8, version,
9583 address_size, offset_size, cu, len, readp);
9584 readp += len;
9585 break;
9586
9587 default:
9588 goto invalid_entry;
9589 }
9590 }
9591
9592 next_table:
9593 if (readp != nexthdr)
9594 {
9595 size_t padding = nexthdr - readp;
9596 printf (_(" %zu padding bytes\n\n"), padding);
9597 readp = nexthdr;
9598 }
9599 }
9600 }
9601
9602
9603 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9604 print_debug_loc_section (Dwfl_Module *dwflmod,
9605 Ebl *ebl, GElf_Ehdr *ehdr,
9606 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9607 {
9608 Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9609 ?: elf_rawdata (scn, NULL));
9610
9611 if (unlikely (data == NULL))
9612 {
9613 error (0, 0, _("cannot get .debug_loc content: %s"),
9614 elf_errmsg (-1));
9615 return;
9616 }
9617
9618 printf (_("\
9619 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9620 elf_ndxscn (scn), section_name (ebl, shdr),
9621 (uint64_t) shdr->sh_offset);
9622
9623 sort_listptr (&known_locsptr, "loclistptr");
9624 size_t listptr_idx = 0;
9625
9626 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9627 uint_fast8_t offset_size = 4;
9628
9629 bool first = true;
9630 Dwarf_Addr base = 0;
9631 unsigned char *readp = data->d_buf;
9632 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9633 Dwarf_CU *last_cu = NULL;
9634 while (readp < endp)
9635 {
9636 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9637 Dwarf_CU *cu = last_cu;
9638 unsigned int attr = 0;
9639
9640 if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9641 &address_size, &offset_size, &base,
9642 &cu, offset, &readp, endp, &attr))
9643 continue;
9644
9645 if (last_cu != cu)
9646 {
9647 Dwarf_Die cudie;
9648 if (dwarf_cu_die (cu, &cudie,
9649 NULL, NULL, NULL, NULL,
9650 NULL, NULL) == NULL)
9651 printf (_("\n Unknown CU base: "));
9652 else
9653 printf (_("\n CU [%6" PRIx64 "] base: "),
9654 dwarf_dieoffset (&cudie));
9655 print_dwarf_addr (dwflmod, address_size, base, base);
9656 printf ("\n");
9657 }
9658 last_cu = cu;
9659
9660 if (attr == DW_AT_GNU_locviews)
9661 {
9662 Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9663 &listptr_idx, offset);
9664 const unsigned char *locp = readp;
9665 const unsigned char *locendp;
9666 if (next_off == 0
9667 || next_off > (size_t) (endp
9668 - (const unsigned char *) data->d_buf))
9669 locendp = endp;
9670 else
9671 locendp = (const unsigned char *) data->d_buf + next_off;
9672
9673 while (locp < locendp)
9674 {
9675 uint64_t v1, v2;
9676 get_uleb128 (v1, locp, locendp);
9677 if (locp >= locendp)
9678 {
9679 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
9680 break;
9681 }
9682 get_uleb128 (v2, locp, locendp);
9683 if (first) /* First view pair in a list. */
9684 printf (" [%6tx] ", offset);
9685 else
9686 printf (" ");
9687 printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9688 first = false;
9689 }
9690
9691 first = true;
9692 readp = (unsigned char *) locendp;
9693 continue;
9694 }
9695
9696 /* GNU DebugFission encoded addresses as addrx. */
9697 bool is_debugfission = ((cu != NULL
9698 || split_dwarf_cu_base (dbg, &cu, &base))
9699 && (cu->version < 5
9700 && cu->unit_type == DW_UT_split_compile));
9701 if (!is_debugfission
9702 && unlikely (data->d_size - offset < (size_t) address_size * 2))
9703 {
9704 invalid_data:
9705 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
9706 break;
9707 }
9708
9709 Dwarf_Addr begin;
9710 Dwarf_Addr end;
9711 bool use_base = true;
9712 if (is_debugfission)
9713 {
9714 const unsigned char *locp = readp;
9715 const unsigned char *locendp = readp + data->d_size;
9716 if (locp >= locendp)
9717 goto invalid_data;
9718
9719 Dwarf_Word idx;
9720 unsigned char code = *locp++;
9721 switch (code)
9722 {
9723 case DW_LLE_GNU_end_of_list_entry:
9724 begin = 0;
9725 end = 0;
9726 break;
9727
9728 case DW_LLE_GNU_base_address_selection_entry:
9729 if (locp >= locendp)
9730 goto invalid_data;
9731 begin = (Dwarf_Addr) -1;
9732 get_uleb128 (idx, locp, locendp);
9733 if (get_indexed_addr (cu, idx, &end) != 0)
9734 end = idx; /* ... */
9735 break;
9736
9737 case DW_LLE_GNU_start_end_entry:
9738 if (locp >= locendp)
9739 goto invalid_data;
9740 get_uleb128 (idx, locp, locendp);
9741 if (get_indexed_addr (cu, idx, &begin) != 0)
9742 begin = idx; /* ... */
9743 if (locp >= locendp)
9744 goto invalid_data;
9745 get_uleb128 (idx, locp, locendp);
9746 if (get_indexed_addr (cu, idx, &end) != 0)
9747 end = idx; /* ... */
9748 use_base = false;
9749 break;
9750
9751 case DW_LLE_GNU_start_length_entry:
9752 if (locp >= locendp)
9753 goto invalid_data;
9754 get_uleb128 (idx, locp, locendp);
9755 if (get_indexed_addr (cu, idx, &begin) != 0)
9756 begin = idx; /* ... */
9757 if (locendp - locp < 4)
9758 goto invalid_data;
9759 end = read_4ubyte_unaligned_inc (dbg, locp);
9760 end += begin;
9761 use_base = false;
9762 break;
9763
9764 default:
9765 goto invalid_data;
9766 }
9767
9768 readp = (unsigned char *) locp;
9769 }
9770 else if (address_size == 8)
9771 {
9772 begin = read_8ubyte_unaligned_inc (dbg, readp);
9773 end = read_8ubyte_unaligned_inc (dbg, readp);
9774 }
9775 else
9776 {
9777 begin = read_4ubyte_unaligned_inc (dbg, readp);
9778 end = read_4ubyte_unaligned_inc (dbg, readp);
9779 if (begin == (Dwarf_Addr) (uint32_t) -1)
9780 begin = (Dwarf_Addr) -1l;
9781 }
9782
9783 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
9784 {
9785 if (first)
9786 printf (" [%6tx] ", offset);
9787 else
9788 printf (" ");
9789 puts (_("base address"));
9790 printf (" ");
9791 print_dwarf_addr (dwflmod, address_size, end, end);
9792 printf ("\n");
9793 base = end;
9794 first = false;
9795 }
9796 else if (begin == 0 && end == 0) /* End of list entry. */
9797 {
9798 if (first)
9799 printf (_(" [%6tx] empty list\n"), offset);
9800 first = true;
9801 }
9802 else
9803 {
9804 /* We have a location expression entry. */
9805 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9806
9807 if (first) /* First entry in a list. */
9808 printf (" [%6tx] ", offset);
9809 else
9810 printf (" ");
9811
9812 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9813 if (! print_unresolved_addresses)
9814 {
9815 Dwarf_Addr dab = use_base ? base + begin : begin;
9816 Dwarf_Addr dae = use_base ? base + end : end;
9817 printf (" ");
9818 print_dwarf_addr (dwflmod, address_size, dab, dab);
9819 printf ("..\n ");
9820 print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9821 printf ("\n");
9822 }
9823
9824 if (endp - readp <= (ptrdiff_t) len)
9825 {
9826 fputs (_(" <INVALID DATA>\n"), stdout);
9827 break;
9828 }
9829
9830 print_ops (dwflmod, dbg, 11, 11,
9831 cu != NULL ? cu->version : 3,
9832 address_size, offset_size, cu, len, readp);
9833
9834 first = false;
9835 readp += len;
9836 }
9837 }
9838 }
9839
9840 struct mac_culist
9841 {
9842 Dwarf_Die die;
9843 Dwarf_Off offset;
9844 Dwarf_Files *files;
9845 struct mac_culist *next;
9846 };
9847
9848
9849 static int
mac_compare(const void * p1,const void * p2)9850 mac_compare (const void *p1, const void *p2)
9851 {
9852 struct mac_culist *m1 = (struct mac_culist *) p1;
9853 struct mac_culist *m2 = (struct mac_culist *) p2;
9854
9855 if (m1->offset < m2->offset)
9856 return -1;
9857 if (m1->offset > m2->offset)
9858 return 1;
9859 return 0;
9860 }
9861
9862
9863 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9864 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9865 Ebl *ebl,
9866 GElf_Ehdr *ehdr __attribute__ ((unused)),
9867 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9868 {
9869 printf (_("\
9870 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9871 elf_ndxscn (scn), section_name (ebl, shdr),
9872 (uint64_t) shdr->sh_offset);
9873 putc_unlocked ('\n', stdout);
9874
9875 /* There is no function in libdw to iterate over the raw content of
9876 the section but it is easy enough to do. */
9877 Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9878 ?: elf_rawdata (scn, NULL));
9879 if (unlikely (data == NULL))
9880 {
9881 error (0, 0, _("cannot get macro information section data: %s"),
9882 elf_errmsg (-1));
9883 return;
9884 }
9885
9886 /* Get the source file information for all CUs. */
9887 Dwarf_Off offset;
9888 Dwarf_Off ncu = 0;
9889 size_t hsize;
9890 struct mac_culist *culist = NULL;
9891 size_t nculist = 0;
9892 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9893 {
9894 Dwarf_Die cudie;
9895 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9896 continue;
9897
9898 Dwarf_Attribute attr;
9899 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9900 continue;
9901
9902 Dwarf_Word macoff;
9903 if (dwarf_formudata (&attr, &macoff) != 0)
9904 continue;
9905
9906 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9907 newp->die = cudie;
9908 newp->offset = macoff;
9909 newp->files = NULL;
9910 newp->next = culist;
9911 culist = newp;
9912 ++nculist;
9913 }
9914
9915 /* Convert the list into an array for easier consumption. */
9916 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9917 * sizeof (*cus));
9918 /* Add sentinel. */
9919 cus[nculist].offset = data->d_size;
9920 cus[nculist].files = (Dwarf_Files *) -1l;
9921 if (nculist > 0)
9922 {
9923 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9924 {
9925 assert (cnt < nculist);
9926 cus[cnt] = *culist;
9927 culist = culist->next;
9928 }
9929
9930 /* Sort the array according to the offset in the .debug_macinfo
9931 section. Note we keep the sentinel at the end. */
9932 qsort (cus, nculist, sizeof (*cus), mac_compare);
9933 }
9934
9935 const unsigned char *readp = (const unsigned char *) data->d_buf;
9936 const unsigned char *readendp = readp + data->d_size;
9937 int level = 1;
9938
9939 while (readp < readendp)
9940 {
9941 unsigned int opcode = *readp++;
9942 unsigned int u128;
9943 unsigned int u128_2;
9944 const unsigned char *endp;
9945
9946 switch (opcode)
9947 {
9948 case DW_MACINFO_define:
9949 case DW_MACINFO_undef:
9950 case DW_MACINFO_vendor_ext:
9951 /* For the first two opcodes the parameters are
9952 line, string
9953 For the latter
9954 number, string.
9955 We can treat these cases together. */
9956 get_uleb128 (u128, readp, readendp);
9957
9958 endp = memchr (readp, '\0', readendp - readp);
9959 if (unlikely (endp == NULL))
9960 {
9961 printf (_("\
9962 %*s*** non-terminated string at end of section"),
9963 level, "");
9964 return;
9965 }
9966
9967 if (opcode == DW_MACINFO_define)
9968 printf ("%*s#define %s, line %u\n",
9969 level, "", (char *) readp, u128);
9970 else if (opcode == DW_MACINFO_undef)
9971 printf ("%*s#undef %s, line %u\n",
9972 level, "", (char *) readp, u128);
9973 else
9974 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9975
9976 readp = endp + 1;
9977 break;
9978
9979 case DW_MACINFO_start_file:
9980 /* The two parameters are line and file index, in this order. */
9981 get_uleb128 (u128, readp, readendp);
9982 if (readendp - readp < 1)
9983 {
9984 printf (_("\
9985 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9986 level, "");
9987 return;
9988 }
9989 get_uleb128 (u128_2, readp, readendp);
9990
9991 /* Find the CU DIE for this file. */
9992 size_t macoff = readp - (const unsigned char *) data->d_buf;
9993 const char *fname = "???";
9994 if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
9995 {
9996 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9997 ++cus;
9998
9999 if (cus[0].files == NULL
10000 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
10001 cus[0].files = (Dwarf_Files *) -1l;
10002
10003 if (cus[0].files != (Dwarf_Files *) -1l)
10004 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
10005 ?: "???");
10006 }
10007
10008 printf ("%*sstart_file %u, [%u] %s\n",
10009 level, "", u128, u128_2, fname);
10010 ++level;
10011 break;
10012
10013 case DW_MACINFO_end_file:
10014 --level;
10015 printf ("%*send_file\n", level, "");
10016 /* Nothing more to do. */
10017 break;
10018
10019 default:
10020 // XXX gcc seems to generate files with a trailing zero.
10021 if (unlikely (opcode != 0 || readp != readendp))
10022 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
10023 break;
10024 }
10025 }
10026 }
10027
10028
10029 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10030 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10031 Ebl *ebl,
10032 GElf_Ehdr *ehdr __attribute__ ((unused)),
10033 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10034 {
10035 printf (_("\
10036 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10037 elf_ndxscn (scn), section_name (ebl, shdr),
10038 (uint64_t) shdr->sh_offset);
10039 putc_unlocked ('\n', stdout);
10040
10041 Elf_Data *data = elf_getdata (scn, NULL);
10042 if (unlikely (data == NULL))
10043 {
10044 error (0, 0, _("cannot get macro information section data: %s"),
10045 elf_errmsg (-1));
10046 return;
10047 }
10048
10049 /* Get the source file information for all CUs. Uses same
10050 datastructure as macinfo. But uses offset field to directly
10051 match .debug_line offset. And just stored in a list. */
10052 Dwarf_Off offset;
10053 Dwarf_Off ncu = 0;
10054 size_t hsize;
10055 struct mac_culist *culist = NULL;
10056 size_t nculist = 0;
10057 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10058 {
10059 Dwarf_Die cudie;
10060 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10061 continue;
10062
10063 Dwarf_Attribute attr;
10064 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
10065 continue;
10066
10067 Dwarf_Word lineoff;
10068 if (dwarf_formudata (&attr, &lineoff) != 0)
10069 continue;
10070
10071 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10072 newp->die = cudie;
10073 newp->offset = lineoff;
10074 newp->files = NULL;
10075 newp->next = culist;
10076 culist = newp;
10077 ++nculist;
10078 }
10079
10080 const unsigned char *readp = (const unsigned char *) data->d_buf;
10081 const unsigned char *readendp = readp + data->d_size;
10082
10083 while (readp < readendp)
10084 {
10085 printf (_(" Offset: 0x%" PRIx64 "\n"),
10086 (uint64_t) (readp - (const unsigned char *) data->d_buf));
10087
10088 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
10089 // optional vendor extension macro entry table.
10090 if (readp + 2 > readendp)
10091 {
10092 invalid_data:
10093 error (0, 0, _("invalid data"));
10094 return;
10095 }
10096 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
10097 printf (_(" Version: %" PRIu16 "\n"), vers);
10098
10099 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
10100 // 5 when it gets standardized.
10101 if (vers != 4 && vers != 5)
10102 {
10103 printf (_(" unknown version, cannot parse section\n"));
10104 return;
10105 }
10106
10107 if (readp + 1 > readendp)
10108 goto invalid_data;
10109 const unsigned char flag = *readp++;
10110 printf (_(" Flag: 0x%" PRIx8), flag);
10111 if (flag != 0)
10112 {
10113 printf (" (");
10114 if ((flag & 0x01) != 0)
10115 {
10116 printf ("offset_size");
10117 if ((flag & 0xFE) != 0)
10118 printf (", ");
10119 }
10120 if ((flag & 0x02) != 0)
10121 {
10122 printf ("debug_line_offset");
10123 if ((flag & 0xFC) != 0)
10124 printf (", ");
10125 }
10126 if ((flag & 0x04) != 0)
10127 {
10128 printf ("operands_table");
10129 if ((flag & 0xF8) != 0)
10130 printf (", ");
10131 }
10132 if ((flag & 0xF8) != 0)
10133 printf ("unknown");
10134 printf (")");
10135 }
10136 printf ("\n");
10137
10138 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
10139 printf (_(" Offset length: %" PRIu8 "\n"), offset_len);
10140 Dwarf_Off line_offset = -1;
10141 if (flag & 0x02)
10142 {
10143 if (offset_len == 8)
10144 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
10145 else
10146 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
10147 printf (_(" .debug_line offset: 0x%" PRIx64 "\n"),
10148 line_offset);
10149 }
10150
10151 struct mac_culist *cu = NULL;
10152 if (line_offset != (Dwarf_Off) -1)
10153 {
10154 cu = culist;
10155 while (cu != NULL && line_offset != cu->offset)
10156 cu = cu->next;
10157 }
10158
10159 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
10160 ? cu->die.cu
10161 : NULL));
10162
10163 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
10164 memset (vendor, 0, sizeof vendor);
10165 if (flag & 0x04)
10166 {
10167 // 1 byte length, for each item, 1 byte opcode, uleb128 number
10168 // of arguments, for each argument 1 byte form code.
10169 if (readp + 1 > readendp)
10170 goto invalid_data;
10171 unsigned int tlen = *readp++;
10172 printf (_(" extension opcode table, %" PRIu8 " items:\n"),
10173 tlen);
10174 for (unsigned int i = 0; i < tlen; i++)
10175 {
10176 if (readp + 1 > readendp)
10177 goto invalid_data;
10178 unsigned int opcode = *readp++;
10179 printf (_(" [%" PRIx8 "]"), opcode);
10180 if (opcode < DW_MACRO_lo_user
10181 || opcode > DW_MACRO_hi_user)
10182 goto invalid_data;
10183 // Record the start of description for this vendor opcode.
10184 // uleb128 nr args, 1 byte per arg form.
10185 vendor[opcode - DW_MACRO_lo_user] = readp;
10186 if (readp + 1 > readendp)
10187 goto invalid_data;
10188 unsigned int args = *readp++;
10189 if (args > 0)
10190 {
10191 printf (_(" %" PRIu8 " arguments:"), args);
10192 while (args > 0)
10193 {
10194 if (readp + 1 > readendp)
10195 goto invalid_data;
10196 unsigned int form = *readp++;
10197 printf (" %s", dwarf_form_name (form));
10198 if (! libdw_valid_user_form (form))
10199 goto invalid_data;
10200 args--;
10201 if (args > 0)
10202 putchar_unlocked (',');
10203 }
10204 }
10205 else
10206 printf (_(" no arguments."));
10207 putchar_unlocked ('\n');
10208 }
10209 }
10210 putchar_unlocked ('\n');
10211
10212 int level = 1;
10213 if (readp + 1 > readendp)
10214 goto invalid_data;
10215 unsigned int opcode = *readp++;
10216 while (opcode != 0)
10217 {
10218 unsigned int u128;
10219 unsigned int u128_2;
10220 const unsigned char *endp;
10221 uint64_t off;
10222
10223 switch (opcode)
10224 {
10225 case DW_MACRO_start_file:
10226 get_uleb128 (u128, readp, readendp);
10227 if (readp >= readendp)
10228 goto invalid_data;
10229 get_uleb128 (u128_2, readp, readendp);
10230
10231 /* Find the CU DIE that matches this line offset. */
10232 const char *fname = "???";
10233 if (cu != NULL)
10234 {
10235 if (cu->files == NULL
10236 && dwarf_getsrcfiles (&cu->die, &cu->files,
10237 NULL) != 0)
10238 cu->files = (Dwarf_Files *) -1l;
10239
10240 if (cu->files != (Dwarf_Files *) -1l)
10241 fname = (dwarf_filesrc (cu->files, u128_2,
10242 NULL, NULL) ?: "???");
10243 }
10244 printf ("%*sstart_file %u, [%u] %s\n",
10245 level, "", u128, u128_2, fname);
10246 ++level;
10247 break;
10248
10249 case DW_MACRO_end_file:
10250 --level;
10251 printf ("%*send_file\n", level, "");
10252 break;
10253
10254 case DW_MACRO_define:
10255 get_uleb128 (u128, readp, readendp);
10256 endp = memchr (readp, '\0', readendp - readp);
10257 if (endp == NULL)
10258 goto invalid_data;
10259 printf ("%*s#define %s, line %u\n",
10260 level, "", readp, u128);
10261 readp = endp + 1;
10262 break;
10263
10264 case DW_MACRO_undef:
10265 get_uleb128 (u128, readp, readendp);
10266 endp = memchr (readp, '\0', readendp - readp);
10267 if (endp == NULL)
10268 goto invalid_data;
10269 printf ("%*s#undef %s, line %u\n",
10270 level, "", readp, u128);
10271 readp = endp + 1;
10272 break;
10273
10274 case DW_MACRO_define_strp:
10275 get_uleb128 (u128, readp, readendp);
10276 if (readp + offset_len > readendp)
10277 goto invalid_data;
10278 if (offset_len == 8)
10279 off = read_8ubyte_unaligned_inc (dbg, readp);
10280 else
10281 off = read_4ubyte_unaligned_inc (dbg, readp);
10282 printf ("%*s#define %s, line %u (indirect)\n",
10283 level, "", dwarf_getstring (dbg, off, NULL), u128);
10284 break;
10285
10286 case DW_MACRO_undef_strp:
10287 get_uleb128 (u128, readp, readendp);
10288 if (readp + offset_len > readendp)
10289 goto invalid_data;
10290 if (offset_len == 8)
10291 off = read_8ubyte_unaligned_inc (dbg, readp);
10292 else
10293 off = read_4ubyte_unaligned_inc (dbg, readp);
10294 printf ("%*s#undef %s, line %u (indirect)\n",
10295 level, "", dwarf_getstring (dbg, off, NULL), u128);
10296 break;
10297
10298 case DW_MACRO_import:
10299 if (readp + offset_len > readendp)
10300 goto invalid_data;
10301 if (offset_len == 8)
10302 off = read_8ubyte_unaligned_inc (dbg, readp);
10303 else
10304 off = read_4ubyte_unaligned_inc (dbg, readp);
10305 printf ("%*s#include offset 0x%" PRIx64 "\n",
10306 level, "", off);
10307 break;
10308
10309 case DW_MACRO_define_sup:
10310 get_uleb128 (u128, readp, readendp);
10311 if (readp + offset_len > readendp)
10312 goto invalid_data;
10313 printf ("%*s#define ", level, "");
10314 readp = print_form_data (dbg, DW_FORM_strp_sup,
10315 readp, readendp, offset_len,
10316 str_offsets_base);
10317 printf (", line %u (sup)\n", u128);
10318 break;
10319
10320 case DW_MACRO_undef_sup:
10321 get_uleb128 (u128, readp, readendp);
10322 if (readp + offset_len > readendp)
10323 goto invalid_data;
10324 printf ("%*s#undef ", level, "");
10325 readp = print_form_data (dbg, DW_FORM_strp_sup,
10326 readp, readendp, offset_len,
10327 str_offsets_base);
10328 printf (", line %u (sup)\n", u128);
10329 break;
10330
10331 case DW_MACRO_import_sup:
10332 if (readp + offset_len > readendp)
10333 goto invalid_data;
10334 if (offset_len == 8)
10335 off = read_8ubyte_unaligned_inc (dbg, readp);
10336 else
10337 off = read_4ubyte_unaligned_inc (dbg, readp);
10338 // XXX Needs support for reading from supplementary object file.
10339 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10340 level, "", off);
10341 break;
10342
10343 case DW_MACRO_define_strx:
10344 get_uleb128 (u128, readp, readendp);
10345 if (readp + offset_len > readendp)
10346 goto invalid_data;
10347 printf ("%*s#define ", level, "");
10348 readp = print_form_data (dbg, DW_FORM_strx,
10349 readp, readendp, offset_len,
10350 str_offsets_base);
10351 printf (", line %u (strx)\n", u128);
10352 break;
10353
10354 case DW_MACRO_undef_strx:
10355 get_uleb128 (u128, readp, readendp);
10356 if (readp + offset_len > readendp)
10357 goto invalid_data;
10358 printf ("%*s#undef ", level, "");
10359 readp = print_form_data (dbg, DW_FORM_strx,
10360 readp, readendp, offset_len,
10361 str_offsets_base);
10362 printf (", line %u (strx)\n", u128);
10363 break;
10364
10365 default:
10366 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10367 if (opcode < DW_MACRO_lo_user
10368 || opcode > DW_MACRO_lo_user
10369 || vendor[opcode - DW_MACRO_lo_user] == NULL)
10370 goto invalid_data;
10371
10372 const unsigned char *op_desc;
10373 op_desc = vendor[opcode - DW_MACRO_lo_user];
10374
10375 // Just skip the arguments, we cannot really interpret them,
10376 // but print as much as we can.
10377 unsigned int args = *op_desc++;
10378 while (args > 0 && readp < readendp)
10379 {
10380 unsigned int form = *op_desc++;
10381 readp = print_form_data (dbg, form, readp, readendp,
10382 offset_len, str_offsets_base);
10383 args--;
10384 if (args > 0)
10385 printf (", ");
10386 }
10387 putchar_unlocked ('\n');
10388 }
10389
10390 if (readp + 1 > readendp)
10391 goto invalid_data;
10392 opcode = *readp++;
10393 if (opcode == 0)
10394 putchar_unlocked ('\n');
10395 }
10396 }
10397 }
10398
10399
10400 /* Callback for printing global names. */
10401 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10402 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10403 void *arg)
10404 {
10405 int *np = (int *) arg;
10406
10407 printf (_(" [%5d] DIE offset: %6" PRId64
10408 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10409 (*np)++, global->die_offset, global->cu_offset, global->name);
10410
10411 return 0;
10412 }
10413
10414
10415 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
10416 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10417 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10418 Ebl *ebl,
10419 GElf_Ehdr *ehdr __attribute__ ((unused)),
10420 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10421 {
10422 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10423 elf_ndxscn (scn), section_name (ebl, shdr),
10424 (uint64_t) shdr->sh_offset);
10425
10426 int n = 0;
10427 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10428 }
10429
10430 /* Print the content of the DWARF string section '.debug_str'. */
10431 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10432 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10433 Ebl *ebl,
10434 GElf_Ehdr *ehdr __attribute__ ((unused)),
10435 Elf_Scn *scn, GElf_Shdr *shdr,
10436 Dwarf *dbg __attribute__ ((unused)))
10437 {
10438 Elf_Data *data = elf_rawdata (scn, NULL);
10439 const size_t sh_size = data ? data->d_size : 0;
10440
10441 /* Compute floor(log16(shdr->sh_size)). */
10442 GElf_Addr tmp = sh_size;
10443 int digits = 1;
10444 while (tmp >= 16)
10445 {
10446 ++digits;
10447 tmp >>= 4;
10448 }
10449 digits = MAX (4, digits);
10450
10451 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10452 " %*s String\n"),
10453 elf_ndxscn (scn),
10454 section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10455 /* TRANS: the debugstr| prefix makes the string unique. */
10456 digits + 2, sgettext ("debugstr|Offset"));
10457
10458 Dwarf_Off offset = 0;
10459 while (offset < sh_size)
10460 {
10461 size_t len;
10462 const char *str = (const char *) data->d_buf + offset;
10463 const char *endp = memchr (str, '\0', sh_size - offset);
10464 if (unlikely (endp == NULL))
10465 {
10466 printf (_(" *** error, missing string terminator\n"));
10467 break;
10468 }
10469
10470 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
10471 len = endp - str;
10472 offset += len + 1;
10473 }
10474 }
10475
10476 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10477 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10478 Ebl *ebl,
10479 GElf_Ehdr *ehdr __attribute__ ((unused)),
10480 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10481 {
10482 printf (_("\
10483 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10484 elf_ndxscn (scn), section_name (ebl, shdr),
10485 (uint64_t) shdr->sh_offset);
10486
10487 if (shdr->sh_size == 0)
10488 return;
10489
10490 /* We like to get the section from libdw to make sure they are relocated. */
10491 Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10492 ?: elf_rawdata (scn, NULL));
10493 if (unlikely (data == NULL))
10494 {
10495 error (0, 0, _("cannot get .debug_str_offsets section data: %s"),
10496 elf_errmsg (-1));
10497 return;
10498 }
10499
10500 size_t idx = 0;
10501 sort_listptr (&known_stroffbases, "str_offsets");
10502
10503 const unsigned char *start = (const unsigned char *) data->d_buf;
10504 const unsigned char *readp = start;
10505 const unsigned char *readendp = ((const unsigned char *) data->d_buf
10506 + data->d_size);
10507
10508 while (readp < readendp)
10509 {
10510 /* Most string offset tables will have a header. For split
10511 dwarf unit GNU DebugFission didn't add one. But they were
10512 also only defined for split units (main or skeleton units
10513 didn't have indirect strings). So if we don't have a
10514 DW_AT_str_offsets_base at all and this is offset zero, then
10515 just start printing offsets immediately, if this is a .dwo
10516 section. */
10517 Dwarf_Off off = (Dwarf_Off) (readp
10518 - (const unsigned char *) data->d_buf);
10519
10520 printf ("Table at offset %" PRIx64 " ", off);
10521
10522 struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10523 const unsigned char *next_unitp = readendp;
10524 uint8_t offset_size;
10525 bool has_header;
10526 if (listptr == NULL)
10527 {
10528 /* This can happen for .dwo files. There is only an header
10529 in the case this is a version 5 split DWARF file. */
10530 Dwarf_CU *cu;
10531 uint8_t unit_type;
10532 if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10533 NULL, NULL) != 0)
10534 {
10535 error (0, 0, "Warning: Cannot find any DWARF unit.");
10536 /* Just guess some values. */
10537 has_header = false;
10538 offset_size = 4;
10539 }
10540 else if (off == 0
10541 && (unit_type == DW_UT_split_type
10542 || unit_type == DW_UT_split_compile))
10543 {
10544 has_header = cu->version > 4;
10545 offset_size = cu->offset_size;
10546 }
10547 else
10548 {
10549 error (0, 0,
10550 "Warning: No CU references .debug_str_offsets after %"
10551 PRIx64, off);
10552 has_header = cu->version > 4;
10553 offset_size = cu->offset_size;
10554 }
10555 printf ("\n");
10556 }
10557 else
10558 {
10559 /* This must be DWARF5, since GNU DebugFission didn't define
10560 DW_AT_str_offsets_base. */
10561 has_header = true;
10562
10563 Dwarf_Die cudie;
10564 if (dwarf_cu_die (listptr->cu, &cudie,
10565 NULL, NULL, NULL, NULL,
10566 NULL, NULL) == NULL)
10567 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10568 else
10569 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10570 }
10571
10572 if (has_header)
10573 {
10574 uint64_t unit_length;
10575 uint16_t version;
10576 uint16_t padding;
10577
10578 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10579 if (unlikely (unit_length == 0xffffffff))
10580 {
10581 if (unlikely (readp > readendp - 8))
10582 {
10583 invalid_data:
10584 error (0, 0, "Invalid data");
10585 return;
10586 }
10587 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10588 offset_size = 8;
10589 }
10590 else
10591 offset_size = 4;
10592
10593 printf ("\n");
10594 printf (_(" Length: %8" PRIu64 "\n"),
10595 unit_length);
10596 printf (_(" Offset size: %8" PRIu8 "\n"),
10597 offset_size);
10598
10599 /* We need at least 2-bytes (version) + 2-bytes (padding) =
10600 4 bytes to complete the header. And this unit cannot go
10601 beyond the section data. */
10602 if (readp > readendp - 4
10603 || unit_length < 4
10604 || unit_length > (uint64_t) (readendp - readp))
10605 goto invalid_data;
10606
10607 next_unitp = readp + unit_length;
10608
10609 version = read_2ubyte_unaligned_inc (dbg, readp);
10610 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
10611
10612 if (version != 5)
10613 {
10614 error (0, 0, _("Unknown version"));
10615 goto next_unit;
10616 }
10617
10618 padding = read_2ubyte_unaligned_inc (dbg, readp);
10619 printf (_(" Padding: %8" PRIx16 "\n"), padding);
10620
10621 if (listptr != NULL
10622 && listptr->offset != (Dwarf_Off) (readp - start))
10623 {
10624 error (0, 0, "String offsets index doesn't start after header");
10625 goto next_unit;
10626 }
10627
10628 printf ("\n");
10629 }
10630
10631 int digits = 1;
10632 size_t offsets = (next_unitp - readp) / offset_size;
10633 while (offsets >= 10)
10634 {
10635 ++digits;
10636 offsets /= 10;
10637 }
10638
10639 unsigned int uidx = 0;
10640 size_t index_offset = readp - (const unsigned char *) data->d_buf;
10641 printf (" Offsets start at 0x%zx:\n", index_offset);
10642 while (readp <= next_unitp - offset_size)
10643 {
10644 Dwarf_Word offset;
10645 if (offset_size == 4)
10646 offset = read_4ubyte_unaligned_inc (dbg, readp);
10647 else
10648 offset = read_8ubyte_unaligned_inc (dbg, readp);
10649 const char *str = dwarf_getstring (dbg, offset, NULL);
10650 printf (" [%*u] [%*" PRIx64 "] \"%s\"\n",
10651 digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10652 }
10653 printf ("\n");
10654
10655 if (readp != next_unitp)
10656 error (0, 0, "extra %zd bytes at end of unit",
10657 (size_t) (next_unitp - readp));
10658
10659 next_unit:
10660 readp = next_unitp;
10661 }
10662 }
10663
10664
10665 /* Print the content of the call frame search table section
10666 '.eh_frame_hdr'. */
10667 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10668 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10669 Ebl *ebl __attribute__ ((unused)),
10670 GElf_Ehdr *ehdr __attribute__ ((unused)),
10671 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10672 {
10673 printf (_("\
10674 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10675 elf_ndxscn (scn));
10676
10677 Elf_Data *data = elf_rawdata (scn, NULL);
10678
10679 if (unlikely (data == NULL))
10680 {
10681 error (0, 0, _("cannot get %s content: %s"),
10682 ".eh_frame_hdr", elf_errmsg (-1));
10683 return;
10684 }
10685
10686 const unsigned char *readp = data->d_buf;
10687 const unsigned char *const dataend = ((unsigned char *) data->d_buf
10688 + data->d_size);
10689
10690 if (unlikely (readp + 4 > dataend))
10691 {
10692 invalid_data:
10693 error (0, 0, _("invalid data"));
10694 return;
10695 }
10696
10697 unsigned int version = *readp++;
10698 unsigned int eh_frame_ptr_enc = *readp++;
10699 unsigned int fde_count_enc = *readp++;
10700 unsigned int table_enc = *readp++;
10701
10702 printf (" version: %u\n"
10703 " eh_frame_ptr_enc: %#x ",
10704 version, eh_frame_ptr_enc);
10705 print_encoding_base ("", eh_frame_ptr_enc);
10706 printf (" fde_count_enc: %#x ", fde_count_enc);
10707 print_encoding_base ("", fde_count_enc);
10708 printf (" table_enc: %#x ", table_enc);
10709 print_encoding_base ("", table_enc);
10710
10711 uint64_t eh_frame_ptr = 0;
10712 if (eh_frame_ptr_enc != DW_EH_PE_omit)
10713 {
10714 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10715 dbg);
10716 if (unlikely (readp == NULL))
10717 goto invalid_data;
10718
10719 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
10720 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10721 printf (" (offset: %#" PRIx64 ")",
10722 /* +4 because of the 4 byte header of the section. */
10723 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10724
10725 putchar_unlocked ('\n');
10726 }
10727
10728 uint64_t fde_count = 0;
10729 if (fde_count_enc != DW_EH_PE_omit)
10730 {
10731 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10732 if (unlikely (readp == NULL))
10733 goto invalid_data;
10734
10735 printf (" fde_count: %" PRIu64 "\n", fde_count);
10736 }
10737
10738 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10739 return;
10740
10741 puts (" Table:");
10742
10743 /* Optimize for the most common case. */
10744 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10745 while (fde_count > 0 && readp + 8 <= dataend)
10746 {
10747 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10748 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10749 + (int64_t) initial_location);
10750 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10751 // XXX Possibly print symbol name or section offset for initial_offset
10752 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10753 " fde=[%6" PRIx64 "]\n",
10754 initial_location, initial_offset,
10755 address, address - (eh_frame_ptr + 4));
10756 }
10757 else
10758 while (0 && readp < dataend)
10759 {
10760
10761 }
10762 }
10763
10764
10765 /* Print the content of the exception handling table section
10766 '.eh_frame_hdr'. */
10767 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10768 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10769 Ebl *ebl __attribute__ ((unused)),
10770 GElf_Ehdr *ehdr __attribute__ ((unused)),
10771 Elf_Scn *scn,
10772 GElf_Shdr *shdr __attribute__ ((unused)),
10773 Dwarf *dbg __attribute__ ((unused)))
10774 {
10775 printf (_("\
10776 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10777 elf_ndxscn (scn));
10778
10779 Elf_Data *data = elf_rawdata (scn, NULL);
10780
10781 if (unlikely (data == NULL))
10782 {
10783 error (0, 0, _("cannot get %s content: %s"),
10784 ".gcc_except_table", elf_errmsg (-1));
10785 return;
10786 }
10787
10788 const unsigned char *readp = data->d_buf;
10789 const unsigned char *const dataend = readp + data->d_size;
10790
10791 if (unlikely (readp + 1 > dataend))
10792 {
10793 invalid_data:
10794 error (0, 0, _("invalid data"));
10795 return;
10796 }
10797 unsigned int lpstart_encoding = *readp++;
10798 printf (_(" LPStart encoding: %#x "), lpstart_encoding);
10799 print_encoding_base ("", lpstart_encoding);
10800 if (lpstart_encoding != DW_EH_PE_omit)
10801 {
10802 uint64_t lpstart;
10803 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10804 printf (" LPStart: %#" PRIx64 "\n", lpstart);
10805 }
10806
10807 if (unlikely (readp + 1 > dataend))
10808 goto invalid_data;
10809 unsigned int ttype_encoding = *readp++;
10810 printf (_(" TType encoding: %#x "), ttype_encoding);
10811 print_encoding_base ("", ttype_encoding);
10812 const unsigned char *ttype_base = NULL;
10813 if (ttype_encoding != DW_EH_PE_omit)
10814 {
10815 unsigned int ttype_base_offset;
10816 get_uleb128 (ttype_base_offset, readp, dataend);
10817 printf (" TType base offset: %#x\n", ttype_base_offset);
10818 if ((size_t) (dataend - readp) > ttype_base_offset)
10819 ttype_base = readp + ttype_base_offset;
10820 }
10821
10822 if (unlikely (readp + 1 > dataend))
10823 goto invalid_data;
10824 unsigned int call_site_encoding = *readp++;
10825 printf (_(" Call site encoding: %#x "), call_site_encoding);
10826 print_encoding_base ("", call_site_encoding);
10827 unsigned int call_site_table_len;
10828 get_uleb128 (call_site_table_len, readp, dataend);
10829
10830 const unsigned char *const action_table = readp + call_site_table_len;
10831 if (unlikely (action_table > dataend))
10832 goto invalid_data;
10833 unsigned int u = 0;
10834 unsigned int max_action = 0;
10835 while (readp < action_table)
10836 {
10837 if (u == 0)
10838 puts (_("\n Call site table:"));
10839
10840 uint64_t call_site_start;
10841 readp = read_encoded (call_site_encoding, readp, dataend,
10842 &call_site_start, dbg);
10843 uint64_t call_site_length;
10844 readp = read_encoded (call_site_encoding, readp, dataend,
10845 &call_site_length, dbg);
10846 uint64_t landing_pad;
10847 readp = read_encoded (call_site_encoding, readp, dataend,
10848 &landing_pad, dbg);
10849 unsigned int action;
10850 get_uleb128 (action, readp, dataend);
10851 max_action = MAX (action, max_action);
10852 printf (_(" [%4u] Call site start: %#" PRIx64 "\n"
10853 " Call site length: %" PRIu64 "\n"
10854 " Landing pad: %#" PRIx64 "\n"
10855 " Action: %u\n"),
10856 u++, call_site_start, call_site_length, landing_pad, action);
10857 }
10858 if (readp != action_table)
10859 goto invalid_data;
10860
10861 unsigned int max_ar_filter = 0;
10862 if (max_action > 0)
10863 {
10864 puts ("\n Action table:");
10865
10866 size_t maxdata = (size_t) (dataend - action_table);
10867 if (max_action > maxdata || maxdata - max_action < 1)
10868 {
10869 invalid_action_table:
10870 fputs (_(" <INVALID DATA>\n"), stdout);
10871 return;
10872 }
10873
10874 const unsigned char *const action_table_end
10875 = action_table + max_action + 1;
10876
10877 u = 0;
10878 do
10879 {
10880 int ar_filter;
10881 get_sleb128 (ar_filter, readp, action_table_end);
10882 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10883 max_ar_filter = ar_filter;
10884 int ar_disp;
10885 if (readp >= action_table_end)
10886 goto invalid_action_table;
10887 get_sleb128 (ar_disp, readp, action_table_end);
10888
10889 printf (" [%4u] ar_filter: % d\n"
10890 " ar_disp: % -5d",
10891 u, ar_filter, ar_disp);
10892 if (abs (ar_disp) & 1)
10893 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10894 else if (ar_disp != 0)
10895 puts (" -> ???");
10896 else
10897 putchar_unlocked ('\n');
10898 ++u;
10899 }
10900 while (readp < action_table_end);
10901 }
10902
10903 if (max_ar_filter > 0 && ttype_base != NULL)
10904 {
10905 unsigned char dsize;
10906 puts ("\n TType table:");
10907
10908 // XXX Not *4, size of encoding;
10909 switch (ttype_encoding & 7)
10910 {
10911 case DW_EH_PE_udata2:
10912 case DW_EH_PE_sdata2:
10913 dsize = 2;
10914 break;
10915 case DW_EH_PE_udata4:
10916 case DW_EH_PE_sdata4:
10917 dsize = 4;
10918 break;
10919 case DW_EH_PE_udata8:
10920 case DW_EH_PE_sdata8:
10921 dsize = 8;
10922 break;
10923 default:
10924 dsize = 0;
10925 error (1, 0, _("invalid TType encoding"));
10926 }
10927
10928 if (max_ar_filter
10929 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10930 goto invalid_data;
10931
10932 readp = ttype_base - max_ar_filter * dsize;
10933 do
10934 {
10935 uint64_t ttype;
10936 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10937 dbg);
10938 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10939 }
10940 while (readp < ttype_base);
10941 }
10942 }
10943
10944 /* Print the content of the '.gdb_index' section.
10945 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10946 */
10947 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10948 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10949 GElf_Ehdr *ehdr __attribute__ ((unused)),
10950 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10951 {
10952 printf (_("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10953 " contains %" PRId64 " bytes :\n"),
10954 elf_ndxscn (scn), section_name (ebl, shdr),
10955 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10956
10957 Elf_Data *data = elf_rawdata (scn, NULL);
10958
10959 if (unlikely (data == NULL))
10960 {
10961 error (0, 0, _("cannot get %s content: %s"),
10962 ".gdb_index", elf_errmsg (-1));
10963 return;
10964 }
10965
10966 // .gdb_index is always in little endian.
10967 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10968 dbg = &dummy_dbg;
10969
10970 const unsigned char *readp = data->d_buf;
10971 const unsigned char *const dataend = readp + data->d_size;
10972
10973 if (unlikely (readp + 4 > dataend))
10974 {
10975 invalid_data:
10976 error (0, 0, _("invalid data"));
10977 return;
10978 }
10979
10980 int32_t vers = read_4ubyte_unaligned (dbg, readp);
10981 printf (_(" Version: %" PRId32 "\n"), vers);
10982
10983 // The only difference between version 4 and version 5 is the
10984 // hash used for generating the table. Version 6 contains symbols
10985 // for inlined functions, older versions didn't. Version 7 adds
10986 // symbol kinds. Version 8 just indicates that it correctly includes
10987 // TUs for symbols.
10988 if (vers < 4 || vers > 8)
10989 {
10990 printf (_(" unknown version, cannot parse section\n"));
10991 return;
10992 }
10993
10994 readp += 4;
10995 if (unlikely (readp + 4 > dataend))
10996 goto invalid_data;
10997
10998 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10999 printf (_(" CU offset: %#" PRIx32 "\n"), cu_off);
11000
11001 readp += 4;
11002 if (unlikely (readp + 4 > dataend))
11003 goto invalid_data;
11004
11005 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
11006 printf (_(" TU offset: %#" PRIx32 "\n"), tu_off);
11007
11008 readp += 4;
11009 if (unlikely (readp + 4 > dataend))
11010 goto invalid_data;
11011
11012 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
11013 printf (_(" address offset: %#" PRIx32 "\n"), addr_off);
11014
11015 readp += 4;
11016 if (unlikely (readp + 4 > dataend))
11017 goto invalid_data;
11018
11019 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
11020 printf (_(" symbol offset: %#" PRIx32 "\n"), sym_off);
11021
11022 readp += 4;
11023 if (unlikely (readp + 4 > dataend))
11024 goto invalid_data;
11025
11026 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
11027 printf (_(" constant offset: %#" PRIx32 "\n"), const_off);
11028
11029 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
11030 < const_off))
11031 goto invalid_data;
11032
11033 readp = data->d_buf + cu_off;
11034
11035 const unsigned char *nextp = data->d_buf + tu_off;
11036 if (tu_off >= data->d_size)
11037 goto invalid_data;
11038
11039 size_t cu_nr = (nextp - readp) / 16;
11040
11041 printf (_("\n CU list at offset %#" PRIx32
11042 " contains %zu entries:\n"),
11043 cu_off, cu_nr);
11044
11045 size_t n = 0;
11046 while (dataend - readp >= 16 && n < cu_nr)
11047 {
11048 uint64_t off = read_8ubyte_unaligned (dbg, readp);
11049 readp += 8;
11050
11051 uint64_t len = read_8ubyte_unaligned (dbg, readp);
11052 readp += 8;
11053
11054 printf (" [%4zu] start: %0#8" PRIx64
11055 ", length: %5" PRIu64 "\n", n, off, len);
11056 n++;
11057 }
11058
11059 readp = data->d_buf + tu_off;
11060 nextp = data->d_buf + addr_off;
11061 if (addr_off >= data->d_size)
11062 goto invalid_data;
11063
11064 size_t tu_nr = (nextp - readp) / 24;
11065
11066 printf (_("\n TU list at offset %#" PRIx32
11067 " contains %zu entries:\n"),
11068 tu_off, tu_nr);
11069
11070 n = 0;
11071 while (dataend - readp >= 24 && n < tu_nr)
11072 {
11073 uint64_t off = read_8ubyte_unaligned (dbg, readp);
11074 readp += 8;
11075
11076 uint64_t type = read_8ubyte_unaligned (dbg, readp);
11077 readp += 8;
11078
11079 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
11080 readp += 8;
11081
11082 printf (" [%4zu] CU offset: %5" PRId64
11083 ", type offset: %5" PRId64
11084 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
11085 n++;
11086 }
11087
11088 readp = data->d_buf + addr_off;
11089 nextp = data->d_buf + sym_off;
11090 if (sym_off >= data->d_size)
11091 goto invalid_data;
11092
11093 size_t addr_nr = (nextp - readp) / 20;
11094
11095 printf (_("\n Address list at offset %#" PRIx32
11096 " contains %zu entries:\n"),
11097 addr_off, addr_nr);
11098
11099 n = 0;
11100 while (dataend - readp >= 20 && n < addr_nr)
11101 {
11102 uint64_t low = read_8ubyte_unaligned (dbg, readp);
11103 readp += 8;
11104
11105 uint64_t high = read_8ubyte_unaligned (dbg, readp);
11106 readp += 8;
11107
11108 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
11109 readp += 4;
11110
11111 printf (" [%4zu] ", n);
11112 print_dwarf_addr (dwflmod, 8, low, low);
11113 printf ("..");
11114 print_dwarf_addr (dwflmod, 8, high - 1, high);
11115 printf (", CU index: %5" PRId32 "\n", idx);
11116 n++;
11117 }
11118
11119 const unsigned char *const_start = data->d_buf + const_off;
11120 if (const_off >= data->d_size)
11121 goto invalid_data;
11122
11123 readp = data->d_buf + sym_off;
11124 nextp = const_start;
11125 size_t sym_nr = (nextp - readp) / 8;
11126
11127 printf (_("\n Symbol table at offset %#" PRIx32
11128 " contains %zu slots:\n"),
11129 addr_off, sym_nr);
11130
11131 n = 0;
11132 while (dataend - readp >= 8 && n < sym_nr)
11133 {
11134 uint32_t name = read_4ubyte_unaligned (dbg, readp);
11135 readp += 4;
11136
11137 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
11138 readp += 4;
11139
11140 if (name != 0 || vector != 0)
11141 {
11142 const unsigned char *sym = const_start + name;
11143 if (unlikely ((size_t) (dataend - const_start) < name
11144 || memchr (sym, '\0', dataend - sym) == NULL))
11145 goto invalid_data;
11146
11147 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
11148
11149 const unsigned char *readcus = const_start + vector;
11150 if (unlikely ((size_t) (dataend - const_start) < vector))
11151 goto invalid_data;
11152 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
11153 while (cus--)
11154 {
11155 uint32_t cu_kind, cu, kind;
11156 bool is_static;
11157 readcus += 4;
11158 if (unlikely (readcus + 4 > dataend))
11159 goto invalid_data;
11160 cu_kind = read_4ubyte_unaligned (dbg, readcus);
11161 cu = cu_kind & ((1 << 24) - 1);
11162 kind = (cu_kind >> 28) & 7;
11163 is_static = cu_kind & (1U << 31);
11164 if (cu > cu_nr - 1)
11165 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
11166 else
11167 printf ("%" PRId32, cu);
11168 if (kind != 0)
11169 {
11170 printf (" (");
11171 switch (kind)
11172 {
11173 case 1:
11174 printf ("type");
11175 break;
11176 case 2:
11177 printf ("var");
11178 break;
11179 case 3:
11180 printf ("func");
11181 break;
11182 case 4:
11183 printf ("other");
11184 break;
11185 default:
11186 printf ("unknown-0x%" PRIx32, kind);
11187 break;
11188 }
11189 printf (":%c)", (is_static ? 'S' : 'G'));
11190 }
11191 if (cus > 0)
11192 printf (", ");
11193 }
11194 printf ("\n");
11195 }
11196 n++;
11197 }
11198 }
11199
11200 /* Returns true and sets split DWARF CU id if there is a split compile
11201 unit in the given Dwarf, and no non-split units are found (before it). */
11202 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11203 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11204 {
11205 Dwarf_CU *cu = NULL;
11206 while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11207 {
11208 uint8_t unit_type;
11209 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11210 id, NULL, NULL) != 0)
11211 return false;
11212
11213 if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11214 return false;
11215
11216 /* We really only care about the split compile unit, the types
11217 should be fine and self sufficient. Also they don't have an
11218 id that we can match with a skeleton unit. */
11219 if (unit_type == DW_UT_split_compile)
11220 {
11221 *split_cu = cu;
11222 return true;
11223 }
11224 }
11225
11226 return false;
11227 }
11228
11229 /* Check that there is one and only one Dwfl_Module, return in arg. */
11230 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11231 getone_dwflmod (Dwfl_Module *dwflmod,
11232 void **userdata __attribute__ ((unused)),
11233 const char *name __attribute__ ((unused)),
11234 Dwarf_Addr base __attribute__ ((unused)),
11235 void *arg)
11236 {
11237 Dwfl_Module **m = (Dwfl_Module **) arg;
11238 if (*m != NULL)
11239 return DWARF_CB_ABORT;
11240 *m = dwflmod;
11241 return DWARF_CB_OK;
11242 }
11243
11244 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11245 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11246 {
11247 /* Used for skeleton file, if necessary for split DWARF. */
11248 Dwfl *skel_dwfl = NULL;
11249 Dwfl_Module *skel_mod = NULL;
11250 char *skel_name = NULL;
11251 Dwarf *split_dbg = NULL;
11252 Dwarf_CU *split_cu = NULL;
11253
11254 /* Before we start the real work get a debug context descriptor. */
11255 Dwarf_Addr dwbias;
11256 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11257 Dwarf dummy_dbg =
11258 {
11259 .elf = ebl->elf,
11260 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11261 };
11262 if (dbg == NULL)
11263 {
11264 if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
11265 error (0, 0, _("cannot get debug context descriptor: %s"),
11266 dwfl_errmsg (-1));
11267 dbg = &dummy_dbg;
11268 }
11269 else
11270 {
11271 /* If we are asked about a split dwarf (.dwo) file, use the user
11272 provided, or find the corresponding skeleton file. If we got
11273 a skeleton file, replace the given dwflmod and dbg, with one
11274 derived from the skeleton file to provide enough context. */
11275 uint64_t split_id;
11276 if (is_split_dwarf (dbg, &split_id, &split_cu))
11277 {
11278 if (dwarf_skeleton != NULL)
11279 skel_name = strdup (dwarf_skeleton);
11280 else
11281 {
11282 /* Replace file.dwo with file.o and see if that matches. */
11283 const char *fname;
11284 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11285 &fname, NULL);
11286 if (fname != NULL)
11287 {
11288 size_t flen = strlen (fname);
11289 if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11290 {
11291 skel_name = strdup (fname);
11292 if (skel_name != NULL)
11293 {
11294 skel_name[flen - 3] = 'o';
11295 skel_name[flen - 2] = '\0';
11296 }
11297 }
11298 }
11299 }
11300
11301 if (skel_name != NULL)
11302 {
11303 int skel_fd = open (skel_name, O_RDONLY);
11304 if (skel_fd == -1)
11305 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11306 " '%s'\n", skel_name);
11307 else
11308 skel_dwfl = create_dwfl (skel_fd, skel_name);
11309
11310 if (skel_dwfl != NULL)
11311 {
11312 if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11313 &skel_mod, 0) != 0)
11314 {
11315 fprintf (stderr, "Warning: Bad DWARF skeleton,"
11316 " multiple modules '%s'\n", skel_name);
11317 dwfl_end (skel_dwfl);
11318 skel_mod = NULL;
11319 }
11320 }
11321 else if (skel_fd != -1)
11322 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11323 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11324
11325 if (skel_mod != NULL)
11326 {
11327 Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11328 if (skel_dbg != NULL)
11329 {
11330 /* First check the skeleton CU DIE, only fetch
11331 the split DIE if we know the id matches to
11332 not unnecessary search for any split DIEs we
11333 don't need. */
11334 Dwarf_CU *cu = NULL;
11335 while (dwarf_get_units (skel_dbg, cu, &cu,
11336 NULL, NULL, NULL, NULL) == 0)
11337 {
11338 uint8_t unit_type;
11339 uint64_t skel_id;
11340 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11341 &skel_id, NULL, NULL) == 0
11342 && unit_type == DW_UT_skeleton
11343 && split_id == skel_id)
11344 {
11345 Dwarf_Die subdie;
11346 if (dwarf_cu_info (cu, NULL, NULL, NULL,
11347 &subdie,
11348 NULL, NULL, NULL) == 0
11349 && dwarf_tag (&subdie) != DW_TAG_invalid)
11350 {
11351 split_dbg = dwarf_cu_getdwarf (subdie.cu);
11352 if (split_dbg == NULL)
11353 fprintf (stderr,
11354 "Warning: Couldn't get split_dbg:"
11355 " %s\n", dwarf_errmsg (-1));
11356 break;
11357 }
11358 else
11359 {
11360 /* Everything matches up, but not
11361 according to libdw. Which means
11362 the user knew better. So...
11363 Terrible hack... We can never
11364 destroy the underlying dwfl
11365 because it would free the wrong
11366 Dwarfs... So we leak memory...*/
11367 if (cu->split == NULL
11368 && dwarf_skeleton != NULL)
11369 {
11370 do_not_close_dwfl = true;
11371 __libdw_link_skel_split (cu, split_cu);
11372 split_dbg = dwarf_cu_getdwarf (split_cu);
11373 break;
11374 }
11375 else
11376 fprintf (stderr, "Warning: Couldn't get"
11377 " skeleton subdie: %s\n",
11378 dwarf_errmsg (-1));
11379 }
11380 }
11381 }
11382 if (split_dbg == NULL)
11383 fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11384 }
11385 else
11386 fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11387 " %s\n", dwfl_errmsg (-1));
11388 }
11389 }
11390
11391 if (split_dbg != NULL)
11392 {
11393 dbg = split_dbg;
11394 dwflmod = skel_mod;
11395 }
11396 else if (skel_name == NULL)
11397 fprintf (stderr,
11398 "Warning: split DWARF file, but no skeleton found.\n");
11399 }
11400 else if (dwarf_skeleton != NULL)
11401 fprintf (stderr, "Warning: DWARF skeleton given,"
11402 " but not a split DWARF file\n");
11403 }
11404
11405 /* Get the section header string table index. */
11406 size_t shstrndx;
11407 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11408 error (EXIT_FAILURE, 0,
11409 _("cannot get section header string table index"));
11410
11411 /* If the .debug_info section is listed as implicitly required then
11412 we must make sure to handle it before handling any other debug
11413 section. Various other sections depend on the CU DIEs being
11414 scanned (silently) first. */
11415 bool implicit_info = (implicit_debug_sections & section_info) != 0;
11416 bool explicit_info = (print_debug_sections & section_info) != 0;
11417 if (implicit_info)
11418 {
11419 Elf_Scn *scn = NULL;
11420 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11421 {
11422 GElf_Shdr shdr_mem;
11423 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11424
11425 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11426 {
11427 const char *name = elf_strptr (ebl->elf, shstrndx,
11428 shdr->sh_name);
11429 if (name == NULL)
11430 continue;
11431
11432 if (strcmp (name, ".debug_info") == 0
11433 || strcmp (name, ".debug_info.dwo") == 0
11434 || strcmp (name, ".zdebug_info") == 0
11435 || strcmp (name, ".zdebug_info.dwo") == 0
11436 || strcmp (name, ".gnu.debuglto_.debug_info") == 0)
11437 {
11438 print_debug_info_section (dwflmod, ebl, ehdr,
11439 scn, shdr, dbg);
11440 break;
11441 }
11442 }
11443 }
11444 print_debug_sections &= ~section_info;
11445 implicit_debug_sections &= ~section_info;
11446 }
11447
11448 /* Look through all the sections for the debugging sections to print. */
11449 Elf_Scn *scn = NULL;
11450 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11451 {
11452 GElf_Shdr shdr_mem;
11453 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11454
11455 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11456 {
11457 static const struct
11458 {
11459 const char *name;
11460 enum section_e bitmask;
11461 void (*fp) (Dwfl_Module *, Ebl *,
11462 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11463 } debug_sections[] =
11464 {
11465 #define NEW_SECTION(name) \
11466 { ".debug_" #name, section_##name, print_debug_##name##_section }
11467 NEW_SECTION (abbrev),
11468 NEW_SECTION (addr),
11469 NEW_SECTION (aranges),
11470 NEW_SECTION (frame),
11471 NEW_SECTION (info),
11472 NEW_SECTION (types),
11473 NEW_SECTION (line),
11474 NEW_SECTION (loc),
11475 /* loclists is loc for DWARF5. */
11476 { ".debug_loclists", section_loc,
11477 print_debug_loclists_section },
11478 NEW_SECTION (pubnames),
11479 NEW_SECTION (str),
11480 /* A DWARF5 specialised debug string section. */
11481 { ".debug_line_str", section_str,
11482 print_debug_str_section },
11483 /* DWARF5 string offsets table. */
11484 { ".debug_str_offsets", section_str,
11485 print_debug_str_offsets_section },
11486 NEW_SECTION (macinfo),
11487 NEW_SECTION (macro),
11488 NEW_SECTION (ranges),
11489 /* rnglists is ranges for DWARF5. */
11490 { ".debug_rnglists", section_ranges,
11491 print_debug_rnglists_section },
11492 { ".eh_frame", section_frame | section_exception,
11493 print_debug_frame_section },
11494 { ".eh_frame_hdr", section_frame | section_exception,
11495 print_debug_frame_hdr_section },
11496 { ".gcc_except_table", section_frame | section_exception,
11497 print_debug_exception_table },
11498 { ".gdb_index", section_gdb_index, print_gdb_index_section }
11499 };
11500 const int ndebug_sections = (sizeof (debug_sections)
11501 / sizeof (debug_sections[0]));
11502 const char *name = elf_strptr (ebl->elf, shstrndx,
11503 shdr->sh_name);
11504 if (name == NULL)
11505 continue;
11506
11507 int n;
11508 for (n = 0; n < ndebug_sections; ++n)
11509 {
11510 size_t dbglen = strlen (debug_sections[n].name);
11511 size_t scnlen = strlen (name);
11512 if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11513 && (dbglen == scnlen
11514 || (scnlen == dbglen + 4
11515 && strstr (name, ".dwo") == name + dbglen)))
11516 || (name[0] == '.' && name[1] == 'z'
11517 && debug_sections[n].name[1] == 'd'
11518 && strncmp (&name[2], &debug_sections[n].name[1],
11519 dbglen - 1) == 0
11520 && (scnlen == dbglen + 1
11521 || (scnlen == dbglen + 5
11522 && strstr (name, ".dwo") == name + dbglen + 1)))
11523 || (scnlen > 14 /* .gnu.debuglto_ prefix. */
11524 && startswith (name, ".gnu.debuglto_")
11525 && strcmp (&name[14], debug_sections[n].name) == 0)
11526 )
11527 {
11528 if ((print_debug_sections | implicit_debug_sections)
11529 & debug_sections[n].bitmask)
11530 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11531 break;
11532 }
11533 }
11534 }
11535 }
11536
11537 dwfl_end (skel_dwfl);
11538 free (skel_name);
11539
11540 /* Turn implicit and/or explicit back on in case we go over another file. */
11541 if (implicit_info)
11542 implicit_debug_sections |= section_info;
11543 if (explicit_info)
11544 print_debug_sections |= section_info;
11545
11546 reset_listptr (&known_locsptr);
11547 reset_listptr (&known_loclistsptr);
11548 reset_listptr (&known_rangelistptr);
11549 reset_listptr (&known_rnglistptr);
11550 reset_listptr (&known_addrbases);
11551 reset_listptr (&known_stroffbases);
11552 }
11553
11554
11555 #define ITEM_INDENT 4
11556 #define WRAP_COLUMN 75
11557
11558 /* Print "NAME: FORMAT", wrapping when output text would make the line
11559 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
11560 but this function is also used for registers which should be printed
11561 aligned. Fortunately registers output uses fixed fields width (such
11562 as %11d) for the alignment.
11563
11564 Line breaks should not depend on the particular values although that
11565 may happen in some cases of the core items. */
11566
11567 static unsigned int
11568 __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,...)11569 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11570 size_t name_width, const char *name, const char *format, ...)
11571 {
11572 size_t len = strlen (name);
11573 if (name_width < len)
11574 name_width = len;
11575
11576 char *out;
11577 va_list ap;
11578 va_start (ap, format);
11579 int out_len = vasprintf (&out, format, ap);
11580 va_end (ap);
11581 if (out_len == -1)
11582 error (EXIT_FAILURE, 0, _("memory exhausted"));
11583
11584 size_t n = name_width + sizeof ": " - 1 + out_len;
11585
11586 if (colno == 0)
11587 {
11588 printf ("%*s", ITEM_INDENT, "");
11589 colno = ITEM_INDENT + n;
11590 }
11591 else if (colno + 2 + n < wrap)
11592 {
11593 printf ("%c ", sep);
11594 colno += 2 + n;
11595 }
11596 else
11597 {
11598 printf ("\n%*s", ITEM_INDENT, "");
11599 colno = ITEM_INDENT + n;
11600 }
11601
11602 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11603
11604 free (out);
11605
11606 return colno;
11607 }
11608
11609 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11610 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11611 void *value, const void *data, size_t size)
11612 {
11613 Elf_Data valuedata =
11614 {
11615 .d_type = type,
11616 .d_buf = value,
11617 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11618 .d_version = EV_CURRENT,
11619 };
11620 Elf_Data indata =
11621 {
11622 .d_type = type,
11623 .d_buf = (void *) data,
11624 .d_size = valuedata.d_size,
11625 .d_version = EV_CURRENT,
11626 };
11627
11628 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11629 ? elf32_xlatetom : elf64_xlatetom)
11630 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11631 if (d == NULL)
11632 error (EXIT_FAILURE, 0,
11633 _("cannot convert core note data: %s"), elf_errmsg (-1));
11634
11635 return data + indata.d_size;
11636 }
11637
11638 typedef uint8_t GElf_Byte;
11639
11640 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11641 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11642 unsigned int colno, size_t *repeated_size)
11643 {
11644 uint_fast16_t count = item->count ?: 1;
11645 /* Ebl_Core_Item count is always a small number.
11646 Make sure the backend didn't put in some large bogus value. */
11647 assert (count < 128);
11648
11649 #define TYPES \
11650 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
11651 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
11652 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
11653 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
11654 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
11655 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11656
11657 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11658 typedef union { TYPES; } value_t;
11659 void *data = alloca (count * sizeof (value_t));
11660 #undef DO_TYPE
11661
11662 #define DO_TYPE(NAME, Name, hex, dec) \
11663 GElf_##Name *value_##Name __attribute__((unused)) = data
11664 TYPES;
11665 #undef DO_TYPE
11666
11667 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11668 size_t convsize = size;
11669 if (repeated_size != NULL)
11670 {
11671 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11672 {
11673 data = alloca (*repeated_size);
11674 count *= *repeated_size / size;
11675 convsize = count * size;
11676 *repeated_size -= convsize;
11677 }
11678 else if (item->count != 0 || item->format != '\n')
11679 *repeated_size -= size;
11680 }
11681
11682 convert (core, item->type, count, data, desc + item->offset, convsize);
11683
11684 Elf_Type type = item->type;
11685 if (type == ELF_T_ADDR)
11686 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11687
11688 switch (item->format)
11689 {
11690 case 'd':
11691 assert (count == 1);
11692 switch (type)
11693 {
11694 #define DO_TYPE(NAME, Name, hex, dec) \
11695 case ELF_T_##NAME: \
11696 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11697 0, item->name, dec, value_##Name[0]); \
11698 break
11699 TYPES;
11700 #undef DO_TYPE
11701 default:
11702 abort ();
11703 }
11704 break;
11705
11706 case 'x':
11707 assert (count == 1);
11708 switch (type)
11709 {
11710 #define DO_TYPE(NAME, Name, hex, dec) \
11711 case ELF_T_##NAME: \
11712 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11713 0, item->name, hex, value_##Name[0]); \
11714 break
11715 TYPES;
11716 #undef DO_TYPE
11717 default:
11718 abort ();
11719 }
11720 break;
11721
11722 case 'b':
11723 case 'B':
11724 assert (size % sizeof (unsigned int) == 0);
11725 unsigned int nbits = count * size * 8;
11726 unsigned int pop = 0;
11727 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11728 pop += __builtin_popcount (*i);
11729 bool negate = pop > nbits / 2;
11730 const unsigned int bias = item->format == 'b';
11731
11732 {
11733 char printed[(negate ? nbits - pop : pop) * 16 + 1];
11734 char *p = printed;
11735 *p = '\0';
11736
11737 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11738 {
11739 assert (size == sizeof (unsigned int) * 2);
11740 for (unsigned int *i = data;
11741 (void *) i < data + count * size; i += 2)
11742 {
11743 unsigned int w = i[1];
11744 i[1] = i[0];
11745 i[0] = w;
11746 }
11747 }
11748
11749 unsigned int lastbit = 0;
11750 unsigned int run = 0;
11751 for (const unsigned int *i = data;
11752 (void *) i < data + count * size; ++i)
11753 {
11754 unsigned int bit = ((void *) i - data) * 8;
11755 unsigned int w = negate ? ~*i : *i;
11756 while (w != 0)
11757 {
11758 /* Note that a right shift equal to (or greater than)
11759 the number of bits of w is undefined behaviour. In
11760 particular when the least significant bit is bit 32
11761 (w = 0x8000000) then w >>= n is undefined. So
11762 explicitly handle that case separately. */
11763 unsigned int n = ffs (w);
11764 if (n < sizeof (w) * 8)
11765 w >>= n;
11766 else
11767 w = 0;
11768 bit += n;
11769
11770 if (lastbit != 0 && lastbit + 1 == bit)
11771 ++run;
11772 else
11773 {
11774 if (lastbit == 0)
11775 p += sprintf (p, "%u", bit - bias);
11776 else if (run == 0)
11777 p += sprintf (p, ",%u", bit - bias);
11778 else
11779 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11780 run = 0;
11781 }
11782
11783 lastbit = bit;
11784 }
11785 }
11786 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11787 p += sprintf (p, "-%u", lastbit - bias);
11788
11789 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11790 negate ? "~<%s>" : "<%s>", printed);
11791 }
11792 break;
11793
11794 case 'T':
11795 case (char) ('T'|0x80):
11796 assert (count == 2);
11797 Dwarf_Word sec;
11798 Dwarf_Word usec;
11799 switch (type)
11800 {
11801 #define DO_TYPE(NAME, Name, hex, dec) \
11802 case ELF_T_##NAME: \
11803 sec = value_##Name[0]; \
11804 usec = value_##Name[1]; \
11805 break
11806 TYPES;
11807 #undef DO_TYPE
11808 default:
11809 abort ();
11810 }
11811 if (unlikely (item->format == (char) ('T'|0x80)))
11812 {
11813 /* This is a hack for an ill-considered 64-bit ABI where
11814 tv_usec is actually a 32-bit field with 32 bits of padding
11815 rounding out struct timeval. We've already converted it as
11816 a 64-bit field. For little-endian, this just means the
11817 high half is the padding; it's presumably zero, but should
11818 be ignored anyway. For big-endian, it means the 32-bit
11819 field went into the high half of USEC. */
11820 GElf_Ehdr ehdr_mem;
11821 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11822 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11823 usec >>= 32;
11824 else
11825 usec &= UINT32_MAX;
11826 }
11827 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11828 "%" PRIu64 ".%.6" PRIu64, sec, usec);
11829 break;
11830
11831 case 'c':
11832 assert (count == 1);
11833 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11834 "%c", value_Byte[0]);
11835 break;
11836
11837 case 's':
11838 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11839 "%.*s", (int) count, value_Byte);
11840 break;
11841
11842 case '\n':
11843 /* This is a list of strings separated by '\n'. */
11844 assert (item->count == 0);
11845 assert (repeated_size != NULL);
11846 assert (item->name == NULL);
11847 if (unlikely (item->offset >= *repeated_size))
11848 break;
11849
11850 const char *s = desc + item->offset;
11851 size = *repeated_size - item->offset;
11852 *repeated_size = 0;
11853 while (size > 0)
11854 {
11855 const char *eol = memchr (s, '\n', size);
11856 int len = size;
11857 if (eol != NULL)
11858 len = eol - s;
11859 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11860 if (eol == NULL)
11861 break;
11862 size -= eol + 1 - s;
11863 s = eol + 1;
11864 }
11865
11866 colno = WRAP_COLUMN;
11867 break;
11868
11869 case 'h':
11870 break;
11871
11872 default:
11873 error (0, 0, "XXX not handling format '%c' for %s",
11874 item->format, item->name);
11875 break;
11876 }
11877
11878 #undef TYPES
11879
11880 return colno;
11881 }
11882
11883
11884 /* Sort items by group, and by layout offset within each group. */
11885 static int
compare_core_items(const void * a,const void * b)11886 compare_core_items (const void *a, const void *b)
11887 {
11888 const Ebl_Core_Item *const *p1 = a;
11889 const Ebl_Core_Item *const *p2 = b;
11890 const Ebl_Core_Item *item1 = *p1;
11891 const Ebl_Core_Item *item2 = *p2;
11892
11893 return ((item1->group == item2->group ? 0
11894 : strcmp (item1->group, item2->group))
11895 ?: (int) item1->offset - (int) item2->offset);
11896 }
11897
11898 /* Sort item groups by layout offset of the first item in the group. */
11899 static int
compare_core_item_groups(const void * a,const void * b)11900 compare_core_item_groups (const void *a, const void *b)
11901 {
11902 const Ebl_Core_Item *const *const *p1 = a;
11903 const Ebl_Core_Item *const *const *p2 = b;
11904 const Ebl_Core_Item *const *group1 = *p1;
11905 const Ebl_Core_Item *const *group2 = *p2;
11906 const Ebl_Core_Item *item1 = *group1;
11907 const Ebl_Core_Item *item2 = *group2;
11908
11909 return (int) item1->offset - (int) item2->offset;
11910 }
11911
11912 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11913 handle_core_items (Elf *core, const void *desc, size_t descsz,
11914 const Ebl_Core_Item *items, size_t nitems)
11915 {
11916 if (nitems == 0)
11917 return 0;
11918 unsigned int colno = 0;
11919
11920 /* FORMAT '\n' makes sense to be present only as a single item as it
11921 processes all the data of a note. FORMATs 'b' and 'B' have a special case
11922 if present as a single item but they can be also processed with other
11923 items below. */
11924 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11925 || items[0].format == 'B'))
11926 {
11927 assert (items[0].offset == 0);
11928 size_t size = descsz;
11929 colno = handle_core_item (core, items, desc, colno, &size);
11930 /* If SIZE is not zero here there is some remaining data. But we do not
11931 know how to process it anyway. */
11932 return colno;
11933 }
11934 for (size_t i = 0; i < nitems; ++i)
11935 assert (items[i].format != '\n');
11936
11937 /* Sort to collect the groups together. */
11938 const Ebl_Core_Item *sorted_items[nitems];
11939 for (size_t i = 0; i < nitems; ++i)
11940 sorted_items[i] = &items[i];
11941 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11942
11943 /* Collect the unique groups and sort them. */
11944 const Ebl_Core_Item **groups[nitems];
11945 groups[0] = &sorted_items[0];
11946 size_t ngroups = 1;
11947 for (size_t i = 1; i < nitems; ++i)
11948 if (sorted_items[i]->group != sorted_items[i - 1]->group
11949 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11950 groups[ngroups++] = &sorted_items[i];
11951 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11952
11953 /* Write out all the groups. */
11954 const void *last = desc;
11955 do
11956 {
11957 for (size_t i = 0; i < ngroups; ++i)
11958 {
11959 for (const Ebl_Core_Item **item = groups[i];
11960 (item < &sorted_items[nitems]
11961 && ((*item)->group == groups[i][0]->group
11962 || !strcmp ((*item)->group, groups[i][0]->group)));
11963 ++item)
11964 colno = handle_core_item (core, *item, desc, colno, NULL);
11965
11966 /* Force a line break at the end of the group. */
11967 colno = WRAP_COLUMN;
11968 }
11969
11970 if (descsz == 0)
11971 break;
11972
11973 /* This set of items consumed a certain amount of the note's data.
11974 If there is more data there, we have another unit of the same size.
11975 Loop to print that out too. */
11976 const Ebl_Core_Item *item = &items[nitems - 1];
11977 size_t eltsz = item->offset + gelf_fsize (core, item->type,
11978 item->count ?: 1, EV_CURRENT);
11979
11980 int reps = -1;
11981 do
11982 {
11983 ++reps;
11984 desc += eltsz;
11985 descsz -= eltsz;
11986 }
11987 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11988
11989 if (reps == 1)
11990 {
11991 /* For just one repeat, print it unabridged twice. */
11992 desc -= eltsz;
11993 descsz += eltsz;
11994 }
11995 else if (reps > 1)
11996 printf (_("\n%*s... <repeats %u more times> ..."),
11997 ITEM_INDENT, "", reps);
11998
11999 last = desc;
12000 }
12001 while (descsz > 0);
12002
12003 return colno;
12004 }
12005
12006 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)12007 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
12008 unsigned int colno)
12009 {
12010 desc += regloc->offset;
12011
12012 abort (); /* XXX */
12013 return colno;
12014 }
12015
12016
12017 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)12018 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
12019 const Ebl_Register_Location *regloc, const void *desc,
12020 unsigned int colno)
12021 {
12022 if (regloc->bits % 8 != 0)
12023 return handle_bit_registers (regloc, desc, colno);
12024
12025 desc += regloc->offset;
12026
12027 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
12028 {
12029 char name[REGNAMESZ];
12030 int bits;
12031 int type;
12032 register_info (ebl, reg, regloc, name, &bits, &type);
12033
12034 #define TYPES \
12035 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
12036 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
12037 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
12038 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
12039
12040 #define BITS(bits, xtype, sfmt, ufmt) \
12041 uint##bits##_t b##bits; int##bits##_t b##bits##s
12042 union { TYPES; uint64_t b128[2]; } value;
12043 #undef BITS
12044
12045 switch (type)
12046 {
12047 case DW_ATE_unsigned:
12048 case DW_ATE_signed:
12049 case DW_ATE_address:
12050 switch (bits)
12051 {
12052 #define BITS(bits, xtype, sfmt, ufmt) \
12053 case bits: \
12054 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
12055 if (type == DW_ATE_signed) \
12056 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
12057 maxregname, name, \
12058 sfmt, value.b##bits##s); \
12059 else \
12060 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
12061 maxregname, name, \
12062 ufmt, value.b##bits); \
12063 break
12064
12065 TYPES;
12066
12067 case 128:
12068 assert (type == DW_ATE_unsigned);
12069 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
12070 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
12071 colno = print_core_item (colno, ' ', WRAP_COLUMN,
12072 maxregname, name,
12073 "0x%.16" PRIx64 "%.16" PRIx64,
12074 value.b128[!be], value.b128[be]);
12075 break;
12076
12077 default:
12078 abort ();
12079 #undef BITS
12080 }
12081 break;
12082
12083 default:
12084 /* Print each byte in hex, the whole thing in native byte order. */
12085 assert (bits % 8 == 0);
12086 const uint8_t *bytes = desc;
12087 desc += bits / 8;
12088 char hex[bits / 4 + 1];
12089 hex[bits / 4] = '\0';
12090 int incr = 1;
12091 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
12092 {
12093 bytes += bits / 8 - 1;
12094 incr = -1;
12095 }
12096 size_t idx = 0;
12097 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
12098 {
12099 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
12100 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
12101 }
12102 colno = print_core_item (colno, ' ', WRAP_COLUMN,
12103 maxregname, name, "0x%s", hex);
12104 break;
12105 }
12106 desc += regloc->pad;
12107
12108 #undef TYPES
12109 }
12110
12111 return colno;
12112 }
12113
12114
12115 struct register_info
12116 {
12117 const Ebl_Register_Location *regloc;
12118 const char *set;
12119 char name[REGNAMESZ];
12120 int regno;
12121 int bits;
12122 int type;
12123 };
12124
12125 static int
register_bitpos(const struct register_info * r)12126 register_bitpos (const struct register_info *r)
12127 {
12128 return (r->regloc->offset * 8
12129 + ((r->regno - r->regloc->regno)
12130 * (r->regloc->bits + r->regloc->pad * 8)));
12131 }
12132
12133 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)12134 compare_sets_by_info (const struct register_info *r1,
12135 const struct register_info *r2)
12136 {
12137 return ((int) r2->bits - (int) r1->bits
12138 ?: register_bitpos (r1) - register_bitpos (r2));
12139 }
12140
12141 /* Sort registers by set, and by size and layout offset within each set. */
12142 static int
compare_registers(const void * a,const void * b)12143 compare_registers (const void *a, const void *b)
12144 {
12145 const struct register_info *r1 = a;
12146 const struct register_info *r2 = b;
12147
12148 /* Unused elements sort last. */
12149 if (r1->regloc == NULL)
12150 return r2->regloc == NULL ? 0 : 1;
12151 if (r2->regloc == NULL)
12152 return -1;
12153
12154 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
12155 ?: compare_sets_by_info (r1, r2));
12156 }
12157
12158 /* Sort register sets by layout offset of the first register in the set. */
12159 static int
compare_register_sets(const void * a,const void * b)12160 compare_register_sets (const void *a, const void *b)
12161 {
12162 const struct register_info *const *p1 = a;
12163 const struct register_info *const *p2 = b;
12164 return compare_sets_by_info (*p1, *p2);
12165 }
12166
12167 static inline bool
same_set(const struct register_info * a,const struct register_info * b,const struct register_info * regs,size_t maxnreg)12168 same_set (const struct register_info *a,
12169 const struct register_info *b,
12170 const struct register_info *regs,
12171 size_t maxnreg)
12172 {
12173 return (a < ®s[maxnreg] && a->regloc != NULL
12174 && b < ®s[maxnreg] && b->regloc != NULL
12175 && a->bits == b->bits
12176 && (a->set == b->set || !strcmp (a->set, b->set)));
12177 }
12178
12179 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)12180 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
12181 const Ebl_Register_Location *reglocs, size_t nregloc)
12182 {
12183 if (nregloc == 0)
12184 return 0;
12185
12186 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12187 if (maxnreg <= 0)
12188 {
12189 for (size_t i = 0; i < nregloc; ++i)
12190 if (maxnreg < reglocs[i].regno + reglocs[i].count)
12191 maxnreg = reglocs[i].regno + reglocs[i].count;
12192 assert (maxnreg > 0);
12193 }
12194
12195 struct register_info regs[maxnreg];
12196 memset (regs, 0, sizeof regs);
12197
12198 /* Sort to collect the sets together. */
12199 int maxreg = 0;
12200 for (size_t i = 0; i < nregloc; ++i)
12201 for (int reg = reglocs[i].regno;
12202 reg < reglocs[i].regno + reglocs[i].count;
12203 ++reg)
12204 {
12205 assert (reg < maxnreg);
12206 if (reg > maxreg)
12207 maxreg = reg;
12208 struct register_info *info = ®s[reg];
12209 info->regloc = ®locs[i];
12210 info->regno = reg;
12211 info->set = register_info (ebl, reg, ®locs[i],
12212 info->name, &info->bits, &info->type);
12213 }
12214 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12215
12216 /* Collect the unique sets and sort them. */
12217 struct register_info *sets[maxreg + 1];
12218 sets[0] = ®s[0];
12219 size_t nsets = 1;
12220 for (int i = 1; i <= maxreg; ++i)
12221 if (regs[i].regloc != NULL
12222 && !same_set (®s[i], ®s[i - 1], regs, maxnreg))
12223 sets[nsets++] = ®s[i];
12224 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12225
12226 /* Write out all the sets. */
12227 unsigned int colno = 0;
12228 for (size_t i = 0; i < nsets; ++i)
12229 {
12230 /* Find the longest name of a register in this set. */
12231 size_t maxname = 0;
12232 const struct register_info *end;
12233 for (end = sets[i]; same_set (sets[i], end, regs, maxnreg); ++end)
12234 {
12235 size_t len = strlen (end->name);
12236 if (len > maxname)
12237 maxname = len;
12238 }
12239
12240 for (const struct register_info *reg = sets[i];
12241 reg < end;
12242 reg += reg->regloc->count ?: 1)
12243 colno = handle_core_register (ebl, core, maxname,
12244 reg->regloc, desc, colno);
12245
12246 /* Force a line break at the end of the group. */
12247 colno = WRAP_COLUMN;
12248 }
12249
12250 return colno;
12251 }
12252
12253 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12254 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12255 {
12256 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12257 if (data == NULL)
12258 elf_error:
12259 error (EXIT_FAILURE, 0,
12260 _("cannot convert core note data: %s"), elf_errmsg (-1));
12261
12262 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12263 for (size_t i = 0; i < nauxv; ++i)
12264 {
12265 GElf_auxv_t av_mem;
12266 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12267 if (av == NULL)
12268 goto elf_error;
12269
12270 const char *name;
12271 const char *fmt;
12272 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12273 {
12274 /* Unknown type. */
12275 if (av->a_un.a_val == 0)
12276 printf (" %" PRIu64 "\n", av->a_type);
12277 else
12278 printf (" %" PRIu64 ": %#" PRIx64 "\n",
12279 av->a_type, av->a_un.a_val);
12280 }
12281 else
12282 switch (fmt[0])
12283 {
12284 case '\0': /* Normally zero. */
12285 if (av->a_un.a_val == 0)
12286 {
12287 printf (" %s\n", name);
12288 break;
12289 }
12290 FALLTHROUGH;
12291 case 'x': /* hex */
12292 case 'p': /* address */
12293 case 's': /* address of string */
12294 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12295 break;
12296 case 'u':
12297 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
12298 break;
12299 case 'd':
12300 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
12301 break;
12302
12303 case 'b':
12304 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
12305 GElf_Xword bit = 1;
12306 const char *pfx = "<";
12307 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12308 {
12309 if (av->a_un.a_val & bit)
12310 {
12311 printf ("%s%s", pfx, p);
12312 pfx = " ";
12313 }
12314 bit <<= 1;
12315 }
12316 printf (">\n");
12317 break;
12318
12319 default:
12320 abort ();
12321 }
12322 }
12323 }
12324
12325 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12326 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12327 {
12328 return ptr < end && (size_t) (end - ptr) >= sz;
12329 }
12330
12331 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12332 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12333 int *retp)
12334 {
12335 if (! buf_has_data (*ptrp, end, 4))
12336 return false;
12337
12338 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12339 return true;
12340 }
12341
12342 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12343 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12344 uint64_t *retp)
12345 {
12346 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12347 if (! buf_has_data (*ptrp, end, sz))
12348 return false;
12349
12350 union
12351 {
12352 uint64_t u64;
12353 uint32_t u32;
12354 } u;
12355
12356 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12357
12358 if (sz == 4)
12359 *retp = u.u32;
12360 else
12361 *retp = u.u64;
12362 return true;
12363 }
12364
12365 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12366 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12367 {
12368 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12369 if (data == NULL)
12370 error (EXIT_FAILURE, 0,
12371 _("cannot convert core note data: %s"), elf_errmsg (-1));
12372
12373 unsigned char const *ptr = data->d_buf;
12374 unsigned char const *const end = data->d_buf + data->d_size;
12375
12376 /* Siginfo head is three ints: signal number, error number, origin
12377 code. */
12378 int si_signo, si_errno, si_code;
12379 if (! buf_read_int (core, &ptr, end, &si_signo)
12380 || ! buf_read_int (core, &ptr, end, &si_errno)
12381 || ! buf_read_int (core, &ptr, end, &si_code))
12382 {
12383 fail:
12384 printf (" Not enough data in NT_SIGINFO note.\n");
12385 return;
12386 }
12387
12388 /* Next is a pointer-aligned union of structures. On 64-bit
12389 machines, that implies a word of padding. */
12390 if (gelf_getclass (core) == ELFCLASS64)
12391 ptr += 4;
12392
12393 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
12394 si_signo, si_errno, si_code);
12395
12396 if (si_code > 0)
12397 switch (si_signo)
12398 {
12399 case CORE_SIGILL:
12400 case CORE_SIGFPE:
12401 case CORE_SIGSEGV:
12402 case CORE_SIGBUS:
12403 {
12404 uint64_t addr;
12405 if (! buf_read_ulong (core, &ptr, end, &addr))
12406 goto fail;
12407 printf (" fault address: %#" PRIx64 "\n", addr);
12408 break;
12409 }
12410 default:
12411 ;
12412 }
12413 else if (si_code == CORE_SI_USER)
12414 {
12415 int pid, uid;
12416 if (! buf_read_int (core, &ptr, end, &pid)
12417 || ! buf_read_int (core, &ptr, end, &uid))
12418 goto fail;
12419 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
12420 }
12421 }
12422
12423 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12424 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12425 {
12426 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12427 if (data == NULL)
12428 error (EXIT_FAILURE, 0,
12429 _("cannot convert core note data: %s"), elf_errmsg (-1));
12430
12431 unsigned char const *ptr = data->d_buf;
12432 unsigned char const *const end = data->d_buf + data->d_size;
12433
12434 uint64_t count, page_size;
12435 if (! buf_read_ulong (core, &ptr, end, &count)
12436 || ! buf_read_ulong (core, &ptr, end, &page_size))
12437 {
12438 fail:
12439 printf (" Not enough data in NT_FILE note.\n");
12440 return;
12441 }
12442
12443 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12444 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12445 if (count > maxcount)
12446 goto fail;
12447
12448 /* Where file names are stored. */
12449 unsigned char const *const fstart = ptr + 3 * count * addrsize;
12450 char const *fptr = (char *) fstart;
12451
12452 printf (" %" PRId64 " files:\n", count);
12453 for (uint64_t i = 0; i < count; ++i)
12454 {
12455 uint64_t mstart, mend, moffset;
12456 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12457 || ! buf_read_ulong (core, &ptr, fstart, &mend)
12458 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12459 goto fail;
12460
12461 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12462 if (fnext == NULL)
12463 goto fail;
12464
12465 int ct = printf (" %08" PRIx64 "-%08" PRIx64
12466 " %08" PRIx64 " %" PRId64,
12467 mstart, mend, moffset * page_size, mend - mstart);
12468 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12469
12470 fptr = fnext + 1;
12471 }
12472 }
12473
12474 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12475 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12476 const char *name, const void *desc)
12477 {
12478 GElf_Word regs_offset;
12479 size_t nregloc;
12480 const Ebl_Register_Location *reglocs;
12481 size_t nitems;
12482 const Ebl_Core_Item *items;
12483
12484 if (! ebl_core_note (ebl, nhdr, name, desc,
12485 ®s_offset, &nregloc, ®locs, &nitems, &items))
12486 return;
12487
12488 /* Pass 0 for DESCSZ when there are registers in the note,
12489 so that the ITEMS array does not describe the whole thing.
12490 For non-register notes, the actual descsz might be a multiple
12491 of the unit size, not just exactly the unit size. */
12492 unsigned int colno = handle_core_items (ebl->elf, desc,
12493 nregloc == 0 ? nhdr->n_descsz : 0,
12494 items, nitems);
12495 if (colno != 0)
12496 putchar_unlocked ('\n');
12497
12498 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12499 reglocs, nregloc);
12500 if (colno != 0)
12501 putchar_unlocked ('\n');
12502 }
12503
12504 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12505 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12506 GElf_Off start, Elf_Data *data)
12507 {
12508 fputs_unlocked (_(" Owner Data size Type\n"), stdout);
12509
12510 if (data == NULL)
12511 goto bad_note;
12512
12513 size_t offset = 0;
12514 GElf_Nhdr nhdr;
12515 size_t name_offset;
12516 size_t desc_offset;
12517 while (offset < data->d_size
12518 && (offset = gelf_getnote (data, offset,
12519 &nhdr, &name_offset, &desc_offset)) > 0)
12520 {
12521 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12522 const char *desc = data->d_buf + desc_offset;
12523
12524 /* GNU Build Attributes are weird, they store most of their data
12525 into the owner name field. Extract just the owner name
12526 prefix here, then use the rest later as data. */
12527 bool is_gnu_build_attr
12528 = startswith (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX);
12529 const char *print_name = (is_gnu_build_attr
12530 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12531 size_t print_namesz = (is_gnu_build_attr
12532 ? strlen (print_name) : nhdr.n_namesz);
12533
12534 char buf[100];
12535 char buf2[100];
12536 printf (_(" %-13.*s %9" PRId32 " %s\n"),
12537 (int) print_namesz, print_name, nhdr.n_descsz,
12538 ehdr->e_type == ET_CORE
12539 ? ebl_core_note_type_name (ebl, nhdr.n_type,
12540 buf, sizeof (buf))
12541 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12542 nhdr.n_descsz,
12543 buf2, sizeof (buf2)));
12544
12545 /* Filter out invalid entries. */
12546 if (memchr (name, '\0', nhdr.n_namesz) != NULL
12547 /* XXX For now help broken Linux kernels. */
12548 || 1)
12549 {
12550 if (ehdr->e_type == ET_CORE)
12551 {
12552 if (nhdr.n_type == NT_AUXV
12553 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
12554 || (nhdr.n_namesz == 5 && name[4] == '\0'))
12555 && !memcmp (name, "CORE", 4))
12556 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12557 start + desc_offset);
12558 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12559 switch (nhdr.n_type)
12560 {
12561 case NT_SIGINFO:
12562 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12563 start + desc_offset);
12564 break;
12565
12566 case NT_FILE:
12567 handle_file_note (ebl->elf, nhdr.n_descsz,
12568 start + desc_offset);
12569 break;
12570
12571 default:
12572 handle_core_note (ebl, &nhdr, name, desc);
12573 }
12574 else
12575 handle_core_note (ebl, &nhdr, name, desc);
12576 }
12577 else
12578 ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12579 nhdr.n_descsz, desc);
12580 }
12581 }
12582
12583 if (offset == data->d_size)
12584 return;
12585
12586 bad_note:
12587 error (0, 0,
12588 _("cannot get content of note: %s"),
12589 data != NULL ? "garbage data" : elf_errmsg (-1));
12590 }
12591
12592 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12593 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12594 {
12595 /* If we have section headers, just look for SHT_NOTE sections.
12596 In a debuginfo file, the program headers are not reliable. */
12597 if (shnum != 0)
12598 {
12599 /* Get the section header string table index. */
12600 size_t shstrndx;
12601 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12602 error (EXIT_FAILURE, 0,
12603 _("cannot get section header string table index"));
12604
12605 Elf_Scn *scn = NULL;
12606 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12607 {
12608 GElf_Shdr shdr_mem;
12609 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12610
12611 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12612 /* Not what we are looking for. */
12613 continue;
12614
12615 if (notes_section != NULL)
12616 {
12617 char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12618 if (sname == NULL || strcmp (sname, notes_section) != 0)
12619 continue;
12620 }
12621
12622 printf (_("\
12623 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12624 elf_ndxscn (scn),
12625 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12626 shdr->sh_size, shdr->sh_offset);
12627
12628 handle_notes_data (ebl, ehdr, shdr->sh_offset,
12629 elf_getdata (scn, NULL));
12630 }
12631 return;
12632 }
12633
12634 /* We have to look through the program header to find the note
12635 sections. There can be more than one. */
12636 for (size_t cnt = 0; cnt < phnum; ++cnt)
12637 {
12638 GElf_Phdr mem;
12639 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12640
12641 if (phdr == NULL || phdr->p_type != PT_NOTE)
12642 /* Not what we are looking for. */
12643 continue;
12644
12645 printf (_("\
12646 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12647 phdr->p_filesz, phdr->p_offset);
12648
12649 handle_notes_data (ebl, ehdr, phdr->p_offset,
12650 elf_getdata_rawchunk (ebl->elf,
12651 phdr->p_offset, phdr->p_filesz,
12652 (phdr->p_align == 8
12653 ? ELF_T_NHDR8 : ELF_T_NHDR)));
12654 }
12655 }
12656
12657
12658 static void
hex_dump(const uint8_t * data,size_t len)12659 hex_dump (const uint8_t *data, size_t len)
12660 {
12661 size_t pos = 0;
12662 while (pos < len)
12663 {
12664 printf (" 0x%08zx ", pos);
12665
12666 const size_t chunk = MIN (len - pos, 16);
12667
12668 for (size_t i = 0; i < chunk; ++i)
12669 if (i % 4 == 3)
12670 printf ("%02x ", data[pos + i]);
12671 else
12672 printf ("%02x", data[pos + i]);
12673
12674 if (chunk < 16)
12675 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12676
12677 for (size_t i = 0; i < chunk; ++i)
12678 {
12679 unsigned char b = data[pos + i];
12680 printf ("%c", isprint (b) ? b : '.');
12681 }
12682
12683 putchar ('\n');
12684 pos += chunk;
12685 }
12686 }
12687
12688 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12689 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12690 {
12691 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12692 printf (_("\nSection [%zu] '%s' has no data to dump.\n"),
12693 elf_ndxscn (scn), name);
12694 else
12695 {
12696 if (print_decompress)
12697 {
12698 /* We try to decompress the section, but keep the old shdr around
12699 so we can show both the original shdr size and the uncompressed
12700 data size. */
12701 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12702 {
12703 if (elf_compress (scn, 0, 0) < 0)
12704 printf ("WARNING: %s [%zd]\n",
12705 _("Couldn't uncompress section"),
12706 elf_ndxscn (scn));
12707 }
12708 else if (startswith (name, ".zdebug"))
12709 {
12710 if (elf_compress_gnu (scn, 0, 0) < 0)
12711 printf ("WARNING: %s [%zd]\n",
12712 _("Couldn't uncompress section"),
12713 elf_ndxscn (scn));
12714 }
12715 }
12716
12717 Elf_Data *data = elf_rawdata (scn, NULL);
12718 if (data == NULL)
12719 error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
12720 elf_ndxscn (scn), name, elf_errmsg (-1));
12721 else
12722 {
12723 if (data->d_size == shdr->sh_size)
12724 printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
12725 " bytes at offset %#0" PRIx64 ":\n"),
12726 elf_ndxscn (scn), name,
12727 shdr->sh_size, shdr->sh_offset);
12728 else
12729 printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
12730 " bytes (%zd uncompressed) at offset %#0"
12731 PRIx64 ":\n"),
12732 elf_ndxscn (scn), name,
12733 shdr->sh_size, data->d_size, shdr->sh_offset);
12734 hex_dump (data->d_buf, data->d_size);
12735 }
12736 }
12737 }
12738
12739 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12740 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12741 {
12742 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12743 printf (_("\nSection [%zu] '%s' has no strings to dump.\n"),
12744 elf_ndxscn (scn), name);
12745 else
12746 {
12747 if (print_decompress)
12748 {
12749 /* We try to decompress the section, but keep the old shdr around
12750 so we can show both the original shdr size and the uncompressed
12751 data size. */
12752 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12753 {
12754 if (elf_compress (scn, 0, 0) < 0)
12755 printf ("WARNING: %s [%zd]\n",
12756 _("Couldn't uncompress section"),
12757 elf_ndxscn (scn));
12758 }
12759 else if (startswith (name, ".zdebug"))
12760 {
12761 if (elf_compress_gnu (scn, 0, 0) < 0)
12762 printf ("WARNING: %s [%zd]\n",
12763 _("Couldn't uncompress section"),
12764 elf_ndxscn (scn));
12765 }
12766 }
12767
12768 Elf_Data *data = elf_rawdata (scn, NULL);
12769 if (data == NULL)
12770 error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
12771 elf_ndxscn (scn), name, elf_errmsg (-1));
12772 else
12773 {
12774 if (data->d_size == shdr->sh_size)
12775 printf (_("\nString section [%zu] '%s' contains %" PRIu64
12776 " bytes at offset %#0" PRIx64 ":\n"),
12777 elf_ndxscn (scn), name,
12778 shdr->sh_size, shdr->sh_offset);
12779 else
12780 printf (_("\nString section [%zu] '%s' contains %" PRIu64
12781 " bytes (%zd uncompressed) at offset %#0"
12782 PRIx64 ":\n"),
12783 elf_ndxscn (scn), name,
12784 shdr->sh_size, data->d_size, shdr->sh_offset);
12785
12786 const char *start = data->d_buf;
12787 const char *const limit = start + data->d_size;
12788 do
12789 {
12790 const char *end = memchr (start, '\0', limit - start);
12791 const size_t pos = start - (const char *) data->d_buf;
12792 if (unlikely (end == NULL))
12793 {
12794 printf (" [%6zx]- %.*s\n",
12795 pos, (int) (limit - start), start);
12796 break;
12797 }
12798 printf (" [%6zx] %s\n", pos, start);
12799 start = end + 1;
12800 } while (start < limit);
12801 }
12802 }
12803 }
12804
12805 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))12806 for_each_section_argument (Elf *elf, const struct section_argument *list,
12807 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12808 const char *name))
12809 {
12810 /* Get the section header string table index. */
12811 size_t shstrndx;
12812 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12813 error (EXIT_FAILURE, 0,
12814 _("cannot get section header string table index"));
12815
12816 for (const struct section_argument *a = list; a != NULL; a = a->next)
12817 {
12818 Elf_Scn *scn;
12819 GElf_Shdr shdr_mem;
12820 const char *name = NULL;
12821
12822 char *endp = NULL;
12823 unsigned long int shndx = strtoul (a->arg, &endp, 0);
12824 if (endp != a->arg && *endp == '\0')
12825 {
12826 scn = elf_getscn (elf, shndx);
12827 if (scn == NULL)
12828 {
12829 error (0, 0, _("\nsection [%lu] does not exist"), shndx);
12830 continue;
12831 }
12832
12833 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12834 error (EXIT_FAILURE, 0, _("cannot get section header: %s"),
12835 elf_errmsg (-1));
12836 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12837 (*dump) (scn, &shdr_mem, name);
12838 }
12839 else
12840 {
12841 /* Need to look up the section by name. */
12842 scn = NULL;
12843 bool found = false;
12844 while ((scn = elf_nextscn (elf, scn)) != NULL)
12845 {
12846 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12847 continue;
12848 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12849 if (name == NULL)
12850 continue;
12851 if (!strcmp (name, a->arg))
12852 {
12853 found = true;
12854 (*dump) (scn, &shdr_mem, name);
12855 }
12856 }
12857
12858 if (unlikely (!found) && !a->implicit)
12859 error (0, 0, _("\nsection '%s' does not exist"), a->arg);
12860 }
12861 }
12862 }
12863
12864 static void
dump_data(Ebl * ebl)12865 dump_data (Ebl *ebl)
12866 {
12867 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12868 }
12869
12870 static void
dump_strings(Ebl * ebl)12871 dump_strings (Ebl *ebl)
12872 {
12873 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12874 }
12875
12876 static void
print_strings(Ebl * ebl)12877 print_strings (Ebl *ebl)
12878 {
12879 /* Get the section header string table index. */
12880 size_t shstrndx;
12881 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12882 error (EXIT_FAILURE, 0,
12883 _("cannot get section header string table index"));
12884
12885 Elf_Scn *scn;
12886 GElf_Shdr shdr_mem;
12887 const char *name;
12888 scn = NULL;
12889 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12890 {
12891 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12892 continue;
12893
12894 if (shdr_mem.sh_type != SHT_PROGBITS
12895 || !(shdr_mem.sh_flags & SHF_STRINGS))
12896 continue;
12897
12898 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12899 if (name == NULL)
12900 continue;
12901
12902 print_string_section (scn, &shdr_mem, name);
12903 }
12904 }
12905
12906 static void
dump_archive_index(Elf * elf,const char * fname)12907 dump_archive_index (Elf *elf, const char *fname)
12908 {
12909 size_t narsym;
12910 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12911 if (arsym == NULL)
12912 {
12913 int result = elf_errno ();
12914 if (unlikely (result != ELF_E_NO_INDEX))
12915 error (EXIT_FAILURE, 0,
12916 _("cannot get symbol index of archive '%s': %s"),
12917 fname, elf_errmsg (result));
12918 else
12919 printf (_("\nArchive '%s' has no symbol index\n"), fname);
12920 return;
12921 }
12922
12923 printf (_("\nIndex of archive '%s' has %zu entries:\n"),
12924 fname, narsym);
12925
12926 size_t as_off = 0;
12927 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12928 {
12929 if (s->as_off != as_off)
12930 {
12931 as_off = s->as_off;
12932
12933 Elf *subelf = NULL;
12934 if (unlikely (elf_rand (elf, as_off) == 0)
12935 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12936 == NULL))
12937 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12938 while (1)
12939 #endif
12940 error (EXIT_FAILURE, 0,
12941 _("cannot extract member at offset %zu in '%s': %s"),
12942 as_off, fname, elf_errmsg (-1));
12943
12944 const Elf_Arhdr *h = elf_getarhdr (subelf);
12945
12946 printf (_("Archive member '%s' contains:\n"), h->ar_name);
12947
12948 elf_end (subelf);
12949 }
12950
12951 printf ("\t%s\n", s->as_name);
12952 }
12953 }
12954
12955 #include "debugpred.h"
12956