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